From 3981a52286ad97c1b3241d69fd302bf3193fefc8 Mon Sep 17 00:00:00 2001 From: "junwei.gu" Date: Wed, 12 Jul 2023 19:23:35 +0800 Subject: [PATCH] demo(examples): update native example --- README.md | 15 +- dist/index.js | 25498 +++++++++++++++++------------- example/mesh/instance.html | 7 +- example/mesh/skybox.html | 2 +- example/native/cube1.html | 8 +- example/native/model.html | 10 +- example/native/particles.html | 95 +- example/native/textureCube.html | 8 +- package.json | 2 +- 9 files changed, 14908 insertions(+), 10737 deletions(-) diff --git a/README.md b/README.md index 7ce42df..ef997e7 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,16 @@ ## install -- `npm install` +- `npm i @gengine-js/gengine` ## build -- `npm run dev` +- `npm install` + +- `npm run build` ## Usage - ``` - ``` ## Native @@ -188,12 +188,6 @@ init(); - - -``` - ## feature - [✔] Camera @@ -230,4 +224,3 @@ 2. Complete core glTF 2.0 3. Text and Sprite 4. Pick -``` diff --git a/dist/index.js b/dist/index.js index ea0d832..e485fb7 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,796 +1,1080 @@ -var e, - t, - i, - r, - n, - s, - a, - o, - c, - l, - h, - u, - f, - d, - m, - p, - g, - x, - v, - y, - S, - b, - w, - T, - E, - M, - U, - _, - L, - C, - R, - A, - D, - z, - I, - P, - N, - B, - O, - V, - F; -!(function (e) { - e.SRGB = "srgb"; -})(e || (e = {})), - (function (e) { - (e.LowPower = "low-power"), (e.HighPerformance = "high-performance"); - })(t || (t = {})), - (function (e) { - (e.DepthClipControl = "depth-clip-control"), - (e.Depth24UnormStencil8 = "depth24unorm-stencil8"), - (e.Depth32FloatStencil8 = "depth32float-stencil8"), - (e.TextureCompressionBC = "texture-compression-bc"), - (e.TextureCompressionETC2 = "texture-compression-etc2"), - (e.TextureCompressionASTC = "texture-compression-astc"), - (e.TimestampQuery = "timestamp-query"), - (e.IndirectFirstInstance = "indirect-first-instance"), - (e.ShaderF16 = "shader-f16"), - (e.BGRA8UnormStorage = "bgra8unorm-storage"); - })(i || (i = {})), - (function (e) { - (e[(e.MapRead = 1)] = "MapRead"), - (e[(e.MapWrite = 2)] = "MapWrite"), - (e[(e.CopySrc = 4)] = "CopySrc"), - (e[(e.CopyDst = 8)] = "CopyDst"), - (e[(e.Index = 16)] = "Index"), - (e[(e.Vertex = 32)] = "Vertex"), - (e[(e.Uniform = 64)] = "Uniform"), - (e[(e.Storage = 128)] = "Storage"), - (e[(e.Indirect = 256)] = "Indirect"), - (e[(e.QueryResolve = 512)] = "QueryResolve"); - })(r || (r = {})), - (function (e) { - (e[(e.Read = 1)] = "Read"), (e[(e.Write = 2)] = "Write"); - })(n || (n = {})), - (function (e) { - (e.E1d = "1d"), (e.E2d = "2d"), (e.E3d = "3d"); - })(s || (s = {})), - (function (e) { - (e[(e.CopySrc = 1)] = "CopySrc"), - (e[(e.CopyDst = 2)] = "CopyDst"), - (e[(e.TextureBinding = 4)] = "TextureBinding"), - (e[(e.StorageBinding = 8)] = "StorageBinding"), - (e[(e.RenderAttachment = 16)] = "RenderAttachment"); - })(a || (a = {})), - (function (e) { - (e.E1d = "1d"), - (e.E2d = "2d"), - (e.E2dArray = "2d-array"), - (e.Cube = "cube"), - (e.CubeArray = "cube-array"), - (e.E3d = "3d"); - })(o || (o = {})), - (function (e) { - (e.All = "all"), (e.StencilOnly = "stencil-only"), (e.DepthOnly = "depth-only"); - })(c || (c = {})), - (function (e) { - (e.R8Unorm = "r8unorm"), - (e.R8Snorm = "r8snorm"), - (e.R8Uint = "r8uint"), - (e.R8Sint = "r8sint"), - (e.R16Uint = "r16uint"), - (e.R16Sint = "r16sint"), - (e.R16Float = "r16float"), - (e.RG8Unorm = "rg8unorm"), - (e.RG8Snorm = "rg8snorm"), - (e.RG8Uint = "rg8uint"), - (e.RG8Sint = "rg8sint"), - (e.R32Uint = "r32uint"), - (e.R32Sint = "r32sint"), - (e.R32Float = "r32float"), - (e.RG16Uint = "rg16uint"), - (e.RG16Sint = "rg16sint"), - (e.RG16Float = "rg16float"), - (e.RGBA8Unorm = "rgba8unorm"), - (e.RGBA8UnormSRGB = "rgba8unorm-srgb"), - (e.RGBA8Snorm = "rgba8snorm"), - (e.RGBA8Uint = "rgba8uint"), - (e.RGBA8Sint = "rgba8sint"), - (e.BGRA8Unorm = "bgra8unorm"), - (e.BGRA8UnormSRGB = "bgra8unorm-srgb"), - (e.RGB9E5UFloat = "rgb9e5ufloat"), - (e.RGB10A2Unorm = "rgb10a2unorm"), - (e.RG11B10UFloat = "rg11b10ufloat"), - (e.RG32Uint = "rg32uint"), - (e.RG32Sint = "rg32sint"), - (e.RG32Float = "rg32float"), - (e.RGBA16Uint = "rgba16uint"), - (e.RGBA16Sint = "rgba16sint"), - (e.RGBA16Float = "rgba16float"), - (e.RGBA32Uint = "rgba32uint"), - (e.RGBA32Sint = "rgba32sint"), - (e.RGBA32Float = "rgba32float"), - (e.Stencil8 = "stencil8"), - (e.Depth16Unorm = "depth16unorm"), - (e.Depth24Plus = "depth24plus"), - (e.Depth24PlusStencil8 = "depth24plus-stencil8"), - (e.Depth32Float = "depth32float"), - (e.BC1RGBAUnorm = "bc1-rgba-unorm"), - (e.BC1RGBAUnormSRGB = "bc1-rgba-unorm-srgb"), - (e.BC2RGBAUnorm = "bc2-rgba-unorm"), - (e.BC2RGBAUnormSRGB = "bc2-rgba-unorm-srgb"), - (e.BC3RGBAUnorm = "bc3-rgba-unorm"), - (e.BC3RGBAUnormSRGB = "bc3-rgba-unorm-srgb"), - (e.BC4RUnorm = "bc4-r-unorm"), - (e.BC4RSnorm = "bc4-r-snorm"), - (e.BC5RGUnorm = "bc5-rg-unorm"), - (e.BC5RGSnorm = "bc5-rg-snorm"), - (e.BC6HRGBUFloat = "bc6h-rgb-ufloat"), - (e.BC6HRGBFloat = "bc6h-rgb-float"), - (e.BC7RGBAUnorm = "bc7-rgba-unorm"), - (e.BC7RGBAUnormSRGB = "bc7-rgba-unorm-srgb"), - (e.ETC2RGB8Unorm = "etc2-rgb8unorm"), - (e.ETC2RGB8UnormSRGB = "etc2-rgb8unorm-srgb"), - (e.ETC2RGB8A1Unorm = "etc2-rgb8a1unorm"), - (e.ETC2RGB8A1UnormSRGB = "etc2-rgb8a1unorm-srgb"), - (e.ETC2RGBA8Unorm = "etc2-rgba8unorm"), - (e.ETC2RGBA8UnormSRGB = "etc2-rgba8unorm-srgb"), - (e.EACR11Unorm = "eac-r11unorm"), - (e.EACR11Snorm = "eac-r11snorm"), - (e.EACRG11Unorm = "eac-rg11unorm"), - (e.EACRG11Snorm = "eac-rg11snorm"), - (e.ASTC4x4Unorm = "astc-4x4-unorm"), - (e.ASTC4x4UnormSRGB = "astc-4x4-unorm-srgb"), - (e.ASTC5x4Unorm = "astc-5x4-unorm"), - (e.ASTC5x4UnormSRGB = "astc-5x4-unorm-srgb"), - (e.ASTC5x5Unorm = "astc-5x5-unorm"), - (e.ASTC5x5UnormSRGB = "astc-5x5-unorm-srgb"), - (e.ASTC6x5Unorm = "astc-6x5-unorm"), - (e.ASTC6x5UnormSRGB = "astc-6x5-unorm-srgb"), - (e.ASTC6x6Unorm = "astc-6x6-unorm"), - (e.ASTC6x6UnormSRGB = "astc-6x6-unorm-srgb"), - (e.ASTC8x5Unorm = "astc-8x5-unorm"), - (e.ASTC8x5UnormSRGB = "astc-8x5-unorm-srgb"), - (e.ASTC8x6Unorm = "astc-8x6-unorm"), - (e.ASTC8x6UnormSRGB = "astc-8x6-unorm-srgb"), - (e.ASTC8x8Unorm = "astc-8x8-unorm"), - (e.ASTC8x8UnormSRGB = "astc-8x8-unorm-srgb"), - (e.ASTC10x5Unorm = "astc-10x5-unorm"), - (e.ASTC10x5UnormSRGB = "astc-10x5-unorm-srgb"), - (e.ASTC10x6Unorm = "astc-10x6-unorm"), - (e.ASTC10x6UnormSRGB = "astc-10x6-unorm-srgb"), - (e.ASTC10x8Unorm = "astc-10x8-unorm"), - (e.ASTC10x8UnormSRGB = "astc-10x8-unorm-srgb"), - (e.ASTC10x10Unorm = "astc-10x10-unorm"), - (e.ASTC10x10UnormSRGB = "astc-10x10-unorm-srgb"), - (e.ASTC12x10Unorm = "astc-12x10-unorm"), - (e.ASTC12x10UnormSRGB = "astc-12x10-unorm-srgb"), - (e.ASTC12x12Unorm = "astc-12x12-unorm"), - (e.ASTC12x12UnormSRGB = "astc-12x12-unorm-srgb"), - (e.Depth24UnormStencil8 = "depth24unorm-stencil8"), - (e.Depth32FloatStencil8 = "depth32float-stencil8"); - })(l || (l = {})), - (function (e) { - (e.ClampToEdge = "clamp-to-edge"), (e.Repeat = "repeat"), (e.MirrorRepeat = "mirror-repeat"); - })(h || (h = {})), - (function (e) { - (e.Nearest = "nearest"), (e.Linear = "linear"); - })(u || (u = {})), - (function (e) { - (e.Never = "never"), - (e.Less = "less"), - (e.Equal = "equal"), - (e.LessEqual = "less-equal"), - (e.Greater = "greater"), - (e.NotEqual = "not-equal"), - (e.GreaterEqual = "greater-equal"), - (e.Always = "always"); - })(f || (f = {})), - (function (e) { - (e[(e.Vertex = 1)] = "Vertex"), (e[(e.Fragment = 2)] = "Fragment"), (e[(e.Compute = 4)] = "Compute"); - })(d || (d = {})), - (function (e) { - (e.Uniform = "uniform"), (e.Storage = "storage"), (e.ReadOnlyStorage = "read-only-storage"); - })(m || (m = {})), - (function (e) { - (e.Filtering = "filtering"), (e.NonFiltering = "non-filtering"), (e.Comparison = "comparison"); - })(p || (p = {})), - (function (e) { - (e.Float = "float"), - (e.UnfilterableFloat = "unfilterable-float"), - (e.Depth = "depth"), - (e.Sint = "sint"), - (e.Uint = "uint"); - })(g || (g = {})), - (function (e) { - e.WriteOnly = "write-only"; - })(x || (x = {})), - (function (e) { - (e.Error = "error"), (e.Warning = "warning"), (e.Info = "info"); - })(v || (v = {})), - (function (e) { - e.Auto = "auto"; - })(y || (y = {})), - (function (e) { - (e.PointList = "point-list"), - (e.LineList = "line-list"), - (e.LineStrip = "line-strip"), - (e.TriangleList = "triangle-list"), - (e.TriangleStrip = "triangle-strip"); - })(S || (S = {})), - (function (e) { - (e.CCW = "ccw"), (e.CW = "cw"); - })(b || (b = {})), - (function (e) { - (e.None = "none"), (e.Front = "front"), (e.Back = "back"); - })(w || (w = {})), - (function (e) { - (e[(e.Red = 1)] = "Red"), - (e[(e.Green = 2)] = "Green"), - (e[(e.Blue = 4)] = "Blue"), - (e[(e.Alpha = 8)] = "Alpha"), - (e[(e.All = 15)] = "All"); - })(T || (T = {})), - (function (e) { - (e.Zero = "zero"), - (e.One = "one"), - (e.Src = "src"), - (e.OneMinusSrc = "one-minus-src"), - (e.SrcAlpha = "src-alpha"), - (e.OneMinusSrcAlpha = "one-minus-src-alpha"), - (e.Dst = "dst"), - (e.OneMinusDst = "one-minus-dst"), - (e.DstAlpha = "dst-alpha"), - (e.OneMinusDstAlpha = "one-minus-dst-alpha"), - (e.SrcAlphaSaturated = "src-alpha-saturated"), - (e.Constant = "constant"), - (e.OneMinusConstant = "one-minus-constant"); - })(E || (E = {})), - (function (e) { - (e.Add = "add"), - (e.Subtract = "subtract"), - (e.ReverseSubtract = "reverse-subtract"), - (e.Min = "min"), - (e.Max = "max"); - })(M || (M = {})), - (function (e) { - (e.Keep = "keep"), - (e.Zero = "zero"), - (e.Replace = "replace"), - (e.Invert = "invert"), - (e.IncrementClamp = "increment-clamp"), - (e.DecrementClamp = "decrement-clamp"), - (e.IncrementWrap = "increment-wrap"), - (e.DecrementWrap = "decrement-wrap"); - })(U || (U = {})), - (function (e) { - (e.Uint16 = "uint16"), (e.Uint32 = "uint32"); - })(_ || (_ = {})), - (function (e) { - (e.Uint8x2 = "uint8x2"), - (e.Uint8x4 = "uint8x4"), - (e.Sint8x2 = "sint8x2"), - (e.Sint8x4 = "sint8x4"), - (e.Unorm8x2 = "unorm8x2"), - (e.Unorm8x4 = "unorm8x4"), - (e.Snorm8x2 = "snorm8x2"), - (e.Snorm8x4 = "snorm8x4"), - (e.Uint16x2 = "uint16x2"), - (e.Uint16x4 = "uint16x4"), - (e.Sint16x2 = "sint16x2"), - (e.Sint16x4 = "sint16x4"), - (e.Unorm16x2 = "unorm16x2"), - (e.Unorm16x4 = "unorm16x4"), - (e.Snorm16x2 = "snorm16x2"), - (e.Snorm16x4 = "snorm16x4"), - (e.Float16x2 = "float16x2"), - (e.Float16x4 = "float16x4"), - (e.Float32 = "float32"), - (e.Float32x2 = "float32x2"), - (e.Float32x3 = "float32x3"), - (e.Float32x4 = "float32x4"), - (e.Uint32 = "uint32"), - (e.Uint32x2 = "uint32x2"), - (e.Uint32x3 = "uint32x3"), - (e.Uint32x4 = "uint32x4"), - (e.Sint32 = "sint32"), - (e.Sint32x2 = "sint32x2"), - (e.Sint32x3 = "sint32x3"), - (e.Sint32x4 = "sint32x4"); - })(L || (L = {})), - (function (e) { - (e.Vertex = "vertex"), (e.Instance = "instance"); - })(C || (C = {})), - (function (e) { - (e.Beginning = "beginning"), (e.End = "end"); - })(R || (R = {})), - (function (e) { - (e.Beginning = "beginning"), (e.End = "end"); - })(A || (A = {})), - (function (e) { - (e.Load = "load"), (e.Clear = "clear"); - })(D || (D = {})), - (function (e) { - (e.Store = "store"), (e.Discard = "discard"); - })(z || (z = {})), - (function (e) { - (e.Occlusion = "occlusion"), (e.Timestamp = "timestamp"); - })(I || (I = {})), - (function (e) { - (e.Opaque = "opaque"), (e.Premultiplied = "premultiplied"); - })(P || (P = {})), - (function (e) { - e.Destroyed = "destroyed"; - })(N || (N = {})), - (function (e) { - (e.OutOfMemory = "out-of-memory"), (e.Validation = "validation"); - })(B || (B = {})), - (function (e) { - (e[(e.Red = 1)] = "Red"), - (e[(e.Green = 2)] = "Green"), - (e[(e.Blue = 4)] = "Blue"), - (e[(e.Alpha = 8)] = "Alpha"), - (e[(e.All = 15)] = "All"); - })(O || (O = {})), - (function (e) { - (e.Shadow = "shadow"), (e.Pick = "pick"); - })(V || (V = {})), - (function (e) { - (e[(e.OUTSIDE = -1)] = "OUTSIDE"), (e[(e.INTERSECTING = 0)] = "INTERSECTING"), (e[(e.INSIDE = 1)] = "INSIDE"); - })(F || (F = {})); -class $ { - constructor(e, t, i, r, n) { - (this.device = t), - (this.usage = i), - (this.data = r), - (this.size = null != n ? (n + 3) & -4 : (r.byteLength + 3) & -4), - (this.gpuBuffer = t.createBuffer({ label: e || "", size: this.size, usage: i })), - r && this.setSubData(0, r, this.size); - } - static create(e, t, i, r, n) { - return new $(e, t, i, r, n); - } - static createVertexBuffer(e, t, i) { - return new $(e, t, r.Vertex | r.CopyDst, i, i.byteLength); - } - static createIndexBuffer(e, t, i) { - return new $(e, t, r.Index | r.CopyDst, i); - } - static createUniformBuffer(e, t, i, r) { - return new $(e, t, r, null, i); - } - static createStorageBuffer(e, t, i, n = r.Storage) { - return new $(e, t, n, null, i); - } - setSubData(e, t, i) { - const r = t.buffer, - n = i ?? r.byteLength, - s = this.device.createBuffer({ mappedAtCreation: !0, size: n, usage: GPUBufferUsage.COPY_SRC }), - a = s.getMappedRange(); - new Uint16Array(a).set(new Uint16Array(r)), s.unmap(), this.copyToBuffer(s, e, n), s.destroy(); - } - copyToBuffer(e, t, i) { - const r = this.device.createCommandEncoder(); - r.copyBufferToBuffer(e, 0, this.gpuBuffer, t, i), this.device.queue.submit([r.finish()]); - } - copyToTexture(e, t, i, r) { - const n = this.device.createCommandEncoder(); - n.copyBufferToTexture({ buffer: this.gpuBuffer, bytesPerRow: e, rowsPerImage: t }, i, r), - this.device.queue.submit([n.finish()]); +/** @internal */ +var PredefinedColorSpace; +(function (PredefinedColorSpace) { + PredefinedColorSpace["SRGB"] = "srgb"; +})(PredefinedColorSpace || (PredefinedColorSpace = {})); +/** @internal */ +var PowerPreference; +(function (PowerPreference) { + PowerPreference["LowPower"] = "low-power"; + PowerPreference["HighPerformance"] = "high-performance"; +})(PowerPreference || (PowerPreference = {})); +/** @internal */ +var FeatureName; +(function (FeatureName) { + FeatureName["DepthClipControl"] = "depth-clip-control"; + FeatureName["Depth24UnormStencil8"] = "depth24unorm-stencil8"; + FeatureName["Depth32FloatStencil8"] = "depth32float-stencil8"; + FeatureName["TextureCompressionBC"] = "texture-compression-bc"; + FeatureName["TextureCompressionETC2"] = "texture-compression-etc2"; + FeatureName["TextureCompressionASTC"] = "texture-compression-astc"; + FeatureName["TimestampQuery"] = "timestamp-query"; + FeatureName["IndirectFirstInstance"] = "indirect-first-instance"; + FeatureName["ShaderF16"] = "shader-f16"; + FeatureName["BGRA8UnormStorage"] = "bgra8unorm-storage"; +})(FeatureName || (FeatureName = {})); +/** @internal */ +var BufferUsage; +(function (BufferUsage) { + BufferUsage[(BufferUsage["MapRead"] = 1)] = "MapRead"; + BufferUsage[(BufferUsage["MapWrite"] = 2)] = "MapWrite"; + BufferUsage[(BufferUsage["CopySrc"] = 4)] = "CopySrc"; + BufferUsage[(BufferUsage["CopyDst"] = 8)] = "CopyDst"; + BufferUsage[(BufferUsage["Index"] = 16)] = "Index"; + BufferUsage[(BufferUsage["Vertex"] = 32)] = "Vertex"; + BufferUsage[(BufferUsage["Uniform"] = 64)] = "Uniform"; + BufferUsage[(BufferUsage["Storage"] = 128)] = "Storage"; + BufferUsage[(BufferUsage["Indirect"] = 256)] = "Indirect"; + BufferUsage[(BufferUsage["QueryResolve"] = 512)] = "QueryResolve"; +})(BufferUsage || (BufferUsage = {})); +/** @internal */ +var MapMode; +(function (MapMode) { + MapMode[(MapMode["Read"] = 1)] = "Read"; + MapMode[(MapMode["Write"] = 2)] = "Write"; +})(MapMode || (MapMode = {})); +/** @internal */ +var TextureDimension; +(function (TextureDimension) { + TextureDimension["E1d"] = "1d"; + TextureDimension["E2d"] = "2d"; + TextureDimension["E3d"] = "3d"; +})(TextureDimension || (TextureDimension = {})); +/** @internal */ +var TextureUsage; +(function (TextureUsage) { + TextureUsage[(TextureUsage["CopySrc"] = 1)] = "CopySrc"; + TextureUsage[(TextureUsage["CopyDst"] = 2)] = "CopyDst"; + TextureUsage[(TextureUsage["TextureBinding"] = 4)] = "TextureBinding"; + TextureUsage[(TextureUsage["StorageBinding"] = 8)] = "StorageBinding"; + TextureUsage[(TextureUsage["RenderAttachment"] = 16)] = "RenderAttachment"; +})(TextureUsage || (TextureUsage = {})); +/** @internal */ +var TextureViewDimension; +(function (TextureViewDimension) { + TextureViewDimension["E1d"] = "1d"; + TextureViewDimension["E2d"] = "2d"; + TextureViewDimension["E2dArray"] = "2d-array"; + TextureViewDimension["Cube"] = "cube"; + TextureViewDimension["CubeArray"] = "cube-array"; + TextureViewDimension["E3d"] = "3d"; +})(TextureViewDimension || (TextureViewDimension = {})); +/** @internal */ +var TextureAspect; +(function (TextureAspect) { + TextureAspect["All"] = "all"; + TextureAspect["StencilOnly"] = "stencil-only"; + TextureAspect["DepthOnly"] = "depth-only"; +})(TextureAspect || (TextureAspect = {})); +/** + * Comments taken from https://github.com/gfx-rs/wgpu/blob/master/wgpu-types/src/lib.rs + * @internal + */ +var TextureFormat; +(function (TextureFormat) { + // 8-bit formats + TextureFormat["R8Unorm"] = "r8unorm"; + TextureFormat["R8Snorm"] = "r8snorm"; + TextureFormat["R8Uint"] = "r8uint"; + TextureFormat["R8Sint"] = "r8sint"; + // 16-bit formats + TextureFormat["R16Uint"] = "r16uint"; + TextureFormat["R16Sint"] = "r16sint"; + TextureFormat["R16Float"] = "r16float"; + TextureFormat["RG8Unorm"] = "rg8unorm"; + TextureFormat["RG8Snorm"] = "rg8snorm"; + TextureFormat["RG8Uint"] = "rg8uint"; + TextureFormat["RG8Sint"] = "rg8sint"; + // 32-bit formats + TextureFormat["R32Uint"] = "r32uint"; + TextureFormat["R32Sint"] = "r32sint"; + TextureFormat["R32Float"] = "r32float"; + TextureFormat["RG16Uint"] = "rg16uint"; + TextureFormat["RG16Sint"] = "rg16sint"; + TextureFormat["RG16Float"] = "rg16float"; + TextureFormat["RGBA8Unorm"] = "rgba8unorm"; + TextureFormat["RGBA8UnormSRGB"] = "rgba8unorm-srgb"; + TextureFormat["RGBA8Snorm"] = "rgba8snorm"; + TextureFormat["RGBA8Uint"] = "rgba8uint"; + TextureFormat["RGBA8Sint"] = "rgba8sint"; + TextureFormat["BGRA8Unorm"] = "bgra8unorm"; + TextureFormat["BGRA8UnormSRGB"] = "bgra8unorm-srgb"; + // Packed 32-bit formats + TextureFormat["RGB9E5UFloat"] = "rgb9e5ufloat"; + TextureFormat["RGB10A2Unorm"] = "rgb10a2unorm"; + TextureFormat["RG11B10UFloat"] = "rg11b10ufloat"; + // 64-bit formats + TextureFormat["RG32Uint"] = "rg32uint"; + TextureFormat["RG32Sint"] = "rg32sint"; + TextureFormat["RG32Float"] = "rg32float"; + TextureFormat["RGBA16Uint"] = "rgba16uint"; + TextureFormat["RGBA16Sint"] = "rgba16sint"; + TextureFormat["RGBA16Float"] = "rgba16float"; + // 128-bit formats + TextureFormat["RGBA32Uint"] = "rgba32uint"; + TextureFormat["RGBA32Sint"] = "rgba32sint"; + TextureFormat["RGBA32Float"] = "rgba32float"; + // Depth and stencil formats + TextureFormat["Stencil8"] = "stencil8"; + TextureFormat["Depth16Unorm"] = "depth16unorm"; + TextureFormat["Depth24Plus"] = "depth24plus"; + TextureFormat["Depth24PlusStencil8"] = "depth24plus-stencil8"; + TextureFormat["Depth32Float"] = "depth32float"; + // BC compressed formats usable if "texture-compression-bc" is both + // supported by the device/user agent and enabled in requestDevice. + TextureFormat["BC1RGBAUnorm"] = "bc1-rgba-unorm"; + TextureFormat["BC1RGBAUnormSRGB"] = "bc1-rgba-unorm-srgb"; + TextureFormat["BC2RGBAUnorm"] = "bc2-rgba-unorm"; + TextureFormat["BC2RGBAUnormSRGB"] = "bc2-rgba-unorm-srgb"; + TextureFormat["BC3RGBAUnorm"] = "bc3-rgba-unorm"; + TextureFormat["BC3RGBAUnormSRGB"] = "bc3-rgba-unorm-srgb"; + TextureFormat["BC4RUnorm"] = "bc4-r-unorm"; + TextureFormat["BC4RSnorm"] = "bc4-r-snorm"; + TextureFormat["BC5RGUnorm"] = "bc5-rg-unorm"; + TextureFormat["BC5RGSnorm"] = "bc5-rg-snorm"; + TextureFormat["BC6HRGBUFloat"] = "bc6h-rgb-ufloat"; + TextureFormat["BC6HRGBFloat"] = "bc6h-rgb-float"; + TextureFormat["BC7RGBAUnorm"] = "bc7-rgba-unorm"; + TextureFormat["BC7RGBAUnormSRGB"] = "bc7-rgba-unorm-srgb"; + // ETC2 compressed formats usable if "texture-compression-etc2" is both + // supported by the device/user agent and enabled in requestDevice. + TextureFormat["ETC2RGB8Unorm"] = "etc2-rgb8unorm"; + TextureFormat["ETC2RGB8UnormSRGB"] = "etc2-rgb8unorm-srgb"; + TextureFormat["ETC2RGB8A1Unorm"] = "etc2-rgb8a1unorm"; + TextureFormat["ETC2RGB8A1UnormSRGB"] = "etc2-rgb8a1unorm-srgb"; + TextureFormat["ETC2RGBA8Unorm"] = "etc2-rgba8unorm"; + TextureFormat["ETC2RGBA8UnormSRGB"] = "etc2-rgba8unorm-srgb"; + TextureFormat["EACR11Unorm"] = "eac-r11unorm"; + TextureFormat["EACR11Snorm"] = "eac-r11snorm"; + TextureFormat["EACRG11Unorm"] = "eac-rg11unorm"; + TextureFormat["EACRG11Snorm"] = "eac-rg11snorm"; + // ASTC compressed formats usable if "texture-compression-astc" is both + // supported by the device/user agent and enabled in requestDevice. + TextureFormat["ASTC4x4Unorm"] = "astc-4x4-unorm"; + TextureFormat["ASTC4x4UnormSRGB"] = "astc-4x4-unorm-srgb"; + TextureFormat["ASTC5x4Unorm"] = "astc-5x4-unorm"; + TextureFormat["ASTC5x4UnormSRGB"] = "astc-5x4-unorm-srgb"; + TextureFormat["ASTC5x5Unorm"] = "astc-5x5-unorm"; + TextureFormat["ASTC5x5UnormSRGB"] = "astc-5x5-unorm-srgb"; + TextureFormat["ASTC6x5Unorm"] = "astc-6x5-unorm"; + TextureFormat["ASTC6x5UnormSRGB"] = "astc-6x5-unorm-srgb"; + TextureFormat["ASTC6x6Unorm"] = "astc-6x6-unorm"; + TextureFormat["ASTC6x6UnormSRGB"] = "astc-6x6-unorm-srgb"; + TextureFormat["ASTC8x5Unorm"] = "astc-8x5-unorm"; + TextureFormat["ASTC8x5UnormSRGB"] = "astc-8x5-unorm-srgb"; + TextureFormat["ASTC8x6Unorm"] = "astc-8x6-unorm"; + TextureFormat["ASTC8x6UnormSRGB"] = "astc-8x6-unorm-srgb"; + TextureFormat["ASTC8x8Unorm"] = "astc-8x8-unorm"; + TextureFormat["ASTC8x8UnormSRGB"] = "astc-8x8-unorm-srgb"; + TextureFormat["ASTC10x5Unorm"] = "astc-10x5-unorm"; + TextureFormat["ASTC10x5UnormSRGB"] = "astc-10x5-unorm-srgb"; + TextureFormat["ASTC10x6Unorm"] = "astc-10x6-unorm"; + TextureFormat["ASTC10x6UnormSRGB"] = "astc-10x6-unorm-srgb"; + TextureFormat["ASTC10x8Unorm"] = "astc-10x8-unorm"; + TextureFormat["ASTC10x8UnormSRGB"] = "astc-10x8-unorm-srgb"; + TextureFormat["ASTC10x10Unorm"] = "astc-10x10-unorm"; + TextureFormat["ASTC10x10UnormSRGB"] = "astc-10x10-unorm-srgb"; + TextureFormat["ASTC12x10Unorm"] = "astc-12x10-unorm"; + TextureFormat["ASTC12x10UnormSRGB"] = "astc-12x10-unorm-srgb"; + TextureFormat["ASTC12x12Unorm"] = "astc-12x12-unorm"; + TextureFormat["ASTC12x12UnormSRGB"] = "astc-12x12-unorm-srgb"; + // "depth24unorm-stencil8" feature + TextureFormat["Depth24UnormStencil8"] = "depth24unorm-stencil8"; + // "depth32float-stencil8" feature + TextureFormat["Depth32FloatStencil8"] = "depth32float-stencil8"; +})(TextureFormat || (TextureFormat = {})); +/** @internal */ +var AddressMode; +(function (AddressMode) { + AddressMode["ClampToEdge"] = "clamp-to-edge"; + AddressMode["Repeat"] = "repeat"; + AddressMode["MirrorRepeat"] = "mirror-repeat"; +})(AddressMode || (AddressMode = {})); +/** @internal */ +var FilterMode; +(function (FilterMode) { + FilterMode["Nearest"] = "nearest"; + FilterMode["Linear"] = "linear"; +})(FilterMode || (FilterMode = {})); +/** @internal */ +var CompareFunction; +(function (CompareFunction) { + CompareFunction["Never"] = "never"; + CompareFunction["Less"] = "less"; + CompareFunction["Equal"] = "equal"; + CompareFunction["LessEqual"] = "less-equal"; + CompareFunction["Greater"] = "greater"; + CompareFunction["NotEqual"] = "not-equal"; + CompareFunction["GreaterEqual"] = "greater-equal"; + CompareFunction["Always"] = "always"; +})(CompareFunction || (CompareFunction = {})); +/** @internal */ +var ShaderStage; +(function (ShaderStage) { + ShaderStage[(ShaderStage["Vertex"] = 1)] = "Vertex"; + ShaderStage[(ShaderStage["Fragment"] = 2)] = "Fragment"; + ShaderStage[(ShaderStage["Compute"] = 4)] = "Compute"; +})(ShaderStage || (ShaderStage = {})); +/** @internal */ +var BufferBindingType; +(function (BufferBindingType) { + BufferBindingType["Uniform"] = "uniform"; + BufferBindingType["Storage"] = "storage"; + BufferBindingType["ReadOnlyStorage"] = "read-only-storage"; +})(BufferBindingType || (BufferBindingType = {})); +/** @internal */ +var SamplerBindingType; +(function (SamplerBindingType) { + SamplerBindingType["Filtering"] = "filtering"; + SamplerBindingType["NonFiltering"] = "non-filtering"; + SamplerBindingType["Comparison"] = "comparison"; +})(SamplerBindingType || (SamplerBindingType = {})); +/** @internal */ +var TextureSampleType; +(function (TextureSampleType) { + TextureSampleType["Float"] = "float"; + TextureSampleType["UnfilterableFloat"] = "unfilterable-float"; + TextureSampleType["Depth"] = "depth"; + TextureSampleType["Sint"] = "sint"; + TextureSampleType["Uint"] = "uint"; +})(TextureSampleType || (TextureSampleType = {})); +/** @internal */ +var StorageTextureAccess; +(function (StorageTextureAccess) { + StorageTextureAccess["WriteOnly"] = "write-only"; +})(StorageTextureAccess || (StorageTextureAccess = {})); +/** @internal */ +var CompilationMessageType; +(function (CompilationMessageType) { + CompilationMessageType["Error"] = "error"; + CompilationMessageType["Warning"] = "warning"; + CompilationMessageType["Info"] = "info"; +})(CompilationMessageType || (CompilationMessageType = {})); +/** @internal */ +var AutoLayoutMode; +(function (AutoLayoutMode) { + AutoLayoutMode["Auto"] = "auto"; +})(AutoLayoutMode || (AutoLayoutMode = {})); +/** @internal */ +var PrimitiveTopology; +(function (PrimitiveTopology) { + PrimitiveTopology["PointList"] = "point-list"; + PrimitiveTopology["LineList"] = "line-list"; + PrimitiveTopology["LineStrip"] = "line-strip"; + PrimitiveTopology["TriangleList"] = "triangle-list"; + PrimitiveTopology["TriangleStrip"] = "triangle-strip"; +})(PrimitiveTopology || (PrimitiveTopology = {})); +/** @internal */ +var FrontFace; +(function (FrontFace) { + FrontFace["CCW"] = "ccw"; + FrontFace["CW"] = "cw"; +})(FrontFace || (FrontFace = {})); +/** @internal */ +var CullMode; +(function (CullMode) { + CullMode["None"] = "none"; + CullMode["Front"] = "front"; + CullMode["Back"] = "back"; +})(CullMode || (CullMode = {})); +/** @internal */ +var ColorWriteFlags; +(function (ColorWriteFlags) { + ColorWriteFlags[(ColorWriteFlags["Red"] = 1)] = "Red"; + ColorWriteFlags[(ColorWriteFlags["Green"] = 2)] = "Green"; + ColorWriteFlags[(ColorWriteFlags["Blue"] = 4)] = "Blue"; + ColorWriteFlags[(ColorWriteFlags["Alpha"] = 8)] = "Alpha"; + ColorWriteFlags[(ColorWriteFlags["All"] = 15)] = "All"; +})(ColorWriteFlags || (ColorWriteFlags = {})); +/** @internal */ +var BlendFactor; +(function (BlendFactor) { + BlendFactor["Zero"] = "zero"; + BlendFactor["One"] = "one"; + BlendFactor["Src"] = "src"; + BlendFactor["OneMinusSrc"] = "one-minus-src"; + BlendFactor["SrcAlpha"] = "src-alpha"; + BlendFactor["OneMinusSrcAlpha"] = "one-minus-src-alpha"; + BlendFactor["Dst"] = "dst"; + BlendFactor["OneMinusDst"] = "one-minus-dst"; + BlendFactor["DstAlpha"] = "dst-alpha"; + BlendFactor["OneMinusDstAlpha"] = "one-minus-dst-alpha"; + BlendFactor["SrcAlphaSaturated"] = "src-alpha-saturated"; + BlendFactor["Constant"] = "constant"; + BlendFactor["OneMinusConstant"] = "one-minus-constant"; +})(BlendFactor || (BlendFactor = {})); +/** @internal */ +var BlendOperation; +(function (BlendOperation) { + BlendOperation["Add"] = "add"; + BlendOperation["Subtract"] = "subtract"; + BlendOperation["ReverseSubtract"] = "reverse-subtract"; + BlendOperation["Min"] = "min"; + BlendOperation["Max"] = "max"; +})(BlendOperation || (BlendOperation = {})); +/** @internal */ +var StencilOperation; +(function (StencilOperation) { + StencilOperation["Keep"] = "keep"; + StencilOperation["Zero"] = "zero"; + StencilOperation["Replace"] = "replace"; + StencilOperation["Invert"] = "invert"; + StencilOperation["IncrementClamp"] = "increment-clamp"; + StencilOperation["DecrementClamp"] = "decrement-clamp"; + StencilOperation["IncrementWrap"] = "increment-wrap"; + StencilOperation["DecrementWrap"] = "decrement-wrap"; +})(StencilOperation || (StencilOperation = {})); +/** @internal */ +var IndexFormat; +(function (IndexFormat) { + IndexFormat["Uint16"] = "uint16"; + IndexFormat["Uint32"] = "uint32"; +})(IndexFormat || (IndexFormat = {})); +/** @internal */ +var VertexFormat; +(function (VertexFormat) { + VertexFormat["Uint8x2"] = "uint8x2"; + VertexFormat["Uint8x4"] = "uint8x4"; + VertexFormat["Sint8x2"] = "sint8x2"; + VertexFormat["Sint8x4"] = "sint8x4"; + VertexFormat["Unorm8x2"] = "unorm8x2"; + VertexFormat["Unorm8x4"] = "unorm8x4"; + VertexFormat["Snorm8x2"] = "snorm8x2"; + VertexFormat["Snorm8x4"] = "snorm8x4"; + VertexFormat["Uint16x2"] = "uint16x2"; + VertexFormat["Uint16x4"] = "uint16x4"; + VertexFormat["Sint16x2"] = "sint16x2"; + VertexFormat["Sint16x4"] = "sint16x4"; + VertexFormat["Unorm16x2"] = "unorm16x2"; + VertexFormat["Unorm16x4"] = "unorm16x4"; + VertexFormat["Snorm16x2"] = "snorm16x2"; + VertexFormat["Snorm16x4"] = "snorm16x4"; + VertexFormat["Float16x2"] = "float16x2"; + VertexFormat["Float16x4"] = "float16x4"; + VertexFormat["Float32"] = "float32"; + VertexFormat["Float32x2"] = "float32x2"; + VertexFormat["Float32x3"] = "float32x3"; + VertexFormat["Float32x4"] = "float32x4"; + VertexFormat["Uint32"] = "uint32"; + VertexFormat["Uint32x2"] = "uint32x2"; + VertexFormat["Uint32x3"] = "uint32x3"; + VertexFormat["Uint32x4"] = "uint32x4"; + VertexFormat["Sint32"] = "sint32"; + VertexFormat["Sint32x2"] = "sint32x2"; + VertexFormat["Sint32x3"] = "sint32x3"; + VertexFormat["Sint32x4"] = "sint32x4"; +})(VertexFormat || (VertexFormat = {})); +/** @internal */ +var InputStepMode; +(function (InputStepMode) { + InputStepMode["Vertex"] = "vertex"; + InputStepMode["Instance"] = "instance"; +})(InputStepMode || (InputStepMode = {})); +/** @internal */ +var ComputePassTimestampLocation; +(function (ComputePassTimestampLocation) { + ComputePassTimestampLocation["Beginning"] = "beginning"; + ComputePassTimestampLocation["End"] = "end"; +})(ComputePassTimestampLocation || (ComputePassTimestampLocation = {})); +/** @internal */ +var RenderPassTimestampLocation; +(function (RenderPassTimestampLocation) { + RenderPassTimestampLocation["Beginning"] = "beginning"; + RenderPassTimestampLocation["End"] = "end"; +})(RenderPassTimestampLocation || (RenderPassTimestampLocation = {})); +/** @internal */ +var LoadOp; +(function (LoadOp) { + LoadOp["Load"] = "load"; + LoadOp["Clear"] = "clear"; +})(LoadOp || (LoadOp = {})); +/** @internal */ +var StoreOp; +(function (StoreOp) { + StoreOp["Store"] = "store"; + StoreOp["Discard"] = "discard"; +})(StoreOp || (StoreOp = {})); +/** @internal */ +var QueryType; +(function (QueryType) { + QueryType["Occlusion"] = "occlusion"; + QueryType["Timestamp"] = "timestamp"; +})(QueryType || (QueryType = {})); +/** @internal */ +var CanvasAlphaMode; +(function (CanvasAlphaMode) { + CanvasAlphaMode["Opaque"] = "opaque"; + CanvasAlphaMode["Premultiplied"] = "premultiplied"; +})(CanvasAlphaMode || (CanvasAlphaMode = {})); +/** @internal */ +var DeviceLostReason; +(function (DeviceLostReason) { + DeviceLostReason["Destroyed"] = "destroyed"; +})(DeviceLostReason || (DeviceLostReason = {})); +/** @internal */ +var ErrorFilter; +(function (ErrorFilter) { + ErrorFilter["OutOfMemory"] = "out-of-memory"; + ErrorFilter["Validation"] = "validation"; +})(ErrorFilter || (ErrorFilter = {})); +var GPUColorWrite; +(function (GPUColorWrite) { + GPUColorWrite[(GPUColorWrite["Red"] = 1)] = "Red"; + GPUColorWrite[(GPUColorWrite["Green"] = 2)] = "Green"; + GPUColorWrite[(GPUColorWrite["Blue"] = 4)] = "Blue"; + GPUColorWrite[(GPUColorWrite["Alpha"] = 8)] = "Alpha"; + GPUColorWrite[(GPUColorWrite["All"] = 15)] = "All"; +})(GPUColorWrite || (GPUColorWrite = {})); +var CommandSubType; +(function (CommandSubType) { + CommandSubType["Shadow"] = "shadow"; + CommandSubType["Pick"] = "pick"; +})(CommandSubType || (CommandSubType = {})); +var Intersect; +(function (Intersect) { + Intersect[(Intersect["OUTSIDE"] = -1)] = "OUTSIDE"; + Intersect[(Intersect["INTERSECTING"] = 0)] = "INTERSECTING"; + Intersect[(Intersect["INSIDE"] = 1)] = "INSIDE"; +})(Intersect || (Intersect = {})); + +class Buffer { + constructor(label, device, usage, data, size) { + this.device = device; + this.usage = usage; + this.data = data; + this.size = size != undefined ? (size + 3) & ~3 : (data.byteLength + 3) & ~3; // 4 bytes alignments (because of the upload which requires this) + this.gpuBuffer = device.createBuffer({ + label: label || "", + size: this.size, + usage + }); + if (data) this.setSubData(0, data, this.size); + } + static create(label, device, usage, data, size) { + return new Buffer(label, device, usage, data, size); + } + static createVertexBuffer(label, device, data) { + return new Buffer(label, device, BufferUsage.Vertex | BufferUsage.CopyDst, data, data.byteLength); + } + static createIndexBuffer(label, device, data) { + return new Buffer(label, device, BufferUsage.Index | BufferUsage.CopyDst, data); + } + static createUniformBuffer(label, device, size, usage) { + return new Buffer(label, device, usage, null, size); + } + static createStorageBuffer(label, device, size, usage = BufferUsage.Storage) { + return new Buffer(label, device, usage, null, size); + } + // https://github.com/gpuweb/gpuweb/blob/main/design/BufferOperations.md + setSubData(offset, data, size) { + const srcArrayBuffer = data.buffer; + const byteCount = size ?? srcArrayBuffer.byteLength; + const srcBuffer = this.device.createBuffer({ + mappedAtCreation: true, + size: byteCount, + usage: GPUBufferUsage.COPY_SRC + }); + const arrayBuffer = srcBuffer.getMappedRange(); + new Uint16Array(arrayBuffer).set(new Uint16Array(srcArrayBuffer)); // memcpy + srcBuffer.unmap(); + this.copyToBuffer(srcBuffer, offset, byteCount); + srcBuffer.destroy(); + } + copyToBuffer(srcBuffer, offset, byteCount) { + const commandEncoder = this.device.createCommandEncoder(); + commandEncoder.copyBufferToBuffer(srcBuffer, 0, this.gpuBuffer, offset, byteCount); + this.device.queue.submit([commandEncoder.finish()]); + } + copyToTexture(bytesPerRow, rowsPerImage, destination, extent) { + const commandEncoder = this.device.createCommandEncoder(); + commandEncoder.copyBufferToTexture( + { + buffer: this.gpuBuffer, + bytesPerRow, + rowsPerImage + }, + destination, + extent + ); + this.device.queue.submit([commandEncoder.finish()]); } destroy() { this.gpuBuffer.destroy(); } } -const G = new Map(); -class k { - constructor(e, t, i = [], r) { - (this.groupLayouts = i), - (this.index = r || 0), - (this.gpuPipelineLayout = e.createPipelineLayout({ - label: t, - bindGroupLayouts: i.map((e) => e.gpuBindGroupLayout) - })); + +const pipelineLayoutCache = new Map(); +class PipelineLayout { + constructor(device, label, groupLayouts = [], index) { + this.groupLayouts = groupLayouts; + this.index = index || 0; + this.gpuPipelineLayout = device.createPipelineLayout({ + label: label, + bindGroupLayouts: groupLayouts.map((layout) => { + return layout.gpuBindGroupLayout; + }) + }); } - static getPipelineLayoutFromCache(e, t, i) { - if (G.has(t)) return G.get(t); - { - const r = new k(e, t, i); - return G.set(t, r), r; + static getPipelineLayoutFromCache(device, label, groupLayouts) { + if (pipelineLayoutCache.has(label)) { + return pipelineLayoutCache.get(label); + } else { + const bindGroupLayout = new PipelineLayout(device, label, groupLayouts); + pipelineLayoutCache.set(label, bindGroupLayout); + return bindGroupLayout; } } } -const q = new Map(), - j = new Map(); -class H { - constructor(e, t, i) { - (this.type = e), (this.descriptor = i), (this.device = t), this.createPipeline(); + +const renderPipelines = new Map(); +const computePipelines = new Map(); +class Pipeline { + constructor(type, device, descriptor) { + this.type = type; + this.descriptor = descriptor; + this.device = device; + this.createPipeline(); } createPipeline() { - "render" == this.type - ? (this.gpuPipeline = this.device.createRenderPipeline(this.descriptor)) - : (this.gpuPipeline = this.device.createComputePipeline(this.descriptor)); - } - bind(e) { - this.type, e.setPipeline(this.gpuPipeline); - } - static getRenderPipelineFromCache(e, t, i) { - const { renderState: r, shaderSource: n } = t, - s = JSON.stringify(r), - a = X(n.uid.concat(s)), - o = i?.filter((e) => null != e)?.sort((e, t) => e.index - t.index); - let c = q.get(a); - if (!c) { - const i = H.getPipelineDescriptor(e, t, r, o, a.toString()); - (c = new H("render", e, i)), q.set(a, c); - } - return c; - } - static getComputePipelineFromCache(e, t, i) { - const { shaderSource: r } = t, - n = X(r.uid); - let s = j.get(n); - return ( - s || - ((s = new H("compute", e, { - layout: k.getPipelineLayoutFromCache(e, n.toString(), i).gpuPipelineLayout, - compute: { module: r.getShaderModule(e).compute, entryPoint: r?.compute?.computeMain || "main" } - })), - j.set(n, s)), - s - ); + if (this.type == "render") { + this.gpuPipeline = this.device.createRenderPipeline(this.descriptor); + } else { + this.gpuPipeline = this.device.createComputePipeline(this.descriptor); + } } - static getPipelineDescriptor(e, t, i, r, n) { - const { vertexBuffers: s, shaderSource: a } = t, - { vert: o, frag: c } = a.getShaderModule(e), - l = { layout: k.getPipelineLayoutFromCache(e, n, r).gpuPipelineLayout }; - return ( - o && - (l.vertex = { - module: o, - entryPoint: a?.render?.vertMain || "main", - buffers: s.map((e) => e.getBufferDes()) - }), - i.primitive && (l.primitive = i.primitive.getGPUPrimitiveDec()), - i.depthStencil && (l.depthStencil = i.depthStencil.getGPUDepthStencilDec()), - i.multisample && (l.multisample = i.multisample.getMultiSampleDec()), - c && - (l.fragment = { - module: c, - entryPoint: a?.render?.fragMain || "main", - targets: i.targets.map((e) => e.getGPUTargetDec()) - }), - l - ); + bind(passEncoder) { + if (this.type == "render") { + passEncoder.setPipeline(this.gpuPipeline); + } else { + passEncoder.setPipeline(this.gpuPipeline); + } } -} -function X(e) { - let t = 0; - if (0 == e.length) return t; - for (let i = 0; i < e.length; i++) { - (t = (t << 5) - t + e.charCodeAt(i)), (t &= t); - } - return t; -} -class Y { - constructor(e) { - (this.shaderData = e.shaderData), - (this.renderTarget = e.renderTarget), - (this.useLight = e.useLight), - (this.vertexBuffers = e.vertexBuffers), - (this.indexBuffer = e.indexBuffer), - (this.renderState = e.renderState), - (this.queryIndex = e.queryIndex), - (this.count = e.count), - (this.instances = e.instances), - (this.shaderSource = e.shaderSource), - (this.dirty = e.dirty), - (this.lightShaderData = e.lightShaderData); - } - shallowClone(e) { - if (e) - return new Y({ - vertexBuffers: this.vertexBuffers, - indexBuffer: this.indexBuffer, - shaderData: e.shaderData, - instances: this.instances, - count: this.count, - renderState: e.renderState, - shaderSource: e.shaderSource, - lightShaderData: e.light ? this.lightShaderData : void 0, - useLight: e.light + static getRenderPipelineFromCache(device, drawComand, groupLayouts) { + const { renderState, shaderSource } = drawComand; + const rsStr = JSON.stringify(renderState); + const combineStr = shaderSource.uid.concat(rsStr); + const hashId = stringToHash(combineStr); + const combineLayouts = groupLayouts + ?.filter((layout) => layout != undefined) + ?.sort((layout1, layout2) => layout1.index - layout2.index); + let pipeline = renderPipelines.get(hashId); + if (!pipeline) { + const descriptor = Pipeline.getPipelineDescriptor( + device, + drawComand, + renderState, + combineLayouts, + hashId.toString() + ); + pipeline = new Pipeline("render", device, descriptor); + renderPipelines.set(hashId, pipeline); + } + return pipeline; + } + static getComputePipelineFromCache(device, computeCommad, groupLayouts) { + const { shaderSource } = computeCommad; + const hashId = stringToHash(shaderSource.uid); + let pipeline = computePipelines.get(hashId); + if (!pipeline) { + pipeline = new Pipeline("compute", device, { + layout: PipelineLayout.getPipelineLayoutFromCache(device, hashId.toString(), groupLayouts) + .gpuPipelineLayout, + compute: { + module: shaderSource.getShaderModule(device).compute, + entryPoint: shaderSource?.compute?.computeMain || "main" + } }); + computePipelines.set(hashId, pipeline); + } + return pipeline; } - render(e) { - const { device: t, passEncoder: i, camera: r, querySet: n, viewPort: s, scissorTest: a } = e || {}, - { - shaderData: o, - renderState: c, - vertexBuffers: l, - indexBuffer: h, - lightShaderData: u, - shaderSource: f, - count: d, - instances: m, - renderTarget: p, - useLight: g, - indirectOffset: x, - indirectBuffer: v, - queryIndex: y - } = this, - S = p?.beginRenderPass?.(t) ?? i, - b = Object.assign({}, u?.defines ?? {}, r?.shaderData?.defines ?? {}); - o?.bind?.(t, S), - r?.shaderData?.bind(t, S), - g && u?.bind?.(t, S), - c?.bind?.({ passEncoder: S, viewPort: s, scissorTest: a }), - l?.forEach?.((e) => e?.bind?.(t, S)), - h?.bind?.(t, S), - f?.setDefines?.(b); - const w = H.getRenderPipelineFromCache(t, this, [o?.groupLayout, u?.groupLayout, r?.shaderData?.groupLayout]); - null != y && n?.beginQuery(S, y), - w.bind(S), - h - ? v - ? S.drawIndexedIndirect(v.gpuBuffer, x || 0) - : S.drawIndexed(d || 0, m || 1, 0, 0, 0) - : d && (v ? S.drawIndirect(v.gpuBuffer, x) : S.draw(d, m || 1, 0, 0)), - null != y && n?.endQuery(S), - p?.endRenderPass?.(); - } -} -const W = "premultiplied"; -var Z, K, Q; -!(function (e) { - (e.Camera = "camera"), - (e.Light = "light"), - (e.Mesh = "mesh"), - (e.SkinMesh = "skinMesh"), - (e.Node = "node"), - (e.Axes = "axes"), - (e.Skybox = "skyBox"), - (e.PostEffect = "postEffect"), - (e.Debug = "debug"); -})(Z || (Z = {})), - (function (e) { - (e.SpotLight = "spotLight"), - (e.PointLight = "pointLight"), - (e.AmbientLight = "ambientLight"), - (e.DirectionalLight = "directionalLight"); - })(K || (K = {})), - (function (e) { - (e.Float = "f32"), - (e.FloatVec2 = "vec2"), - (e.FloatVec3 = "vec3"), - (e.FloatVec4 = "vec4"), - (e.FloatArray = "array"), - (e.Mat2 = "mat2x2"), - (e.Mat3 = "mat3x3"), - (e.Mat4 = "mat4x4"), - (e.Color = "color"), - (e.Mat4Array = "array>"), - (e.Vec2Array = "array>"), - (e.Vec3Array = "array>"), - (e.Vec4Array = "array>"), - (e.UniformUint = "u32"), - (e.PointLights = "pointLights"), - (e.PointLightShadows = "pointLightShadows"), - (e.SpotLights = "spotLights"), - (e.SpotLightShadows = "spotLightShadows"), - (e.DirtectLights = "dirtectLights"), - (e.DirtectLightShadows = "dirtectLightShadows"), - (e.UniformStructArray = "StructArray"); - })(Q || (Q = {})); -class J { - constructor(e) { - (this.device = e), (this.sampler = e.createSampler({ minFilter: "linear" })), (this.pipelines = {}); - } - getMipmapPipeline(e) { - let t = this.pipelines[e]; - return ( - t || - (this.mipmapShaderModule || - (this.mipmapShaderModule = this.device.createShaderModule({ - code: "\n var pos : array, 3> = array, 3>(\n vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0));\n struct VertexOutput {\n @builtin(position) position : vec4,\n @location(0) texCoord : vec2,\n };\n @vertex\n fn vertexMain(@builtin(vertex_index) vertexIndex : u32) -> VertexOutput {\n var output : VertexOutput;\n output.texCoord = pos[vertexIndex] * vec2(0.5, -0.5) + vec2(0.5);\n output.position = vec4(pos[vertexIndex], 0.0, 1.0);\n return output;\n }\n @group(0) @binding(0) var imgSampler : sampler;\n @group(0) @binding(1) var img : texture_2d;\n @fragment\n fn fragmentMain(@location(0) texCoord : vec2) -> @location(0) vec4 {\n return textureSample(img, imgSampler, texCoord);\n }\n " - })), - (t = this.device.createRenderPipeline({ - layout: "auto", - vertex: { module: this.mipmapShaderModule, entryPoint: "vertexMain" }, - fragment: { module: this.mipmapShaderModule, entryPoint: "fragmentMain", targets: [{ format: e }] } - })), - (this.pipelines[e] = t)), - t - ); + static getPipelineDescriptor(device, drawComand, renderState, groupLayouts, hashId) { + const { vertexBuffers, shaderSource } = drawComand; + const { vert, frag } = shaderSource.getShaderModule(device); + const pipelineDec = { + layout: PipelineLayout.getPipelineLayoutFromCache(device, hashId, groupLayouts).gpuPipelineLayout + }; + if (vert) + pipelineDec.vertex = { + module: vert, + entryPoint: shaderSource?.render?.vertMain || "main", + buffers: vertexBuffers.map((vertexBuffer) => vertexBuffer.getBufferDes()) + }; + if (renderState.primitive) pipelineDec.primitive = renderState.primitive.getGPUPrimitiveDec(); + if (renderState.depthStencil) pipelineDec.depthStencil = renderState.depthStencil.getGPUDepthStencilDec(); + if (renderState.multisample) pipelineDec.multisample = renderState.multisample.getMultiSampleDec(); + if (frag) + pipelineDec.fragment = { + module: frag, + entryPoint: shaderSource?.render?.fragMain || "main", + targets: renderState.targets.map((target) => { + return target.getGPUTargetDec(); + }) + }; + return pipelineDec; + } +} +// Borrowed from https://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/ +function stringToHash(str) { + let hash = 0; + if (str.length == 0) return hash; + for (let i = 0; i < str.length; i++) { + const char = str.charCodeAt(i); + hash = (hash << 5) - hash + char; + hash = hash & hash; // Convert to 32bit integer + } + return hash; +} + +class DrawCommand { + constructor(options) { + this.shaderData = options.shaderData; + this.renderTarget = options.renderTarget; + this.useLight = options.useLight; + this.vertexBuffers = options.vertexBuffers; + this.indexBuffer = options.indexBuffer; + this.renderState = options.renderState; + this.queryIndex = options.queryIndex; + this.count = options.count; + this.instances = options.instances; + this.shaderSource = options.shaderSource; + this.dirty = options.dirty; + this.lightShaderData = options.lightShaderData; + } + shallowClone(material) { + if (!material) return; + return new DrawCommand({ + vertexBuffers: this.vertexBuffers, + indexBuffer: this.indexBuffer, + shaderData: material.shaderData, + instances: this.instances, + count: this.count, + renderState: material.renderState, + shaderSource: material.shaderSource, + lightShaderData: material.light ? this.lightShaderData : undefined, + useLight: material.light + }); + } + render(params) { + const { device, passEncoder, camera, querySet, viewPort, scissorTest } = params || {}; + const { + shaderData, + renderState, + vertexBuffers, + indexBuffer, + lightShaderData, + shaderSource, + count, + instances, + renderTarget, + useLight, + indirectOffset, + indirectBuffer, + queryIndex + } = this; + const currentPassEncoder = renderTarget?.beginRenderPass?.(device) ?? passEncoder; + const defines = Object.assign({}, lightShaderData?.defines ?? {}, camera?.shaderData?.defines ?? {}); + shaderData?.bind?.(device, currentPassEncoder); + camera?.shaderData?.bind(device, currentPassEncoder); + useLight && lightShaderData?.bind?.(device, currentPassEncoder); + renderState?.bind?.({ + passEncoder: currentPassEncoder, + viewPort: viewPort, + scissorTest: scissorTest + }); + vertexBuffers?.forEach?.((vertexBuffer) => vertexBuffer?.bind?.(device, currentPassEncoder)); + indexBuffer?.bind?.(device, currentPassEncoder); + shaderSource?.setDefines?.(defines); + const pipeline = Pipeline.getRenderPipelineFromCache(device, this, [ + shaderData?.groupLayout, + lightShaderData?.groupLayout, + camera?.shaderData?.groupLayout + ]); + if (queryIndex != undefined) querySet?.beginQuery(currentPassEncoder, queryIndex); + pipeline.bind(currentPassEncoder); + if (indexBuffer) { + if (indirectBuffer) { + currentPassEncoder.drawIndexedIndirect(indirectBuffer.gpuBuffer, indirectOffset || 0); + } else { + currentPassEncoder.drawIndexed(count || 0, instances || 1, 0, 0, 0); + } + } else if (count) { + if (indirectBuffer) { + currentPassEncoder.drawIndirect(indirectBuffer.gpuBuffer, indirectOffset); + } else { + currentPassEncoder.draw(count, instances || 1, 0, 0); + } + } + if (queryIndex != undefined) querySet?.endQuery(currentPassEncoder); + renderTarget?.endRenderPass?.(); } - generateMipmap(e) { - const t = e.gpuTexture, - i = e.textureProp, - r = this.getMipmapPipeline(i.format); - if ("3d" == i.dimension || "1d" == i.dimension) +} + +const GPUCanvasCompositingAlphaMode = { + Opaque: "opaque", + Premultiplied: "premultiplied" +}; +var RenderObjectType; +(function (RenderObjectType) { + RenderObjectType["Camera"] = "camera"; + RenderObjectType["Light"] = "light"; + RenderObjectType["Mesh"] = "mesh"; + RenderObjectType["SkinMesh"] = "skinMesh"; + RenderObjectType["Node"] = "node"; + RenderObjectType["Axes"] = "axes"; + RenderObjectType["Skybox"] = "skyBox"; + RenderObjectType["PostEffect"] = "postEffect"; + RenderObjectType["Debug"] = "debug"; +})(RenderObjectType || (RenderObjectType = {})); +var LightType; +(function (LightType) { + LightType["SpotLight"] = "spotLight"; + LightType["PointLight"] = "pointLight"; + LightType["AmbientLight"] = "ambientLight"; + LightType["DirectionalLight"] = "directionalLight"; +})(LightType || (LightType = {})); +var UniformEnum; +(function (UniformEnum) { + UniformEnum["Float"] = "f32"; + UniformEnum["FloatVec2"] = "vec2"; + UniformEnum["FloatVec3"] = "vec3"; + UniformEnum["FloatVec4"] = "vec4"; + UniformEnum["FloatArray"] = "array"; + UniformEnum["Mat2"] = "mat2x2"; + UniformEnum["Mat3"] = "mat3x3"; + UniformEnum["Mat4"] = "mat4x4"; + UniformEnum["Color"] = "color"; + UniformEnum["Mat4Array"] = "array>"; + UniformEnum["Vec2Array"] = "array>"; + UniformEnum["Vec3Array"] = "array>"; + UniformEnum["Vec4Array"] = "array>"; + UniformEnum["UniformUint"] = "u32"; + UniformEnum["PointLights"] = "pointLights"; + UniformEnum["PointLightShadows"] = "pointLightShadows"; + UniformEnum["SpotLights"] = "spotLights"; + UniformEnum["SpotLightShadows"] = "spotLightShadows"; + UniformEnum["DirtectLights"] = "dirtectLights"; + UniformEnum["DirtectLightShadows"] = "dirtectLightShadows"; + UniformEnum["UniformStructArray"] = "StructArray"; +})(UniformEnum || (UniformEnum = {})); + +class MipmapGenerator { + constructor(device) { + this.device = device; + this.sampler = device.createSampler({ minFilter: "linear" }); + // We'll need a new pipeline for every texture format used. + this.pipelines = {}; + } + getMipmapPipeline(format) { + let pipeline = this.pipelines[format]; + if (!pipeline) { + // Shader modules is shared between all pipelines, so only create once. + if (!this.mipmapShaderModule) { + this.mipmapShaderModule = this.device.createShaderModule({ + code: ` + var pos : array, 3> = array, 3>( + vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0)); + struct VertexOutput { + @builtin(position) position : vec4, + @location(0) texCoord : vec2, + }; + @vertex + fn vertexMain(@builtin(vertex_index) vertexIndex : u32) -> VertexOutput { + var output : VertexOutput; + output.texCoord = pos[vertexIndex] * vec2(0.5, -0.5) + vec2(0.5); + output.position = vec4(pos[vertexIndex], 0.0, 1.0); + return output; + } + @group(0) @binding(0) var imgSampler : sampler; + @group(0) @binding(1) var img : texture_2d; + @fragment + fn fragmentMain(@location(0) texCoord : vec2) -> @location(0) vec4 { + return textureSample(img, imgSampler, texCoord); + } + ` + }); + } + pipeline = this.device.createRenderPipeline({ + layout: "auto", + vertex: { + module: this.mipmapShaderModule, + entryPoint: "vertexMain" + }, + fragment: { + module: this.mipmapShaderModule, + entryPoint: "fragmentMain", + targets: [{ format }] + } + }); + this.pipelines[format] = pipeline; + } + return pipeline; + } + /** + * Generates mipmaps for the given GPUTexture from the data in level 0. + * + * @param {module:External.GPUTexture} texture - Texture to generate mipmaps for. + * @param {object} textureDescriptor - GPUTextureDescriptor the texture was created with. + * @returns {module:External.GPUTexture} - The originally passed texture + */ + generateMipmap(sourceTexture) { + const texture = sourceTexture.gpuTexture; + const textureDescriptor = sourceTexture.textureProp; + // TODO: Does this need to handle sRGB formats differently? + const pipeline = this.getMipmapPipeline(textureDescriptor.format); + if (textureDescriptor.dimension == "3d" || textureDescriptor.dimension == "1d") { throw new Error("Generating mipmaps for non-2d textures is currently unsupported!"); - let n = t; - const s = i.size.depth || 1, - a = i.usage & GPUTextureUsage.RENDER_ATTACHMENT; - if (!a) { - const e = { + } + let mipTexture = texture; + const arrayLayerCount = textureDescriptor.size.depth || 1; // Only valid for 2D textures. + // If the texture was created with RENDER_ATTACHMENT usage we can render directly between mip levels. + const renderToSource = textureDescriptor.usage & GPUTextureUsage.RENDER_ATTACHMENT; + if (!renderToSource) { + // Otherwise we have to use a separate texture to render into. It can be one mip level smaller than the source + // texture, since we already have the top level. + const mipTextureDescriptor = { size: { - width: Math.ceil(i.size.width / 2), - height: Math.ceil(i.size.height / 2), - depthOrArrayLayers: s + width: Math.ceil(textureDescriptor.size.width / 2), + height: Math.ceil(textureDescriptor.size.height / 2), + depthOrArrayLayers: arrayLayerCount }, - format: i.format, + format: textureDescriptor.format, usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC | GPUTextureUsage.RENDER_ATTACHMENT, - mipLevelCount: i.mipLevelCount - 1 + mipLevelCount: textureDescriptor.mipLevelCount - 1 }; - n = this.device.createTexture(e); + mipTexture = this.device.createTexture(mipTextureDescriptor); } - const o = this.device.createCommandEncoder({}), - c = r.getBindGroupLayout(0); - for (let e = 0; e < s; ++e) { - let s = t.createView({ - baseMipLevel: 0, + const commandEncoder = this.device.createCommandEncoder({}); + // TODO: Consider making this static. + const bindGroupLayout = pipeline.getBindGroupLayout(0); + for (let arrayLayer = 0; arrayLayer < arrayLayerCount; ++arrayLayer) { + let srcView = texture.createView({ + baseMipLevel: 0, + mipLevelCount: 1, + dimension: "2d", + baseArrayLayer: arrayLayer, + arrayLayerCount: 1 + }); + let dstMipLevel = renderToSource ? 1 : 0; + for (let i = 1; i < textureDescriptor.mipLevelCount; ++i) { + const dstView = mipTexture.createView({ + baseMipLevel: dstMipLevel++, mipLevelCount: 1, dimension: "2d", - baseArrayLayer: e, + baseArrayLayer: arrayLayer, arrayLayerCount: 1 - }), - l = a ? 1 : 0; - for (let t = 1; t < i.mipLevelCount; ++t) { - const t = n.createView({ - baseMipLevel: l++, - mipLevelCount: 1, - dimension: "2d", - baseArrayLayer: e, - arrayLayerCount: 1 - }), - i = o.beginRenderPass({ colorAttachments: [{ view: t, loadOp: "clear", storeOp: "store" }] }), - a = this.device.createBindGroup({ - layout: c, - entries: [ - { binding: 0, resource: this.sampler }, - { binding: 1, resource: s } - ] - }); - i.setPipeline(r), i.setBindGroup(0, a), i.draw(3, 1, 0, 0), i.end(), (s = t); + }); + const passEncoder = commandEncoder.beginRenderPass({ + colorAttachments: [ + { + view: dstView, + loadOp: "clear", + storeOp: "store" + } + ] + }); + const bindGroup = this.device.createBindGroup({ + layout: bindGroupLayout, + entries: [ + { + binding: 0, + resource: this.sampler + }, + { + binding: 1, + resource: srcView + } + ] + }); + passEncoder.setPipeline(pipeline); + passEncoder.setBindGroup(0, bindGroup); + passEncoder.draw(3, 1, 0, 0); + passEncoder.end(); + srcView = dstView; } } - if (!a) { - const e = { - width: Math.ceil(i.size.width / 2), - height: Math.ceil(i.size.height / 2), - depthOrArrayLayers: s + // If we didn't render to the source texture, finish by copying the mip results from the temporary mipmap texture + // to the source. + if (!renderToSource) { + const mipLevelSize = { + width: Math.ceil(textureDescriptor.size.width / 2), + height: Math.ceil(textureDescriptor.size.height / 2), + depthOrArrayLayers: arrayLayerCount }; - for (let r = 1; r < i.mipLevelCount; ++r) - o.copyTextureToTexture({ texture: n, mipLevel: r - 1 }, { texture: t, mipLevel: r }, e), - (e.width = Math.ceil(e.width / 2)), - (e.height = Math.ceil(e.height / 2)); - } - return this.device.queue.submit([o.finish()]), a || n.destroy(), t; - } -} -function ee(e, t) { - return null != e ? e : t; -} -ee.EMPTY_OBJECT = Object.freeze({}); -class te { - constructor(e) { - (this.scissorTest = e?.scissorTest), - (this.viewport = e?.viewport), - (this.depthStencil = e?.depthStencil), - (this.blendConstant = e?.blendConstant), - (this.stencilReference = e?.stencilReference), - (this.multisample = e?.multisample), - (this.primitive = e?.primitive), - (this.stencilEnabled = !1), - (this.scissorTestEnabled = !1), - (this.targets = e?.targets); - } - bind(e) { - const { passEncoder: t, viewPort: i, scissorTest: r } = e, - n = this.viewport ?? i, - s = this.scissorTest ?? r; - if ((this.stencilReference && t.setStencilReference(this.stencilReference), n?.equalsAndUpdateCache(le))) { - const { x: e, y: i, width: r, height: s, minDepth: a, maxDepth: o } = n; - t.setViewport(e, i, r, s, a, o); - } - if ((this.blendConstant && t.setBlendConstant(this.blendConstant), s?.equalsAndUpdateCache(he))) { - const { x: e, y: i, width: r, height: n } = s; - t.setScissorRect(e, i, r, n); + for (let i = 1; i < textureDescriptor.mipLevelCount; ++i) { + commandEncoder.copyTextureToTexture( + { + texture: mipTexture, + mipLevel: i - 1 + }, + { + texture: texture, + mipLevel: i + }, + mipLevelSize + ); + mipLevelSize.width = Math.ceil(mipLevelSize.width / 2); + mipLevelSize.height = Math.ceil(mipLevelSize.height / 2); + } } - } - destroy() { - (this.scissorTest = void 0), - (this.viewport = void 0), - (this.depthStencil = void 0), - (this.blendConstant = void 0), - (this.stencilReference = -1), - (this.multisample = void 0), - (this.primitive = void 0), - (this.stencilEnabled = !1), - (this.scissorTestEnabled = !1); + this.device.queue.submit([commandEncoder.finish()]); + if (!renderToSource) { + mipTexture.destroy(); + } + return texture; } } -class ie { - constructor(e, t, i, r) { - (this.r = e), (this.g = t), (this.b = i), (this.a = r); + +function defaultValue(a, b) { + if (a !== undefined && a !== null) { + return a; } + return b; } -class re { - constructor(e = 1, t = 4294967295, i = !1) { - (this.count = e), (this.mask = t), (this.alphaToCoverageEnabled = i); +/** + * A frozen empty object that can be used as the default value for options passed as + * an object literal. + * @type {Object} + * @memberof defaultValue + */ +defaultValue.EMPTY_OBJECT = Object.freeze({}); + +class RenderState { + constructor(params) { + this.scissorTest = params?.scissorTest; + this.viewport = params?.viewport; + this.depthStencil = params?.depthStencil; + this.blendConstant = params?.blendConstant; + this.stencilReference = params?.stencilReference; + this.multisample = params?.multisample; + this.primitive = params?.primitive; + this.stencilEnabled = false; + this.scissorTestEnabled = false; + this.targets = params?.targets; + } + bind(params) { + const { passEncoder, viewPort, scissorTest } = params; + const finalViewport = this.viewport ?? viewPort; + const finalScissorTest = this.scissorTest ?? scissorTest; + if (this.stencilReference) passEncoder.setStencilReference(this.stencilReference); + if (finalViewport?.equalsAndUpdateCache(cacheViewPort)) { + const { x, y, width, height, minDepth, maxDepth } = finalViewport; + passEncoder.setViewport(x, y, width, height, minDepth, maxDepth); + } + if (this.blendConstant) passEncoder.setBlendConstant(this.blendConstant); + if (finalScissorTest?.equalsAndUpdateCache(cacheScissorTest)) { + const { x, y, width, height } = finalScissorTest; + passEncoder.setScissorRect(x, y, width, height); + } } - getMultiSampleDec() { - return { count: this.count, mask: this.mask, alphaToCoverageEnabled: this.alphaToCoverageEnabled }; + destroy() { + this.scissorTest = undefined; + this.viewport = undefined; + this.depthStencil = undefined; + this.blendConstant = undefined; + this.stencilReference = -1; + this.multisample = undefined; + this.primitive = undefined; + this.stencilEnabled = false; + this.scissorTestEnabled = false; } } -class ne { - constructor(e = 0, t = 0, i = 0, r = 0, n = !0) { - (this.x = e), (this.y = t), (this.width = i), (this.height = r), (this.variable = n); +class BlendConstant { + constructor(r, g, b, a) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; } - set(e, t, i, r) { - (this.x = e), (this.y = t), (this.width = i), (this.height = r); +} +class MultiSample { + constructor(count = 1, mask = 0xffffffff, alphaToCoverageEnabled = false) { + this.count = count; + this.mask = mask; + this.alphaToCoverageEnabled = alphaToCoverageEnabled; } - equalsAndUpdateCache(e) { - const { x: t, y: i, width: r, height: n } = e; - return ( - (this.x != t || this.y != i || this.width != r || this.height != n) && - (e.set(this.x, this.y, this.width, this.height), !0) - ); + getMultiSampleDec() { + return { + count: this.count, + mask: this.mask, + alphaToCoverageEnabled: this.alphaToCoverageEnabled + }; } } -class se { - constructor(e = 0, t = 0, i = 0, r = 0, n = 0, s = 1, a = !0) { - (this.x = e), - (this.y = t), - (this.width = i), - (this.height = r), - (this.minDepth = n), - (this.maxDepth = s), - (this.variable = a); - } - set(e, t, i, r, n = 0, s = 1) { - this.variable && - ((this.x = e), (this.y = t), (this.width = i), (this.height = r), (this.minDepth = n), (this.maxDepth = s)); +class ScissorTest { + constructor(x = 0, y = 0, width = 0, height = 0, variable = true) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.variable = variable; + } + set(x, y, width, height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + equalsAndUpdateCache(scissorTest) { + const { x, y, width, height } = scissorTest; + if (this.x != x || this.y != y || this.width != width || this.height != height) { + scissorTest.set(this.x, this.y, this.width, this.height); + return true; + } + return false; } - equalsAndUpdateCache(e) { - const { x: t, y: i, width: r, height: n, minDepth: s, maxDepth: a } = e; - return ( - (this.x != t || - this.y != i || - this.width != r || - this.height != n || - this.minDepth != s || - this.maxDepth != a) && - (e.set(this.x, this.y, this.width, this.height, this.minDepth, this.maxDepth), !0) - ); +} +class ViewPort { + constructor(x = 0, y = 0, width = 0, height = 0, minDepth = 0, maxDepth = 1, variable = true) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.minDepth = minDepth; + this.maxDepth = maxDepth; + this.variable = variable; + } + set(x, y, width, height, minDepth = 0, maxDepth = 1) { + if (!this.variable) return; + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.minDepth = minDepth; + this.maxDepth = maxDepth; + } + equalsAndUpdateCache(viewPort) { + const { x, y, width, height, minDepth, maxDepth } = viewPort; + if ( + this.x != x || + this.y != y || + this.width != width || + this.height != height || + this.minDepth != minDepth || + this.maxDepth != maxDepth + ) { + viewPort.set(this.x, this.y, this.width, this.height, this.minDepth, this.maxDepth); + return true; + } + return false; } } -class ae { - constructor(e, t, i, r) { - (this.frontFace = ee(i, b.CCW)), - (this.cullMode = ee(t, w.None)), - (this.unclippedDepth = ee(r, !1)), - (this.topology = ee(e, S.TriangleList)); +class Primitive { + constructor(topology, cullMode, frontFace, unclippedDepth) { + this.frontFace = defaultValue(frontFace, FrontFace.CCW); + this.cullMode = defaultValue(cullMode, CullMode.None); + this.unclippedDepth = defaultValue(unclippedDepth, false); + this.topology = defaultValue(topology, PrimitiveTopology.TriangleList); } getGPUPrimitiveDec() { return { @@ -801,24 +1085,24 @@ class ae { }; } } -class oe { - constructor(e) { - (this.format = ee(e?.format, l.Depth24Plus)), - (this.depthWriteEnabled = ee(e?.depthWriteEnabled, !0)), - (this.depthCompare = ee(e?.depthCompare, f.Less)), - (this.stencilReadMask = ee(e?.stencilReadMask, 4294967295)), - (this.stencilWriteMask = ee(e?.stencilWriteMask, 4294967295)), - (this.stencilFrontCompare = ee(e?.stencilFrontCompare, f.Always)), - (this.stencilFrontFailOp = ee(e?.stencilFrontFailOp, U.Keep)), - (this.stencilFrontDepthFailOp = ee(e?.stencilFrontDepthFailOp, U.Keep)), - (this.stencilFrontPassOp = ee(e?.stencilFrontPassOp, U.Keep)), - (this.stencilBackCompare = ee(e?.stencilBackCompare, f.Always)), - (this.stencilBackFailOp = ee(e?.stencilBackFailOp, U.Keep)), - (this.stencilBackDepthFailOp = ee(e?.stencilBackDepthFailOp, U.Keep)), - (this.stencilBackPassOp = ee(e?.stencilBackPassOp, U.Keep)), - (this.depthBias = ee(e?.depthBias, 0)), - (this.depthBiasSlopeScale = ee(e?.depthBiasSlopeScale, 0)), - (this.depthBiasClamp = ee(e?.depthBiasClamp, 0)); +class DepthStencil { + constructor(options) { + this.format = defaultValue(options?.format, TextureFormat.Depth24Plus); + this.depthWriteEnabled = defaultValue(options?.depthWriteEnabled, true); + this.depthCompare = defaultValue(options?.depthCompare, CompareFunction.Less); + this.stencilReadMask = defaultValue(options?.stencilReadMask, 0xffffffff); + this.stencilWriteMask = defaultValue(options?.stencilWriteMask, 0xffffffff); + this.stencilFrontCompare = defaultValue(options?.stencilFrontCompare, CompareFunction.Always); + this.stencilFrontFailOp = defaultValue(options?.stencilFrontFailOp, StencilOperation.Keep); + this.stencilFrontDepthFailOp = defaultValue(options?.stencilFrontDepthFailOp, StencilOperation.Keep); + this.stencilFrontPassOp = defaultValue(options?.stencilFrontPassOp, StencilOperation.Keep); + this.stencilBackCompare = defaultValue(options?.stencilBackCompare, CompareFunction.Always); + this.stencilBackFailOp = defaultValue(options?.stencilBackFailOp, StencilOperation.Keep); + this.stencilBackDepthFailOp = defaultValue(options?.stencilBackDepthFailOp, StencilOperation.Keep); + this.stencilBackPassOp = defaultValue(options?.stencilBackPassOp, StencilOperation.Keep); + this.depthBias = defaultValue(options?.depthBias, 0); + this.depthBiasSlopeScale = defaultValue(options?.depthBiasSlopeScale, 0); + this.depthBiasClamp = defaultValue(options?.depthBiasClamp, 0); } getGPUDepthStencilDec() { return { @@ -845,16 +1129,16 @@ class oe { }; } } -class ce { - constructor(e) { - (this.format = ee(e?.format, l.BGRA8Unorm)), - (this.blendColorOperation = ee(e?.blendColorOperation, M.Add)), - (this.blendColorSrcFactor = ee(e?.blendColorSrcFactor, E?.SrcAlpha)), - (this.blendColorDstFactor = ee(e?.blendColorDstFactor, E.OneMinusSrcAlpha)), - (this.blendAlphaOperation = ee(e?.blendAlphaOperation, M.Add)), - (this.blendAlphaSrcFactor = ee(e?.blendAlphaSrcFactor, E.One)), - (this.blendAlphaDstFactor = ee(e?.blendAlphaDstFactor, E.One)), - (this.writeMask = ee(e?.writeMask, O.All)); +class Target { + constructor(options) { + this.format = defaultValue(options?.format, TextureFormat.BGRA8Unorm); + this.blendColorOperation = defaultValue(options?.blendColorOperation, BlendOperation.Add); + this.blendColorSrcFactor = defaultValue(options?.blendColorSrcFactor, BlendFactor?.SrcAlpha); + this.blendColorDstFactor = defaultValue(options?.blendColorDstFactor, BlendFactor.OneMinusSrcAlpha); + this.blendAlphaOperation = defaultValue(options?.blendAlphaOperation, BlendOperation.Add); + this.blendAlphaSrcFactor = defaultValue(options?.blendAlphaSrcFactor, BlendFactor.One); + this.blendAlphaDstFactor = defaultValue(options?.blendAlphaDstFactor, BlendFactor.One); + this.writeMask = defaultValue(options?.writeMask, GPUColorWrite.All); } getGPUTargetDec() { return { @@ -875,192 +1159,239 @@ class ce { }; } } -const le = new se(), - he = new ne(); -class ue { +const cacheViewPort = new ViewPort(); +const cacheScissorTest = new ScissorTest(); + +class Context { get viewPort() { return this._viewPort; } get scissorTest() { return this._scissorTest; } - constructor({ canvas: e, container: t, context: i, pixelRatio: r } = {}) { - if (!t.clientWidth || !t.clientHeight) throw new Error("container width or height illegality"); - (this.canvas = e || document.createElement("canvas")), (this.pixelRatio = r || window.devicePixelRatio || 1); - const n = t.clientWidth * this.pixelRatio, - s = t.clientHeight * this.pixelRatio; - (this.canvas.width = n), - (this.canvas.height = s), - (this.canvas.style.width = t.clientWidth + "px"), - (this.canvas.style.height = t.clientHeight + "px"), - t.appendChild(this.canvas), - (this.context = i || this.canvas.getContext("webgpu")), - (this.device = void 0); - } - async init(e = {}, t = {}, i = {}) { + constructor({ canvas, container, context, pixelRatio } = {}) { + if (!container.clientWidth || !container.clientHeight) throw new Error("container width or height illegality"); + this.canvas = canvas || document.createElement("canvas"); + // this.canvas.style.display = "block"; + this.pixelRatio = pixelRatio || window.devicePixelRatio || 1; + const width = container.clientWidth * this.pixelRatio; + const height = container.clientHeight * this.pixelRatio; + this.canvas.width = width; + this.canvas.height = height; + this.canvas.style.width = container.clientWidth + "px"; + this.canvas.style.height = container.clientHeight + "px"; + container.appendChild(this.canvas); + this.context = context || this.canvas.getContext("webgpu"); + this.device = undefined; + } + async init(requestAdapter = {}, deviceDescriptor = {}, presentationContextDescriptor = {}) { try { - if (!this.context) throw new Error('Failed to instantiate "webgpu" context.'); - if (!navigator.gpu) throw new Error('Missing "navigator.gpu".'); - (this.adapter = await navigator.gpu.requestAdapter()), - (this.device = await this.adapter.requestDevice()), - (this.presentationSize = { - width: this.canvas.clientWidth * this.pixelRatio, - height: this.canvas.clientHeight * this.pixelRatio, - depth: 1 - }), - (this.presentationFormat = navigator.gpu.getPreferredCanvasFormat()), - this.device.addEventListener("uncapturederror", (e) => { - console.error(e); - }), - (this.mipmapTools = new J(this.device)), - this.context.configure({ - device: this.device, - format: this.presentationFormat, - usage: a.RenderAttachment, - alphaMode: "premultiplied", - ...i - }), - (this._viewPort = new se( - 0, - 0, - this.canvas.clientWidth * this.pixelRatio, - this.canvas.clientHeight * this.pixelRatio - )), - (this._scissorTest = new ne( - 0, - 0, - this.canvas.clientWidth * this.pixelRatio, - this.canvas.clientHeight * this.pixelRatio - )); - } catch (e) { - return console.error(e), !1; + if (!this.context) { + throw new Error(`Failed to instantiate "webgpu" context.`); + } + if (!navigator.gpu) { + throw new Error(`Missing "navigator.gpu".`); + } + this.adapter = await navigator.gpu.requestAdapter(); + this.device = await this.adapter.requestDevice(); + this.presentationSize = { + width: this.canvas.clientWidth * this.pixelRatio, + height: this.canvas.clientHeight * this.pixelRatio, + depth: 1 + }; + this.presentationFormat = navigator.gpu.getPreferredCanvasFormat(); + this.device.addEventListener("uncapturederror", (error) => { + console.error(error); + // State.error = true; + }); + this.mipmapTools = new MipmapGenerator(this.device); + this.context.configure({ + device: this.device, + format: this.presentationFormat, + usage: TextureUsage.RenderAttachment, + alphaMode: "premultiplied", + ...presentationContextDescriptor + }); + this._viewPort = new ViewPort( + 0, + 0, + this.canvas.clientWidth * this.pixelRatio, + this.canvas.clientHeight * this.pixelRatio + ); + this._scissorTest = new ScissorTest( + 0, + 0, + this.canvas.clientWidth * this.pixelRatio, + this.canvas.clientHeight * this.pixelRatio + ); + } catch (error) { + console.error(error); + return false; } - return !0; + return true; } - setViewPort(e, t, i, r) { - this._viewPort.set(e, t, i, r); + setViewPort(x, y, width, height) { + this._viewPort.set(x, y, width, height); } resetViewPortToFullCanvas() { this._viewPort.set(0, 0, this.canvas.clientWidth * this.pixelRatio, this.canvas.clientHeight * this.pixelRatio); } - setScissorTest(e, t, i, r) { - this._scissorTest.set(e, t, i, r); - } - resize(e, t, i = {}) { - const r = e * this.pixelRatio, - n = t * this.pixelRatio; - (this.canvas.style.width = r + "px"), - (this.canvas.style.height = n + "px"), - (this.canvas.width = r), - (this.canvas.height = n), - (this.presentationSize = { width: r, height: n, depth: 1 }), - this.context.configure({ - device: this.device, - format: navigator.gpu.getPreferredCanvasFormat(), - usage: a.RenderAttachment, - alphaMode: W, - ...i - }); + setScissorTest(x, y, width, height) { + this._scissorTest.set(x, y, width, height); + } + resize(width, height, presentationContextDescriptor = {}) { + const w = width * this.pixelRatio; + const h = height * this.pixelRatio; + this.canvas.style.width = w + "px"; + this.canvas.style.height = h + "px"; + this.canvas.width = w; + this.canvas.height = h; + this.presentationSize = { + width: w, + height: h, + depth: 1 + }; + this.context.configure({ + device: this.device, + format: navigator.gpu.getPreferredCanvasFormat(), + usage: TextureUsage.RenderAttachment, + alphaMode: GPUCanvasCompositingAlphaMode.Premultiplied, + ...presentationContextDescriptor + }); } } -class fe { - constructor(e) { - (this.textureProp = Object.assign( + +class Texture { + constructor(textureProp) { + this.textureProp = Object.assign( { - format: l.RGBA8Unorm, + format: TextureFormat.RGBA8Unorm, usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT, - dataIsTexture: !1 + dataIsTexture: false }, - e - )), - (this.dirty = !0), - (this.fixedSize = e.fixedSize || !1); + textureProp + ); + this.dirty = true; + this.fixedSize = textureProp.fixedSize || false; } get layoutType() { - const { viewFormats: e, sampleType: t, sampleCount: i } = this.textureProp; - return { sampleType: ee(t, "float"), viewDimension: ee(e, "2d"), multisampled: !!(i && i > 1) }; + const { viewFormats, sampleType, sampleCount } = this.textureProp; + // const + return { + sampleType: defaultValue(sampleType, "float"), + viewDimension: defaultValue(viewFormats, "2d"), + multisampled: sampleCount && sampleCount > 1 ? true : false + }; } get storageTextureLayoutType() { - const { access: e = x.WriteOnly, viewFormats: t, format: i } = this.textureProp; - return { viewDimension: ee(t, "2d"), access: e, format: i }; + const { access = StorageTextureAccess.WriteOnly, viewFormats, format } = this.textureProp; + return { + viewDimension: defaultValue(viewFormats, "2d"), + access, + format + }; } get textureView() { - return ( - this._textureView || - (this._textureView = this.gpuTexture.createView({ dimension: ee(this.textureProp.viewFormats, "2d") })), - this._textureView - ); + if (!this._textureView) + this._textureView = this.gpuTexture.createView({ + dimension: defaultValue(this.textureProp.viewFormats, "2d") + }); + return this._textureView; + } + update(device) { + if (!this.device) this.device = device; + if (this.dirty) { + this.checkNeedCreateTexture(); + this.dirty = false; + if (this.textureProp.data) { + if (Array.isArray(this.textureProp.data)) { + this.textureProp.data.forEach((imageData) => { + this.setData(imageData); + }); + } else { + this.setData(this.textureProp.data); + } + } + if (this.textureProp.needMipMap) { + if (!Texture.mipmapTools) Texture.mipmapTools = new MipmapGenerator(this.device); + this.gpuTexture = Texture.mipmapTools.generateMipmap(this); + } + } } - update(e) { - this.device || (this.device = e), - this.dirty && - (this.checkNeedCreateTexture(), - (this.dirty = !1), - this.textureProp.data && - (Array.isArray(this.textureProp.data) - ? this.textureProp.data.forEach((e) => { - this.setData(e); - }) - : this.setData(this.textureProp.data)), - this.textureProp.needMipMap && - (fe.mipmapTools || (fe.mipmapTools = new J(this.device)), - (this.gpuTexture = fe.mipmapTools.generateMipmap(this)))); - } - setData(e) { + setData(options) { const { - source: t, - width: i = e.source.width, - height: r = e.source.height, - depth: n = 1, - sourceX: s = 0, - sourceY: a = 0, - mipLevel: o = 0, - x: c = 0, - y: l = 0, - z: h = 0, - aspect: u = "all", - colorSpace: f = "srgb", - premultipliedAlpha: d = !1 - } = e; - if (t instanceof fe) { - let e = this.device.createCommandEncoder(); - e.copyTextureToTexture( - { texture: t.gpuTexture, origin: [s, a] }, - { texture: this.gpuTexture, origin: { x: 0, y: 0, z: h }, mipLevel: o }, - { width: i, height: r, depthOrArrayLayers: 1 } - ), - this.device.queue.submit([e.finish()]), - (e = null); - } else + source, + width = options.source.width, + height = options.source.height, + depth = 1, + sourceX = 0, + sourceY = 0, + mipLevel = 0, + x = 0, + y = 0, + z = 0, + aspect = "all", + colorSpace = "srgb", + premultipliedAlpha = false + } = options; + if (source instanceof Texture) { + let commandEncoder = this.device.createCommandEncoder(); + commandEncoder.copyTextureToTexture( + { + texture: source.gpuTexture, + origin: [sourceX, sourceY] + // aspect + }, + { + texture: this.gpuTexture, + origin: { x: 0, y: 0, z }, + mipLevel + // aspect + }, + { + width, + height, + depthOrArrayLayers: 1 + } + ); + this.device.queue.submit([commandEncoder.finish()]); + commandEncoder = null; + } else { this.device.queue.copyExternalImageToTexture( - { source: t, origin: [s, a] }, + { + source, + origin: [sourceX, sourceY] + }, { texture: this.gpuTexture, - origin: [c, l, h], - mipLevel: o, - aspect: u, - colorSpace: f, - premultipliedAlpha: d + origin: [x, y, z], + mipLevel, + aspect, + colorSpace, + premultipliedAlpha }, - [i, r, n] + [width, height, depth] ); + } } - setSize(e, t, i) { - this.fixedSize || - ((this.textureProp.size.width = e), - (this.textureProp.size.height = t), - i && (this.textureProp.size.depth = i), - (this.dirty = !0)); + setSize(width, height, depth) { + if (this.fixedSize) return; + this.textureProp.size.width = width; + this.textureProp.size.height = height; + if (depth) this.textureProp.size.depth = depth; + this.dirty = true; } destroy() { this.gpuTexture.destroy(); } createGPUTexture() { - if ("number" == typeof this.textureProp.format) throw new Error("number format"); - const { width: e, height: t, depth: i } = this.textureProp.size; + if (typeof this.textureProp.format === "number") { + throw new Error("number format"); + } + const { width, height, depth } = this.textureProp.size; return this.device.createTexture({ label: this.textureProp?.label || "undefined", - size: [e, t, i], + size: [width, height, depth], dimension: this.textureProp.dimension || "2d", format: this.textureProp.format, usage: this.textureProp.usage, @@ -1069,3502 +1400,4804 @@ class fe { }); } checkNeedCreateTexture() { - const { width: e, height: t, depth: i } = this.textureProp.size; - this.gpuTexture - ? (e == this.gpuTexture.width && t == this.gpuTexture.height) || - ((this._textureView = void 0), this.gpuTexture.destroy(), (this.gpuTexture = this.createGPUTexture())) - : (this.gpuTexture = this.createGPUTexture()); - } -} -class de { - constructor(e, t = { type: "filtering" }) { - (this.descriptor = e), - (this.descriptor = {}), - Object.assign( - this.descriptor, - { - magFilter: "linear", - minFilter: "linear", - addressModeU: "clamp-to-edge", - addressModeV: "clamp-to-edge" - }, - e - ), - (this.layoutType = t); - } - update(e) { - this.gpuSampler || (this.gpuSampler = e.createSampler(this.descriptor)); - } -} -de.baseSampler = new de({ magFilter: "linear", minFilter: "linear" }); -class me { - constructor(e, t) { - (this.value = e), (this.op = "clear"), (this.storeOp = "store"), Object.assign(this, t); + const { width, height, depth } = this.textureProp.size; + if (this.gpuTexture) { + if (width != this.gpuTexture.width || height != this.gpuTexture.height) { + this._textureView = undefined; + this.gpuTexture.destroy(); + this.gpuTexture = this.createGPUTexture(); + } + } else { + this.gpuTexture = this.createGPUTexture(); + } } } -function pe(e) { - return null != e; -} -var ge = function (e) { - null == e && (e = new Date().getTime()), - (this.N = 624), - (this.M = 397), - (this.MATRIX_A = 2567483615), - (this.UPPER_MASK = 2147483648), - (this.LOWER_MASK = 2147483647), - (this.mt = new Array(this.N)), - (this.mti = this.N + 1), - e.constructor == Array ? this.init_by_array(e, e.length) : this.init_seed(e); -}; -(ge.prototype.init_seed = function (e) { - for (this.mt[0] = e >>> 0, this.mti = 1; this.mti < this.N; this.mti++) { - e = this.mt[this.mti - 1] ^ (this.mt[this.mti - 1] >>> 30); - (this.mt[this.mti] = ((1812433253 * ((4294901760 & e) >>> 16)) << 16) + 1812433253 * (65535 & e) + this.mti), - (this.mt[this.mti] >>>= 0); - } -}), - (ge.prototype.init_by_array = function (e, t) { - var i, r, n; - for (this.init_seed(19650218), i = 1, r = 0, n = this.N > t ? this.N : t; n; n--) { - var s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30); - (this.mt[i] = - (this.mt[i] ^ (((1664525 * ((4294901760 & s) >>> 16)) << 16) + 1664525 * (65535 & s))) + e[r] + r), - (this.mt[i] >>>= 0), - r++, - ++i >= this.N && ((this.mt[0] = this.mt[this.N - 1]), (i = 1)), - r >= t && (r = 0); - } - for (n = this.N - 1; n; n--) { - s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30); - (this.mt[i] = - (this.mt[i] ^ (((1566083941 * ((4294901760 & s) >>> 16)) << 16) + 1566083941 * (65535 & s))) - i), - (this.mt[i] >>>= 0), - ++i >= this.N && ((this.mt[0] = this.mt[this.N - 1]), (i = 1)); - } - this.mt[0] = 2147483648; - }), - (ge.prototype.random_int = function () { - var e, - t = new Array(0, this.MATRIX_A); - if (this.mti >= this.N) { - var i; - for (this.mti == this.N + 1 && this.init_seed(5489), i = 0; i < this.N - this.M; i++) - (e = (this.mt[i] & this.UPPER_MASK) | (this.mt[i + 1] & this.LOWER_MASK)), - (this.mt[i] = this.mt[i + this.M] ^ (e >>> 1) ^ t[1 & e]); - for (; i < this.N - 1; i++) - (e = (this.mt[i] & this.UPPER_MASK) | (this.mt[i + 1] & this.LOWER_MASK)), - (this.mt[i] = this.mt[i + (this.M - this.N)] ^ (e >>> 1) ^ t[1 & e]); - (e = (this.mt[this.N - 1] & this.UPPER_MASK) | (this.mt[0] & this.LOWER_MASK)), - (this.mt[this.N - 1] = this.mt[this.M - 1] ^ (e >>> 1) ^ t[1 & e]), - (this.mti = 0); + +class Sampler { + constructor( + descriptor, + layoutType = { + type: "filtering" } - return ( - (e = this.mt[this.mti++]), - (e ^= e >>> 11), - (e ^= (e << 7) & 2636928640), - (e ^= (e << 15) & 4022730752), - (e ^= e >>> 18) >>> 0 - ); - }), - (ge.prototype.random_int31 = function () { - return this.random_int() >>> 1; - }), - (ge.prototype.random_incl = function () { - return this.random_int() * (1 / 4294967295); - }), - (ge.prototype.random = function () { - return this.random_int() * (1 / 4294967296); - }), - (ge.prototype.random_excl = function () { - return (this.random_int() + 0.5) * (1 / 4294967296); - }), - (ge.prototype.random_long = function () { - return (67108864 * (this.random_int() >>> 5) + (this.random_int() >>> 6)) * (1 / 9007199254740992); - }); -var xe = ge; -class ve { - static signNotZero(e) { - return e < 0 ? -1 : 1; - } - static toSNorm(e, t) { - return (t = ee(t, 255)), Math.round((0.5 * ve.clamp(e, -1, 1) + 0.5) * t); - } - static fromSNorm(e, t) { - return (t = ee(t, 255)), (ve.clamp(e, 0, t) / t) * 2 - 1; - } - static normalize(e, t, i) { - return 0 === (i = Math.max(i - t, 0)) ? 0 : ve.clamp((e - t) / i, 0, 1); - } - static lerp(e, t, i) { - return (1 - i) * e + i * t; - } - static toRadians(e) { - if (!pe(e)) throw new Error("degrees is required."); - return e * ve.RADIANS_PER_DEGREE; - } - static toDegrees(e) { - if (!pe(e)) throw new Error("radians is required."); - return e * ve.DEGREES_PER_RADIAN; - } - static negativePiToPi(e) { - if (!pe(e)) throw new Error("angle is required."); - return e >= -ve.PI && e <= ve.PI ? e : ve.zeroToTwoPi(e + ve.PI) - ve.PI; - } - static zeroToTwoPi(e) { - if (!pe(e)) throw new Error("angle is required."); - if (e >= 0 && e <= ve.TWO_PI) return e; - const t = ve.mod(e, ve.TWO_PI); - return Math.abs(t) < ve.EPSILON14 && Math.abs(e) > ve.EPSILON14 ? ve.TWO_PI : t; - } - static mod(e, t) { - if (!pe(e)) throw new Error("m is required."); - if (!pe(t)) throw new Error("n is required."); - if (0 === t) throw new Error("divisor cannot be 0."); - return ve.sign(e) === ve.sign(t) && Math.abs(e) < Math.abs(t) ? e : ((e % t) + t) % t; - } - static equalsEpsilon(e, t, i, r = i) { - if (!pe(e)) throw new Error("left is required."); - if (!pe(t)) throw new Error("right is required."); - (i = ee(i, 0)), (r = ee(r, i)); - const n = Math.abs(e - t); - return n <= r || n <= i * Math.max(Math.abs(e), Math.abs(t)); - } - static lessThan(e, t, i = 0) { - if (!pe(e)) throw new Error("first is required."); - if (!pe(t)) throw new Error("second is required."); - if (!pe(i)) throw new Error("absoluteEpsilon is required."); - return e - t < -i; - } - static lessThanOrEquals(e, t, i = 0) { - if (!pe(e)) throw new Error("first is required."); - if (!pe(t)) throw new Error("second is required."); - if (!pe(i)) throw new Error("absoluteEpsilon is required."); - return e - t < i; - } - static greaterThan(e, t, i = 0) { - if (!pe(e)) throw new Error("first is required."); - if (!pe(t)) throw new Error("second is required."); - if (!pe(i)) throw new Error("absoluteEpsilon is required."); - return e - t > i; - } - static greaterThanOrEquals(e, t, i = 0) { - if (!pe(e)) throw new Error("first is required."); - if (!pe(t)) throw new Error("second is required."); - if (!pe(i)) throw new Error("absoluteEpsilon is required."); - return e - t > -i; - } - static isPowerOfTwo(e) { - if ("number" != typeof e || e < 0 || e > 4294967295) - throw new Error("A number between 0 and (2^32)-1 is required."); - return 0 !== e && 0 == (e & (e - 1)); - } - static nextPowerOfTwo(e) { - if ("number" != typeof e || e < 0 || e > 2147483648) - throw new Error("A number between 0 and 2^31 is required."); - return --e, (e |= e >> 1), (e |= e >> 2), (e |= e >> 4), (e |= e >> 8), (e |= e >> 16), ++e; - } - static previousPowerOfTwo(e) { - if ("number" != typeof e || e < 0 || e > 4294967295) - throw new Error("A number between 0 and (2^32)-1 is required."); - return ( - (e |= e >> 1), - (e |= e >> 2), - (e |= e >> 4), - (e |= e >> 8), - (e |= e >> 16), - (e = ((e |= e >> 32) >>> 0) - (e >>> 1)) + ) { + this.descriptor = descriptor; + this.descriptor = {}; + Object.assign( + this.descriptor, + { + magFilter: "linear", + minFilter: "linear", + // mipmapFilter: "linear", + addressModeU: "clamp-to-edge", + addressModeV: "clamp-to-edge" + // addressModeW: "clamp-to-edge", + }, + descriptor ); + this.layoutType = layoutType; } - static clamp(e, t, i) { - return e < t ? t : e > i ? i : e; - } - static fog(e, t) { - const i = e * t; - return 1 - Math.exp(-i * i); - } -} -(ve.EPSILON1 = 0.1), - (ve.EPSILON2 = 0.01), - (ve.EPSILON3 = 0.001), - (ve.EPSILON4 = 1e-4), - (ve.EPSILON5 = 1e-5), - (ve.EPSILON6 = 1e-6), - (ve.EPSILON7 = 1e-7), - (ve.EPSILON8 = 1e-8), - (ve.EPSILON9 = 1e-9), - (ve.EPSILON10 = 1e-10), - (ve.EPSILON11 = 1e-11), - (ve.EPSILON12 = 1e-12), - (ve.EPSILON13 = 1e-13), - (ve.EPSILON14 = 1e-14), - (ve.EPSILON15 = 1e-15), - (ve.EPSILON16 = 1e-16), - (ve.EPSILON17 = 1e-17), - (ve.EPSILON18 = 1e-18), - (ve.EPSILON19 = 1e-19), - (ve.EPSILON20 = 1e-20), - (ve.EPSILON21 = 1e-21), - (ve.GRAVITATIONALPARAMETER = 3986004418e5), - (ve.SIXTY_FOUR_KILOBYTES = 65536), - (ve.FOUR_GIGABYTES = 4294967296), - (ve.sign = ee(Math.sign, function (e) { - return 0 === (e = +e) || e != e ? e : e > 0 ? 1 : -1; - })), - (ve.sinh = ee(Math.sinh, function (e) { - return (Math.exp(e) - Math.exp(-e)) / 2; - })), - (ve.cosh = ee(Math.cosh, function (e) { - return (Math.exp(e) + Math.exp(-e)) / 2; - })), - (ve.PI = Math.PI), - (ve.ONE_OVER_PI = 1 / Math.PI), - (ve.PI_OVER_TWO = Math.PI / 2), - (ve.PI_OVER_THREE = Math.PI / 3), - (ve.PI_OVER_FOUR = Math.PI / 4), - (ve.PI_OVER_SIX = Math.PI / 6), - (ve.THREE_PI_OVER_TWO = (3 * Math.PI) / 2), - (ve.TWO_PI = 2 * Math.PI), - (ve.ONE_OVER_TWO_PI = 1 / (2 * Math.PI)), - (ve.RADIANS_PER_DEGREE = Math.PI / 180), - (ve.DEGREES_PER_RADIAN = 180 / Math.PI), - (ve.RADIANS_PER_ARCSECOND = ve.RADIANS_PER_DEGREE / 3600), - (ve.nextRandomNumber = function () { - return ye.random(); - }), - (ve.randomBetween = function (e, t) { - return ve.nextRandomNumber() * (t - e) + e; - }), - (ve.acosClamped = function (e) { - if (!pe(e)) throw new Error("value is required."); - return Math.acos(ve.clamp(e, -1, 1)); - }), - (ve.asinClamped = function (e) { - if (!pe(e)) throw new Error("value is required."); - return Math.asin(ve.clamp(e, -1, 1)); - }), - (ve.chordLength = function (e, t) { - if (!pe(e)) throw new Error("angle is required."); - if (!pe(t)) throw new Error("radius is required."); - return 2 * t * Math.sin(0.5 * e); - }), - (ve.logBase = function (e, t) { - if (!pe(e)) throw new Error("number is required."); - if (!pe(t)) throw new Error("base is required."); - return Math.log(e) / Math.log(t); - }), - (ve.cbrt = ee(Math.cbrt, function (e) { - const t = Math.pow(Math.abs(e), 1 / 3); - return e < 0 ? -t : t; - })), - (ve.log2 = ee(Math.log2, function (e) { - return Math.log(e) * Math.LOG2E; - })); -const ye = new xe(); -class Se { - constructor(e = 0, t = 0) { - (this.x = e), (this.y = t), (this.x = e), (this.y = t); - } - set(e, t) { - return (this.x = e), (this.y = t), this; + update(device) { + if (!this.gpuSampler) this.gpuSampler = device.createSampler(this.descriptor); } - toArray() { - return [this.x, this.y]; +} +Sampler.baseSampler = new Sampler({ + magFilter: "linear", + minFilter: "linear" +}); + +class Attachment { + constructor(value, options) { + this.value = value; + this.op = "clear"; + this.storeOp = "store"; + Object.assign(this, options); } - clone(e) { - return Se.clone(this, e); +} + +function defined(value) { + return value !== undefined && value !== null; +} + +/* + https://github.com/banksean wrapped Makoto Matsumoto and Takuji Nishimura's code in a namespace + so it's better encapsulated. Now you can have multiple random number generators + and they won't stomp all over eachother's state. + + If you want to use this as a substitute for Math.random(), use the random() + method like so: + + var m = new MersenneTwister(); + var randomNumber = m.random(); + + You can also call the other genrand_{foo}() methods on the instance. + + If you want to use a specific seed in order to get a repeatable random + sequence, pass an integer into the constructor: + + var m = new MersenneTwister(123); + + and that will always produce the same random sequence. + + Sean McCullough (banksean@gmail.com) +*/ + +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_seed(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +var MersenneTwister = function (seed) { + if (seed == undefined) { + seed = new Date().getTime(); } - equals(e) { - return Se.equals(this, e); + + /* Period parameters */ + this.N = 624; + this.M = 397; + this.MATRIX_A = 0x9908b0df; /* constant vector a */ + this.UPPER_MASK = 0x80000000; /* most significant w-r bits */ + this.LOWER_MASK = 0x7fffffff; /* least significant r bits */ + + this.mt = new Array(this.N); /* the array for the state vector */ + this.mti = this.N + 1; /* mti==N+1 means mt[N] is not initialized */ + + if (seed.constructor == Array) { + this.init_by_array(seed, seed.length); + } else { + this.init_seed(seed); } - equalsEpsilon(e, t = 0, i = 0) { - return Se.equalsEpsilon(this, e, t, i); +}; + +/* initializes mt[N] with a seed */ +/* origin name init_genrand */ +MersenneTwister.prototype.init_seed = function (s) { + this.mt[0] = s >>> 0; + for (this.mti = 1; this.mti < this.N; this.mti++) { + var s = this.mt[this.mti - 1] ^ (this.mt[this.mti - 1] >>> 30); + this.mt[this.mti] = ((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253 + this.mti; + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + this.mt[this.mti] >>>= 0; + /* for >32 bit machines */ } - toString() { - return `(${this.x}, ${this.y})`; +}; + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +/* slight change for C++, 2004/2/26 */ +MersenneTwister.prototype.init_by_array = function (init_key, key_length) { + var i, j, k; + this.init_seed(19650218); + i = 1; + j = 0; + k = this.N > key_length ? this.N : key_length; + for (; k; k--) { + var s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30); + this.mt[i] = + (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1664525) << 16) + (s & 0x0000ffff) * 1664525)) + + init_key[j] + + j; /* non linear */ + this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */ + i++; + j++; + if (i >= this.N) { + this.mt[0] = this.mt[this.N - 1]; + i = 1; + } + if (j >= key_length) j = 0; + } + for (k = this.N - 1; k; k--) { + var s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30); + this.mt[i] = + (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1566083941) << 16) + (s & 0x0000ffff) * 1566083941)) - + i; /* non linear */ + this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */ + i++; + if (i >= this.N) { + this.mt[0] = this.mt[this.N - 1]; + i = 1; + } } - fromBufferAttribute(e, t) { - return (this.x = e.getX(t)), (this.y = e.getY(t)), this; + + this.mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */ +}; + +/* generates a random number on [0,0xffffffff]-interval */ +/* origin name genrand_int32 */ +MersenneTwister.prototype.random_int = function () { + var y; + var mag01 = new Array(0x0, this.MATRIX_A); + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (this.mti >= this.N) { + /* generate N words at one time */ + var kk; + + if (this.mti == this.N + 1) + /* if init_seed() has not been called, */ + this.init_seed(5489); /* a default initial seed is used */ + + for (kk = 0; kk < this.N - this.M; kk++) { + y = (this.mt[kk] & this.UPPER_MASK) | (this.mt[kk + 1] & this.LOWER_MASK); + this.mt[kk] = this.mt[kk + this.M] ^ (y >>> 1) ^ mag01[y & 0x1]; + } + for (; kk < this.N - 1; kk++) { + y = (this.mt[kk] & this.UPPER_MASK) | (this.mt[kk + 1] & this.LOWER_MASK); + this.mt[kk] = this.mt[kk + (this.M - this.N)] ^ (y >>> 1) ^ mag01[y & 0x1]; + } + y = (this.mt[this.N - 1] & this.UPPER_MASK) | (this.mt[0] & this.LOWER_MASK); + this.mt[this.N - 1] = this.mt[this.M - 1] ^ (y >>> 1) ^ mag01[y & 0x1]; + + this.mti = 0; } - applyMatrix3(e) { - const t = this.x, - i = this.y; - return (this.x = e[0] * t + e[3] * i + e[6]), (this.y = e[1] * t + e[4] * i + e[7]), this; + + y = this.mt[this.mti++]; + + /* Tempering */ + y ^= y >>> 11; + y ^= (y << 7) & 0x9d2c5680; + y ^= (y << 15) & 0xefc60000; + y ^= y >>> 18; + + return y >>> 0; +}; + +/* generates a random number on [0,0x7fffffff]-interval */ +/* origin name genrand_int31 */ +MersenneTwister.prototype.random_int31 = function () { + return this.random_int() >>> 1; +}; + +/* generates a random number on [0,1]-real-interval */ +/* origin name genrand_real1 */ +MersenneTwister.prototype.random_incl = function () { + return this.random_int() * (1.0 / 4294967295.0); + /* divided by 2^32-1 */ +}; + +/* generates a random number on [0,1)-real-interval */ +MersenneTwister.prototype.random = function () { + return this.random_int() * (1.0 / 4294967296.0); + /* divided by 2^32 */ +}; + +/* generates a random number on (0,1)-real-interval */ +/* origin name genrand_real3 */ +MersenneTwister.prototype.random_excl = function () { + return (this.random_int() + 0.5) * (1.0 / 4294967296.0); + /* divided by 2^32 */ +}; + +/* generates a random number on [0,1) with 53-bit resolution*/ +/* origin name genrand_res53 */ +MersenneTwister.prototype.random_long = function () { + var a = this.random_int() >>> 5, + b = this.random_int() >>> 6; + return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); +}; + +/* These real versions are due to Isaku Wada, 2002/01/09 added */ + +var mersenneTwister = MersenneTwister; + +class GMath { + static signNotZero(value) { + return value < 0.0 ? -1.0 : 1.0; } - static fromElements(e, t, i) { - return pe(i) ? ((i.x = e), (i.y = t), i) : new Se(e, t); + static toSNorm(value, rangeMaximum) { + rangeMaximum = defaultValue(rangeMaximum, 255); + return Math.round((GMath.clamp(value, -1.0, 1.0) * 0.5 + 0.5) * rangeMaximum); } - static clone(e, t) { - if (pe(e)) return pe(t) ? ((t.x = e.x), (t.y = e.y), t) : new Se(e.x, e.y); + static fromSNorm(value, rangeMaximum) { + rangeMaximum = defaultValue(rangeMaximum, 255); + return (GMath.clamp(value, 0.0, rangeMaximum) / rangeMaximum) * 2.0 - 1.0; } - static maximumComponent(e) { - return Math.max(e.x, e.y); + static normalize(value, rangeMinimum, rangeMaximum) { + rangeMaximum = Math.max(rangeMaximum - rangeMinimum, 0.0); + return rangeMaximum === 0.0 ? 0.0 : GMath.clamp((value - rangeMinimum) / rangeMaximum, 0.0, 1.0); } - static minimumComponent(e) { - return Math.min(e.x, e.y); + static lerp(p, q, time) { + return (1.0 - time) * p + time * q; } - static minimumByComponent(e, t, i) { - return (i.x = Math.min(e.x, t.x)), (i.y = Math.min(e.y, t.y)), i; + static toRadians(degrees) { + if (!defined(degrees)) { + throw new Error("degrees is required."); + } + return degrees * GMath.RADIANS_PER_DEGREE; } - static maximumByComponent(e, t, i) { - return (i.x = Math.max(e.x, t.x)), (i.y = Math.max(e.y, t.y)), i; + static toDegrees(radians) { + if (!defined(radians)) { + throw new Error("radians is required."); + } + return radians * GMath.DEGREES_PER_RADIAN; } - static clamp(e, t, i, r) { - const n = ve.clamp(e.x, t.x, i.x), - s = ve.clamp(e.y, t.y, i.y); - return (r.x = n), (r.y = s), r; + static negativePiToPi(angle) { + if (!defined(angle)) { + throw new Error("angle is required."); + } + if (angle >= -GMath.PI && angle <= GMath.PI) { + // Early exit if the input is already inside the range. This avoids + // unnecessary math which could introduce floating point error. + return angle; + } + return GMath.zeroToTwoPi(angle + GMath.PI) - GMath.PI; } - static magnitudeSquared(e) { - return e.x * e.x + e.y * e.y; + static zeroToTwoPi(angle) { + if (!defined(angle)) { + throw new Error("angle is required."); + } + if (angle >= 0 && angle <= GMath.TWO_PI) { + // Early exit if the input is already inside the range. This avoids + // unnecessary math which could introduce floating point error. + return angle; + } + const mod = GMath.mod(angle, GMath.TWO_PI); + if (Math.abs(mod) < GMath.EPSILON14 && Math.abs(angle) > GMath.EPSILON14) { + return GMath.TWO_PI; + } + return mod; } - static magnitude(e) { - return Math.sqrt(Se.magnitudeSquared(e)); + static mod(m, n) { + if (!defined(m)) { + throw new Error("m is required."); + } + if (!defined(n)) { + throw new Error("n is required."); + } + if (n === 0.0) { + throw new Error("divisor cannot be 0."); + } + if (GMath.sign(m) === GMath.sign(n) && Math.abs(m) < Math.abs(n)) { + // Early exit if the input does not need to be modded. This avoids + // unnecessary math which could introduce floating point error. + return m; + } + return ((m % n) + n) % n; } - static distance(e, t) { - return Se.subtract(e, t, be), Se.magnitude(be); + static equalsEpsilon(left, right, relativeEpsilon, absoluteEpsilon = relativeEpsilon) { + if (!defined(left)) { + throw new Error("left is required."); + } + if (!defined(right)) { + throw new Error("right is required."); + } + relativeEpsilon = defaultValue(relativeEpsilon, 0.0); + absoluteEpsilon = defaultValue(absoluteEpsilon, relativeEpsilon); + const absDiff = Math.abs(left - right); + return absDiff <= absoluteEpsilon || absDiff <= relativeEpsilon * Math.max(Math.abs(left), Math.abs(right)); + } + static lessThan(left, right, absoluteEpsilon = 0) { + if (!defined(left)) { + throw new Error("first is required."); + } + if (!defined(right)) { + throw new Error("second is required."); + } + if (!defined(absoluteEpsilon)) { + throw new Error("absoluteEpsilon is required."); + } + return left - right < -absoluteEpsilon; } - static distanceSquared(e, t) { - return Se.subtract(e, t, be), Se.magnitudeSquared(be); + static lessThanOrEquals(left, right, absoluteEpsilon = 0) { + if (!defined(left)) { + throw new Error("first is required."); + } + if (!defined(right)) { + throw new Error("second is required."); + } + if (!defined(absoluteEpsilon)) { + throw new Error("absoluteEpsilon is required."); + } + return left - right < absoluteEpsilon; } - static normalize(e, t) { - const i = Se.magnitude(e); - if (((t.x = e.x / i), (t.y = e.y / i), isNaN(t.x) || isNaN(t.y))) - throw new Error("normalized result is not a number"); - return t; - } - static dot(e, t) { - return e.x * t.x + e.y * t.y; - } - static cross(e, t) { - return e.x * t.y - e.y * t.x; - } - static multiplyComponents(e, t, i) { - return (i.x = e.x * t.x), (i.y = e.y * t.y), i; + static greaterThan(left, right, absoluteEpsilon = 0) { + if (!defined(left)) { + throw new Error("first is required."); + } + if (!defined(right)) { + throw new Error("second is required."); + } + if (!defined(absoluteEpsilon)) { + throw new Error("absoluteEpsilon is required."); + } + return left - right > absoluteEpsilon; } - static divideComponents(e, t, i) { - return (i.x = e.x / t.x), (i.y = e.y / t.y), i; + static greaterThanOrEquals(left, right, absoluteEpsilon = 0) { + if (!defined(left)) { + throw new Error("first is required."); + } + if (!defined(right)) { + throw new Error("second is required."); + } + if (!defined(absoluteEpsilon)) { + throw new Error("absoluteEpsilon is required."); + } + return left - right > -absoluteEpsilon; } - static add(e, t, i) { - return (i.x = e.x + t.x), (i.y = e.y + t.y), i; + static isPowerOfTwo(n) { + // >>includeStart('debug', pragmas.debug); + if (typeof n !== "number" || n < 0 || n > 4294967295) { + throw new Error("A number between 0 and (2^32)-1 is required."); + } + // >>includeEnd('debug'); + return n !== 0 && (n & (n - 1)) === 0; } - static subtract(e, t, i) { - return (i.x = e.x - t.x), (i.y = e.y - t.y), i; + static nextPowerOfTwo(n) { + if (typeof n !== "number" || n < 0 || n > 2147483648) { + throw new Error("A number between 0 and 2^31 is required."); + } + // From http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 + --n; + n |= n >> 1; + n |= n >> 2; + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + ++n; + return n; } - static multiplyByScalar(e, t, i) { - return (i.x = e.x * t), (i.y = e.y * t), i; + static previousPowerOfTwo(n) { + if (typeof n !== "number" || n < 0 || n > 4294967295) { + throw new Error("A number between 0 and (2^32)-1 is required."); + } + n |= n >> 1; + n |= n >> 2; + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + n |= n >> 32; + // The previous bitwise operations implicitly convert to signed 32-bit. Use `>>>` to convert to unsigned + n = (n >>> 0) - (n >>> 1); + return n; } - static divideByScalar(e, t, i) { - return (i.x = e.x / t), (i.y = e.y / t), i; + static clamp(value, min, max) { + return value < min ? min : value > max ? max : value; } - static negate(e, t) { - return (t.x = -e.x), (t.y = -e.y), t; + /** + * @private + */ + static fog(distanceToCamera, density) { + const scalar = distanceToCamera * density; + return 1.0 - Math.exp(-(scalar * scalar)); } - static abs(e, t) { - return (t.x = Math.abs(e.x)), (t.y = Math.abs(e.y)), t; +} +GMath.EPSILON1 = 0.1; +GMath.EPSILON2 = 0.01; +GMath.EPSILON3 = 0.001; +GMath.EPSILON4 = 0.0001; +GMath.EPSILON5 = 0.00001; +GMath.EPSILON6 = 0.000001; +GMath.EPSILON7 = 0.0000001; +GMath.EPSILON8 = 0.00000001; +GMath.EPSILON9 = 0.000000001; +GMath.EPSILON10 = 0.0000000001; +GMath.EPSILON11 = 0.00000000001; +GMath.EPSILON12 = 0.000000000001; +GMath.EPSILON13 = 0.0000000000001; +GMath.EPSILON14 = 0.00000000000001; +GMath.EPSILON15 = 0.000000000000001; +GMath.EPSILON16 = 0.0000000000000001; +GMath.EPSILON17 = 0.00000000000000001; +GMath.EPSILON18 = 0.000000000000000001; +GMath.EPSILON19 = 0.0000000000000000001; +GMath.EPSILON20 = 0.00000000000000000001; +GMath.EPSILON21 = 0.000000000000000000001; +GMath.GRAVITATIONALPARAMETER = 3.986004418e14; +GMath.SIXTY_FOUR_KILOBYTES = 64 * 1024; +GMath.FOUR_GIGABYTES = 4 * 1024 * 1024 * 1024; +GMath.sign = defaultValue(Math.sign, function sign(value) { + value = +value; // coerce to number + if (value === 0 || value !== value) { + // zero or NaN + return value; + } + return value > 0 ? 1 : -1; +}); +GMath.sinh = defaultValue(Math.sinh, function sinh(value) { + return (Math.exp(value) - Math.exp(-value)) / 2.0; +}); +GMath.cosh = defaultValue(Math.cosh, function cosh(value) { + return (Math.exp(value) + Math.exp(-value)) / 2.0; +}); +GMath.PI = Math.PI; +GMath.ONE_OVER_PI = 1.0 / Math.PI; +GMath.PI_OVER_TWO = Math.PI / 2.0; +GMath.PI_OVER_THREE = Math.PI / 3.0; +GMath.PI_OVER_FOUR = Math.PI / 4.0; +GMath.PI_OVER_SIX = Math.PI / 6.0; +GMath.THREE_PI_OVER_TWO = (3.0 * Math.PI) / 2.0; +GMath.TWO_PI = 2.0 * Math.PI; +GMath.ONE_OVER_TWO_PI = 1.0 / (2.0 * Math.PI); +GMath.RADIANS_PER_DEGREE = Math.PI / 180.0; +GMath.DEGREES_PER_RADIAN = 180.0 / Math.PI; +GMath.RADIANS_PER_ARCSECOND = GMath.RADIANS_PER_DEGREE / 3600.0; +GMath.nextRandomNumber = function () { + return randomNumberGenerator.random(); +}; +GMath.randomBetween = function (min, max) { + return GMath.nextRandomNumber() * (max - min) + min; +}; +GMath.acosClamped = function (value) { + if (!defined(value)) { + throw new Error("value is required."); } - static lerp(e, t, i, r) { - return Se.multiplyByScalar(t, i, we), (r = Se.multiplyByScalar(e, 1 - i, r)), Se.add(we, r, r); + return Math.acos(GMath.clamp(value, -1.0, 1.0)); +}; +GMath.asinClamped = function (value) { + if (!defined(value)) { + throw new Error("value is required."); } - static angleBetween(e, t) { - return Se.normalize(e, Te), Se.normalize(t, Ee), ve.acosClamped(Se.dot(Te, Ee)); + return Math.asin(GMath.clamp(value, -1.0, 1.0)); +}; +GMath.chordLength = function (angle, radius) { + if (!defined(angle)) { + throw new Error("angle is required."); } - static mostOrthogonalAxis(e, t) { - const i = Se.normalize(e, Me); - return Se.abs(i, i), (t = i.x <= i.y ? Se.clone(Se.UNIT_X, t) : Se.clone(Se.UNIT_Y, t)); + if (!defined(radius)) { + throw new Error("radius is required."); } - static equals(e, t) { - return e === t || (pe(e) && pe(t) && e.x === t.x && e.y === t.y); + return 2.0 * radius * Math.sin(angle * 0.5); +}; +GMath.logBase = function (number, base) { + if (!defined(number)) { + throw new Error("number is required."); } - static equalsArray(e, t, i) { - return e.x === t[i] && e.y === t[i + 1]; + if (!defined(base)) { + throw new Error("base is required."); } - static equalsEpsilon(e, t, i = 0, r = 0) { - return e === t || (pe(e) && pe(t) && ve.equalsEpsilon(e.x, t.x, i, r) && ve.equalsEpsilon(e.y, t.y, i, r)); + return Math.log(number) / Math.log(base); +}; +GMath.cbrt = defaultValue(Math.cbrt, function cbrt(number) { + const result = Math.pow(Math.abs(number), 1.0 / 3.0); + return number < 0.0 ? -result : result; +}); +GMath.log2 = defaultValue(Math.log2, function log2(number) { + return Math.log(number) * Math.LOG2E; +}); +const randomNumberGenerator = new mersenneTwister(); + +/** + * A 2D Cartesian point. + * @alias Vector2 + * @constructor + * + * @param {Number} [x=0.0] The X component. + * @param {Number} [y=0.0] The Y component. + * + */ +class Vector2 { + constructor(x = 0.0, y = 0.0) { + this.x = x; + this.y = y; + this.x = x; + this.y = y; + } + set(x, y) { + this.x = x; + this.y = y; + return this; } -} -(Se.ZERO = Object.freeze(new Se(0, 0))), - (Se.ONE = Object.freeze(new Se(1, 1))), - (Se.UNIT_X = Object.freeze(new Se(1, 0))), - (Se.UNIT_Y = Object.freeze(new Se(0, 1))); -const be = new Se(), - we = new Se(), - Te = new Se(), - Ee = new Se(), - Me = new Se(); -class Ue { - constructor(e = 0, t = 0, i = 0) { - (this.x = e), (this.y = t), (this.z = i); + toArray() { + return [this.x, this.y]; } - set(e, t, i) { - return (this.x = e), (this.y = t), (this.z = i), this; + clone(result) { + return Vector2.clone(this, result); } - toArray() { - return [this.x, this.y, this.z]; + equals(right) { + return Vector2.equals(this, right); } - copy(e) { - return (this.x = e.x), (this.y = e.y), (this.z = e.z), this; - } - lerp(e, t) { - return Ue.lerp(this, e, t, this), this; - } - add(e) { - return Ue.add(this, e, this), this; - } - addScaledVector(e, t) { - return (this.x += e.x * t), (this.y += e.y * t), (this.z += e.z * t), this; - } - subtract(e) { - return Ue.subtract(this, e, this), this; - } - applyQuaternion(e) { - const t = this.x, - i = this.y, - r = this.z, - n = e.x, - s = e.y, - a = e.z, - o = e.w, - c = o * t + s * r - a * i, - l = o * i + a * t - n * r, - h = o * r + n * i - s * t, - u = -n * t - s * i - a * r; - return ( - (this.x = c * o + u * -n + l * -a - h * -s), - (this.y = l * o + u * -s + h * -n - c * -a), - (this.z = h * o + u * -a + c * -s - l * -n), - this - ); + equalsEpsilon(right, relativeEpsilon = 0, absoluteEpsilon = 0) { + return Vector2.equalsEpsilon(this, right, relativeEpsilon, absoluteEpsilon); } - setFromMatrixColumn(e, t) { - return this.fromArray(e, 4 * t); + toString() { + return `(${this.x}, ${this.y})`; } - fromArray(e, t = 0) { - return (this.x = e[t]), (this.y = e[t + 1]), (this.z = e[t + 2]), this; + fromBufferAttribute(attribute, index) { + this.x = attribute.getX(index); + this.y = attribute.getY(index); + return this; } - multiplyByScalar(e) { - return Ue.multiplyByScalar(this, e, this), this; + applyMatrix3(matrix3) { + const x = this.x, + y = this.y; + this.x = matrix3[0] * x + matrix3[3] * y + matrix3[6]; + this.y = matrix3[1] * x + matrix3[4] * y + matrix3[7]; + return this; } - clone() { - return Ue.clone(this, new Ue()); + static fromElements(x, y, result) { + if (!defined(result)) { + return new Vector2(x, y); + } + result.x = x; + result.y = y; + return result; } - length() { - return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + static clone(cartesian, result) { + if (!defined(cartesian)) { + return undefined; + } + if (!defined(result)) { + return new Vector2(cartesian.x, cartesian.y); + } + result.x = cartesian.x; + result.y = cartesian.y; + return result; + } + static maximumComponent(cartesian) { + return Math.max(cartesian.x, cartesian.y); + } + static minimumComponent(cartesian) { + return Math.min(cartesian.x, cartesian.y); + } + static minimumByComponent(first, second, result) { + result.x = Math.min(first.x, second.x); + result.y = Math.min(first.y, second.y); + return result; + } + static maximumByComponent(first, second, result) { + result.x = Math.max(first.x, second.x); + result.y = Math.max(first.y, second.y); + return result; + } + static clamp(value, min, max, result) { + const x = GMath.clamp(value.x, min.x, max.x); + const y = GMath.clamp(value.y, min.y, max.y); + result.x = x; + result.y = y; + return result; + } + static magnitudeSquared(cartesian) { + return cartesian.x * cartesian.x + cartesian.y * cartesian.y; + } + static magnitude(cartesian) { + return Math.sqrt(Vector2.magnitudeSquared(cartesian)); + } + static distance(left, right) { + Vector2.subtract(left, right, distanceScratch$2); + return Vector2.magnitude(distanceScratch$2); + } + static distanceSquared(left, right) { + Vector2.subtract(left, right, distanceScratch$2); + return Vector2.magnitudeSquared(distanceScratch$2); + } + static normalize(cartesian, result) { + const magnitude = Vector2.magnitude(cartesian); + result.x = cartesian.x / magnitude; + result.y = cartesian.y / magnitude; + // >>includeStart('debug', pragmas.debug); + if (isNaN(result.x) || isNaN(result.y)) { + throw new Error("normalized result is not a number"); + } + // >>includeEnd('debug'); + return result; + } + static dot(left, right) { + return left.x * right.x + left.y * right.y; + } + static cross(left, right) { + return left.x * right.y - left.y * right.x; + } + static multiplyComponents(left, right, result) { + result.x = left.x * right.x; + result.y = left.y * right.y; + return result; + } + static divideComponents(left, right, result) { + result.x = left.x / right.x; + result.y = left.y / right.y; + return result; + } + static add(left, right, result) { + result.x = left.x + right.x; + result.y = left.y + right.y; + return result; + } + static subtract(left, right, result) { + result.x = left.x - right.x; + result.y = left.y - right.y; + return result; + } + static multiplyByScalar(cartesian, scalar, result) { + result.x = cartesian.x * scalar; + result.y = cartesian.y * scalar; + return result; + } + static divideByScalar(cartesian, scalar, result) { + result.x = cartesian.x / scalar; + result.y = cartesian.y / scalar; + return result; + } + static negate(cartesian, result) { + result.x = -cartesian.x; + result.y = -cartesian.y; + return result; + } + static abs(cartesian, result) { + result.x = Math.abs(cartesian.x); + result.y = Math.abs(cartesian.y); + return result; + } + static lerp(start, end, t, result) { + Vector2.multiplyByScalar(end, t, lerpScratch$3); + result = Vector2.multiplyByScalar(start, 1.0 - t, result); + return Vector2.add(lerpScratch$3, result, result); + } + static angleBetween(left, right) { + Vector2.normalize(left, angleBetweenScratch$1); + Vector2.normalize(right, angleBetweenScratch2$1); + return GMath.acosClamped(Vector2.dot(angleBetweenScratch$1, angleBetweenScratch2$1)); + } + static mostOrthogonalAxis(cartesian, result) { + const f = Vector2.normalize(cartesian, mostOrthogonalAxisScratch$1); + Vector2.abs(f, f); + if (f.x <= f.y) { + result = Vector2.clone(Vector2.UNIT_X, result); + } else { + result = Vector2.clone(Vector2.UNIT_Y, result); + } + return result; } - applyMatrix4(e) { - const t = this.x, - i = this.y, - r = this.z, - n = e, - s = 1 / (n[3] * t + n[7] * i + n[11] * r + n[15]); - return ( - (this.x = (n[0] * t + n[4] * i + n[8] * r + n[12]) * s), - (this.y = (n[1] * t + n[5] * i + n[9] * r + n[13]) * s), - (this.z = (n[2] * t + n[6] * i + n[10] * r + n[14]) * s), - this - ); + static equals(left, right) { + return left === right || (defined(left) && defined(right) && left.x === right.x && left.y === right.y); } - applyMatrix3(e) { - const t = this.x, - i = this.y, - r = this.z; - return ( - (this.x = t * e[0] + i * e[3] + r * e[6]), - (this.y = t * e[1] + i * e[4] + r * e[7]), - (this.z = t * e[2] + i * e[5] + r * e[8]), - this - ); + /** + * @private + */ + static equalsArray(cartesian, array, offset) { + return cartesian.x === array[offset] && cartesian.y === array[offset + 1]; } - transformDirection(e) { - const t = this.x, - i = this.y, - r = this.z, - n = e; + static equalsEpsilon(left, right, relativeEpsilon = 0, absoluteEpsilon = 0) { return ( - (this.x = n[0] * t + n[4] * i + n[8] * r), - (this.y = n[1] * t + n[5] * i + n[9] * r), - (this.z = n[2] * t + n[6] * i + n[10] * r), - this.normalize() + left === right || + (defined(left) && + defined(right) && + GMath.equalsEpsilon(left.x, right.x, relativeEpsilon, absoluteEpsilon) && + GMath.equalsEpsilon(left.y, right.y, relativeEpsilon, absoluteEpsilon)) ); } - setFromMatrixPosition(e) { - const t = e; - return (this.x = t[12]), (this.y = t[13]), (this.z = t[14]), this; - } - normalize() { - return Ue.normalize(this, this), this; - } - equals(e) { - return Ue.equals(this, e); - } - equalsEpsilon(e, t = 0, i = 0) { - return Ue.equalsEpsilon(this, e, t, i); - } - toString() { - return `(${this.x}, ${this.y}, ${this.z})`; - } - fromBufferAttribute(e, t) { - return (this.x = e.getX(t)), (this.y = e.getY(t)), (this.z = e.getZ(t)), this; - } - static fromVector4(e, t) { - return (t.x = e.x), (t.y = e.y), (t.z = e.z), t; - } - static fromSpherical(e, t) { - pe(t) || (t = new Ue()); - const { phi: i, radius: r, theta: n } = e, - s = Math.sin(i) * r; - return (t.x = s * Math.sin(n)), (t.y = Math.cos(i) * r), (t.z = s * Math.cos(n)), t; +} +Vector2.ZERO = Object.freeze(new Vector2(0.0, 0.0)); +Vector2.ONE = Object.freeze(new Vector2(1.0, 1.0)); +Vector2.UNIT_X = Object.freeze(new Vector2(1.0, 0.0)); +Vector2.UNIT_Y = Object.freeze(new Vector2(0.0, 1.0)); +const distanceScratch$2 = new Vector2(); +const lerpScratch$3 = new Vector2(); +const angleBetweenScratch$1 = new Vector2(); +const angleBetweenScratch2$1 = new Vector2(); +const mostOrthogonalAxisScratch$1 = new Vector2(); + +class Vector3 { + constructor(x = 0, y = 0, z = 0) { + this.x = x; + this.y = y; + this.z = z; + } + set(x, y, z) { + this.x = x; + this.y = y; + this.z = z; + return this; } - static fromElements(e, t, i, r) { - return pe(r) ? ((r.x = e), (r.y = t), (r.z = i), r) : new Ue(e, t, i); + toArray() { + return [this.x, this.y, this.z]; } - static clone(e, t = new Ue()) { - if (pe(e)) return pe(t) ? ((t.x = e.x), (t.y = e.y), (t.z = e.z), t) : new Ue(e.x, e.y, e.z); + copy(v) { + this.x = v.x; + this.y = v.y; + this.z = v.z; + return this; } - static maximumComponent(e) { - return Math.max(e.x, e.y, e.z); + lerp(end, t) { + Vector3.lerp(this, end, t, this); + return this; } - static minimumComponent(e) { - return Math.min(e.x, e.y, e.z); + add(v) { + Vector3.add(this, v, this); + return this; } - static minimumByComponent(e, t, i) { - return (i.x = Math.min(e.x, t.x)), (i.y = Math.min(e.y, t.y)), (i.z = Math.min(e.z, t.z)), i; + addScaledVector(v, s) { + this.x += v.x * s; + this.y += v.y * s; + this.z += v.z * s; + return this; } - static maximumByComponent(e, t, i) { - return (i.x = Math.max(e.x, t.x)), (i.y = Math.max(e.y, t.y)), (i.z = Math.max(e.z, t.z)), i; + subtract(v) { + Vector3.subtract(this, v, this); + return this; } - static clamp(e, t, i, r) { - const n = ve.clamp(e.x, t.x, i.x), - s = ve.clamp(e.y, t.y, i.y), - a = ve.clamp(e.z, t.z, i.z); - return (r.x = n), (r.y = s), (r.z = a), r; + applyQuaternion(q) { + const x = this.x, + y = this.y, + z = this.z; + const qx = q.x, + qy = q.y, + qz = q.z, + qw = q.w; + // calculate quat * vector + const ix = qw * x + qy * z - qz * y; + const iy = qw * y + qz * x - qx * z; + const iz = qw * z + qx * y - qy * x; + const iw = -qx * x - qy * y - qz * z; + // calculate result * inverse quat + this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + return this; } - static magnitudeSquared(e) { - return e.x * e.x + e.y * e.y + e.z * e.z; + setFromMatrixColumn(m, index) { + return this.fromArray(m, index * 4); } - static magnitude(e) { - return Math.sqrt(Ue.magnitudeSquared(e)); + fromArray(array, offset = 0) { + this.x = array[offset]; + this.y = array[offset + 1]; + this.z = array[offset + 2]; + return this; } - static distance(e, t) { - return Ue.subtract(e, t, _e), Ue.magnitude(_e); + multiplyByScalar(scale) { + Vector3.multiplyByScalar(this, scale, this); + return this; } - static distanceSquared(e, t) { - return Ue.subtract(e, t, _e), Ue.magnitudeSquared(_e); + clone() { + return Vector3.clone(this, new Vector3()); } - static normalize(e, t) { - const i = Ue.magnitude(e); - if (((t.x = e.x / i), (t.y = e.y / i), (t.z = e.z / i), isNaN(t.x) || isNaN(t.y) || isNaN(t.z))) - throw new Error("normalized result is not a number"); - return t; + length() { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); } - static dot(e, t) { - return e.x * t.x + e.y * t.y + e.z * t.z; + applyMatrix4(matrix) { + const x = this.x, + y = this.y, + z = this.z; + const e = matrix; + const w = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]); + this.x = (e[0] * x + e[4] * y + e[8] * z + e[12]) * w; + this.y = (e[1] * x + e[5] * y + e[9] * z + e[13]) * w; + this.z = (e[2] * x + e[6] * y + e[10] * z + e[14]) * w; + return this; } - static multiplyComponents(e, t, i) { - return (i.x = e.x * t.x), (i.y = e.y * t.y), (i.z = e.z * t.z), i; + applyMatrix3(matrix) { + const x = this.x, + y = this.y, + z = this.z; + this.x = x * matrix[0] + y * matrix[3] + z * matrix[6]; + this.y = x * matrix[1] + y * matrix[4] + z * matrix[7]; + this.z = x * matrix[2] + y * matrix[5] + z * matrix[8]; + return this; } - static divideComponents(e, t, i) { - return (i.x = e.x / t.x), (i.y = e.y / t.y), (i.z = e.z / t.z), i; + transformDirection(matrix) { + const x = this.x, + y = this.y, + z = this.z; + const e = matrix; + this.x = e[0] * x + e[4] * y + e[8] * z; + this.y = e[1] * x + e[5] * y + e[9] * z; + this.z = e[2] * x + e[6] * y + e[10] * z; + return this.normalize(); + } + setFromMatrixPosition(matrix) { + const e = matrix; + this.x = e[12]; + this.y = e[13]; + this.z = e[14]; + return this; } - static add(e, t, i) { - return (i.x = e.x + t.x), (i.y = e.y + t.y), (i.z = e.z + t.z), i; + normalize() { + Vector3.normalize(this, this); + return this; } - static subtract(e, t, i) { - return (i.x = e.x - t.x), (i.y = e.y - t.y), (i.z = e.z - t.z), i; + equals(right) { + return Vector3.equals(this, right); } - static multiplyByScalar(e, t, i) { - return (i.x = e.x * t), (i.y = e.y * t), (i.z = e.z * t), i; + equalsEpsilon(right, relativeEpsilon = 0, absoluteEpsilon = 0) { + return Vector3.equalsEpsilon(this, right, relativeEpsilon, absoluteEpsilon); } - static divideByScalar(e, t, i) { - return (i.x = e.x / t), (i.y = e.y / t), (i.z = e.z / t), i; + toString() { + return `(${this.x}, ${this.y}, ${this.z})`; } - static negate(e, t) { - return (t.x = -e.x), (t.y = -e.y), (t.z = -e.z), t; + fromBufferAttribute(attribute, index) { + this.x = attribute.getX(index); + this.y = attribute.getY(index); + this.z = attribute.getZ(index); + return this; } - static abs(e, t) { - return (t.x = Math.abs(e.x)), (t.y = Math.abs(e.y)), (t.z = Math.abs(e.z)), t; + static fromVector4(vec4, result) { + result.x = vec4.x; + result.y = vec4.y; + result.z = vec4.z; + return result; } - static lerp(e, t, i, r) { - return Ue.multiplyByScalar(t, i, Le), (r = Ue.multiplyByScalar(e, 1 - i, r)), Ue.add(Le, r, r); + static fromSpherical(spherical, result) { + if (!defined(result)) { + result = new Vector3(); + } + const { phi, radius, theta } = spherical; + const sinPhiRadius = Math.sin(phi) * radius; + result.x = sinPhiRadius * Math.sin(theta); + result.y = Math.cos(phi) * radius; + result.z = sinPhiRadius * Math.cos(theta); + return result; + } + static fromElements(x, y, z, result) { + if (!defined(result)) { + return new Vector3(x, y, z); + } + result.x = x; + result.y = y; + result.z = z; + return result; + } + static clone(cartesian, result = new Vector3()) { + if (!defined(cartesian)) { + return undefined; + } + if (!defined(result)) { + return new Vector3(cartesian.x, cartesian.y, cartesian.z); + } + result.x = cartesian.x; + result.y = cartesian.y; + result.z = cartesian.z; + return result; + } + static maximumComponent(cartesian) { + return Math.max(cartesian.x, cartesian.y, cartesian.z); + } + static minimumComponent(cartesian) { + return Math.min(cartesian.x, cartesian.y, cartesian.z); + } + static minimumByComponent(first, second, result) { + result.x = Math.min(first.x, second.x); + result.y = Math.min(first.y, second.y); + result.z = Math.min(first.z, second.z); + return result; + } + static maximumByComponent(first, second, result) { + result.x = Math.max(first.x, second.x); + result.y = Math.max(first.y, second.y); + result.z = Math.max(first.z, second.z); + return result; + } + static clamp(value, min, max, result) { + const x = GMath.clamp(value.x, min.x, max.x); + const y = GMath.clamp(value.y, min.y, max.y); + const z = GMath.clamp(value.z, min.z, max.z); + result.x = x; + result.y = y; + result.z = z; + return result; + } + static magnitudeSquared(cartesian) { + return cartesian.x * cartesian.x + cartesian.y * cartesian.y + cartesian.z * cartesian.z; + } + static magnitude(cartesian) { + return Math.sqrt(Vector3.magnitudeSquared(cartesian)); + } + static distance(left, right) { + Vector3.subtract(left, right, distanceScratch$1); + return Vector3.magnitude(distanceScratch$1); + } + static distanceSquared(left, right) { + Vector3.subtract(left, right, distanceScratch$1); + return Vector3.magnitudeSquared(distanceScratch$1); + } + static normalize(cartesian, result) { + const magnitude = Vector3.magnitude(cartesian); + result.x = cartesian.x / magnitude; + result.y = cartesian.y / magnitude; + result.z = cartesian.z / magnitude; + if (isNaN(result.x) || isNaN(result.y) || isNaN(result.z)) { + throw new Error("normalized result is not a number"); + } + return result; + } + static dot(left, right) { + return left.x * right.x + left.y * right.y + left.z * right.z; + } + static multiplyComponents(left, right, result) { + result.x = left.x * right.x; + result.y = left.y * right.y; + result.z = left.z * right.z; + return result; + } + static divideComponents(left, right, result) { + result.x = left.x / right.x; + result.y = left.y / right.y; + result.z = left.z / right.z; + return result; + } + static add(left, right, result) { + result.x = left.x + right.x; + result.y = left.y + right.y; + result.z = left.z + right.z; + return result; + } + static subtract(left, right, result) { + result.x = left.x - right.x; + result.y = left.y - right.y; + result.z = left.z - right.z; + return result; + } + static multiplyByScalar(cartesian, scalar, result) { + result.x = cartesian.x * scalar; + result.y = cartesian.y * scalar; + result.z = cartesian.z * scalar; + return result; + } + static divideByScalar(cartesian, scalar, result) { + result.x = cartesian.x / scalar; + result.y = cartesian.y / scalar; + result.z = cartesian.z / scalar; + return result; + } + static negate(cartesian, result) { + result.x = -cartesian.x; + result.y = -cartesian.y; + result.z = -cartesian.z; + return result; + } + static abs(cartesian, result) { + result.x = Math.abs(cartesian.x); + result.y = Math.abs(cartesian.y); + result.z = Math.abs(cartesian.z); + return result; + } + static lerp(start, end, t, result) { + Vector3.multiplyByScalar(end, t, lerpScratch$2); + result = Vector3.multiplyByScalar(start, 1.0 - t, result); + return Vector3.add(lerpScratch$2, result, result); + } + static angleBetween(left, right) { + Vector3.normalize(left, angleBetweenScratch); + Vector3.normalize(right, angleBetweenScratch2); + const cosine = Vector3.dot(angleBetweenScratch, angleBetweenScratch2); + const sine = Vector3.magnitude(Vector3.cross(angleBetweenScratch, angleBetweenScratch2, angleBetweenScratch)); + return Math.atan2(sine, cosine); + } + static mostOrthogonalAxis(cartesian, result) { + const f = Vector3.normalize(cartesian, mostOrthogonalAxisScratch); + Vector3.abs(f, f); + if (f.x <= f.y) { + if (f.x <= f.z) { + result = Vector3.clone(Vector3.UNIT_X, result); + } else { + result = Vector3.clone(Vector3.UNIT_Z, result); + } + } else if (f.y <= f.z) { + result = Vector3.clone(Vector3.UNIT_Y, result); + } else { + result = Vector3.clone(Vector3.UNIT_Z, result); + } + return result; } - static angleBetween(e, t) { - Ue.normalize(e, Ce), Ue.normalize(t, Re); - const i = Ue.dot(Ce, Re), - r = Ue.magnitude(Ue.cross(Ce, Re, Ce)); - return Math.atan2(r, i); + static projectVector(a, b, result) { + const scalar = Vector3.dot(a, b) / Vector3.dot(b, b); + return Vector3.multiplyByScalar(b, scalar, result); } - static mostOrthogonalAxis(e, t) { - const i = Ue.normalize(e, Ae); + static equals(left, right) { return ( - Ue.abs(i, i), - (t = - i.x <= i.y - ? i.x <= i.z - ? Ue.clone(Ue.UNIT_X, t) - : Ue.clone(Ue.UNIT_Z, t) - : i.y <= i.z - ? Ue.clone(Ue.UNIT_Y, t) - : Ue.clone(Ue.UNIT_Z, t)) + left === right || + (defined(left) && defined(right) && left.x === right.x && left.y === right.y && left.z === right.z) ); } - static projectVector(e, t, i) { - const r = Ue.dot(e, t) / Ue.dot(t, t); - return Ue.multiplyByScalar(t, r, i); - } - static equals(e, t) { - return e === t || (pe(e) && pe(t) && e.x === t.x && e.y === t.y && e.z === t.z); + /** + * @private + */ + static equalsArray(cartesian, array, offset) { + return cartesian.x === array[offset] && cartesian.y === array[offset + 1] && cartesian.z === array[offset + 2]; } - static equalsArray(e, t, i) { - return e.x === t[i] && e.y === t[i + 1] && e.z === t[i + 2]; - } - static equalsEpsilon(e, t, i = 0, r = 0) { + static equalsEpsilon(left, right, relativeEpsilon = 0, absoluteEpsilon = 0) { return ( - e === t || - (pe(e) && - pe(t) && - ve.equalsEpsilon(e.x, t.x, i, r) && - ve.equalsEpsilon(e.y, t.y, i, r) && - ve.equalsEpsilon(e.z, t.z, i, r)) + left === right || + (defined(left) && + defined(right) && + GMath.equalsEpsilon(left.x, right.x, relativeEpsilon, absoluteEpsilon) && + GMath.equalsEpsilon(left.y, right.y, relativeEpsilon, absoluteEpsilon) && + GMath.equalsEpsilon(left.z, right.z, relativeEpsilon, absoluteEpsilon)) ); } - static cross(e, t, i) { - const r = e.x, - n = e.y, - s = e.z, - a = t.x, - o = t.y, - c = t.z, - l = n * c - s * o, - h = s * a - r * c, - u = r * o - n * a; - return (i.x = l), (i.y = h), (i.z = u), i; - } -} -(Ue.ZERO = Object.freeze(new Ue(0, 0, 0))), - (Ue.ONE = Object.freeze(new Ue(1, 1, 1))), - (Ue.UNIT_X = Object.freeze(new Ue(1, 0, 0))), - (Ue.UNIT_Y = Object.freeze(new Ue(0, 1, 0))), - (Ue.UNIT_Z = Object.freeze(new Ue(0, 0, 1))), - (Ue.midpoint = function (e, t, i) { - return (i.x = 0.5 * (e.x + t.x)), (i.y = 0.5 * (e.y + t.y)), (i.z = 0.5 * (e.z + t.z)), i; - }); -const _e = new Ue(), - Le = new Ue(), - Ce = new Ue(), - Re = new Ue(), - Ae = new Ue(); -class De { - constructor(e, t, i) { - (this.name = e), - (this.value = t), - (this.itemSize = i), - (this.name = e), - (this.offset = 0), - (this.shaderLocation = 0), - (this.attributeType = Be.attribute), - (this.dirty = !0); + static cross(left, right, result) { + const leftX = left.x; + const leftY = left.y; + const leftZ = left.z; + const rightX = right.x; + const rightY = right.y; + const rightZ = right.z; + const x = leftY * rightZ - leftZ * rightY; + const y = leftZ * rightX - leftX * rightZ; + const z = leftX * rightY - leftY * rightX; + result.x = x; + result.y = y; + result.z = z; + return result; + } +} +Vector3.ZERO = Object.freeze(new Vector3(0.0, 0.0, 0.0)); +Vector3.ONE = Object.freeze(new Vector3(1.0, 1.0, 1.0)); +Vector3.UNIT_X = Object.freeze(new Vector3(1.0, 0.0, 0.0)); +Vector3.UNIT_Y = Object.freeze(new Vector3(0.0, 1.0, 0.0)); +Vector3.UNIT_Z = Object.freeze(new Vector3(0.0, 0.0, 1.0)); +Vector3.midpoint = function (left, right, result) { + result.x = (left.x + right.x) * 0.5; + result.y = (left.y + right.y) * 0.5; + result.z = (left.z + right.z) * 0.5; + return result; +}; +const distanceScratch$1 = new Vector3(); +const lerpScratch$2 = new Vector3(); +const angleBetweenScratch = new Vector3(); +const angleBetweenScratch2 = new Vector3(); +const mostOrthogonalAxisScratch = new Vector3(); + +class Attribute { + constructor(name, value, itemSize) { + this.name = name; + this.value = value; + this.itemSize = itemSize; + this.name = name; + this.offset = 0; + this.shaderLocation = 0; + this.attributeType = AttributeType.attribute; + this.dirty = true; } getGPUAttribute() { - return [{ shaderLocation: this.shaderLocation, format: this.format, offset: this.offset }]; + return [ + { + shaderLocation: this.shaderLocation, + format: this.format, + offset: this.offset + } + ]; } destroy() { this.value = []; } - applyMatrix3(e) { - if (2 === this.itemSize) - for (let t = 0, i = this.value.length / this.itemSize; t < i; t++) - De.v2.fromBufferAttribute(this, t), De.v2.applyMatrix3(e), this.setXY(t, De.v2.x, De.v2.y); - else if (3 === this.itemSize) - for (let t = 0, i = this.value.length / this.itemSize; t < i; t++) - De.v3.fromBufferAttribute(this, t), De.v3.applyMatrix3(e), this.setXYZ(t, De.v3.x, De.v3.y, De.v3.z); + applyMatrix3(matrix3) { + if (this.itemSize === 2) { + for (let i = 0, l = this.value.length / this.itemSize; i < l; i++) { + Attribute.v2.fromBufferAttribute(this, i); + Attribute.v2.applyMatrix3(matrix3); + this.setXY(i, Attribute.v2.x, Attribute.v2.y); + } + } else if (this.itemSize === 3) { + for (let i = 0, l = this.value.length / this.itemSize; i < l; i++) { + Attribute.v3.fromBufferAttribute(this, i); + Attribute.v3.applyMatrix3(matrix3); + this.setXYZ(i, Attribute.v3.x, Attribute.v3.y, Attribute.v3.z); + } + } return this; } - applyMatrix4(e) { - for (let t = 0, i = this.value.length / this.itemSize; t < i; t++) - De.v3.fromBufferAttribute(this, t), De.v3.applyMatrix4(e), this.setXYZ(t, De.v3.x, De.v3.y, De.v3.z); + applyMatrix4(matrix4) { + for (let i = 0, l = this.value.length / this.itemSize; i < l; i++) { + Attribute.v3.fromBufferAttribute(this, i); + Attribute.v3.applyMatrix4(matrix4); + this.setXYZ(i, Attribute.v3.x, Attribute.v3.y, Attribute.v3.z); + } return this; } - setX(e, t) { - return (this.value[e * this.itemSize] = t), this; + setX(index, x) { + this.value[index * this.itemSize] = x; + return this; } - getX(e) { - return this.value[e * this.itemSize]; + getX(index) { + const x = this.value[index * this.itemSize]; + return x; } - setY(e, t) { - return (this.value[e * this.itemSize + 1] = t), this; + setY(index, y) { + this.value[index * this.itemSize + 1] = y; + return this; } - getY(e) { - return this.value[e * this.itemSize + 1]; + getY(index) { + const y = this.value[index * this.itemSize + 1]; + return y; } - setZ(e, t) { - return (this.value[e * this.itemSize + 2] = t), this; + setZ(index, z) { + this.value[index * this.itemSize + 2] = z; + return this; } - getZ(e) { - return this.value[e * this.itemSize + 2]; + getZ(index) { + const z = this.value[index * this.itemSize + 2]; + return z; } - getW(e) { - return this.value[e * this.itemSize + 3]; + getW(index) { + const w = this.value[index * this.itemSize + 3]; + return w; } - setXY(e, t, i) { - return (e *= this.itemSize), (this.value[e + 0] = t), (this.value[e + 1] = i), this; + setXY(index, x, y) { + index *= this.itemSize; + this.value[index + 0] = x; + this.value[index + 1] = y; + return this; } - setXYZ(e, t, i, r) { - return (e *= this.itemSize), (this.value[e + 0] = t), (this.value[e + 1] = i), (this.value[e + 2] = r), this; + setXYZ(index, x, y, z) { + index *= this.itemSize; + this.value[index + 0] = x; + this.value[index + 1] = y; + this.value[index + 2] = z; + return this; } - setXYZW(e, t, i, r, n) { - return ( - (e *= this.itemSize), - (this.value[e + 0] = t), - (this.value[e + 1] = i), - (this.value[e + 2] = r), - (this.value[e + 3] = n), - this - ); + setXYZW(index, x, y, z, w) { + index *= this.itemSize; + this.value[index + 0] = x; + this.value[index + 1] = y; + this.value[index + 2] = z; + this.value[index + 3] = w; + return this; } } -(De.v3 = new Ue()), (De.v2 = new Se()); -class ze { - constructor(e, t, i) { - (this.names = e), - (this.itemSizes = i), - (this.value = t), - (this.attributeType = Be.interleavedAttribute), - (this.dirty = !0); +Attribute.v3 = new Vector3(); +Attribute.v2 = new Vector2(); +class InterleavedAttribute { + constructor(names, value, itemSizes) { + this.names = names; + this.itemSizes = itemSizes; + this.value = value; + this.attributeType = AttributeType.interleavedAttribute; + this.dirty = true; } getGPUAttribute() { - const e = []; - return ( - this.itemSizes.reduce( - (t, i, r) => ( - e.push({ - shaderLocation: r, - format: 1 == i ? `${this.format}` : `${this.format}x${i}`, - offset: t * this.byteSize - }), - t + i - ), - 0 - ), - e - ); + const result = []; + this.itemSizes.reduce((total, current, index) => { + result.push({ + shaderLocation: index, + format: current == 1 ? `${this.format}` : `${this.format}x${current}`, + offset: total * this.byteSize + }); + return (total += current); + }, 0); + return result; } destroy() { - (this.value = null), (this.names = null), (this.itemSizes = null); + this.value = null; + this.names = null; + this.itemSizes = null; } } -class Ie extends De { - constructor(e, t, i) { - super(e, t, i); - const { format: r, totalByteSize: n } = (function (e, t) { - const i = `${e}x${t}`; - return { - [L.Float32]: { - format: "float32", - totalByteSize: Float32Array.BYTES_PER_ELEMENT * t, - byteSize: Float32Array.BYTES_PER_ELEMENT - }, - [L.Float32x2]: { - format: "float32x2", - totalByteSize: Float32Array.BYTES_PER_ELEMENT * t, - byteSize: Float32Array.BYTES_PER_ELEMENT - }, - [L.Float32x3]: { - format: "float32x3", - totalByteSize: Float32Array.BYTES_PER_ELEMENT * t, - byteSize: Float32Array.BYTES_PER_ELEMENT - }, - [L.Float32x4]: { - format: "float32x4", - totalByteSize: Float32Array.BYTES_PER_ELEMENT * t, - byteSize: Float32Array.BYTES_PER_ELEMENT - } - }[i]; - })(L.Float32, i); - (this.format = r), (this.attributeByteSize = n); - } -} -class Pe extends ze { - constructor(e, t, i) { - super(e, t, i), (this.format = L.Float32), (this.byteSize = Float32Array.BYTES_PER_ELEMENT); - } -} -class Ne extends Pe { - constructor(e, t, i) { - super(e, void 0, i), (this.buffer = t); - } -} -var Be; -!(function (e) { - (e[(e.interleavedAttribute = 0)] = "interleavedAttribute"), (e[(e.attribute = 1)] = "attribute"); -})(Be || (Be = {})); -const Oe = new Map(); -class Ve { - constructor(e) { - (this.index = e.index || 0), - (this.offset = e.offset ?? 0), - (this.alignedSize = e.alignedSize ?? 0), - (this.maxOffset = e.maxOffset ?? 0), - (this.dynamic = e.dynamic ?? !1), - (this.gpuBindGroup = e.device.createBindGroup({ - label: e.label, - layout: e.layout.gpuBindGroupLayout, - entries: e.entires.map((e) => ({ binding: e.binding, resource: e.resource })) - })); - } - bind(e) { +class Float32Attribute extends Attribute { + constructor(name, value, itemSize) { + super(name, value, itemSize); + const { format, totalByteSize } = getAttributeFormat(VertexFormat.Float32, itemSize); + this.format = format; + this.attributeByteSize = totalByteSize; + } +} +class InterleavedFloat32Attribute extends InterleavedAttribute { + constructor(names, value, itemSizes) { + super(names, value, itemSizes); + this.format = VertexFormat.Float32; + this.byteSize = Float32Array.BYTES_PER_ELEMENT; + } +} +class BufferFloat32Attribute extends InterleavedFloat32Attribute { + constructor(names, buffer, itemSizes) { + super(names, undefined, itemSizes); + this.buffer = buffer; + } +} +var AttributeType; +(function (AttributeType) { + AttributeType[(AttributeType["interleavedAttribute"] = 0)] = "interleavedAttribute"; + AttributeType[(AttributeType["attribute"] = 1)] = "attribute"; +})(AttributeType || (AttributeType = {})); +function getAttributeFormat(type, itemSize) { + const key = `${type}x${itemSize}`; + return { + [VertexFormat.Float32]: { + format: "float32", + totalByteSize: Float32Array.BYTES_PER_ELEMENT * itemSize, + byteSize: Float32Array.BYTES_PER_ELEMENT + }, + [VertexFormat.Float32x2]: { + format: "float32x2", + totalByteSize: Float32Array.BYTES_PER_ELEMENT * itemSize, + byteSize: Float32Array.BYTES_PER_ELEMENT + }, + [VertexFormat.Float32x3]: { + format: "float32x3", + totalByteSize: Float32Array.BYTES_PER_ELEMENT * itemSize, + byteSize: Float32Array.BYTES_PER_ELEMENT + }, + [VertexFormat.Float32x4]: { + format: "float32x4", + totalByteSize: Float32Array.BYTES_PER_ELEMENT * itemSize, + byteSize: Float32Array.BYTES_PER_ELEMENT + } + }[key]; +} + +const bindGroupCache = new Map(); +class BindGroup { + constructor(options) { + this.index = options.index || 0; + this.offset = options.offset ?? 0; + this.alignedSize = options.alignedSize ?? 0; + this.maxOffset = options.maxOffset ?? 0; + this.dynamic = options.dynamic ?? false; + this.gpuBindGroup = options.device.createBindGroup({ + label: options.label, + layout: options.layout.gpuBindGroupLayout, + entries: options.entires.map((entity) => ({ + binding: entity.binding, + resource: entity.resource + })) + }); + } + bind(passEncoder) { + // dynamic uniforms must bind multiple times if (this.dynamic) { - const t = [0]; - (t[0] = this.offset * this.alignedSize), - (this.offset = ++this.offset < this.maxOffset ? this.offset : 0), - e.setBindGroup(this.index, this.gpuBindGroup, t); - } else e.setBindGroup(this.index, this.gpuBindGroup); + const dynamicOffsets = [0]; + dynamicOffsets[0] = this.offset * this.alignedSize; + this.offset = ++this.offset < this.maxOffset ? this.offset : 0; + passEncoder.setBindGroup(this.index, this.gpuBindGroup, dynamicOffsets); + } else { + passEncoder.setBindGroup(this.index, this.gpuBindGroup); + } } destroy() { - (this.gpuBindGroup = void 0), (this.device = void 0); + this.gpuBindGroup = undefined; + this.device = undefined; } - static getBindGroupFromCache(e) { - if (Oe.has(e.label)) return Oe.get(e.label); - { - const t = new Ve(e); - return Oe.set(e.label, t), t; + static getBindGroupFromCache(options) { + if (bindGroupCache.has(options.label)) { + return bindGroupCache.get(options.label); + } else { + const bindGroup = new BindGroup(options); + bindGroupCache.set(options.label, bindGroup); + return bindGroup; } } - static removeBindGroupFromCache(e) { - Oe.delete(e); + static removeBindGroupFromCache(bindGroup) { + bindGroupCache.delete(bindGroup); } } -class Fe { - constructor(e) { - (this.binding = e.binding), (this.resource = e.resource); + +class BindGroupEntity { + constructor(options) { + this.binding = options.binding; + this.resource = options.resource; } getGPUGroupEntity() { - return { binding: this.binding, resource: this.resource }; - } -} -class $e { - constructor(e, t, i, r, n, s) { - (this.type = e), - (this.colorAttachments = t), - (this.depthAttachment = i), - (this.stencilAttachment = r), - (this.querySet = n), - (this.fixedSize = s), - (this.renderEncoder = void 0), - (this.computeEncoder = void 0), - (this._renderPassDescriptor = void 0), - (this.commandEncoder = void 0), - (this.device = void 0), - (this.fixedSize = !1); + return { + binding: this.binding, + resource: this.resource + }; + } +} + +class RenderTarget { + constructor(type, colorAttachments, depthAttachment, stencilAttachment, querySet, fixedSize) { + this.type = type; + this.colorAttachments = colorAttachments; + this.depthAttachment = depthAttachment; + this.stencilAttachment = stencilAttachment; + this.querySet = querySet; + this.fixedSize = fixedSize; + this.renderEncoder = undefined; + this.computeEncoder = undefined; + this._renderPassDescriptor = undefined; + this.commandEncoder = undefined; + this.device = undefined; + this.fixedSize = false; } get renderPassDescriptor() { - return (this._renderPassDescriptor = this.getRenderPassDescriptor()), this._renderPassDescriptor; + this._renderPassDescriptor = this.getRenderPassDescriptor(); + return this._renderPassDescriptor; } - getColorTexture(e = 0) { - const t = this.colorAttachments[e]; - return t ? t.texture : null; + getColorTexture(index = 0) { + const colAtt = this.colorAttachments[index]; + if (colAtt) { + return colAtt.texture; + } else { + return null; + } } getDepthTexture() { - if (this.depthAttachment) return this.depthAttachment.texture; + if (this.depthAttachment) { + return this.depthAttachment.texture; + } } getRenderPassDescriptor() { - return ( - this.depthAttachment?.texture?.update(this.device), - this?.querySet?.update(this.device), - { - ...(this.colorAttachments && { - colorAttachments: this.colorAttachments.map( - (e) => ( - e?.texture?.update && e?.texture?.update(this.device), - { - view: e?.textureView?.() ?? e.texture.textureView, - resolveTarget: null != e.resolveTarget ? e.resolveTarget.textureView : void 0, - clearValue: e.value, - loadOp: e.op, - storeOp: e.storeOp - } - ) - ) - }), - ...((this.depthAttachment || this.stencilAttachment) && { - depthStencilAttachment: { - view: this.depthAttachment?.texture?.textureView || void 0, - depthLoadOp: this.depthAttachment?.op || "clear", - depthClearValue: this.depthAttachment?.value || 1, - depthStoreOp: this.depthAttachment?.storeOp || "store", - depthReadOnly: this.depthAttachment?.readOnly || !1 - } - }), - ...(this.querySet && { occlusionQuerySet: this.querySet.gpuQuerySet }) - } - ); + this.depthAttachment?.texture?.update(this.device); + this?.querySet?.update(this.device); + return { + ...(this.colorAttachments && { + colorAttachments: this.colorAttachments.map((colorAttachment) => { + colorAttachment?.texture?.update && colorAttachment?.texture?.update(this.device); + return { + view: + // 暂时这么写 + colorAttachment?.textureView?.() ?? colorAttachment.texture.textureView, + resolveTarget: + colorAttachment.resolveTarget != undefined + ? colorAttachment.resolveTarget.textureView + : undefined, + clearValue: colorAttachment.value, + loadOp: colorAttachment.op, + storeOp: colorAttachment.storeOp + }; + }) + }), + ...((this.depthAttachment || this.stencilAttachment) && { + depthStencilAttachment: { + view: this.depthAttachment?.texture?.textureView || undefined, + depthLoadOp: this.depthAttachment?.op || "clear", + depthClearValue: this.depthAttachment?.value || 1.0, + depthStoreOp: this.depthAttachment?.storeOp || "store", + depthReadOnly: this.depthAttachment?.readOnly || false + // stencilLoadOp: this.stencilAttachment?.op || "clear", + // stencilClearValue: this.stencilAttachment?.value || 0, + // stencilStoreOp: this.stencilAttachment?.storeOp || "store", + } + }), + ...(this.querySet && { occlusionQuerySet: this.querySet.gpuQuerySet }) + }; } - beginRenderPass(e) { - return ( - this.device || (this.device = e), - (this.commandEncoder = this.device.createCommandEncoder()), - (this.renderEncoder = this.commandEncoder.beginRenderPass(this.renderPassDescriptor)), - this.renderEncoder - ); + beginRenderPass(device) { + if (!this.device) this.device = device; + this.commandEncoder = this.device.createCommandEncoder(); + this.renderEncoder = this.commandEncoder.beginRenderPass(this.renderPassDescriptor); + return this.renderEncoder; } endRenderPass() { - this.renderEncoder?.end(), - this.device.queue.submit([this.commandEncoder.finish()]), - (this.commandEncoder = null), - (this.renderEncoder = null); + this.renderEncoder?.end(); + this.device.queue.submit([this.commandEncoder.finish()]); + this.commandEncoder = null; + this.renderEncoder = null; } - beginComputePassEncoder(e) { - return ( - this.device || (this.device = e), - (this.commandEncoder = this.device.createCommandEncoder()), - (this.computeEncoder = this.commandEncoder.beginComputePass()), - this.computeEncoder - ); + beginComputePassEncoder(device) { + if (!this.device) this.device = device; + this.commandEncoder = this.device.createCommandEncoder(); + this.computeEncoder = this.commandEncoder.beginComputePass(); + return this.computeEncoder; } endComputePassEncoder() { - this.computeEncoder?.end(), - this.device.queue.submit([this.commandEncoder.finish()]), - (this.commandEncoder = null), - (this.renderEncoder = null); - } - setSize(e, t, i = 1) { - this.fixedSize || - (this?.depthAttachment?.texture?.setSize?.(e, t, i), - this?.colorAttachments?.forEach?.((r) => r?.texture?.setSize?.(e, t, i))); + this.computeEncoder?.end(); + this.device.queue.submit([this.commandEncoder.finish()]); + this.commandEncoder = null; + this.renderEncoder = null; + } + setSize(width, height, depth = 1) { + if (this.fixedSize) return; + this?.depthAttachment?.texture?.setSize?.(width, height, depth); + this?.colorAttachments?.forEach?.((colorAttachment) => + colorAttachment?.texture?.setSize?.(width, height, depth) + ); } destroy() { - this.colorAttachments && - this.colorAttachments.forEach((e) => { - e.texture && e.texture.destroy(); - }), - this.depthAttachment.texture && this.depthAttachment.texture.destroy(); - } -} -class Ge { - constructor(e = 0, t = 0, i = 0, r = 0, n = 0, s = 0, a = 0, o = 0, c = 0) { - (this[0] = e), - (this[1] = r), - (this[2] = a), - (this[3] = t), - (this[4] = n), - (this[5] = o), - (this[6] = i), - (this[7] = s), - (this[8] = c); - } - setFromMatrix4(e) { - return ( - (this[0] = e[0]), - (this[1] = e[1]), - (this[2] = e[2]), - (this[3] = e[4]), - (this[4] = e[5]), - (this[5] = e[2]), - (this[6] = e[8]), - (this[7] = e[9]), - (this[8] = e[10]), - this - ); + if (this.colorAttachments) { + this.colorAttachments.forEach((colorAttachment) => { + if (colorAttachment.texture) { + colorAttachment.texture.destroy(); + } + }); + } + if (this.depthAttachment.texture) this.depthAttachment.texture.destroy(); + } +} + +/** + * A 3x3 matrix, indexable as a column-major order array. + * @param {Number} [column0Row0=0.0] The value for column 0, row 0. + * @param {Number} [column1Row0=0.0] The value for column 1, row 0. + * @param {Number} [column2Row0=0.0] The value for column 2, row 0. + * @param {Number} [column0Row1=0.0] The value for column 0, row 1. + * @param {Number} [column1Row1=0.0] The value for column 1, row 1. + * @param {Number} [column2Row1=0.0] The value for column 2, row 1. + * @param {Number} [column0Row2=0.0] The value for column 0, row 2. + * @param {Number} [column1Row2=0.0] The value for column 1, row 2. + * @param {Number} [column2Row2=0.0] The value for column 2, row 2. + */ +class Matrix3 { + constructor( + column0Row0 = 0, + column1Row0 = 0, + column2Row0 = 0, + column0Row1 = 0, + column1Row1 = 0, + column2Row1 = 0, + column0Row2 = 0, + column1Row2 = 0, + column2Row2 = 0 + ) { + this[0] = column0Row0; + this[1] = column0Row1; + this[2] = column0Row2; + this[3] = column1Row0; + this[4] = column1Row1; + this[5] = column1Row2; + this[6] = column2Row0; + this[7] = column2Row1; + this[8] = column2Row2; + } + setFromMatrix4(matrix) { + this[0] = matrix[0]; + this[1] = matrix[1]; + this[2] = matrix[2]; + this[3] = matrix[4]; + this[4] = matrix[5]; + this[5] = matrix[2]; + this[6] = matrix[8]; + this[7] = matrix[9]; + this[8] = matrix[10]; + return this; + } + getNormalMatrix(matrix4) { + this.setFromMatrix4(matrix4); + Matrix3.inverse(this, this); + Matrix3.transpose(this, this); + return this; } - getNormalMatrix(e) { - return this.setFromMatrix4(e), Ge.inverse(this, this), Ge.transpose(this, this), this; - } - static clone(e, t) { - if (pe(e)) - return pe(t) - ? ((t[0] = e[0]), - (t[1] = e[1]), - (t[2] = e[2]), - (t[3] = e[3]), - (t[4] = e[4]), - (t[5] = e[5]), - (t[6] = e[6]), - (t[7] = e[7]), - (t[8] = e[8]), - t) - : new Ge(e[0], e[3], e[6], e[1], e[4], e[7], e[2], e[5], e[8]); - } - static fromColumnMajorArray(e, t) { - return pe(t) || (t = new Ge()), Ge.clone(e, t); - } - static fromRowMajorArray(e, t) { - return pe(t) - ? ((t[0] = e[0]), - (t[1] = e[3]), - (t[2] = e[6]), - (t[3] = e[1]), - (t[4] = e[4]), - (t[5] = e[7]), - (t[6] = e[2]), - (t[7] = e[5]), - (t[8] = e[8]), - t) - : new Ge(e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8]); - } - static fromQuaternion(e, t) { - const i = e.x * e.x, - r = e.x * e.y, - n = e.x * e.z, - s = e.x * e.w, - a = e.y * e.y, - o = e.y * e.z, - c = e.y * e.w, - l = e.z * e.z, - h = e.z * e.w, - u = e.w * e.w, - f = i - a - l + u, - d = 2 * (r - h), - m = 2 * (n + c), - p = 2 * (r + h), - g = -i + a - l + u, - x = 2 * (o - s), - v = 2 * (n - c), - y = 2 * (o + s), - S = -i - a + l + u; - return pe(t) - ? ((t[0] = f), - (t[1] = p), - (t[2] = v), - (t[3] = d), - (t[4] = g), - (t[5] = y), - (t[6] = m), - (t[7] = x), - (t[8] = S), - t) - : new Ge(f, d, m, p, g, x, v, y, S); - } - static fromScale(e, t) { - return pe(t) - ? ((t[0] = e.x), - (t[1] = 0), - (t[2] = 0), - (t[3] = 0), - (t[4] = e.y), - (t[5] = 0), - (t[6] = 0), - (t[7] = 0), - (t[8] = e.z), - t) - : new Ge(e.x, 0, 0, 0, e.y, 0, 0, 0, e.z); - } - static fromRotationX(e, t) { - const i = Math.cos(e), - r = Math.sin(e); - return pe(t) - ? ((t[0] = 1), - (t[1] = 0), - (t[2] = 0), - (t[3] = 0), - (t[4] = i), - (t[5] = r), - (t[6] = 0), - (t[7] = -r), - (t[8] = i), - t) - : new Ge(1, 0, 0, 0, i, -r, 0, r, i); - } - static fromRotationY(e, t) { - const i = Math.cos(e), - r = Math.sin(e); - return pe(t) - ? ((t[0] = i), - (t[1] = 0), - (t[2] = -r), - (t[3] = 0), - (t[4] = 1), - (t[5] = 0), - (t[6] = r), - (t[7] = 0), - (t[8] = i), - t) - : new Ge(i, 0, r, 0, 1, 0, -r, 0, i); - } - static fromRotationZstatic(e, t) { - const i = Math.cos(e), - r = Math.sin(e); - return pe(t) - ? ((t[0] = i), - (t[1] = r), - (t[2] = 0), - (t[3] = -r), - (t[4] = i), - (t[5] = 0), - (t[6] = 0), - (t[7] = 0), - (t[8] = 1), - t) - : new Ge(i, -r, 0, r, i, 0, 0, 0, 1); + static clone(matrix, result) { + if (!defined(matrix)) { + return undefined; + } + if (!defined(result)) { + return new Matrix3( + matrix[0], + matrix[3], + matrix[6], + matrix[1], + matrix[4], + matrix[7], + matrix[2], + matrix[5], + matrix[8] + ); + } + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[3]; + result[4] = matrix[4]; + result[5] = matrix[5]; + result[6] = matrix[6]; + result[7] = matrix[7]; + result[8] = matrix[8]; + return result; + } + static fromColumnMajorArray(values, result) { + if (!defined(result)) { + result = new Matrix3(); + } + return Matrix3.clone(values, result); + } + static fromRowMajorArray(values, result) { + if (!defined(result)) { + return new Matrix3( + values[0], + values[1], + values[2], + values[3], + values[4], + values[5], + values[6], + values[7], + values[8] + ); + } + result[0] = values[0]; + result[1] = values[3]; + result[2] = values[6]; + result[3] = values[1]; + result[4] = values[4]; + result[5] = values[7]; + result[6] = values[2]; + result[7] = values[5]; + result[8] = values[8]; + return result; + } + static fromQuaternion(quaternion, result) { + const x2 = quaternion.x * quaternion.x; + const xy = quaternion.x * quaternion.y; + const xz = quaternion.x * quaternion.z; + const xw = quaternion.x * quaternion.w; + const y2 = quaternion.y * quaternion.y; + const yz = quaternion.y * quaternion.z; + const yw = quaternion.y * quaternion.w; + const z2 = quaternion.z * quaternion.z; + const zw = quaternion.z * quaternion.w; + const w2 = quaternion.w * quaternion.w; + const m00 = x2 - y2 - z2 + w2; + const m01 = 2.0 * (xy - zw); + const m02 = 2.0 * (xz + yw); + const m10 = 2.0 * (xy + zw); + const m11 = -x2 + y2 - z2 + w2; + const m12 = 2.0 * (yz - xw); + const m20 = 2.0 * (xz - yw); + const m21 = 2.0 * (yz + xw); + const m22 = -x2 - y2 + z2 + w2; + if (!defined(result)) { + return new Matrix3(m00, m01, m02, m10, m11, m12, m20, m21, m22); + } + result[0] = m00; + result[1] = m10; + result[2] = m20; + result[3] = m01; + result[4] = m11; + result[5] = m21; + result[6] = m02; + result[7] = m12; + result[8] = m22; + return result; + } + static fromScale(scale, result) { + if (!defined(result)) { + return new Matrix3(scale.x, 0.0, 0.0, 0.0, scale.y, 0.0, 0.0, 0.0, scale.z); + } + result[0] = scale.x; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 0.0; + result[4] = scale.y; + result[5] = 0.0; + result[6] = 0.0; + result[7] = 0.0; + result[8] = scale.z; + return result; + } + static fromRotationX(angle, result) { + const cosAngle = Math.cos(angle); + const sinAngle = Math.sin(angle); + if (!defined(result)) { + return new Matrix3(1.0, 0.0, 0.0, 0.0, cosAngle, -sinAngle, 0.0, sinAngle, cosAngle); + } + result[0] = 1.0; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 0.0; + result[4] = cosAngle; + result[5] = sinAngle; + result[6] = 0.0; + result[7] = -sinAngle; + result[8] = cosAngle; + return result; + } + static fromRotationY(angle, result) { + const cosAngle = Math.cos(angle); + const sinAngle = Math.sin(angle); + if (!defined(result)) { + return new Matrix3(cosAngle, 0.0, sinAngle, 0.0, 1.0, 0.0, -sinAngle, 0.0, cosAngle); + } + result[0] = cosAngle; + result[1] = 0.0; + result[2] = -sinAngle; + result[3] = 0.0; + result[4] = 1.0; + result[5] = 0.0; + result[6] = sinAngle; + result[7] = 0.0; + result[8] = cosAngle; + return result; + } + static fromRotationZstatic(angle, result) { + const cosAngle = Math.cos(angle); + const sinAngle = Math.sin(angle); + if (!defined(result)) { + return new Matrix3(cosAngle, -sinAngle, 0.0, sinAngle, cosAngle, 0.0, 0.0, 0.0, 1.0); + } + result[0] = cosAngle; + result[1] = sinAngle; + result[2] = 0.0; + result[3] = -sinAngle; + result[4] = cosAngle; + result[5] = 0.0; + result[6] = 0.0; + result[7] = 0.0; + result[8] = 1.0; + return result; } toArray() { - const e = []; - return Ge.toArray(this, e), e; - } - static toArray(e, t) { - return pe(t) - ? ((t[0] = e[0]), - (t[1] = e[1]), - (t[2] = e[2]), - (t[3] = e[3]), - (t[4] = e[4]), - (t[5] = e[5]), - (t[6] = e[6]), - (t[7] = e[7]), - (t[8] = e[8]), - t) - : [e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8]]; - } - static getElementIndex(e, t) { - return 3 * e + t; - } - static getColumn(e, t, i) { - const r = 3 * t, - n = e[r], - s = e[r + 1], - a = e[r + 2]; - return (i.x = n), (i.y = s), (i.z = a), i; - } - static setColumn(e, t, i, r) { - const n = 3 * t; - return ((r = Ge.clone(e, r))[n] = i.x), (r[n + 1] = i.y), (r[n + 2] = i.z), r; - } - static getRow(e, t, i) { - const r = e[t], - n = e[t + 3], - s = e[t + 6]; - return (i.x = r), (i.y = n), (i.z = s), i; - } - static setRow(e, t, i, r) { - return ((r = Ge.clone(e, r))[t] = i.x), (r[t + 3] = i.y), (r[t + 6] = i.z), r; - } - static setScale(e, t, i) { - const r = Ge.getScale(e, ke), - n = t.x / r.x, - s = t.y / r.y, - a = t.z / r.z; + const result = []; + Matrix3.toArray(this, result); + return result; + } + static toArray(matrix, result) { + if (!defined(result)) { + return [matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6], matrix[7], matrix[8]]; + } + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[3]; + result[4] = matrix[4]; + result[5] = matrix[5]; + result[6] = matrix[6]; + result[7] = matrix[7]; + result[8] = matrix[8]; + return result; + } + static getElementIndex(column, row) { + return column * 3 + row; + } + static getColumn(matrix, index, result) { + const startIndex = index * 3; + const x = matrix[startIndex]; + const y = matrix[startIndex + 1]; + const z = matrix[startIndex + 2]; + result.x = x; + result.y = y; + result.z = z; + return result; + } + static setColumn(matrix, index, cartesian, result) { + result = Matrix3.clone(matrix, result); + const startIndex = index * 3; + result[startIndex] = cartesian.x; + result[startIndex + 1] = cartesian.y; + result[startIndex + 2] = cartesian.z; + return result; + } + static getRow(matrix, index, result) { + const x = matrix[index]; + const y = matrix[index + 3]; + const z = matrix[index + 6]; + result.x = x; + result.y = y; + result.z = z; + return result; + } + static setRow(matrix, index, cartesian, result) { + result = Matrix3.clone(matrix, result); + result[index] = cartesian.x; + result[index + 3] = cartesian.y; + result[index + 6] = cartesian.z; + return result; + } + static setScale(matrix, scale, result) { + const existingScale = Matrix3.getScale(matrix, scaleScratch1$2); + const scaleRatioX = scale.x / existingScale.x; + const scaleRatioY = scale.y / existingScale.y; + const scaleRatioZ = scale.z / existingScale.z; + result[0] = matrix[0] * scaleRatioX; + result[1] = matrix[1] * scaleRatioX; + result[2] = matrix[2] * scaleRatioX; + result[3] = matrix[3] * scaleRatioY; + result[4] = matrix[4] * scaleRatioY; + result[5] = matrix[5] * scaleRatioY; + result[6] = matrix[6] * scaleRatioZ; + result[7] = matrix[7] * scaleRatioZ; + result[8] = matrix[8] * scaleRatioZ; + return result; + } + static getScale(matrix, result) { + result.x = Vector3.magnitude(Vector3.fromElements(matrix[0], matrix[1], matrix[2], scratchColumn$2)); + result.y = Vector3.magnitude(Vector3.fromElements(matrix[3], matrix[4], matrix[5], scratchColumn$2)); + result.z = Vector3.magnitude(Vector3.fromElements(matrix[6], matrix[7], matrix[8], scratchColumn$2)); + return result; + } + static getMaximumScale(matrix) { + Matrix3.getScale(matrix, scaleScratch3$2); + return Vector3.maximumComponent(scaleScratch3$2); + } + static setRotation(matrix, rotation, result) { + const scale = Matrix3.getScale(matrix, scaleScratch4$2); + result[0] = rotation[0] * scale.x; + result[1] = rotation[1] * scale.x; + result[2] = rotation[2] * scale.x; + result[3] = rotation[3] * scale.y; + result[4] = rotation[4] * scale.y; + result[5] = rotation[5] * scale.y; + result[6] = rotation[6] * scale.z; + result[7] = rotation[7] * scale.z; + result[8] = rotation[8] * scale.z; + return result; + } + static getRotation(matrix, result) { + const scale = Matrix3.getScale(matrix, scaleScratch5$2); + result[0] = matrix[0] / scale.x; + result[1] = matrix[1] / scale.x; + result[2] = matrix[2] / scale.x; + result[3] = matrix[3] / scale.y; + result[4] = matrix[4] / scale.y; + result[5] = matrix[5] / scale.y; + result[6] = matrix[6] / scale.z; + result[7] = matrix[7] / scale.z; + result[8] = matrix[8] / scale.z; + return result; + } + static multiply(left, right, result) { + const column0Row0 = left[0] * right[0] + left[3] * right[1] + left[6] * right[2]; + const column0Row1 = left[1] * right[0] + left[4] * right[1] + left[7] * right[2]; + const column0Row2 = left[2] * right[0] + left[5] * right[1] + left[8] * right[2]; + const column1Row0 = left[0] * right[3] + left[3] * right[4] + left[6] * right[5]; + const column1Row1 = left[1] * right[3] + left[4] * right[4] + left[7] * right[5]; + const column1Row2 = left[2] * right[3] + left[5] * right[4] + left[8] * right[5]; + const column2Row0 = left[0] * right[6] + left[3] * right[7] + left[6] * right[8]; + const column2Row1 = left[1] * right[6] + left[4] * right[7] + left[7] * right[8]; + const column2Row2 = left[2] * right[6] + left[5] * right[7] + left[8] * right[8]; + result[0] = column0Row0; + result[1] = column0Row1; + result[2] = column0Row2; + result[3] = column1Row0; + result[4] = column1Row1; + result[5] = column1Row2; + result[6] = column2Row0; + result[7] = column2Row1; + result[8] = column2Row2; + return result; + } + static add(left, right, result) { + result[0] = left[0] + right[0]; + result[1] = left[1] + right[1]; + result[2] = left[2] + right[2]; + result[3] = left[3] + right[3]; + result[4] = left[4] + right[4]; + result[5] = left[5] + right[5]; + result[6] = left[6] + right[6]; + result[7] = left[7] + right[7]; + result[8] = left[8] + right[8]; + return result; + } + static subtract(left, right, result) { + result[0] = left[0] - right[0]; + result[1] = left[1] - right[1]; + result[2] = left[2] - right[2]; + result[3] = left[3] - right[3]; + result[4] = left[4] - right[4]; + result[5] = left[5] - right[5]; + result[6] = left[6] - right[6]; + result[7] = left[7] - right[7]; + result[8] = left[8] - right[8]; + return result; + } + static multiplyByVector(matrix, cartesian, result) { + const vX = cartesian.x; + const vY = cartesian.y; + const vZ = cartesian.z; + const x = matrix[0] * vX + matrix[3] * vY + matrix[6] * vZ; + const y = matrix[1] * vX + matrix[4] * vY + matrix[7] * vZ; + const z = matrix[2] * vX + matrix[5] * vY + matrix[8] * vZ; + result.x = x; + result.y = y; + result.z = z; + return result; + } + static multiplyByScalar(matrix, scalar, result) { + result[0] = matrix[0] * scalar; + result[1] = matrix[1] * scalar; + result[2] = matrix[2] * scalar; + result[3] = matrix[3] * scalar; + result[4] = matrix[4] * scalar; + result[5] = matrix[5] * scalar; + result[6] = matrix[6] * scalar; + result[7] = matrix[7] * scalar; + result[8] = matrix[8] * scalar; + return result; + } + static multiplyByScale(matrix, scale, result) { + result[0] = matrix[0] * scale.x; + result[1] = matrix[1] * scale.x; + result[2] = matrix[2] * scale.x; + result[3] = matrix[3] * scale.y; + result[4] = matrix[4] * scale.y; + result[5] = matrix[5] * scale.y; + result[6] = matrix[6] * scale.z; + result[7] = matrix[7] * scale.z; + result[8] = matrix[8] * scale.z; + return result; + } + static negate(matrix, result) { + result[0] = -matrix[0]; + result[1] = -matrix[1]; + result[2] = -matrix[2]; + result[3] = -matrix[3]; + result[4] = -matrix[4]; + result[5] = -matrix[5]; + result[6] = -matrix[6]; + result[7] = -matrix[7]; + result[8] = -matrix[8]; + return result; + } + static transpose(matrix, result) { + const column0Row0 = matrix[0]; + const column0Row1 = matrix[3]; + const column0Row2 = matrix[6]; + const column1Row0 = matrix[1]; + const column1Row1 = matrix[4]; + const column1Row2 = matrix[7]; + const column2Row0 = matrix[2]; + const column2Row1 = matrix[5]; + const column2Row2 = matrix[8]; + result[0] = column0Row0; + result[1] = column0Row1; + result[2] = column0Row2; + result[3] = column1Row0; + result[4] = column1Row1; + result[5] = column1Row2; + result[6] = column2Row0; + result[7] = column2Row1; + result[8] = column2Row2; + return result; + } + static abs(matrix, result) { + result[0] = Math.abs(matrix[0]); + result[1] = Math.abs(matrix[1]); + result[2] = Math.abs(matrix[2]); + result[3] = Math.abs(matrix[3]); + result[4] = Math.abs(matrix[4]); + result[5] = Math.abs(matrix[5]); + result[6] = Math.abs(matrix[6]); + result[7] = Math.abs(matrix[7]); + result[8] = Math.abs(matrix[8]); + return result; + } + static determinant(matrix) { + const m11 = matrix[0]; + const m21 = matrix[3]; + const m31 = matrix[6]; + const m12 = matrix[1]; + const m22 = matrix[4]; + const m32 = matrix[7]; + const m13 = matrix[2]; + const m23 = matrix[5]; + const m33 = matrix[8]; + return m11 * (m22 * m33 - m23 * m32) + m12 * (m23 * m31 - m21 * m33) + m13 * (m21 * m32 - m22 * m31); + } + static inverse(matrix, result) { + const m11 = matrix[0]; + const m21 = matrix[1]; + const m31 = matrix[2]; + const m12 = matrix[3]; + const m22 = matrix[4]; + const m32 = matrix[5]; + const m13 = matrix[6]; + const m23 = matrix[7]; + const m33 = matrix[8]; + const determinant = Matrix3.determinant(matrix); + // >>includeStart('debug', pragmas.debug); + if (Math.abs(determinant) <= GMath.EPSILON15) { + throw new Error("matrix is not invertible"); + } + // >>includeEnd('debug'); + result[0] = m22 * m33 - m23 * m32; + result[1] = m23 * m31 - m21 * m33; + result[2] = m21 * m32 - m22 * m31; + result[3] = m13 * m32 - m12 * m33; + result[4] = m11 * m33 - m13 * m31; + result[5] = m12 * m31 - m11 * m32; + result[6] = m12 * m23 - m13 * m22; + result[7] = m13 * m21 - m11 * m23; + result[8] = m11 * m22 - m12 * m21; + const scale = 1.0 / determinant; + return Matrix3.multiplyByScalar(result, scale, result); + } + static inverseTranspose(matrix, result) { + return Matrix3.inverse(Matrix3.transpose(matrix, scratchTransposeMatrix$1), result); + } + static equals(left, right) { return ( - (i[0] = e[0] * n), - (i[1] = e[1] * n), - (i[2] = e[2] * n), - (i[3] = e[3] * s), - (i[4] = e[4] * s), - (i[5] = e[5] * s), - (i[6] = e[6] * a), - (i[7] = e[7] * a), - (i[8] = e[8] * a), - i + left === right || + (defined(left) && + defined(right) && + left[0] === right[0] && + left[1] === right[1] && + left[2] === right[2] && + left[3] === right[3] && + left[4] === right[4] && + left[5] === right[5] && + left[6] === right[6] && + left[7] === right[7] && + left[8] === right[8]) ); } - static getScale(e, t) { + static equalsEpsilon(left, right, epsilon = 0) { + epsilon = defaultValue(epsilon, 0); return ( - (t.x = Ue.magnitude(Ue.fromElements(e[0], e[1], e[2], qe))), - (t.y = Ue.magnitude(Ue.fromElements(e[3], e[4], e[5], qe))), - (t.z = Ue.magnitude(Ue.fromElements(e[6], e[7], e[8], qe))), - t + left === right || + (defined(left) && + defined(right) && + Math.abs(left[0] - right[0]) <= epsilon && + Math.abs(left[1] - right[1]) <= epsilon && + Math.abs(left[2] - right[2]) <= epsilon && + Math.abs(left[3] - right[3]) <= epsilon && + Math.abs(left[4] - right[4]) <= epsilon && + Math.abs(left[5] - right[5]) <= epsilon && + Math.abs(left[6] - right[6]) <= epsilon && + Math.abs(left[7] - right[7]) <= epsilon && + Math.abs(left[8] - right[8]) <= epsilon) ); } - static getMaximumScale(e) { - return Ge.getScale(e, je), Ue.maximumComponent(je); + clone(result) { + return Matrix3.clone(this, result); } - static setRotation(e, t, i) { - const r = Ge.getScale(e, He); - return ( - (i[0] = t[0] * r.x), - (i[1] = t[1] * r.x), - (i[2] = t[2] * r.x), - (i[3] = t[3] * r.y), - (i[4] = t[4] * r.y), - (i[5] = t[5] * r.y), - (i[6] = t[6] * r.z), - (i[7] = t[7] * r.z), - (i[8] = t[8] * r.z), - i - ); + equals(right) { + return Matrix3.equals(this, right); } - static getRotation(e, t) { - const i = Ge.getScale(e, Xe); + /** + * @private + */ + equalsArray(matrix, array, offset) { return ( - (t[0] = e[0] / i.x), - (t[1] = e[1] / i.x), - (t[2] = e[2] / i.x), - (t[3] = e[3] / i.y), - (t[4] = e[4] / i.y), - (t[5] = e[5] / i.y), - (t[6] = e[6] / i.z), - (t[7] = e[7] / i.z), - (t[8] = e[8] / i.z), - t + matrix[0] === array[offset] && + matrix[1] === array[offset + 1] && + matrix[2] === array[offset + 2] && + matrix[3] === array[offset + 3] && + matrix[4] === array[offset + 4] && + matrix[5] === array[offset + 5] && + matrix[6] === array[offset + 6] && + matrix[7] === array[offset + 7] && + matrix[8] === array[offset + 8] ); } - static multiply(e, t, i) { - const r = e[0] * t[0] + e[3] * t[1] + e[6] * t[2], - n = e[1] * t[0] + e[4] * t[1] + e[7] * t[2], - s = e[2] * t[0] + e[5] * t[1] + e[8] * t[2], - a = e[0] * t[3] + e[3] * t[4] + e[6] * t[5], - o = e[1] * t[3] + e[4] * t[4] + e[7] * t[5], - c = e[2] * t[3] + e[5] * t[4] + e[8] * t[5], - l = e[0] * t[6] + e[3] * t[7] + e[6] * t[8], - h = e[1] * t[6] + e[4] * t[7] + e[7] * t[8], - u = e[2] * t[6] + e[5] * t[7] + e[8] * t[8]; - return ( - (i[0] = r), - (i[1] = n), - (i[2] = s), - (i[3] = a), - (i[4] = o), - (i[5] = c), - (i[6] = l), - (i[7] = h), - (i[8] = u), - i - ); + /** + * Compares this matrix to the provided matrix componentwise and returns + * true if they are within the provided epsilon, + * false otherwise. + * + * @param {Matrix3} [right] The right hand side matrix. + * @param {Number} [epsilon=0] The epsilon to use for equality testing. + * @returns {Boolean} true if they are within the provided epsilon, false otherwise. + */ + equalsEpsilon(right, epsilon) { + return Matrix3.equalsEpsilon(this, right, epsilon); } - static add(e, t, i) { + toString() { return ( - (i[0] = e[0] + t[0]), - (i[1] = e[1] + t[1]), - (i[2] = e[2] + t[2]), - (i[3] = e[3] + t[3]), - (i[4] = e[4] + t[4]), - (i[5] = e[5] + t[5]), - (i[6] = e[6] + t[6]), - (i[7] = e[7] + t[7]), - (i[8] = e[8] + t[8]), - i + `(${this[0]}, ${this[3]}, ${this[6]})\n` + + `(${this[1]}, ${this[4]}, ${this[7]})\n` + + `(${this[2]}, ${this[5]}, ${this[8]})` ); } - static subtract(e, t, i) { - return ( - (i[0] = e[0] - t[0]), - (i[1] = e[1] - t[1]), - (i[2] = e[2] - t[2]), - (i[3] = e[3] - t[3]), - (i[4] = e[4] - t[4]), - (i[5] = e[5] - t[5]), - (i[6] = e[6] - t[6]), - (i[7] = e[7] - t[7]), - (i[8] = e[8] - t[8]), - i - ); +} +Matrix3.IDENTITY = Object.freeze(new Matrix3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)); +Matrix3.ZERO = Object.freeze(new Matrix3(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); +const scaleScratch1$2 = new Vector3(); +new Vector3(); +const scratchColumn$2 = new Vector3(); +const scaleScratch3$2 = new Vector3(); +const scaleScratch4$2 = new Vector3(); +const scaleScratch5$2 = new Vector3(); +const scratchTransposeMatrix$1 = new Matrix3(); + +class Vector4 { + constructor(x = 0, y = 0, z = 0, w = 0) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + set(x, y, z, w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; } - static multiplyByVector(e, t, i) { - const r = t.x, - n = t.y, - s = t.z, - a = e[0] * r + e[3] * n + e[6] * s, - o = e[1] * r + e[4] * n + e[7] * s, - c = e[2] * r + e[5] * n + e[8] * s; - return (i.x = a), (i.y = o), (i.z = c), i; + toArray() { + return [this.x, this.y, this.z, this.w]; } - static multiplyByScalar(e, t, i) { - return ( - (i[0] = e[0] * t), - (i[1] = e[1] * t), - (i[2] = e[2] * t), - (i[3] = e[3] * t), - (i[4] = e[4] * t), - (i[5] = e[5] * t), - (i[6] = e[6] * t), - (i[7] = e[7] * t), - (i[8] = e[8] * t), - i - ); + clone(result) { + return Vector4.clone(this, result); } - static multiplyByScale(e, t, i) { - return ( - (i[0] = e[0] * t.x), - (i[1] = e[1] * t.x), - (i[2] = e[2] * t.x), - (i[3] = e[3] * t.y), - (i[4] = e[4] * t.y), - (i[5] = e[5] * t.y), - (i[6] = e[6] * t.z), - (i[7] = e[7] * t.z), - (i[8] = e[8] * t.z), - i - ); + equals(right) { + return Vector4.equals(this, right); } - static negate(e, t) { - return ( - (t[0] = -e[0]), - (t[1] = -e[1]), - (t[2] = -e[2]), - (t[3] = -e[3]), - (t[4] = -e[4]), - (t[5] = -e[5]), - (t[6] = -e[6]), - (t[7] = -e[7]), - (t[8] = -e[8]), - t - ); + equalsEpsilon(right, relativeEpsilon = 0, absoluteEpsilon = 0) { + return Vector4.equalsEpsilon(this, right, relativeEpsilon, absoluteEpsilon); } - static transpose(e, t) { - const i = e[0], - r = e[3], - n = e[6], - s = e[1], - a = e[4], - o = e[7], - c = e[2], - l = e[5], - h = e[8]; - return ( - (t[0] = i), - (t[1] = r), - (t[2] = n), - (t[3] = s), - (t[4] = a), - (t[5] = o), - (t[6] = c), - (t[7] = l), - (t[8] = h), - t - ); + toString() { + return `(${this.x}, ${this.y}, ${this.z}, ${this.w})`; + } + fromBufferAttribute(attribute, index) { + this.x = attribute.getX(index); + this.y = attribute.getY(index); + this.z = attribute.getZ(index); + this.w = attribute.getW(index); + return this; } - static abs(e, t) { + static fromElements(x, y, z, w, result) { + if (!defined(result)) { + return new Vector4(x, y, z, w); + } + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; + } + static clone(cartesian, result) { + if (!defined(cartesian)) { + return undefined; + } + if (!defined(result)) { + return new Vector4(cartesian.x, cartesian.y, cartesian.z, cartesian.w); + } + result.x = cartesian.x; + result.y = cartesian.y; + result.z = cartesian.z; + result.w = cartesian.w; + return result; + } + static maximumComponent(cartesian) { + return Math.max(cartesian.x, cartesian.y, cartesian.z, cartesian.w); + } + static minimumComponent(cartesian) { + return Math.min(cartesian.x, cartesian.y, cartesian.z, cartesian.w); + } + static minimumByComponent(first, second, result) { + result.x = Math.min(first.x, second.x); + result.y = Math.min(first.y, second.y); + result.z = Math.min(first.z, second.z); + result.w = Math.min(first.w, second.w); + return result; + } + static maximumByComponent(first, second, result) { + result.x = Math.max(first.x, second.x); + result.y = Math.max(first.y, second.y); + result.z = Math.max(first.z, second.z); + result.w = Math.max(first.w, second.w); + return result; + } + static clamp(value, min, max, result) { + const x = GMath.clamp(value.x, min.x, max.x); + const y = GMath.clamp(value.y, min.y, max.y); + const z = GMath.clamp(value.z, min.z, max.z); + const w = GMath.clamp(value.w, min.w, max.w); + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; + } + static magnitudeSquared(cartesian) { return ( - (t[0] = Math.abs(e[0])), - (t[1] = Math.abs(e[1])), - (t[2] = Math.abs(e[2])), - (t[3] = Math.abs(e[3])), - (t[4] = Math.abs(e[4])), - (t[5] = Math.abs(e[5])), - (t[6] = Math.abs(e[6])), - (t[7] = Math.abs(e[7])), - (t[8] = Math.abs(e[8])), - t + cartesian.x * cartesian.x + + cartesian.y * cartesian.y + + cartesian.z * cartesian.z + + cartesian.w * cartesian.w ); } - static determinant(e) { - const t = e[0], - i = e[3], - r = e[6], - n = e[1], - s = e[4], - a = e[7], - o = e[2], - c = e[5], - l = e[8]; - return t * (s * l - c * a) + n * (c * r - i * l) + o * (i * a - s * r); - } - static inverse(e, t) { - const i = e[0], - r = e[1], - n = e[2], - s = e[3], - a = e[4], - o = e[5], - c = e[6], - l = e[7], - h = e[8], - u = Ge.determinant(e); - if (Math.abs(u) <= ve.EPSILON15) throw new Error("matrix is not invertible"); - (t[0] = a * h - l * o), - (t[1] = l * n - r * h), - (t[2] = r * o - a * n), - (t[3] = c * o - s * h), - (t[4] = i * h - c * n), - (t[5] = s * n - i * o), - (t[6] = s * l - c * a), - (t[7] = c * r - i * l), - (t[8] = i * a - s * r); - const f = 1 / u; - return Ge.multiplyByScalar(t, f, t); - } - static inverseTranspose(e, t) { - return Ge.inverse(Ge.transpose(e, Ye), t); - } - static equals(e, t) { + static magnitude(cartesian) { + return Math.sqrt(Vector4.magnitudeSquared(cartesian)); + } + static distance(left, right) { + Vector4.subtract(left, right, distanceScratch); + return Vector4.magnitude(distanceScratch); + } + static distanceSquared(left, right) { + Vector4.subtract(left, right, distanceScratch); + return Vector4.magnitudeSquared(distanceScratch); + } + static normalize(cartesian, result) { + const magnitude = Vector4.magnitude(cartesian); + result.x = cartesian.x / magnitude; + result.y = cartesian.y / magnitude; + result.z = cartesian.z / magnitude; + result.w = cartesian.w / magnitude; + // >>includeStart('debug', pragmas.debug); + if (isNaN(result.x) || isNaN(result.y) || isNaN(result.z) || isNaN(result.w)) { + throw new Error("normalized result is not a number"); + } + // >>includeEnd('debug'); + return result; + } + static dot(left, right) { + return left.x * right.x + left.y * right.y + left.z * right.z + left.w * right.w; + } + static multiplyComponents(left, right, result) { + result.x = left.x * right.x; + result.y = left.y * right.y; + result.z = left.z * right.z; + result.w = left.w * right.w; + return result; + } + static divideComponents(left, right, result) { + result.x = left.x / right.x; + result.y = left.y / right.y; + result.z = left.z / right.z; + result.w = left.w / right.w; + return result; + } + static add(left, right, result) { + result.x = left.x + right.x; + result.y = left.y + right.y; + result.z = left.z + right.z; + result.w = left.w + right.w; + return result; + } + static subtract(left, right, result) { + result.x = left.x - right.x; + result.y = left.y - right.y; + result.z = left.z - right.z; + result.w = left.w - right.w; + return result; + } + static multiplyByScalar(cartesian, scalar, result) { + result.x = cartesian.x * scalar; + result.y = cartesian.y * scalar; + result.z = cartesian.z * scalar; + result.w = cartesian.w * scalar; + return result; + } + static divideByScalar(cartesian, scalar, result) { + result.x = cartesian.x / scalar; + result.y = cartesian.y / scalar; + result.z = cartesian.z / scalar; + result.w = cartesian.w / scalar; + return result; + } + static negate(cartesian, result) { + result.x = -cartesian.x; + result.y = -cartesian.y; + result.z = -cartesian.z; + result.w = -cartesian.w; + return result; + } + static abs(cartesian, result) { + result.x = Math.abs(cartesian.x); + result.y = Math.abs(cartesian.y); + result.z = Math.abs(cartesian.z); + result.w = Math.abs(cartesian.w); + return result; + } + static lerp(start, end, t, result) { + Vector4.multiplyByScalar(end, t, lerpScratch$1); + result = Vector4.multiplyByScalar(start, 1.0 - t, result); + return Vector4.add(lerpScratch$1, result, result); + } + static equals(left, right) { return ( - e === t || - (pe(e) && - pe(t) && - e[0] === t[0] && - e[1] === t[1] && - e[2] === t[2] && - e[3] === t[3] && - e[4] === t[4] && - e[5] === t[5] && - e[6] === t[6] && - e[7] === t[7] && - e[8] === t[8]) + left === right || + (defined(left) && + defined(right) && + left.x === right.x && + left.y === right.y && + left.z === right.z && + left.w === right.w) ); } - static equalsEpsilon(e, t, i = 0) { + static equalsArray(cartesian, array, offset) { return ( - (i = ee(i, 0)), - e === t || - (pe(e) && - pe(t) && - Math.abs(e[0] - t[0]) <= i && - Math.abs(e[1] - t[1]) <= i && - Math.abs(e[2] - t[2]) <= i && - Math.abs(e[3] - t[3]) <= i && - Math.abs(e[4] - t[4]) <= i && - Math.abs(e[5] - t[5]) <= i && - Math.abs(e[6] - t[6]) <= i && - Math.abs(e[7] - t[7]) <= i && - Math.abs(e[8] - t[8]) <= i) + cartesian.x === array[offset] && + cartesian.y === array[offset + 1] && + cartesian.z === array[offset + 2] && + cartesian.w === array[offset + 3] ); } - clone(e) { - return Ge.clone(this, e); - } - equals(e) { - return Ge.equals(this, e); - } - equalsArray(e, t, i) { + static equalsEpsilon(left, right, relativeEpsilon = 0, absoluteEpsilon = 0) { return ( - e[0] === t[i] && - e[1] === t[i + 1] && - e[2] === t[i + 2] && - e[3] === t[i + 3] && - e[4] === t[i + 4] && - e[5] === t[i + 5] && - e[6] === t[i + 6] && - e[7] === t[i + 7] && - e[8] === t[i + 8] + left === right || + (defined(left) && + defined(right) && + GMath.equalsEpsilon(left.x, right.x, relativeEpsilon, absoluteEpsilon) && + GMath.equalsEpsilon(left.y, right.y, relativeEpsilon, absoluteEpsilon) && + GMath.equalsEpsilon(left.z, right.z, relativeEpsilon, absoluteEpsilon) && + GMath.equalsEpsilon(left.w, right.w, relativeEpsilon, absoluteEpsilon)) ); } - equalsEpsilon(e, t) { - return Ge.equalsEpsilon(this, e, t); - } - toString() { - return `(${this[0]}, ${this[3]}, ${this[6]})\n(${this[1]}, ${this[4]}, ${this[7]})\n(${this[2]}, ${this[5]}, ${this[8]})`; - } } -(Ge.IDENTITY = Object.freeze(new Ge(1, 0, 0, 0, 1, 0, 0, 0, 1))), - (Ge.ZERO = Object.freeze(new Ge(0, 0, 0, 0, 0, 0, 0, 0, 0))); -const ke = new Ue(); -new Ue(); -const qe = new Ue(), - je = new Ue(), - He = new Ue(), - Xe = new Ue(), - Ye = new Ge(); -class We { - constructor(e = 0, t = 0, i = 0, r = 0) { - (this.x = e), (this.y = t), (this.z = i), (this.w = r); - } - set(e, t, i, r) { - (this.x = e), (this.y = t), (this.z = i), (this.w = r); - } - toArray() { - return [this.x, this.y, this.z, this.w]; +Vector4.ZERO = Object.freeze(new Vector4(0.0, 0.0, 0.0, 0.0)); +Vector4.ONE = Object.freeze(new Vector4(1.0, 1.0, 1.0, 1.0)); +Vector4.UNIT_X = Object.freeze(new Vector4(1.0, 0.0, 0.0, 0.0)); +Vector4.UNIT_Y = Object.freeze(new Vector4(0.0, 1.0, 0.0, 0.0)); +Vector4.UNIT_Z = Object.freeze(new Vector4(0.0, 0.0, 1.0, 0.0)); +Vector4.UNIT_W = Object.freeze(new Vector4(0.0, 0.0, 0.0, 1.0)); +// scratchU8Array and scratchF32Array are views into the same buffer +const scratchF32Array = new Float32Array(1); +new Uint8Array(scratchF32Array.buffer); +const testU32 = new Uint32Array([0x11223344]); +const testU8 = new Uint8Array(testU32.buffer); +testU8[0] === 0x44; +const distanceScratch = new Vector4(); +const lerpScratch$1 = new Vector4(); +new Vector4(); + +class Matrix4 { + /** + * A 4x4 matrix, indexable as a column-major order array. + * @param {Number} [column0Row0=0.0] The value for column 0, row 0. + * @param {Number} [column1Row0=0.0] The value for column 1, row 0. + * @param {Number} [column2Row0=0.0] The value for column 2, row 0. + * @param {Number} [column3Row0=0.0] The value for column 3, row 0. + * @param {Number} [column0Row1=0.0] The value for column 0, row 1. + * @param {Number} [column1Row1=0.0] The value for column 1, row 1. + * @param {Number} [column2Row1=0.0] The value for column 2, row 1. + * @param {Number} [column3Row1=0.0] The value for column 3, row 1. + * @param {Number} [column0Row2=0.0] The value for column 0, row 2. + * @param {Number} [column1Row2=0.0] The value for column 1, row 2. + * @param {Number} [column2Row2=0.0] The value for column 2, row 2. + * @param {Number} [column3Row2=0.0] The value for column 3, row 2. + * @param {Number} [column0Row3=0.0] The value for column 0, row 3. + * @param {Number} [column1Row3=0.0] The value for column 1, row 3. + * @param {Number} [column2Row3=0.0] The value for column 2, row 3. + * @param {Number} [column3Row3=0.0] The value for column 3, row 3. + */ + constructor( + column0Row0 = 0, + column1Row0 = 0, + column2Row0 = 0, + column3Row0 = 0, + column0Row1 = 0, + column1Row1 = 0, + column2Row1 = 0, + column3Row1 = 0, + column0Row2 = 0, + column1Row2 = 0, + column2Row2 = 0, + column3Row2 = 0, + column0Row3 = 0, + column1Row3 = 0, + column2Row3 = 0, + column3Row3 = 0 + ) { + this[0] = column0Row0; + this[1] = column0Row1; + this[2] = column0Row2; + this[3] = column0Row3; + this[4] = column1Row0; + this[5] = column1Row1; + this[6] = column1Row2; + this[7] = column1Row3; + this[8] = column2Row0; + this[9] = column2Row1; + this[10] = column2Row2; + this[11] = column2Row3; + this[12] = column3Row0; + this[13] = column3Row1; + this[14] = column3Row2; + this[15] = column3Row3; + } + // ???? + clone(result = new Matrix4()) { + return Matrix4.clone(this, result); + } + set(mat4) { + Matrix4.clone(mat4, this); + return this; } - clone(e) { - return We.clone(this, e); + equals(right) { + return Matrix4.equals(this, right); + } + compose(position, quaternion, scale) { + const te = this; + const x = quaternion.x, + y = quaternion.y, + z = quaternion.z, + w = quaternion.w; + const x2 = x + x, + y2 = y + y, + z2 = z + z; + const xx = x * x2, + xy = x * y2, + xz = x * z2; + const yy = y * y2, + yz = y * z2, + zz = z * z2; + const wx = w * x2, + wy = w * y2, + wz = w * z2; + const sx = scale.x, + sy = scale.y, + sz = scale.z; + te[0] = (1 - (yy + zz)) * sx; + te[1] = (xy + wz) * sx; + te[2] = (xz - wy) * sx; + te[3] = 0; + te[4] = (xy - wz) * sy; + te[5] = (1 - (xx + zz)) * sy; + te[6] = (yz + wx) * sy; + te[7] = 0; + te[8] = (xz + wy) * sz; + te[9] = (yz - wx) * sz; + te[10] = (1 - (xx + yy)) * sz; + te[11] = 0; + te[12] = position.x; + te[13] = position.y; + te[14] = position.z; + te[15] = 1; + return this; } - equals(e) { - return We.equals(this, e); + equalsEpsilon(right, epsilon = 0) { + return Matrix4.equalsEpsilon(this, right, epsilon); } - equalsEpsilon(e, t = 0, i = 0) { - return We.equalsEpsilon(this, e, t, i); + lookAt(eye, target, up) { + const matrix = this; + Vector3.subtract(eye, target, z); + if (z.length() === 0) { + // eye and target are in the same position + z.z = 1; + } + z.normalize(); + Vector3.cross(up, z, x); + if (x.length() === 0) { + // up and z are parallel + if (Math.abs(up.z) === 1) { + z.x += 0.0001; + } else { + z.z += 0.0001; + } + z.normalize(); + Vector3.cross(up, z, x); + } + x.normalize(); + Vector3.cross(z, x, y); + matrix[0] = x.x; + matrix[4] = y.x; + matrix[8] = z.x; + matrix[1] = x.y; + matrix[5] = y.y; + matrix[9] = z.y; + matrix[2] = x.z; + matrix[6] = y.z; + matrix[10] = z.z; + return this; } toString() { - return `(${this.x}, ${this.y}, ${this.z}, ${this.w})`; - } - fromBufferAttribute(e, t) { - return (this.x = e.getX(t)), (this.y = e.getY(t)), (this.z = e.getZ(t)), (this.w = e.getW(t)), this; - } - static fromElements(e, t, i, r, n) { - return pe(n) ? ((n.x = e), (n.y = t), (n.z = i), (n.w = r), n) : new We(e, t, i, r); - } - static clone(e, t) { - if (pe(e)) return pe(t) ? ((t.x = e.x), (t.y = e.y), (t.z = e.z), (t.w = e.w), t) : new We(e.x, e.y, e.z, e.w); - } - static maximumComponent(e) { - return Math.max(e.x, e.y, e.z, e.w); - } - static minimumComponent(e) { - return Math.min(e.x, e.y, e.z, e.w); - } - static minimumByComponent(e, t, i) { return ( - (i.x = Math.min(e.x, t.x)), - (i.y = Math.min(e.y, t.y)), - (i.z = Math.min(e.z, t.z)), - (i.w = Math.min(e.w, t.w)), - i + `(${this[0]}, ${this[4]}, ${this[8]}, ${this[12]})\n` + + `(${this[1]}, ${this[5]}, ${this[9]}, ${this[13]})\n` + + `(${this[2]}, ${this[6]}, ${this[10]}, ${this[14]})\n` + + `(${this[3]}, ${this[7]}, ${this[11]}, ${this[15]})` ); } - static maximumByComponent(e, t, i) { - return ( - (i.x = Math.max(e.x, t.x)), - (i.y = Math.max(e.y, t.y)), - (i.z = Math.max(e.z, t.z)), - (i.w = Math.max(e.w, t.w)), - i - ); - } - static clamp(e, t, i, r) { - const n = ve.clamp(e.x, t.x, i.x), - s = ve.clamp(e.y, t.y, i.y), - a = ve.clamp(e.z, t.z, i.z), - o = ve.clamp(e.w, t.w, i.w); - return (r.x = n), (r.y = s), (r.z = a), (r.w = o), r; - } - static magnitudeSquared(e) { - return e.x * e.x + e.y * e.y + e.z * e.z + e.w * e.w; - } - static magnitude(e) { - return Math.sqrt(We.magnitudeSquared(e)); - } - static distance(e, t) { - return We.subtract(e, t, Qe), We.magnitude(Qe); - } - static distanceSquared(e, t) { - return We.subtract(e, t, Qe), We.magnitudeSquared(Qe); - } - static normalize(e, t) { - const i = We.magnitude(e); - if ( - ((t.x = e.x / i), - (t.y = e.y / i), - (t.z = e.z / i), - (t.w = e.w / i), - isNaN(t.x) || isNaN(t.y) || isNaN(t.z) || isNaN(t.w)) - ) - throw new Error("normalized result is not a number"); - return t; - } - static dot(e, t) { - return e.x * t.x + e.y * t.y + e.z * t.z + e.w * t.w; - } - static multiplyComponents(e, t, i) { - return (i.x = e.x * t.x), (i.y = e.y * t.y), (i.z = e.z * t.z), (i.w = e.w * t.w), i; - } - static divideComponents(e, t, i) { - return (i.x = e.x / t.x), (i.y = e.y / t.y), (i.z = e.z / t.z), (i.w = e.w / t.w), i; - } - static add(e, t, i) { - return (i.x = e.x + t.x), (i.y = e.y + t.y), (i.z = e.z + t.z), (i.w = e.w + t.w), i; - } - static subtract(e, t, i) { - return (i.x = e.x - t.x), (i.y = e.y - t.y), (i.z = e.z - t.z), (i.w = e.w - t.w), i; - } - static multiplyByScalar(e, t, i) { - return (i.x = e.x * t), (i.y = e.y * t), (i.z = e.z * t), (i.w = e.w * t), i; - } - static divideByScalar(e, t, i) { - return (i.x = e.x / t), (i.y = e.y / t), (i.z = e.z / t), (i.w = e.w / t), i; - } - static negate(e, t) { - return (t.x = -e.x), (t.y = -e.y), (t.z = -e.z), (t.w = -e.w), t; - } - static abs(e, t) { - return (t.x = Math.abs(e.x)), (t.y = Math.abs(e.y)), (t.z = Math.abs(e.z)), (t.w = Math.abs(e.w)), t; - } - static lerp(e, t, i, r) { - return We.multiplyByScalar(t, i, Je), (r = We.multiplyByScalar(e, 1 - i, r)), We.add(Je, r, r); - } - static equals(e, t) { - return e === t || (pe(e) && pe(t) && e.x === t.x && e.y === t.y && e.z === t.z && e.w === t.w); - } - static equalsArray(e, t, i) { - return e.x === t[i] && e.y === t[i + 1] && e.z === t[i + 2] && e.w === t[i + 3]; - } - static equalsEpsilon(e, t, i = 0, r = 0) { - return ( - e === t || - (pe(e) && - pe(t) && - ve.equalsEpsilon(e.x, t.x, i, r) && - ve.equalsEpsilon(e.y, t.y, i, r) && - ve.equalsEpsilon(e.z, t.z, i, r) && - ve.equalsEpsilon(e.w, t.w, i, r)) - ); - } -} -(We.ZERO = Object.freeze(new We(0, 0, 0, 0))), - (We.ONE = Object.freeze(new We(1, 1, 1, 1))), - (We.UNIT_X = Object.freeze(new We(1, 0, 0, 0))), - (We.UNIT_Y = Object.freeze(new We(0, 1, 0, 0))), - (We.UNIT_Z = Object.freeze(new We(0, 0, 1, 0))), - (We.UNIT_W = Object.freeze(new We(0, 0, 0, 1))); -const Ze = new Float32Array(1); -new Uint8Array(Ze.buffer); -const Ke = new Uint32Array([287454020]); -new Uint8Array(Ke.buffer)[0]; -const Qe = new We(), - Je = new We(); -new We(); -class et { - constructor( - e = 0, - t = 0, - i = 0, - r = 0, - n = 0, - s = 0, - a = 0, - o = 0, - c = 0, - l = 0, - h = 0, - u = 0, - f = 0, - d = 0, - m = 0, - p = 0 - ) { - (this[0] = e), - (this[1] = n), - (this[2] = c), - (this[3] = f), - (this[4] = t), - (this[5] = s), - (this[6] = l), - (this[7] = d), - (this[8] = i), - (this[9] = a), - (this[10] = h), - (this[11] = m), - (this[12] = r), - (this[13] = o), - (this[14] = u), - (this[15] = p); - } - clone(e = new et()) { - return et.clone(this, e); - } - set(e) { - return et.clone(e, this), this; - } - equals(e) { - return et.equals(this, e); - } - compose(e, t, i) { - const r = this, - n = t.x, - s = t.y, - a = t.z, - o = t.w, - c = n + n, - l = s + s, - h = a + a, - u = n * c, - f = n * l, - d = n * h, - m = s * l, - p = s * h, - g = a * h, - x = o * c, - v = o * l, - y = o * h, - S = i.x, - b = i.y, - w = i.z; - return ( - (r[0] = (1 - (m + g)) * S), - (r[1] = (f + y) * S), - (r[2] = (d - v) * S), - (r[3] = 0), - (r[4] = (f - y) * b), - (r[5] = (1 - (u + g)) * b), - (r[6] = (p + x) * b), - (r[7] = 0), - (r[8] = (d + v) * w), - (r[9] = (p - x) * w), - (r[10] = (1 - (u + m)) * w), - (r[11] = 0), - (r[12] = e.x), - (r[13] = e.y), - (r[14] = e.z), - (r[15] = 1), - this - ); - } - equalsEpsilon(e, t = 0) { - return et.equalsEpsilon(this, e, t); - } - lookAt(e, t, i) { - const r = this; - return ( - Ue.subtract(e, t, dt), - 0 === dt.length() && (dt.z = 1), - dt.normalize(), - Ue.cross(i, dt, ut), - 0 === ut.length() && - (1 === Math.abs(i.z) ? (dt.x += 1e-4) : (dt.z += 1e-4), dt.normalize(), Ue.cross(i, dt, ut)), - ut.normalize(), - Ue.cross(dt, ut, ft), - (r[0] = ut.x), - (r[4] = ft.x), - (r[8] = dt.x), - (r[1] = ut.y), - (r[5] = ft.y), - (r[9] = dt.y), - (r[2] = ut.z), - (r[6] = ft.z), - (r[10] = dt.z), - this - ); - } - toString() { - return `(${this[0]}, ${this[4]}, ${this[8]}, ${this[12]})\n(${this[1]}, ${this[5]}, ${this[9]}, ${this[13]})\n(${this[2]}, ${this[6]}, ${this[10]}, ${this[14]})\n(${this[3]}, ${this[7]}, ${this[11]}, ${this[15]})`; - } - static clone(e, t) { - if (pe(e)) - return pe(t) - ? ((t[0] = e[0]), - (t[1] = e[1]), - (t[2] = e[2]), - (t[3] = e[3]), - (t[4] = e[4]), - (t[5] = e[5]), - (t[6] = e[6]), - (t[7] = e[7]), - (t[8] = e[8]), - (t[9] = e[9]), - (t[10] = e[10]), - (t[11] = e[11]), - (t[12] = e[12]), - (t[13] = e[13]), - (t[14] = e[14]), - (t[15] = e[15]), - t) - : new et( - e[0], - e[4], - e[8], - e[12], - e[1], - e[5], - e[9], - e[13], - e[2], - e[6], - e[10], - e[14], - e[3], - e[7], - e[11], - e[15] - ); - } - static fromColumnMajorArray(e, t) { - return et.clone(e, t); - } - static fromRowMajorArray(e, t) { - return pe(t) - ? ((t[0] = e[0]), - (t[1] = e[4]), - (t[2] = e[8]), - (t[3] = e[12]), - (t[4] = e[1]), - (t[5] = e[5]), - (t[6] = e[9]), - (t[7] = e[13]), - (t[8] = e[2]), - (t[9] = e[6]), - (t[10] = e[10]), - (t[11] = e[14]), - (t[12] = e[3]), - (t[13] = e[7]), - (t[14] = e[11]), - (t[15] = e[15]), - t) - : new et( - e[0], - e[1], - e[2], - e[3], - e[4], - e[5], - e[6], - e[7], - e[8], - e[9], - e[10], - e[11], - e[12], - e[13], - e[14], - e[15] - ); - } - static fromRotationTranslation(e, t, i) { - return ( - (t = ee(t, Ue.ZERO)), - pe(i) - ? ((i[0] = e[0]), - (i[1] = e[1]), - (i[2] = e[2]), - (i[3] = 0), - (i[4] = e[3]), - (i[5] = e[4]), - (i[6] = e[5]), - (i[7] = 0), - (i[8] = e[6]), - (i[9] = e[7]), - (i[10] = e[8]), - (i[11] = 0), - (i[12] = t.x), - (i[13] = t.y), - (i[14] = t.z), - (i[15] = 1), - i) - : new et(e[0], e[3], e[6], t.x, e[1], e[4], e[7], t.y, e[2], e[5], e[8], t.z, 0, 0, 0, 1) - ); - } - static fromTranslationQuaternionRotationScale(e, t, i, r) { - pe(r) || (r = new et()); - const n = i.x, - s = i.y, - a = i.z, - o = t.x * t.x, - c = t.x * t.y, - l = t.x * t.z, - h = t.x * t.w, - u = t.y * t.y, - f = t.y * t.z, - d = t.y * t.w, - m = t.z * t.z, - p = t.z * t.w, - g = t.w * t.w, - x = o - u - m + g, - v = 2 * (c - p), - y = 2 * (l + d), - S = 2 * (c + p), - b = -o + u - m + g, - w = 2 * (f - h), - T = 2 * (l - d), - E = 2 * (f + h), - M = -o - u + m + g; - return ( - (r[0] = x * n), - (r[1] = S * n), - (r[2] = T * n), - (r[3] = 0), - (r[4] = v * s), - (r[5] = b * s), - (r[6] = E * s), - (r[7] = 0), - (r[8] = y * a), - (r[9] = w * a), - (r[10] = M * a), - (r[11] = 0), - (r[12] = e.x), - (r[13] = e.y), - (r[14] = e.z), - (r[15] = 1), - r - ); - } - static fromTranslationRotationScale(e, t) { - return et.fromTranslationQuaternionRotationScale(e.translation, e.rotation, e.scale, t); - } - static fromTranslation(e, t) { - return et.fromRotationTranslation(Ge.IDENTITY, e, t); - } - static fromScale(e, t) { - return pe(t) - ? ((t[0] = e.x), - (t[1] = 0), - (t[2] = 0), - (t[3] = 0), - (t[4] = 0), - (t[5] = e.y), - (t[6] = 0), - (t[7] = 0), - (t[8] = 0), - (t[9] = 0), - (t[10] = e.z), - (t[11] = 0), - (t[12] = 0), - (t[13] = 0), - (t[14] = 0), - (t[15] = 1), - t) - : new et(e.x, 0, 0, 0, 0, e.y, 0, 0, 0, 0, e.z, 0, 0, 0, 0, 1); - } - static fromRotation(e, t) { - return ( - pe(t) || (t = new et()), - (t[0] = e[0]), - (t[1] = e[1]), - (t[2] = e[2]), - (t[3] = 0), - (t[4] = e[3]), - (t[5] = e[4]), - (t[6] = e[5]), - (t[7] = 0), - (t[8] = e[6]), - (t[9] = e[7]), - (t[10] = e[8]), - (t[11] = 0), - (t[12] = 0), - (t[13] = 0), - (t[14] = 0), - (t[15] = 1), - t - ); - } - static makePerspective(e, t, i, r, n, s) { - const a = new et(), - o = (2 * n) / (t - e), - c = (2 * n) / (i - r), - l = (t + e) / (t - e), - h = (i + r) / (i - r), - u = -s / (s - n), - f = (-s * n) / (s - n); - return ( - (a[0] = o), - (a[4] = 0), - (a[8] = l), - (a[12] = 0), - (a[1] = 0), - (a[5] = c), - (a[9] = h), - (a[13] = 0), - (a[2] = 0), - (a[6] = 0), - (a[10] = u), - (a[14] = f), - (a[3] = 0), - (a[7] = 0), - (a[11] = -1), - (a[15] = 0), - a + static clone(matrix, result) { + if (!defined(matrix)) { + return undefined; + } + if (!defined(result)) { + return new Matrix4( + matrix[0], + matrix[4], + matrix[8], + matrix[12], + matrix[1], + matrix[5], + matrix[9], + matrix[13], + matrix[2], + matrix[6], + matrix[10], + matrix[14], + matrix[3], + matrix[7], + matrix[11], + matrix[15] + ); + } + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[3]; + result[4] = matrix[4]; + result[5] = matrix[5]; + result[6] = matrix[6]; + result[7] = matrix[7]; + result[8] = matrix[8]; + result[9] = matrix[9]; + result[10] = matrix[10]; + result[11] = matrix[11]; + result[12] = matrix[12]; + result[13] = matrix[13]; + result[14] = matrix[14]; + result[15] = matrix[15]; + return result; + } + static fromColumnMajorArray(values, result) { + return Matrix4.clone(values, result); + } + static fromRowMajorArray(values, result) { + if (!defined(result)) { + return new Matrix4( + values[0], + values[1], + values[2], + values[3], + values[4], + values[5], + values[6], + values[7], + values[8], + values[9], + values[10], + values[11], + values[12], + values[13], + values[14], + values[15] + ); + } + result[0] = values[0]; + result[1] = values[4]; + result[2] = values[8]; + result[3] = values[12]; + result[4] = values[1]; + result[5] = values[5]; + result[6] = values[9]; + result[7] = values[13]; + result[8] = values[2]; + result[9] = values[6]; + result[10] = values[10]; + result[11] = values[14]; + result[12] = values[3]; + result[13] = values[7]; + result[14] = values[11]; + result[15] = values[15]; + return result; + } + static fromRotationTranslation(rotation, translation, result) { + translation = defaultValue(translation, Vector3.ZERO); + if (!defined(result)) { + return new Matrix4( + rotation[0], + rotation[3], + rotation[6], + translation.x, + rotation[1], + rotation[4], + rotation[7], + translation.y, + rotation[2], + rotation[5], + rotation[8], + translation.z, + 0.0, + 0.0, + 0.0, + 1.0 + ); + } + result[0] = rotation[0]; + result[1] = rotation[1]; + result[2] = rotation[2]; + result[3] = 0.0; + result[4] = rotation[3]; + result[5] = rotation[4]; + result[6] = rotation[5]; + result[7] = 0.0; + result[8] = rotation[6]; + result[9] = rotation[7]; + result[10] = rotation[8]; + result[11] = 0.0; + result[12] = translation.x; + result[13] = translation.y; + result[14] = translation.z; + result[15] = 1.0; + return result; + } + static fromTranslationQuaternionRotationScale(translation, rotation, scale, result) { + if (!defined(result)) { + result = new Matrix4(); + } + const scaleX = scale.x; + const scaleY = scale.y; + const scaleZ = scale.z; + const x2 = rotation.x * rotation.x; + const xy = rotation.x * rotation.y; + const xz = rotation.x * rotation.z; + const xw = rotation.x * rotation.w; + const y2 = rotation.y * rotation.y; + const yz = rotation.y * rotation.z; + const yw = rotation.y * rotation.w; + const z2 = rotation.z * rotation.z; + const zw = rotation.z * rotation.w; + const w2 = rotation.w * rotation.w; + const m00 = x2 - y2 - z2 + w2; + const m01 = 2.0 * (xy - zw); + const m02 = 2.0 * (xz + yw); + const m10 = 2.0 * (xy + zw); + const m11 = -x2 + y2 - z2 + w2; + const m12 = 2.0 * (yz - xw); + const m20 = 2.0 * (xz - yw); + const m21 = 2.0 * (yz + xw); + const m22 = -x2 - y2 + z2 + w2; + result[0] = m00 * scaleX; + result[1] = m10 * scaleX; + result[2] = m20 * scaleX; + result[3] = 0.0; + result[4] = m01 * scaleY; + result[5] = m11 * scaleY; + result[6] = m21 * scaleY; + result[7] = 0.0; + result[8] = m02 * scaleZ; + result[9] = m12 * scaleZ; + result[10] = m22 * scaleZ; + result[11] = 0.0; + result[12] = translation.x; + result[13] = translation.y; + result[14] = translation.z; + result[15] = 1.0; + return result; + } + static fromTranslationRotationScale(translationRotationScale, result) { + return Matrix4.fromTranslationQuaternionRotationScale( + translationRotationScale.translation, + translationRotationScale.rotation, + translationRotationScale.scale, + result ); } - static makeOrthographic(e, t, i, r, n, s) { - const a = new et(), - o = 1 / (t - e), - c = 1 / (i - r), - l = 1 / (s - n), - h = (t + e) * o, - u = (i + r) * c, - f = n * l; - return ( - (a[0] = 2 * o), - (a[4] = 0), - (a[8] = 0), - (a[12] = -h), - (a[1] = 0), - (a[5] = 2 * c), - (a[9] = 0), - (a[13] = -u), - (a[2] = 0), - (a[6] = 0), - (a[10] = -1 * l), - (a[14] = -f), - (a[3] = 0), - (a[7] = 0), - (a[11] = 0), - (a[15] = 1), - a - ); + static fromTranslation(translation, result) { + return Matrix4.fromRotationTranslation(Matrix3.IDENTITY, translation, result); + } + static fromScale(scale, result) { + if (!defined(result)) { + return new Matrix4( + scale.x, + 0.0, + 0.0, + 0.0, + 0.0, + scale.y, + 0.0, + 0.0, + 0.0, + 0.0, + scale.z, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ); + } + result[0] = scale.x; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 0.0; + result[4] = 0.0; + result[5] = scale.y; + result[6] = 0.0; + result[7] = 0.0; + result[8] = 0.0; + result[9] = 0.0; + result[10] = scale.z; + result[11] = 0.0; + result[12] = 0.0; + result[13] = 0.0; + result[14] = 0.0; + result[15] = 1.0; + return result; + } + static fromRotation(rotation, result) { + if (!defined(result)) { + result = new Matrix4(); + } + result[0] = rotation[0]; + result[1] = rotation[1]; + result[2] = rotation[2]; + result[3] = 0.0; + result[4] = rotation[3]; + result[5] = rotation[4]; + result[6] = rotation[5]; + result[7] = 0.0; + result[8] = rotation[6]; + result[9] = rotation[7]; + result[10] = rotation[8]; + result[11] = 0.0; + result[12] = 0.0; + result[13] = 0.0; + result[14] = 0.0; + result[15] = 1.0; + return result; + } + static makePerspective(left, right, top, bottom, near, far) { + // from three.js + const matrix = new Matrix4(); + const x = (2 * near) / (right - left); + const y = (2 * near) / (top - bottom); + const a = (right + left) / (right - left); + const b = (top + bottom) / (top - bottom); + const c = -far / (far - near); + const d = (-far * near) / (far - near); + matrix[0] = x; + matrix[4] = 0; + matrix[8] = a; + matrix[12] = 0; + matrix[1] = 0; + matrix[5] = y; + matrix[9] = b; + matrix[13] = 0; + matrix[2] = 0; + matrix[6] = 0; + matrix[10] = c; + matrix[14] = d; + matrix[3] = 0; + matrix[7] = 0; + matrix[11] = -1; + matrix[15] = 0; + return matrix; + } + static makeOrthographic(left, right, top, bottom, near, far) { + const matrix = new Matrix4(); + const w = 1.0 / (right - left); + const h = 1.0 / (top - bottom); + const p = 1.0 / (far - near); + const x = (right + left) * w; + const y = (top + bottom) * h; + const z = near * p; + matrix[0] = 2 * w; + matrix[4] = 0; + matrix[8] = 0; + matrix[12] = -x; + matrix[1] = 0; + matrix[5] = 2 * h; + matrix[9] = 0; + matrix[13] = -y; + matrix[2] = 0; + matrix[6] = 0; + matrix[10] = -1 * p; + matrix[14] = -z; + matrix[3] = 0; + matrix[7] = 0; + matrix[11] = 0; + matrix[15] = 1; + return matrix; } toArray() { - const e = []; - return et.toArray(this, e), e; - } - static toArray(e, t) { - return pe(t) - ? ((t[0] = e[0]), - (t[1] = e[1]), - (t[2] = e[2]), - (t[3] = e[3]), - (t[4] = e[4]), - (t[5] = e[5]), - (t[6] = e[6]), - (t[7] = e[7]), - (t[8] = e[8]), - (t[9] = e[9]), - (t[10] = e[10]), - (t[11] = e[11]), - (t[12] = e[12]), - (t[13] = e[13]), - (t[14] = e[14]), - (t[15] = e[15]), - t) - : [e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], e[8], e[9], e[10], e[11], e[12], e[13], e[14], e[15]]; - } - static getElementIndex(e, t) { - return 4 * e + t; - } - static getColumn(e, t, i) { - const r = 4 * t, - n = e[r], - s = e[r + 1], - a = e[r + 2], - o = e[r + 3]; - return (i.x = n), (i.y = s), (i.z = a), (i.w = o), i; - } - static setColumn(e, t, i, r) { - const n = 4 * t; - return ((r = et.clone(e, r))[n] = i.x), (r[n + 1] = i.y), (r[n + 2] = i.z), (r[n + 3] = i.w), r; - } - static getRow(e, t, i) { - const r = e[t], - n = e[t + 4], - s = e[t + 8], - a = e[t + 12]; - return (i.x = r), (i.y = n), (i.z = s), (i.w = a), i; - } - static setRow(e, t, i, r) { - return ((r = et.clone(e, r))[t] = i.x), (r[t + 4] = i.y), (r[t + 8] = i.z), (r[t + 12] = i.w), r; - } - static setTranslation(e, t, i) { - return ( - (i[0] = e[0]), - (i[1] = e[1]), - (i[2] = e[2]), - (i[3] = e[3]), - (i[4] = e[4]), - (i[5] = e[5]), - (i[6] = e[6]), - (i[7] = e[7]), - (i[8] = e[8]), - (i[9] = e[9]), - (i[10] = e[10]), - (i[11] = e[11]), - (i[12] = t.x), - (i[13] = t.y), - (i[14] = t.z), - (i[15] = e[15]), - i - ); - } - static setScale(e, t, i) { - const r = et.getScale(e, it), - n = t.x / r.x, - s = t.y / r.y, - a = t.z / r.z; - return ( - (i[0] = e[0] * n), - (i[1] = e[1] * n), - (i[2] = e[2] * n), - (i[3] = e[3]), - (i[4] = e[4] * s), - (i[5] = e[5] * s), - (i[6] = e[6] * s), - (i[7] = e[7]), - (i[8] = e[8] * a), - (i[9] = e[9] * a), - (i[10] = e[10] * a), - (i[11] = e[11]), - (i[12] = e[12]), - (i[13] = e[13]), - (i[14] = e[14]), - (i[15] = e[15]), - i - ); - } - static getScale(e, t) { - return ( - (t.x = Ue.magnitude(Ue.fromElements(e[0], e[1], e[2], rt))), - (t.y = Ue.magnitude(Ue.fromElements(e[4], e[5], e[6], rt))), - (t.z = Ue.magnitude(Ue.fromElements(e[8], e[9], e[10], rt))), - t - ); - } - static getMaximumScale(e) { - return et.getScale(e, nt), Ue.maximumComponent(nt); - } - static setRotation(e, t, i) { - const r = et.getScale(e, st); - return ( - (i[0] = t[0] * r.x), - (i[1] = t[1] * r.x), - (i[2] = t[2] * r.x), - (i[3] = e[3]), - (i[4] = t[3] * r.y), - (i[5] = t[4] * r.y), - (i[6] = t[5] * r.y), - (i[7] = e[7]), - (i[8] = t[6] * r.z), - (i[9] = t[7] * r.z), - (i[10] = t[8] * r.z), - (i[11] = e[11]), - (i[12] = e[12]), - (i[13] = e[13]), - (i[14] = e[14]), - (i[15] = e[15]), - i - ); - } - static getRotation(e, t) { - const i = et.getScale(e, at), - r = 1 / i.x, - n = 1 / i.y, - s = 1 / i.z, - a = e[0] * r, - o = e[1] * n, - c = e[2] * s, - l = e[4] * r, - h = e[5] * n, - u = e[6] * s, - f = e[8] * r, - d = e[9] * n, - m = e[10] * s, - p = a + h + m; - let g = 0; - return ( - p > 0 - ? ((g = 2 * Math.sqrt(p + 1)), - (t.w = 0.25 * g), - (t.x = (u - d) / g), - (t.y = (f - c) / g), - (t.z = (o - l) / g)) - : a > h && a > m - ? ((g = 2 * Math.sqrt(1 + a - h - m)), - (t.w = (u - d) / g), - (t.x = 0.25 * g), - (t.y = (o + l) / g), - (t.z = (f + c) / g)) - : h > m - ? ((g = 2 * Math.sqrt(1 + h - a - m)), - (t.w = (f - c) / g), - (t.x = (o + l) / g), - (t.y = 0.25 * g), - (t.z = (u + d) / g)) - : ((g = 2 * Math.sqrt(1 + m - a - h)), - (t.w = (o - l) / g), - (t.x = (f + c) / g), - (t.y = (u + d) / g), - (t.z = 0.25 * g)), - t - ); - } - static multiply(e, t, i) { - const r = e[0], - n = e[1], - s = e[2], - a = e[3], - o = e[4], - c = e[5], - l = e[6], - h = e[7], - u = e[8], - f = e[9], - d = e[10], - m = e[11], - p = e[12], - g = e[13], - x = e[14], - v = e[15], - y = t[0], - S = t[1], - b = t[2], - w = t[3], - T = t[4], - E = t[5], - M = t[6], - U = t[7], - _ = t[8], - L = t[9], - C = t[10], - R = t[11], - A = t[12], - D = t[13], - z = t[14], - I = t[15], - P = r * y + o * S + u * b + p * w, - N = n * y + c * S + f * b + g * w, - B = s * y + l * S + d * b + x * w, - O = a * y + h * S + m * b + v * w, - V = r * T + o * E + u * M + p * U, - F = n * T + c * E + f * M + g * U, - $ = s * T + l * E + d * M + x * U, - G = a * T + h * E + m * M + v * U, - k = r * _ + o * L + u * C + p * R, - q = n * _ + c * L + f * C + g * R, - j = s * _ + l * L + d * C + x * R, - H = a * _ + h * L + m * C + v * R, - X = r * A + o * D + u * z + p * I, - Y = n * A + c * D + f * z + g * I, - W = s * A + l * D + d * z + x * I, - Z = a * A + h * D + m * z + v * I; - return ( - (i[0] = P), - (i[1] = N), - (i[2] = B), - (i[3] = O), - (i[4] = V), - (i[5] = F), - (i[6] = $), - (i[7] = G), - (i[8] = k), - (i[9] = q), - (i[10] = j), - (i[11] = H), - (i[12] = X), - (i[13] = Y), - (i[14] = W), - (i[15] = Z), - i - ); - } - static add(e, t, i) { - return ( - (i[0] = e[0] + t[0]), - (i[1] = e[1] + t[1]), - (i[2] = e[2] + t[2]), - (i[3] = e[3] + t[3]), - (i[4] = e[4] + t[4]), - (i[5] = e[5] + t[5]), - (i[6] = e[6] + t[6]), - (i[7] = e[7] + t[7]), - (i[8] = e[8] + t[8]), - (i[9] = e[9] + t[9]), - (i[10] = e[10] + t[10]), - (i[11] = e[11] + t[11]), - (i[12] = e[12] + t[12]), - (i[13] = e[13] + t[13]), - (i[14] = e[14] + t[14]), - (i[15] = e[15] + t[15]), - i - ); - } - static subtract(e, t, i) { - return ( - (i[0] = e[0] - t[0]), - (i[1] = e[1] - t[1]), - (i[2] = e[2] - t[2]), - (i[3] = e[3] - t[3]), - (i[4] = e[4] - t[4]), - (i[5] = e[5] - t[5]), - (i[6] = e[6] - t[6]), - (i[7] = e[7] - t[7]), - (i[8] = e[8] - t[8]), - (i[9] = e[9] - t[9]), - (i[10] = e[10] - t[10]), - (i[11] = e[11] - t[11]), - (i[12] = e[12] - t[12]), - (i[13] = e[13] - t[13]), - (i[14] = e[14] - t[14]), - (i[15] = e[15] - t[15]), - i - ); - } - static multiplyTransformation(e, t, i) { - const r = e[0], - n = e[1], - s = e[2], - a = e[4], - o = e[5], - c = e[6], - l = e[8], - h = e[9], - u = e[10], - f = e[12], - d = e[13], - m = e[14], - p = t[0], - g = t[1], - x = t[2], - v = t[4], - y = t[5], - S = t[6], - b = t[8], - w = t[9], - T = t[10], - E = t[12], - M = t[13], - U = t[14], - _ = r * p + a * g + l * x, - L = n * p + o * g + h * x, - C = s * p + c * g + u * x, - R = r * v + a * y + l * S, - A = n * v + o * y + h * S, - D = s * v + c * y + u * S, - z = r * b + a * w + l * T, - I = n * b + o * w + h * T, - P = s * b + c * w + u * T, - N = r * E + a * M + l * U + f, - B = n * E + o * M + h * U + d, - O = s * E + c * M + u * U + m; - return ( - (i[0] = _), - (i[1] = L), - (i[2] = C), - (i[3] = 0), - (i[4] = R), - (i[5] = A), - (i[6] = D), - (i[7] = 0), - (i[8] = z), - (i[9] = I), - (i[10] = P), - (i[11] = 0), - (i[12] = N), - (i[13] = B), - (i[14] = O), - (i[15] = 1), - i - ); - } - static multiplyByMatrix3(e, t, i) { - const r = e[0], - n = e[1], - s = e[2], - a = e[4], - o = e[5], - c = e[6], - l = e[8], - h = e[9], - u = e[10], - f = t[0], - d = t[1], - m = t[2], - p = t[3], - g = t[4], - x = t[5], - v = t[6], - y = t[7], - S = t[8], - b = r * f + a * d + l * m, - w = n * f + o * d + h * m, - T = s * f + c * d + u * m, - E = r * p + a * g + l * x, - M = n * p + o * g + h * x, - U = s * p + c * g + u * x, - _ = r * v + a * y + l * S, - L = n * v + o * y + h * S, - C = s * v + c * y + u * S; - return ( - (i[0] = b), - (i[1] = w), - (i[2] = T), - (i[3] = 0), - (i[4] = E), - (i[5] = M), - (i[6] = U), - (i[7] = 0), - (i[8] = _), - (i[9] = L), - (i[10] = C), - (i[11] = 0), - (i[12] = e[12]), - (i[13] = e[13]), - (i[14] = e[14]), - (i[15] = e[15]), - i - ); - } - static multiplyByTranslation(e, t, i) { - const r = t.x, - n = t.y, - s = t.z, - a = r * e[0] + n * e[4] + s * e[8] + e[12], - o = r * e[1] + n * e[5] + s * e[9] + e[13], - c = r * e[2] + n * e[6] + s * e[10] + e[14]; - return ( - (i[0] = e[0]), - (i[1] = e[1]), - (i[2] = e[2]), - (i[3] = e[3]), - (i[4] = e[4]), - (i[5] = e[5]), - (i[6] = e[6]), - (i[7] = e[7]), - (i[8] = e[8]), - (i[9] = e[9]), - (i[10] = e[10]), - (i[11] = e[11]), - (i[12] = a), - (i[13] = o), - (i[14] = c), - (i[15] = e[15]), - i - ); - } - static multiplyByScale(e, t, i) { - const r = t.x, - n = t.y, - s = t.z; - return 1 === r && 1 === n && 1 === s - ? et.clone(e, i) - : ((i[0] = r * e[0]), - (i[1] = r * e[1]), - (i[2] = r * e[2]), - (i[3] = e[3]), - (i[4] = n * e[4]), - (i[5] = n * e[5]), - (i[6] = n * e[6]), - (i[7] = e[7]), - (i[8] = s * e[8]), - (i[9] = s * e[9]), - (i[10] = s * e[10]), - (i[11] = e[11]), - (i[12] = e[12]), - (i[13] = e[13]), - (i[14] = e[14]), - (i[15] = e[15]), - i); - } - static multiplyByUniformScale(e, t, i) { - return ( - (i[0] = e[0] * t), - (i[1] = e[1] * t), - (i[2] = e[2] * t), - (i[3] = e[3]), - (i[4] = e[4] * t), - (i[5] = e[5] * t), - (i[6] = e[6] * t), - (i[7] = e[7]), - (i[8] = e[8] * t), - (i[9] = e[9] * t), - (i[10] = e[10] * t), - (i[11] = e[11]), - (i[12] = e[12]), - (i[13] = e[13]), - (i[14] = e[14]), - (i[15] = e[15]), - i - ); - } - static multiplyByVector(e, t, i) { - const r = t.x, - n = t.y, - s = t.z, - a = t.w, - o = e[0] * r + e[4] * n + e[8] * s + e[12] * a, - c = e[1] * r + e[5] * n + e[9] * s + e[13] * a, - l = e[2] * r + e[6] * n + e[10] * s + e[14] * a, - h = e[3] * r + e[7] * n + e[11] * s + e[15] * a; - return (i.x = o), (i.y = c), (i.z = l), (i.w = h), i; - } - static multiplyByPointAsVector(e, t, i) { - const r = t.x, - n = t.y, - s = t.z, - a = e[0] * r + e[4] * n + e[8] * s, - o = e[1] * r + e[5] * n + e[9] * s, - c = e[2] * r + e[6] * n + e[10] * s; - return (i.x = a), (i.y = o), (i.z = c), i; - } - static multiplyByPoint(e, t, i) { - const r = t.x, - n = t.y, - s = t.z, - a = e[0] * r + e[4] * n + e[8] * s + e[12], - o = e[1] * r + e[5] * n + e[9] * s + e[13], - c = e[2] * r + e[6] * n + e[10] * s + e[14]; - return (i.x = a), (i.y = o), (i.z = c), i; - } - static multiplyByScalar(e, t, i) { - return ( - (i[0] = e[0] * t), - (i[1] = e[1] * t), - (i[2] = e[2] * t), - (i[3] = e[3] * t), - (i[4] = e[4] * t), - (i[5] = e[5] * t), - (i[6] = e[6] * t), - (i[7] = e[7] * t), - (i[8] = e[8] * t), - (i[9] = e[9] * t), - (i[10] = e[10] * t), - (i[11] = e[11] * t), - (i[12] = e[12] * t), - (i[13] = e[13] * t), - (i[14] = e[14] * t), - (i[15] = e[15] * t), - i - ); - } - static negate(e, t) { - return ( - (t[0] = -e[0]), - (t[1] = -e[1]), - (t[2] = -e[2]), - (t[3] = -e[3]), - (t[4] = -e[4]), - (t[5] = -e[5]), - (t[6] = -e[6]), - (t[7] = -e[7]), - (t[8] = -e[8]), - (t[9] = -e[9]), - (t[10] = -e[10]), - (t[11] = -e[11]), - (t[12] = -e[12]), - (t[13] = -e[13]), - (t[14] = -e[14]), - (t[15] = -e[15]), - t - ); - } - static transpose(e, t) { - const i = e[1], - r = e[2], - n = e[3], - s = e[6], - a = e[7], - o = e[11]; - return ( - (t[0] = e[0]), - (t[1] = e[4]), - (t[2] = e[8]), - (t[3] = e[12]), - (t[4] = i), - (t[5] = e[5]), - (t[6] = e[9]), - (t[7] = e[13]), - (t[8] = r), - (t[9] = s), - (t[10] = e[10]), - (t[11] = e[14]), - (t[12] = n), - (t[13] = a), - (t[14] = o), - (t[15] = e[15]), - t - ); - } - static abs(e, t) { - return ( - (t[0] = Math.abs(e[0])), - (t[1] = Math.abs(e[1])), - (t[2] = Math.abs(e[2])), - (t[3] = Math.abs(e[3])), - (t[4] = Math.abs(e[4])), - (t[5] = Math.abs(e[5])), - (t[6] = Math.abs(e[6])), - (t[7] = Math.abs(e[7])), - (t[8] = Math.abs(e[8])), - (t[9] = Math.abs(e[9])), - (t[10] = Math.abs(e[10])), - (t[11] = Math.abs(e[11])), - (t[12] = Math.abs(e[12])), - (t[13] = Math.abs(e[13])), - (t[14] = Math.abs(e[14])), - (t[15] = Math.abs(e[15])), - t - ); - } - static equals(e, t) { - return ( - e === t || - (pe(e) && - pe(t) && - e[12] === t[12] && - e[13] === t[13] && - e[14] === t[14] && - e[0] === t[0] && - e[1] === t[1] && - e[2] === t[2] && - e[4] === t[4] && - e[5] === t[5] && - e[6] === t[6] && - e[8] === t[8] && - e[9] === t[9] && - e[10] === t[10] && - e[3] === t[3] && - e[7] === t[7] && - e[11] === t[11] && - e[15] === t[15]) - ); - } - static equalsEpsilon(e, t, i) { + const result = []; + Matrix4.toArray(this, result); + return result; + } + /** + * Computes an Array from the provided Matrix4 instance. + * The array will be in column-major order. + * @example + * //create an array from an instance of Matrix4 + * // m = [10.0, 14.0, 18.0, 22.0] + * // [11.0, 15.0, 19.0, 23.0] + * // [12.0, 16.0, 20.0, 24.0] + * // [13.0, 17.0, 21.0, 25.0] + * const a = Matrix4.toArray(m); + * + * // m remains the same + * //creates a = [10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0] + */ + static toArray(matrix, result) { + if (!defined(result)) { + return [ + matrix[0], + matrix[1], + matrix[2], + matrix[3], + matrix[4], + matrix[5], + matrix[6], + matrix[7], + matrix[8], + matrix[9], + matrix[10], + matrix[11], + matrix[12], + matrix[13], + matrix[14], + matrix[15] + ]; + } + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[3]; + result[4] = matrix[4]; + result[5] = matrix[5]; + result[6] = matrix[6]; + result[7] = matrix[7]; + result[8] = matrix[8]; + result[9] = matrix[9]; + result[10] = matrix[10]; + result[11] = matrix[11]; + result[12] = matrix[12]; + result[13] = matrix[13]; + result[14] = matrix[14]; + result[15] = matrix[15]; + return result; + } + static getElementIndex(column, row) { + return column * 4 + row; + } + static getColumn(matrix, index, result) { + const startIndex = index * 4; + const x = matrix[startIndex]; + const y = matrix[startIndex + 1]; + const z = matrix[startIndex + 2]; + const w = matrix[startIndex + 3]; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; + } + static setColumn(matrix, index, cartesian, result) { + result = Matrix4.clone(matrix, result); + const startIndex = index * 4; + result[startIndex] = cartesian.x; + result[startIndex + 1] = cartesian.y; + result[startIndex + 2] = cartesian.z; + result[startIndex + 3] = cartesian.w; + return result; + } + static getRow(matrix, index, result) { + const x = matrix[index]; + const y = matrix[index + 4]; + const z = matrix[index + 8]; + const w = matrix[index + 12]; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; + } + static setRow(matrix, index, cartesian, result) { + result = Matrix4.clone(matrix, result); + result[index] = cartesian.x; + result[index + 4] = cartesian.y; + result[index + 8] = cartesian.z; + result[index + 12] = cartesian.w; + return result; + } + static setTranslation(matrix, translation, result) { + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[3]; + result[4] = matrix[4]; + result[5] = matrix[5]; + result[6] = matrix[6]; + result[7] = matrix[7]; + result[8] = matrix[8]; + result[9] = matrix[9]; + result[10] = matrix[10]; + result[11] = matrix[11]; + result[12] = translation.x; + result[13] = translation.y; + result[14] = translation.z; + result[15] = matrix[15]; + return result; + } + static setScale(matrix, scale, result) { + const existingScale = Matrix4.getScale(matrix, scaleScratch1$1); + const scaleRatioX = scale.x / existingScale.x; + const scaleRatioY = scale.y / existingScale.y; + const scaleRatioZ = scale.z / existingScale.z; + result[0] = matrix[0] * scaleRatioX; + result[1] = matrix[1] * scaleRatioX; + result[2] = matrix[2] * scaleRatioX; + result[3] = matrix[3]; + result[4] = matrix[4] * scaleRatioY; + result[5] = matrix[5] * scaleRatioY; + result[6] = matrix[6] * scaleRatioY; + result[7] = matrix[7]; + result[8] = matrix[8] * scaleRatioZ; + result[9] = matrix[9] * scaleRatioZ; + result[10] = matrix[10] * scaleRatioZ; + result[11] = matrix[11]; + result[12] = matrix[12]; + result[13] = matrix[13]; + result[14] = matrix[14]; + result[15] = matrix[15]; + return result; + } + static getScale(matrix, result) { + result.x = Vector3.magnitude(Vector3.fromElements(matrix[0], matrix[1], matrix[2], scratchColumn$1)); + result.y = Vector3.magnitude(Vector3.fromElements(matrix[4], matrix[5], matrix[6], scratchColumn$1)); + result.z = Vector3.magnitude(Vector3.fromElements(matrix[8], matrix[9], matrix[10], scratchColumn$1)); + return result; + } + static getMaximumScale(matrix) { + Matrix4.getScale(matrix, scaleScratch3$1); + return Vector3.maximumComponent(scaleScratch3$1); + } + static setRotation(matrix, rotation, result) { + const scale = Matrix4.getScale(matrix, scaleScratch4$1); + result[0] = rotation[0] * scale.x; + result[1] = rotation[1] * scale.x; + result[2] = rotation[2] * scale.x; + result[3] = matrix[3]; + result[4] = rotation[3] * scale.y; + result[5] = rotation[4] * scale.y; + result[6] = rotation[5] * scale.y; + result[7] = matrix[7]; + result[8] = rotation[6] * scale.z; + result[9] = rotation[7] * scale.z; + result[10] = rotation[8] * scale.z; + result[11] = matrix[11]; + result[12] = matrix[12]; + result[13] = matrix[13]; + result[14] = matrix[14]; + result[15] = matrix[15]; + return result; + } + static getRotation(matrix, result) { + const scale = Matrix4.getScale(matrix, scaleScratch5$1); + const is1 = 1 / scale.x; + const is2 = 1 / scale.y; + const is3 = 1 / scale.z; + const sm11 = matrix[0] * is1; + const sm12 = matrix[1] * is2; + const sm13 = matrix[2] * is3; + const sm21 = matrix[4] * is1; + const sm22 = matrix[5] * is2; + const sm23 = matrix[6] * is3; + const sm31 = matrix[8] * is1; + const sm32 = matrix[9] * is2; + const sm33 = matrix[10] * is3; + const trace = sm11 + sm22 + sm33; + let S = 0; + if (trace > 0) { + S = Math.sqrt(trace + 1.0) * 2; + result.w = 0.25 * S; + result.x = (sm23 - sm32) / S; + result.y = (sm31 - sm13) / S; + result.z = (sm12 - sm21) / S; + } else if (sm11 > sm22 && sm11 > sm33) { + S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2; + result.w = (sm23 - sm32) / S; + result.x = 0.25 * S; + result.y = (sm12 + sm21) / S; + result.z = (sm31 + sm13) / S; + } else if (sm22 > sm33) { + S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2; + result.w = (sm31 - sm13) / S; + result.x = (sm12 + sm21) / S; + result.y = 0.25 * S; + result.z = (sm23 + sm32) / S; + } else { + S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2; + result.w = (sm12 - sm21) / S; + result.x = (sm31 + sm13) / S; + result.y = (sm23 + sm32) / S; + result.z = 0.25 * S; + } + return result; + } + static multiply(left, right, result) { + const left0 = left[0]; + const left1 = left[1]; + const left2 = left[2]; + const left3 = left[3]; + const left4 = left[4]; + const left5 = left[5]; + const left6 = left[6]; + const left7 = left[7]; + const left8 = left[8]; + const left9 = left[9]; + const left10 = left[10]; + const left11 = left[11]; + const left12 = left[12]; + const left13 = left[13]; + const left14 = left[14]; + const left15 = left[15]; + const right0 = right[0]; + const right1 = right[1]; + const right2 = right[2]; + const right3 = right[3]; + const right4 = right[4]; + const right5 = right[5]; + const right6 = right[6]; + const right7 = right[7]; + const right8 = right[8]; + const right9 = right[9]; + const right10 = right[10]; + const right11 = right[11]; + const right12 = right[12]; + const right13 = right[13]; + const right14 = right[14]; + const right15 = right[15]; + const column0Row0 = left0 * right0 + left4 * right1 + left8 * right2 + left12 * right3; + const column0Row1 = left1 * right0 + left5 * right1 + left9 * right2 + left13 * right3; + const column0Row2 = left2 * right0 + left6 * right1 + left10 * right2 + left14 * right3; + const column0Row3 = left3 * right0 + left7 * right1 + left11 * right2 + left15 * right3; + const column1Row0 = left0 * right4 + left4 * right5 + left8 * right6 + left12 * right7; + const column1Row1 = left1 * right4 + left5 * right5 + left9 * right6 + left13 * right7; + const column1Row2 = left2 * right4 + left6 * right5 + left10 * right6 + left14 * right7; + const column1Row3 = left3 * right4 + left7 * right5 + left11 * right6 + left15 * right7; + const column2Row0 = left0 * right8 + left4 * right9 + left8 * right10 + left12 * right11; + const column2Row1 = left1 * right8 + left5 * right9 + left9 * right10 + left13 * right11; + const column2Row2 = left2 * right8 + left6 * right9 + left10 * right10 + left14 * right11; + const column2Row3 = left3 * right8 + left7 * right9 + left11 * right10 + left15 * right11; + const column3Row0 = left0 * right12 + left4 * right13 + left8 * right14 + left12 * right15; + const column3Row1 = left1 * right12 + left5 * right13 + left9 * right14 + left13 * right15; + const column3Row2 = left2 * right12 + left6 * right13 + left10 * right14 + left14 * right15; + const column3Row3 = left3 * right12 + left7 * right13 + left11 * right14 + left15 * right15; + result[0] = column0Row0; + result[1] = column0Row1; + result[2] = column0Row2; + result[3] = column0Row3; + result[4] = column1Row0; + result[5] = column1Row1; + result[6] = column1Row2; + result[7] = column1Row3; + result[8] = column2Row0; + result[9] = column2Row1; + result[10] = column2Row2; + result[11] = column2Row3; + result[12] = column3Row0; + result[13] = column3Row1; + result[14] = column3Row2; + result[15] = column3Row3; + return result; + } + static add(left, right, result) { + result[0] = left[0] + right[0]; + result[1] = left[1] + right[1]; + result[2] = left[2] + right[2]; + result[3] = left[3] + right[3]; + result[4] = left[4] + right[4]; + result[5] = left[5] + right[5]; + result[6] = left[6] + right[6]; + result[7] = left[7] + right[7]; + result[8] = left[8] + right[8]; + result[9] = left[9] + right[9]; + result[10] = left[10] + right[10]; + result[11] = left[11] + right[11]; + result[12] = left[12] + right[12]; + result[13] = left[13] + right[13]; + result[14] = left[14] + right[14]; + result[15] = left[15] + right[15]; + return result; + } + static subtract(left, right, result) { + result[0] = left[0] - right[0]; + result[1] = left[1] - right[1]; + result[2] = left[2] - right[2]; + result[3] = left[3] - right[3]; + result[4] = left[4] - right[4]; + result[5] = left[5] - right[5]; + result[6] = left[6] - right[6]; + result[7] = left[7] - right[7]; + result[8] = left[8] - right[8]; + result[9] = left[9] - right[9]; + result[10] = left[10] - right[10]; + result[11] = left[11] - right[11]; + result[12] = left[12] - right[12]; + result[13] = left[13] - right[13]; + result[14] = left[14] - right[14]; + result[15] = left[15] - right[15]; + return result; + } + static multiplyTransformation(left, right, result) { + const left0 = left[0]; + const left1 = left[1]; + const left2 = left[2]; + const left4 = left[4]; + const left5 = left[5]; + const left6 = left[6]; + const left8 = left[8]; + const left9 = left[9]; + const left10 = left[10]; + const left12 = left[12]; + const left13 = left[13]; + const left14 = left[14]; + const right0 = right[0]; + const right1 = right[1]; + const right2 = right[2]; + const right4 = right[4]; + const right5 = right[5]; + const right6 = right[6]; + const right8 = right[8]; + const right9 = right[9]; + const right10 = right[10]; + const right12 = right[12]; + const right13 = right[13]; + const right14 = right[14]; + const column0Row0 = left0 * right0 + left4 * right1 + left8 * right2; + const column0Row1 = left1 * right0 + left5 * right1 + left9 * right2; + const column0Row2 = left2 * right0 + left6 * right1 + left10 * right2; + const column1Row0 = left0 * right4 + left4 * right5 + left8 * right6; + const column1Row1 = left1 * right4 + left5 * right5 + left9 * right6; + const column1Row2 = left2 * right4 + left6 * right5 + left10 * right6; + const column2Row0 = left0 * right8 + left4 * right9 + left8 * right10; + const column2Row1 = left1 * right8 + left5 * right9 + left9 * right10; + const column2Row2 = left2 * right8 + left6 * right9 + left10 * right10; + const column3Row0 = left0 * right12 + left4 * right13 + left8 * right14 + left12; + const column3Row1 = left1 * right12 + left5 * right13 + left9 * right14 + left13; + const column3Row2 = left2 * right12 + left6 * right13 + left10 * right14 + left14; + result[0] = column0Row0; + result[1] = column0Row1; + result[2] = column0Row2; + result[3] = 0.0; + result[4] = column1Row0; + result[5] = column1Row1; + result[6] = column1Row2; + result[7] = 0.0; + result[8] = column2Row0; + result[9] = column2Row1; + result[10] = column2Row2; + result[11] = 0.0; + result[12] = column3Row0; + result[13] = column3Row1; + result[14] = column3Row2; + result[15] = 1.0; + return result; + } + static multiplyByMatrix3(matrix, rotation, result) { + const left0 = matrix[0]; + const left1 = matrix[1]; + const left2 = matrix[2]; + const left4 = matrix[4]; + const left5 = matrix[5]; + const left6 = matrix[6]; + const left8 = matrix[8]; + const left9 = matrix[9]; + const left10 = matrix[10]; + const right0 = rotation[0]; + const right1 = rotation[1]; + const right2 = rotation[2]; + const right4 = rotation[3]; + const right5 = rotation[4]; + const right6 = rotation[5]; + const right8 = rotation[6]; + const right9 = rotation[7]; + const right10 = rotation[8]; + const column0Row0 = left0 * right0 + left4 * right1 + left8 * right2; + const column0Row1 = left1 * right0 + left5 * right1 + left9 * right2; + const column0Row2 = left2 * right0 + left6 * right1 + left10 * right2; + const column1Row0 = left0 * right4 + left4 * right5 + left8 * right6; + const column1Row1 = left1 * right4 + left5 * right5 + left9 * right6; + const column1Row2 = left2 * right4 + left6 * right5 + left10 * right6; + const column2Row0 = left0 * right8 + left4 * right9 + left8 * right10; + const column2Row1 = left1 * right8 + left5 * right9 + left9 * right10; + const column2Row2 = left2 * right8 + left6 * right9 + left10 * right10; + result[0] = column0Row0; + result[1] = column0Row1; + result[2] = column0Row2; + result[3] = 0.0; + result[4] = column1Row0; + result[5] = column1Row1; + result[6] = column1Row2; + result[7] = 0.0; + result[8] = column2Row0; + result[9] = column2Row1; + result[10] = column2Row2; + result[11] = 0.0; + result[12] = matrix[12]; + result[13] = matrix[13]; + result[14] = matrix[14]; + result[15] = matrix[15]; + return result; + } + static multiplyByTranslation(matrix, translation, result) { + const x = translation.x; + const y = translation.y; + const z = translation.z; + const tx = x * matrix[0] + y * matrix[4] + z * matrix[8] + matrix[12]; + const ty = x * matrix[1] + y * matrix[5] + z * matrix[9] + matrix[13]; + const tz = x * matrix[2] + y * matrix[6] + z * matrix[10] + matrix[14]; + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[3]; + result[4] = matrix[4]; + result[5] = matrix[5]; + result[6] = matrix[6]; + result[7] = matrix[7]; + result[8] = matrix[8]; + result[9] = matrix[9]; + result[10] = matrix[10]; + result[11] = matrix[11]; + result[12] = tx; + result[13] = ty; + result[14] = tz; + result[15] = matrix[15]; + return result; + } + static multiplyByScale(matrix, scale, result) { + const scaleX = scale.x; + const scaleY = scale.y; + const scaleZ = scale.z; + // Faster than Vector3.equals + if (scaleX === 1.0 && scaleY === 1.0 && scaleZ === 1.0) { + return Matrix4.clone(matrix, result); + } + result[0] = scaleX * matrix[0]; + result[1] = scaleX * matrix[1]; + result[2] = scaleX * matrix[2]; + result[3] = matrix[3]; + result[4] = scaleY * matrix[4]; + result[5] = scaleY * matrix[5]; + result[6] = scaleY * matrix[6]; + result[7] = matrix[7]; + result[8] = scaleZ * matrix[8]; + result[9] = scaleZ * matrix[9]; + result[10] = scaleZ * matrix[10]; + result[11] = matrix[11]; + result[12] = matrix[12]; + result[13] = matrix[13]; + result[14] = matrix[14]; + result[15] = matrix[15]; + return result; + } + static multiplyByUniformScale(matrix, scale, result) { + result[0] = matrix[0] * scale; + result[1] = matrix[1] * scale; + result[2] = matrix[2] * scale; + result[3] = matrix[3]; + result[4] = matrix[4] * scale; + result[5] = matrix[5] * scale; + result[6] = matrix[6] * scale; + result[7] = matrix[7]; + result[8] = matrix[8] * scale; + result[9] = matrix[9] * scale; + result[10] = matrix[10] * scale; + result[11] = matrix[11]; + result[12] = matrix[12]; + result[13] = matrix[13]; + result[14] = matrix[14]; + result[15] = matrix[15]; + return result; + } + static multiplyByVector(matrix, cartesian, result) { + const vX = cartesian.x; + const vY = cartesian.y; + const vZ = cartesian.z; + const vW = cartesian.w; + const x = matrix[0] * vX + matrix[4] * vY + matrix[8] * vZ + matrix[12] * vW; + const y = matrix[1] * vX + matrix[5] * vY + matrix[9] * vZ + matrix[13] * vW; + const z = matrix[2] * vX + matrix[6] * vY + matrix[10] * vZ + matrix[14] * vW; + const w = matrix[3] * vX + matrix[7] * vY + matrix[11] * vZ + matrix[15] * vW; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; + } + static multiplyByPointAsVector(matrix, cartesian, result) { + const vX = cartesian.x; + const vY = cartesian.y; + const vZ = cartesian.z; + const x = matrix[0] * vX + matrix[4] * vY + matrix[8] * vZ; + const y = matrix[1] * vX + matrix[5] * vY + matrix[9] * vZ; + const z = matrix[2] * vX + matrix[6] * vY + matrix[10] * vZ; + result.x = x; + result.y = y; + result.z = z; + return result; + } + static multiplyByPoint(matrix, cartesian, result) { + const vX = cartesian.x; + const vY = cartesian.y; + const vZ = cartesian.z; + const x = matrix[0] * vX + matrix[4] * vY + matrix[8] * vZ + matrix[12]; + const y = matrix[1] * vX + matrix[5] * vY + matrix[9] * vZ + matrix[13]; + const z = matrix[2] * vX + matrix[6] * vY + matrix[10] * vZ + matrix[14]; + result.x = x; + result.y = y; + result.z = z; + return result; + } + static multiplyByScalar(matrix, scalar, result) { + result[0] = matrix[0] * scalar; + result[1] = matrix[1] * scalar; + result[2] = matrix[2] * scalar; + result[3] = matrix[3] * scalar; + result[4] = matrix[4] * scalar; + result[5] = matrix[5] * scalar; + result[6] = matrix[6] * scalar; + result[7] = matrix[7] * scalar; + result[8] = matrix[8] * scalar; + result[9] = matrix[9] * scalar; + result[10] = matrix[10] * scalar; + result[11] = matrix[11] * scalar; + result[12] = matrix[12] * scalar; + result[13] = matrix[13] * scalar; + result[14] = matrix[14] * scalar; + result[15] = matrix[15] * scalar; + return result; + } + static negate(matrix, result) { + result[0] = -matrix[0]; + result[1] = -matrix[1]; + result[2] = -matrix[2]; + result[3] = -matrix[3]; + result[4] = -matrix[4]; + result[5] = -matrix[5]; + result[6] = -matrix[6]; + result[7] = -matrix[7]; + result[8] = -matrix[8]; + result[9] = -matrix[9]; + result[10] = -matrix[10]; + result[11] = -matrix[11]; + result[12] = -matrix[12]; + result[13] = -matrix[13]; + result[14] = -matrix[14]; + result[15] = -matrix[15]; + return result; + } + static transpose(matrix, result) { + const matrix1 = matrix[1]; + const matrix2 = matrix[2]; + const matrix3 = matrix[3]; + const matrix6 = matrix[6]; + const matrix7 = matrix[7]; + const matrix11 = matrix[11]; + result[0] = matrix[0]; + result[1] = matrix[4]; + result[2] = matrix[8]; + result[3] = matrix[12]; + result[4] = matrix1; + result[5] = matrix[5]; + result[6] = matrix[9]; + result[7] = matrix[13]; + result[8] = matrix2; + result[9] = matrix6; + result[10] = matrix[10]; + result[11] = matrix[14]; + result[12] = matrix3; + result[13] = matrix7; + result[14] = matrix11; + result[15] = matrix[15]; + return result; + } + static abs(matrix, result) { + result[0] = Math.abs(matrix[0]); + result[1] = Math.abs(matrix[1]); + result[2] = Math.abs(matrix[2]); + result[3] = Math.abs(matrix[3]); + result[4] = Math.abs(matrix[4]); + result[5] = Math.abs(matrix[5]); + result[6] = Math.abs(matrix[6]); + result[7] = Math.abs(matrix[7]); + result[8] = Math.abs(matrix[8]); + result[9] = Math.abs(matrix[9]); + result[10] = Math.abs(matrix[10]); + result[11] = Math.abs(matrix[11]); + result[12] = Math.abs(matrix[12]); + result[13] = Math.abs(matrix[13]); + result[14] = Math.abs(matrix[14]); + result[15] = Math.abs(matrix[15]); + return result; + } + static equals(left, right) { + // Given that most matrices will be transformation matrices, the elements + // are tested in order such that the test is likely to fail as early + // as possible. I _think_ this is just as friendly to the L1 cache + // as testing in index order. It is certainty faster in practice. return ( - (i = ee(i, 0)), - e === t || - (pe(e) && - pe(t) && - Math.abs(e[0] - t[0]) <= i && - Math.abs(e[1] - t[1]) <= i && - Math.abs(e[2] - t[2]) <= i && - Math.abs(e[3] - t[3]) <= i && - Math.abs(e[4] - t[4]) <= i && - Math.abs(e[5] - t[5]) <= i && - Math.abs(e[6] - t[6]) <= i && - Math.abs(e[7] - t[7]) <= i && - Math.abs(e[8] - t[8]) <= i && - Math.abs(e[9] - t[9]) <= i && - Math.abs(e[10] - t[10]) <= i && - Math.abs(e[11] - t[11]) <= i && - Math.abs(e[12] - t[12]) <= i && - Math.abs(e[13] - t[13]) <= i && - Math.abs(e[14] - t[14]) <= i && - Math.abs(e[15] - t[15]) <= i) + left === right || + (defined(left) && + defined(right) && + // Translation + left[12] === right[12] && + left[13] === right[13] && + left[14] === right[14] && + // Rotation/scale + left[0] === right[0] && + left[1] === right[1] && + left[2] === right[2] && + left[4] === right[4] && + left[5] === right[5] && + left[6] === right[6] && + left[8] === right[8] && + left[9] === right[9] && + left[10] === right[10] && + // Bottom row + left[3] === right[3] && + left[7] === right[7] && + left[11] === right[11] && + left[15] === right[15]) ); } - static getTranslation(e, t) { - return (t.x = e[12]), (t.y = e[13]), (t.z = e[14]), t; - } - static getMatrix3(e, t) { + static equalsEpsilon(left, right, epsilon) { + epsilon = defaultValue(epsilon, 0); return ( - (t[0] = e[0]), - (t[1] = e[1]), - (t[2] = e[2]), - (t[3] = e[4]), - (t[4] = e[5]), - (t[5] = e[6]), - (t[6] = e[8]), - (t[7] = e[9]), - (t[8] = e[10]), - t + left === right || + (defined(left) && + defined(right) && + Math.abs(left[0] - right[0]) <= epsilon && + Math.abs(left[1] - right[1]) <= epsilon && + Math.abs(left[2] - right[2]) <= epsilon && + Math.abs(left[3] - right[3]) <= epsilon && + Math.abs(left[4] - right[4]) <= epsilon && + Math.abs(left[5] - right[5]) <= epsilon && + Math.abs(left[6] - right[6]) <= epsilon && + Math.abs(left[7] - right[7]) <= epsilon && + Math.abs(left[8] - right[8]) <= epsilon && + Math.abs(left[9] - right[9]) <= epsilon && + Math.abs(left[10] - right[10]) <= epsilon && + Math.abs(left[11] - right[11]) <= epsilon && + Math.abs(left[12] - right[12]) <= epsilon && + Math.abs(left[13] - right[13]) <= epsilon && + Math.abs(left[14] - right[14]) <= epsilon && + Math.abs(left[15] - right[15]) <= epsilon) ); } - static inverse(e, t) { - const i = e[0], - r = e[4], - n = e[8], - s = e[12], - a = e[1], - o = e[5], - c = e[9], - l = e[13], - h = e[2], - u = e[6], - f = e[10], - d = e[14], - m = e[3], - p = e[7], - g = e[11], - x = e[15]; - let v = f * x, - y = d * g, - S = u * x, - b = d * p, - w = u * g, - T = f * p, - E = h * x, - M = d * m, - U = h * g, - _ = f * m, - L = h * p, - C = u * m; - const R = v * o + b * c + w * l - (y * o + S * c + T * l), - A = y * a + E * c + _ * l - (v * a + M * c + U * l), - D = S * a + M * o + L * l - (b * a + E * o + C * l), - z = T * a + U * o + C * c - (w * a + _ * o + L * c), - I = y * r + S * n + T * s - (v * r + b * n + w * s), - P = v * i + M * n + U * s - (y * i + E * n + _ * s), - N = b * i + E * r + C * s - (S * i + M * r + L * s), - B = w * i + _ * r + L * n - (T * i + U * r + C * n); - (v = n * l), - (y = s * c), - (S = r * l), - (b = s * o), - (w = r * c), - (T = n * o), - (E = i * l), - (M = s * a), - (U = i * c), - (_ = n * a), - (L = i * o), - (C = r * a); - const O = v * p + b * g + w * x - (y * p + S * g + T * x), - V = y * m + E * g + _ * x - (v * m + M * g + U * x), - F = S * m + M * p + L * x - (b * m + E * p + C * x), - $ = T * m + U * p + C * g - (w * m + _ * p + L * g), - G = S * f + T * d + y * u - (w * d + v * u + b * f), - k = U * d + v * h + M * f - (E * f + _ * d + y * h), - q = E * u + C * d + b * h - (L * d + S * h + M * u), - j = L * f + w * h + _ * u - (U * u + C * f + T * h); - let H = i * R + r * A + n * D + s * z; - if (Math.abs(H) < ve.EPSILON21) { - if (Ge.equalsEpsilon(et.getMatrix3(e, ot), ct, ve.EPSILON7) && We.equals(et.getRow(e, 3, lt), ht)) - return ( - (t[0] = 0), - (t[1] = 0), - (t[2] = 0), - (t[3] = 0), - (t[4] = 0), - (t[5] = 0), - (t[6] = 0), - (t[7] = 0), - (t[8] = 0), - (t[9] = 0), - (t[10] = 0), - (t[11] = 0), - (t[12] = -e[12]), - (t[13] = -e[13]), - (t[14] = -e[14]), - (t[15] = 1), - t - ); + static getTranslation(matrix, result) { + result.x = matrix[12]; + result.y = matrix[13]; + result.z = matrix[14]; + return result; + } + static getMatrix3(matrix, result) { + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[4]; + result[4] = matrix[5]; + result[5] = matrix[6]; + result[6] = matrix[8]; + result[7] = matrix[9]; + result[8] = matrix[10]; + return result; + } + static inverse(matrix, result) { + // + // Ported from: + // ftp://download.intel.com/design/PentiumIII/sml/24504301.pdf + // + const src0 = matrix[0]; + const src1 = matrix[4]; + const src2 = matrix[8]; + const src3 = matrix[12]; + const src4 = matrix[1]; + const src5 = matrix[5]; + const src6 = matrix[9]; + const src7 = matrix[13]; + const src8 = matrix[2]; + const src9 = matrix[6]; + const src10 = matrix[10]; + const src11 = matrix[14]; + const src12 = matrix[3]; + const src13 = matrix[7]; + const src14 = matrix[11]; + const src15 = matrix[15]; + // calculate pairs for first 8 elements (cofactors) + let tmp0 = src10 * src15; + let tmp1 = src11 * src14; + let tmp2 = src9 * src15; + let tmp3 = src11 * src13; + let tmp4 = src9 * src14; + let tmp5 = src10 * src13; + let tmp6 = src8 * src15; + let tmp7 = src11 * src12; + let tmp8 = src8 * src14; + let tmp9 = src10 * src12; + let tmp10 = src8 * src13; + let tmp11 = src9 * src12; + // calculate first 8 elements (cofactors) + const dst0 = tmp0 * src5 + tmp3 * src6 + tmp4 * src7 - (tmp1 * src5 + tmp2 * src6 + tmp5 * src7); + const dst1 = tmp1 * src4 + tmp6 * src6 + tmp9 * src7 - (tmp0 * src4 + tmp7 * src6 + tmp8 * src7); + const dst2 = tmp2 * src4 + tmp7 * src5 + tmp10 * src7 - (tmp3 * src4 + tmp6 * src5 + tmp11 * src7); + const dst3 = tmp5 * src4 + tmp8 * src5 + tmp11 * src6 - (tmp4 * src4 + tmp9 * src5 + tmp10 * src6); + const dst4 = tmp1 * src1 + tmp2 * src2 + tmp5 * src3 - (tmp0 * src1 + tmp3 * src2 + tmp4 * src3); + const dst5 = tmp0 * src0 + tmp7 * src2 + tmp8 * src3 - (tmp1 * src0 + tmp6 * src2 + tmp9 * src3); + const dst6 = tmp3 * src0 + tmp6 * src1 + tmp11 * src3 - (tmp2 * src0 + tmp7 * src1 + tmp10 * src3); + const dst7 = tmp4 * src0 + tmp9 * src1 + tmp10 * src2 - (tmp5 * src0 + tmp8 * src1 + tmp11 * src2); + // calculate pairs for second 8 elements (cofactors) + tmp0 = src2 * src7; + tmp1 = src3 * src6; + tmp2 = src1 * src7; + tmp3 = src3 * src5; + tmp4 = src1 * src6; + tmp5 = src2 * src5; + tmp6 = src0 * src7; + tmp7 = src3 * src4; + tmp8 = src0 * src6; + tmp9 = src2 * src4; + tmp10 = src0 * src5; + tmp11 = src1 * src4; + // calculate second 8 elements (cofactors) + const dst8 = tmp0 * src13 + tmp3 * src14 + tmp4 * src15 - (tmp1 * src13 + tmp2 * src14 + tmp5 * src15); + const dst9 = tmp1 * src12 + tmp6 * src14 + tmp9 * src15 - (tmp0 * src12 + tmp7 * src14 + tmp8 * src15); + const dst10 = tmp2 * src12 + tmp7 * src13 + tmp10 * src15 - (tmp3 * src12 + tmp6 * src13 + tmp11 * src15); + const dst11 = tmp5 * src12 + tmp8 * src13 + tmp11 * src14 - (tmp4 * src12 + tmp9 * src13 + tmp10 * src14); + const dst12 = tmp2 * src10 + tmp5 * src11 + tmp1 * src9 - (tmp4 * src11 + tmp0 * src9 + tmp3 * src10); + const dst13 = tmp8 * src11 + tmp0 * src8 + tmp7 * src10 - (tmp6 * src10 + tmp9 * src11 + tmp1 * src8); + const dst14 = tmp6 * src9 + tmp11 * src11 + tmp3 * src8 - (tmp10 * src11 + tmp2 * src8 + tmp7 * src9); + const dst15 = tmp10 * src10 + tmp4 * src8 + tmp9 * src9 - (tmp8 * src9 + tmp11 * src10 + tmp5 * src8); + // calculate determinant + let det = src0 * dst0 + src1 * dst1 + src2 * dst2 + src3 * dst3; + if (Math.abs(det) < GMath.EPSILON21) { + // Special case for a zero scale matrix that can occur, for example, + // when a model's node has a [0, 0, 0] scale. + if ( + Matrix3.equalsEpsilon( + Matrix4.getMatrix3(matrix, scratchInverseRotation), + scratchMatrix3Zero, + GMath.EPSILON7 + ) && + Vector4.equals(Matrix4.getRow(matrix, 3, scratchBottomRow), scratchExpectedBottomRow) + ) { + result[0] = 0.0; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 0.0; + result[4] = 0.0; + result[5] = 0.0; + result[6] = 0.0; + result[7] = 0.0; + result[8] = 0.0; + result[9] = 0.0; + result[10] = 0.0; + result[11] = 0.0; + result[12] = -matrix[12]; + result[13] = -matrix[13]; + result[14] = -matrix[14]; + result[15] = 1.0; + return result; + } throw new Error("matrix is not invertible because its determinate is zero."); } + // calculate matrix inverse + det = 1.0 / det; + result[0] = dst0 * det; + result[1] = dst1 * det; + result[2] = dst2 * det; + result[3] = dst3 * det; + result[4] = dst4 * det; + result[5] = dst5 * det; + result[6] = dst6 * det; + result[7] = dst7 * det; + result[8] = dst8 * det; + result[9] = dst9 * det; + result[10] = dst10 * det; + result[11] = dst11 * det; + result[12] = dst12 * det; + result[13] = dst13 * det; + result[14] = dst14 * det; + result[15] = dst15 * det; + return result; + } + static inverseTransformation(matrix, result) { + // This function is an optimized version of the below 4 lines. + // const rT = Matrix3.transpose(Matrix4.getMatrix3(matrix)); + // const rTN = Matrix3.negate(rT); + // const rTT = Matrix3.multiplyByVector(rTN, Matrix4.getTranslation(matrix)); + // return Matrix4.fromRotationTranslation(rT, rTT, result); + const matrix0 = matrix[0]; + const matrix1 = matrix[1]; + const matrix2 = matrix[2]; + const matrix4 = matrix[4]; + const matrix5 = matrix[5]; + const matrix6 = matrix[6]; + const matrix8 = matrix[8]; + const matrix9 = matrix[9]; + const matrix10 = matrix[10]; + const vX = matrix[12]; + const vY = matrix[13]; + const vZ = matrix[14]; + const x = -matrix0 * vX - matrix1 * vY - matrix2 * vZ; + const y = -matrix4 * vX - matrix5 * vY - matrix6 * vZ; + const z = -matrix8 * vX - matrix9 * vY - matrix10 * vZ; + result[0] = matrix0; + result[1] = matrix4; + result[2] = matrix8; + result[3] = 0.0; + result[4] = matrix1; + result[5] = matrix5; + result[6] = matrix9; + result[7] = 0.0; + result[8] = matrix2; + result[9] = matrix6; + result[10] = matrix10; + result[11] = 0.0; + result[12] = x; + result[13] = y; + result[14] = z; + result[15] = 1.0; + return result; + } + static inverseTranspose(matrix, result) { + return Matrix4.inverse(Matrix4.transpose(matrix, scratchTransposeMatrix), result); + } + /** + * @private + */ + static equalsArray(matrix, array, offset) { return ( - (H = 1 / H), - (t[0] = R * H), - (t[1] = A * H), - (t[2] = D * H), - (t[3] = z * H), - (t[4] = I * H), - (t[5] = P * H), - (t[6] = N * H), - (t[7] = B * H), - (t[8] = O * H), - (t[9] = V * H), - (t[10] = F * H), - (t[11] = $ * H), - (t[12] = G * H), - (t[13] = k * H), - (t[14] = q * H), - (t[15] = j * H), - t - ); - } - static inverseTransformation(e, t) { - const i = e[0], - r = e[1], - n = e[2], - s = e[4], - a = e[5], - o = e[6], - c = e[8], - l = e[9], - h = e[10], - u = e[12], - f = e[13], - d = e[14], - m = -i * u - r * f - n * d, - p = -s * u - a * f - o * d, - g = -c * u - l * f - h * d; - return ( - (t[0] = i), - (t[1] = s), - (t[2] = c), - (t[3] = 0), - (t[4] = r), - (t[5] = a), - (t[6] = l), - (t[7] = 0), - (t[8] = n), - (t[9] = o), - (t[10] = h), - (t[11] = 0), - (t[12] = m), - (t[13] = p), - (t[14] = g), - (t[15] = 1), - t - ); - } - static inverseTranspose(e, t) { - return et.inverse(et.transpose(e, tt), t); - } - static equalsArray(e, t, i) { - return ( - e[0] === t[i] && - e[1] === t[i + 1] && - e[2] === t[i + 2] && - e[3] === t[i + 3] && - e[4] === t[i + 4] && - e[5] === t[i + 5] && - e[6] === t[i + 6] && - e[7] === t[i + 7] && - e[8] === t[i + 8] && - e[9] === t[i + 9] && - e[10] === t[i + 10] && - e[11] === t[i + 11] && - e[12] === t[i + 12] && - e[13] === t[i + 13] && - e[14] === t[i + 14] && - e[15] === t[i + 15] + matrix[0] === array[offset] && + matrix[1] === array[offset + 1] && + matrix[2] === array[offset + 2] && + matrix[3] === array[offset + 3] && + matrix[4] === array[offset + 4] && + matrix[5] === array[offset + 5] && + matrix[6] === array[offset + 6] && + matrix[7] === array[offset + 7] && + matrix[8] === array[offset + 8] && + matrix[9] === array[offset + 9] && + matrix[10] === array[offset + 10] && + matrix[11] === array[offset + 11] && + matrix[12] === array[offset + 12] && + matrix[13] === array[offset + 13] && + matrix[14] === array[offset + 14] && + matrix[15] === array[offset + 15] ); } } -(et.IDENTITY = Object.freeze(new et(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1))), - (et.ZERO = Object.freeze(new et(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); -const tt = new et(); -new Ue(), new Ue(), new Ue(); -const it = new Ue(); -new Ue(); -const rt = new Ue(), - nt = new Ue(), - st = new Ue(), - at = new Ue(), - ot = new Ge(), - ct = new Ge(), - lt = new We(), - ht = new We(0, 0, 0, 1), - ut = new Ue(), - ft = new Ue(), - dt = new Ue(); -class mt { - constructor(e = new Ue(0, 0, 0), t = 0) { - (this.center = e), (this.radius = t), (this.originCenter = this.center.clone()), (this.originRadius = t); - } - static fromPoints(e) { - const t = new mt(); - if (!pe(e) || 0 === e.length) return (t.center = Ue.clone(Ue.ZERO, t.center)), (t.radius = 0), t; - const i = Ue.clone(e[0], bt), - r = Ue.clone(i, pt), - n = Ue.clone(i, gt), - s = Ue.clone(i, xt), - a = Ue.clone(i, vt), - o = Ue.clone(i, yt), - c = Ue.clone(i, St), - l = e.length; - let h; - for (h = 1; h < l; h++) { - Ue.clone(e[h], i); - const t = i.x, - l = i.y, - u = i.z; - t < r.x && Ue.clone(i, r), - t > a.x && Ue.clone(i, a), - l < n.y && Ue.clone(i, n), - l > o.y && Ue.clone(i, o), - u < s.z && Ue.clone(i, s), - u > c.z && Ue.clone(i, c); - } - const u = Ue.magnitudeSquared(Ue.subtract(a, r, wt)), - f = Ue.magnitudeSquared(Ue.subtract(o, n, wt)), - d = Ue.magnitudeSquared(Ue.subtract(c, s, wt)); - let m = r, - p = a, - g = u; - f > g && ((g = f), (m = n), (p = o)), d > g && ((g = d), (m = s), (p = c)); - const x = Tt; - (x.x = 0.5 * (m.x + p.x)), (x.y = 0.5 * (m.y + p.y)), (x.z = 0.5 * (m.z + p.z)); - let v = Ue.magnitudeSquared(Ue.subtract(p, x, wt)), - y = Math.sqrt(v); - const S = Et; - (S.x = r.x), (S.y = n.y), (S.z = s.z); - const b = Mt; - (b.x = a.x), (b.y = o.y), (b.z = c.z); - const w = Ue.midpoint(S, b, Ut); - let T = 0; - for (h = 0; h < l; h++) { - Ue.clone(e[h], i); - const t = Ue.magnitude(Ue.subtract(i, w, wt)); - t > T && (T = t); - const r = Ue.magnitudeSquared(Ue.subtract(i, x, wt)); - if (r > v) { - const e = Math.sqrt(r); - (y = 0.5 * (y + e)), (v = y * y); - const t = e - y; - (x.x = (y * x.x + t * i.x) / e), (x.y = (y * x.y + t * i.y) / e), (x.z = (y * x.z + t * i.z) / e); +Matrix4.IDENTITY = Object.freeze( + new Matrix4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0) +); +Matrix4.ZERO = Object.freeze( + new Matrix4(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) +); +const scratchTransposeMatrix = new Matrix4(); +new Vector3(); +new Vector3(); +new Vector3(); +const scaleScratch1$1 = new Vector3(); +new Vector3(); +const scratchColumn$1 = new Vector3(); +const scaleScratch3$1 = new Vector3(); +const scaleScratch4$1 = new Vector3(); +const scaleScratch5$1 = new Vector3(); +const scratchInverseRotation = new Matrix3(); +const scratchMatrix3Zero = new Matrix3(); +const scratchBottomRow = new Vector4(); +const scratchExpectedBottomRow = new Vector4(0.0, 0.0, 0.0, 1.0); +const x = new Vector3(); +const y = new Vector3(); +const z = new Vector3(); + +class BoundingSphere { + constructor(center = new Vector3(0, 0, 0), radius = 0) { + this.center = center; + this.radius = radius; + this.originCenter = this.center.clone(); + this.originRadius = radius; + } + /** + * @param {Vector3[]} [positions] An array of points that the bounding sphere will enclose. Each point must have x, y, and z properties. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided. + */ + static fromPoints(positions) { + const result = new BoundingSphere(); + if (!defined(positions) || positions.length === 0) { + result.center = Vector3.clone(Vector3.ZERO, result.center); + result.radius = 0.0; + return result; + } + const currentPos = Vector3.clone(positions[0], fromPointsCurrentPos); + const xMin = Vector3.clone(currentPos, fromPointsXMin); + const yMin = Vector3.clone(currentPos, fromPointsYMin); + const zMin = Vector3.clone(currentPos, fromPointsZMin); + const xMax = Vector3.clone(currentPos, fromPointsXMax); + const yMax = Vector3.clone(currentPos, fromPointsYMax); + const zMax = Vector3.clone(currentPos, fromPointsZMax); + const numPositions = positions.length; + let i; + for (i = 1; i < numPositions; i++) { + Vector3.clone(positions[i], currentPos); + const x = currentPos.x; + const y = currentPos.y; + const z = currentPos.z; + // Store points containing the the smallest and largest components + if (x < xMin.x) { + Vector3.clone(currentPos, xMin); + } + if (x > xMax.x) { + Vector3.clone(currentPos, xMax); + } + if (y < yMin.y) { + Vector3.clone(currentPos, yMin); + } + if (y > yMax.y) { + Vector3.clone(currentPos, yMax); + } + if (z < zMin.z) { + Vector3.clone(currentPos, zMin); + } + if (z > zMax.z) { + Vector3.clone(currentPos, zMax); + } + } + // Compute x-, y-, and z-spans (Squared distances b/n each component's min. and max.). + const xSpan = Vector3.magnitudeSquared(Vector3.subtract(xMax, xMin, fromPointsScratch)); + const ySpan = Vector3.magnitudeSquared(Vector3.subtract(yMax, yMin, fromPointsScratch)); + const zSpan = Vector3.magnitudeSquared(Vector3.subtract(zMax, zMin, fromPointsScratch)); + // Set the diameter endpoints to the largest span. + let diameter1 = xMin; + let diameter2 = xMax; + let maxSpan = xSpan; + if (ySpan > maxSpan) { + maxSpan = ySpan; + diameter1 = yMin; + diameter2 = yMax; + } + if (zSpan > maxSpan) { + maxSpan = zSpan; + diameter1 = zMin; + diameter2 = zMax; + } + // Calculate the center of the initial sphere found by Ritter's algorithm + const ritterCenter = fromPointsRitterCenter; + ritterCenter.x = (diameter1.x + diameter2.x) * 0.5; + ritterCenter.y = (diameter1.y + diameter2.y) * 0.5; + ritterCenter.z = (diameter1.z + diameter2.z) * 0.5; + // Calculate the radius of the initial sphere found by Ritter's algorithm + let radiusSquared = Vector3.magnitudeSquared(Vector3.subtract(diameter2, ritterCenter, fromPointsScratch)); + let ritterRadius = Math.sqrt(radiusSquared); + // Find the center of the sphere found using the Naive method. + const minBoxPt = fromPointsMinBoxPt; + minBoxPt.x = xMin.x; + minBoxPt.y = yMin.y; + minBoxPt.z = zMin.z; + const maxBoxPt = fromPointsMaxBoxPt; + maxBoxPt.x = xMax.x; + maxBoxPt.y = yMax.y; + maxBoxPt.z = zMax.z; + const naiveCenter = Vector3.midpoint(minBoxPt, maxBoxPt, fromPointsNaiveCenterScratch); + // Begin 2nd pass to find naive radius and modify the ritter sphere. + let naiveRadius = 0; + for (i = 0; i < numPositions; i++) { + Vector3.clone(positions[i], currentPos); + // Find the furthest point from the naive center to calculate the naive radius. + const r = Vector3.magnitude(Vector3.subtract(currentPos, naiveCenter, fromPointsScratch)); + if (r > naiveRadius) { + naiveRadius = r; + } + // Make adjustments to the Ritter Sphere to include all points. + const oldCenterToPointSquared = Vector3.magnitudeSquared( + Vector3.subtract(currentPos, ritterCenter, fromPointsScratch) + ); + if (oldCenterToPointSquared > radiusSquared) { + const oldCenterToPoint = Math.sqrt(oldCenterToPointSquared); + // Calculate new radius to include the point that lies outside + ritterRadius = (ritterRadius + oldCenterToPoint) * 0.5; + radiusSquared = ritterRadius * ritterRadius; + // Calculate center of new Ritter sphere + const oldToNew = oldCenterToPoint - ritterRadius; + ritterCenter.x = (ritterRadius * ritterCenter.x + oldToNew * currentPos.x) / oldCenterToPoint; + ritterCenter.y = (ritterRadius * ritterCenter.y + oldToNew * currentPos.y) / oldCenterToPoint; + ritterCenter.z = (ritterRadius * ritterCenter.z + oldToNew * currentPos.z) / oldCenterToPoint; + } + } + if (ritterRadius < naiveRadius) { + Vector3.clone(ritterCenter, result.center); + result.radius = ritterRadius; + } else { + Vector3.clone(naiveCenter, result.center); + result.radius = naiveRadius; + } + return result; + } + /** + * Computes a tight-fitting bounding sphere enclosing a list of 3D points, where the points are + * stored in a flat array in X, Y, Z, order. The bounding sphere is computed by running two + * algorithms, a naive algorithm and Ritter's algorithm. The smaller of the two spheres is used to + * ensure a tight fit. + * + * @param {Number[]} [positions] An array of points that the bounding sphere will enclose. Each point + * is formed from three elements in the array in the order X, Y, Z. + * @param {Vector3} [center=Vector3.ZERO] The position to which the positions are relative, which need not be the + * origin of the coordinate system. This is useful when the positions are to be used for + * relative-to-center (RTC) rendering. + * @param {Number} [stride=3] The number of array elements per vertex. It must be at least 3, but it may + * be higher. Regardless of the value of this parameter, the X coordinate of the first position + * is at array index 0, the Y coordinate is at array index 1, and the Z coordinate is at array index + * 2. When stride is 3, the X coordinate of the next position then begins at array index 3. If + * the stride is 5, however, two array elements are skipped and the next position begins at array + * index 5. + * @param {BoundingSphere} [result] The object onto which to store the result. + * @returns {BoundingSphere} The modified result parameter or a new BoundingSphere instance if one was not provided. + * + * @example + * // Compute the bounding sphere from 3 positions, each specified relative to a center. + * // In addition to the X, Y, and Z coordinates, the points array contains two additional + * // elements per point which are ignored for the purpose of computing the bounding sphere. + * const center = new Vector3(1.0, 2.0, 3.0); + * const points = [1.0, 2.0, 3.0, 0.1, 0.2, + * 4.0, 5.0, 6.0, 0.1, 0.2, + * 7.0, 8.0, 9.0, 0.1, 0.2]; + * const sphere = BoundingSphere.fromVertices(points, center, 5); + * + */ + static fromVertices(positions, center = Vector3.ZERO, stride = 3) { + const result = new BoundingSphere(); + if (!defined(positions) || positions.length === 0) { + result.center = Vector3.clone(Vector3.ZERO, result.center); + result.radius = 0.0; + return result; + } + center = defaultValue(center, Vector3.ZERO); + stride = defaultValue(stride, 3); + const currentPos = fromPointsCurrentPos; + currentPos.x = positions[0] + center.x; + currentPos.y = positions[1] + center.y; + currentPos.z = positions[2] + center.z; + const xMin = Vector3.clone(currentPos, fromPointsXMin); + const yMin = Vector3.clone(currentPos, fromPointsYMin); + const zMin = Vector3.clone(currentPos, fromPointsZMin); + const xMax = Vector3.clone(currentPos, fromPointsXMax); + const yMax = Vector3.clone(currentPos, fromPointsYMax); + const zMax = Vector3.clone(currentPos, fromPointsZMax); + const numElements = positions.length; + let i; + for (i = 0; i < numElements; i += stride) { + const x = positions[i] + center.x; + const y = positions[i + 1] + center.y; + const z = positions[i + 2] + center.z; + currentPos.x = x; + currentPos.y = y; + currentPos.z = z; + // Store points containing the the smallest and largest components + if (x < xMin.x) { + Vector3.clone(currentPos, xMin); + } + if (x > xMax.x) { + Vector3.clone(currentPos, xMax); + } + if (y < yMin.y) { + Vector3.clone(currentPos, yMin); + } + if (y > yMax.y) { + Vector3.clone(currentPos, yMax); + } + if (z < zMin.z) { + Vector3.clone(currentPos, zMin); + } + if (z > zMax.z) { + Vector3.clone(currentPos, zMax); } } - return y < T ? (Ue.clone(x, t.center), (t.radius = y)) : (Ue.clone(w, t.center), (t.radius = T)), t; - } - static fromVertices(e, t = Ue.ZERO, i = 3) { - const r = new mt(); - if (!pe(e) || 0 === e.length) return (r.center = Ue.clone(Ue.ZERO, r.center)), (r.radius = 0), r; - (t = ee(t, Ue.ZERO)), (i = ee(i, 3)); - const n = bt; - (n.x = e[0] + t.x), (n.y = e[1] + t.y), (n.z = e[2] + t.z); - const s = Ue.clone(n, pt), - a = Ue.clone(n, gt), - o = Ue.clone(n, xt), - c = Ue.clone(n, vt), - l = Ue.clone(n, yt), - h = Ue.clone(n, St), - u = e.length; - let f; - for (f = 0; f < u; f += i) { - const i = e[f] + t.x, - r = e[f + 1] + t.y, - u = e[f + 2] + t.z; - (n.x = i), - (n.y = r), - (n.z = u), - i < s.x && Ue.clone(n, s), - i > c.x && Ue.clone(n, c), - r < a.y && Ue.clone(n, a), - r > l.y && Ue.clone(n, l), - u < o.z && Ue.clone(n, o), - u > h.z && Ue.clone(n, h); - } - const d = Ue.magnitudeSquared(Ue.subtract(c, s, wt)), - m = Ue.magnitudeSquared(Ue.subtract(l, a, wt)), - p = Ue.magnitudeSquared(Ue.subtract(h, o, wt)); - let g = s, - x = c, - v = d; - m > v && ((v = m), (g = a), (x = l)), p > v && ((v = p), (g = o), (x = h)); - const y = Tt; - (y.x = 0.5 * (g.x + x.x)), (y.y = 0.5 * (g.y + x.y)), (y.z = 0.5 * (g.z + x.z)); - let S = Ue.magnitudeSquared(Ue.subtract(x, y, wt)), - b = Math.sqrt(S); - const w = Et; - (w.x = s.x), (w.y = a.y), (w.z = o.z); - const T = Mt; - (T.x = c.x), (T.y = l.y), (T.z = h.z); - const E = Ue.midpoint(w, T, Ut); - let M = 0; - for (f = 0; f < u; f += i) { - (n.x = e[f] + t.x), (n.y = e[f + 1] + t.y), (n.z = e[f + 2] + t.z); - const i = Ue.magnitude(Ue.subtract(n, E, wt)); - i > M && (M = i); - const r = Ue.magnitudeSquared(Ue.subtract(n, y, wt)); - if (r > S) { - const e = Math.sqrt(r); - (b = 0.5 * (b + e)), (S = b * b); - const t = e - b; - (y.x = (b * y.x + t * n.x) / e), (y.y = (b * y.y + t * n.y) / e), (y.z = (b * y.z + t * n.z) / e); + // Compute x-, y-, and z-spans (Squared distances b/n each component's min. and max.). + const xSpan = Vector3.magnitudeSquared(Vector3.subtract(xMax, xMin, fromPointsScratch)); + const ySpan = Vector3.magnitudeSquared(Vector3.subtract(yMax, yMin, fromPointsScratch)); + const zSpan = Vector3.magnitudeSquared(Vector3.subtract(zMax, zMin, fromPointsScratch)); + // Set the diameter endpoints to the largest span. + let diameter1 = xMin; + let diameter2 = xMax; + let maxSpan = xSpan; + if (ySpan > maxSpan) { + maxSpan = ySpan; + diameter1 = yMin; + diameter2 = yMax; + } + if (zSpan > maxSpan) { + maxSpan = zSpan; + diameter1 = zMin; + diameter2 = zMax; + } + // Calculate the center of the initial sphere found by Ritter's algorithm + const ritterCenter = fromPointsRitterCenter; + ritterCenter.x = (diameter1.x + diameter2.x) * 0.5; + ritterCenter.y = (diameter1.y + diameter2.y) * 0.5; + ritterCenter.z = (diameter1.z + diameter2.z) * 0.5; + // Calculate the radius of the initial sphere found by Ritter's algorithm + let radiusSquared = Vector3.magnitudeSquared(Vector3.subtract(diameter2, ritterCenter, fromPointsScratch)); + let ritterRadius = Math.sqrt(radiusSquared); + // Find the center of the sphere found using the Naive method. + const minBoxPt = fromPointsMinBoxPt; + minBoxPt.x = xMin.x; + minBoxPt.y = yMin.y; + minBoxPt.z = zMin.z; + const maxBoxPt = fromPointsMaxBoxPt; + maxBoxPt.x = xMax.x; + maxBoxPt.y = yMax.y; + maxBoxPt.z = zMax.z; + const naiveCenter = Vector3.midpoint(minBoxPt, maxBoxPt, fromPointsNaiveCenterScratch); + // Begin 2nd pass to find naive radius and modify the ritter sphere. + let naiveRadius = 0; + for (i = 0; i < numElements; i += stride) { + currentPos.x = positions[i] + center.x; + currentPos.y = positions[i + 1] + center.y; + currentPos.z = positions[i + 2] + center.z; + // Find the furthest point from the naive center to calculate the naive radius. + const r = Vector3.magnitude(Vector3.subtract(currentPos, naiveCenter, fromPointsScratch)); + if (r > naiveRadius) { + naiveRadius = r; + } + // Make adjustments to the Ritter Sphere to include all points. + const oldCenterToPointSquared = Vector3.magnitudeSquared( + Vector3.subtract(currentPos, ritterCenter, fromPointsScratch) + ); + if (oldCenterToPointSquared > radiusSquared) { + const oldCenterToPoint = Math.sqrt(oldCenterToPointSquared); + // Calculate new radius to include the point that lies outside + ritterRadius = (ritterRadius + oldCenterToPoint) * 0.5; + radiusSquared = ritterRadius * ritterRadius; + // Calculate center of new Ritter sphere + const oldToNew = oldCenterToPoint - ritterRadius; + ritterCenter.x = (ritterRadius * ritterCenter.x + oldToNew * currentPos.x) / oldCenterToPoint; + ritterCenter.y = (ritterRadius * ritterCenter.y + oldToNew * currentPos.y) / oldCenterToPoint; + ritterCenter.z = (ritterRadius * ritterCenter.z + oldToNew * currentPos.z) / oldCenterToPoint; } } - return b < M ? (Ue.clone(y, r.center), (r.radius = b)) : (Ue.clone(E, r.center), (r.radius = M)), r; - } - intersectPlane(e) { - const t = this.center, - i = this.radius, - r = e.normal, - n = Ue.dot(r, t) + e.distance; - return n < -i ? F.OUTSIDE : n < i ? F.INTERSECTING : F.INSIDE; - } - update(e) { - et.multiplyByPoint(e, this.originCenter, this.center), - (this.radius = et.getMaximumScale(e) * this.originRadius); - } - distanceToCamera(e) { - return Math.max(0, Ue.distance(this.center, e.position) - this.radius); - } -} -const pt = new Ue(), - gt = new Ue(), - xt = new Ue(), - vt = new Ue(), - yt = new Ue(), - St = new Ue(), - bt = new Ue(), - wt = new Ue(), - Tt = new Ue(), - Et = new Ue(), - Mt = new Ue(), - Ut = new Ue(); -class _t { - constructor(e, t) { - (this.label = e), (this.indices = t), (this.indexFormat = _.Uint16), (this.dirty = !0); - } - setIndices(e) { - (this.indices = e), (this.dirty = !0); - } - bind(e, t) { - this.dirty && - ((this.dirty = !1), - (this.buffer = $.createIndexBuffer( + if (ritterRadius < naiveRadius) { + Vector3.clone(ritterCenter, result.center); + result.radius = ritterRadius; + } else { + Vector3.clone(naiveCenter, result.center); + result.radius = naiveRadius; + } + return result; + } + intersectPlane(plane) { + const center = this.center; + const radius = this.radius; + const normal = plane.normal; + const distanceToPlane = Vector3.dot(normal, center) + plane.distance; + if (distanceToPlane < -radius) { + // The center point is negative side of the plane normal + return Intersect.OUTSIDE; + } else if (distanceToPlane < radius) { + // The center point is positive side of the plane, but radius extends beyond it; partial overlap + return Intersect.INTERSECTING; + } + return Intersect.INSIDE; + } + update(transform) { + Matrix4.multiplyByPoint(transform, this.originCenter, this.center); + this.radius = Matrix4.getMaximumScale(transform) * this.originRadius; + } + distanceToCamera(camera) { + return Math.max(0.0, Vector3.distance(this.center, camera.position) - this.radius); + } +} +const fromPointsXMin = new Vector3(); +const fromPointsYMin = new Vector3(); +const fromPointsZMin = new Vector3(); +const fromPointsXMax = new Vector3(); +const fromPointsYMax = new Vector3(); +const fromPointsZMax = new Vector3(); +const fromPointsCurrentPos = new Vector3(); +const fromPointsScratch = new Vector3(); +const fromPointsRitterCenter = new Vector3(); +const fromPointsMinBoxPt = new Vector3(); +const fromPointsMaxBoxPt = new Vector3(); +const fromPointsNaiveCenterScratch = new Vector3(); + +class IndexBuffer { + constructor(label, indices) { + this.label = label; + this.indices = indices; + this.indexFormat = IndexFormat.Uint16; + this.dirty = true; + } + setIndices(indices) { + this.indices = indices; + this.dirty = true; + } + bind(device, passEncoder) { + if (this.dirty) { + this.dirty = false; + this.buffer = Buffer.createIndexBuffer( this.label, - e, - this.indexFormat == _.Uint16 ? new Uint16Array(this.indices) : new Uint32Array(this.indices) - ))), - t.setIndexBuffer(this.buffer.gpuBuffer, this.indexFormat); + device, + this.indexFormat == IndexFormat.Uint16 ? new Uint16Array(this.indices) : new Uint32Array(this.indices) + ); + } + passEncoder.setIndexBuffer(this.buffer.gpuBuffer, this.indexFormat); } destroy() { this.buffer.destroy(); } } -class Lt { - constructor(e = 0) { - (this._attributes = new Map()), (this.shaderLocation = e), (this.offset = 0), (this.interleave = !1); + +class Attributes { + constructor(shaderLocation = 0) { + this._attributes = new Map(); + this.shaderLocation = shaderLocation; + this.offset = 0; + this.interleave = false; } get dirty() { - let e = !1; - return this._attributes.forEach((t) => !e && (e = t.dirty)), e; + let result = false; + this._attributes.forEach((attribute) => (!result ? (result = attribute.dirty) : false)); + return result; } - set dirty(e) { - this._attributes.forEach((t) => (t.dirty = e)); + set dirty(value) { + this._attributes.forEach((attribute) => (attribute.dirty = value)); } get values() { return this._attributes; } - getAttribute(e) { - return this._attributes.get(e); + getAttribute(name) { + return this._attributes.get(name); } - setAttribute(e) { - e.attributeType === Be.attribute ? this.setNotInterleavedAttribute(e) : this.setInterleavedAttribute(e); + setAttribute(attribute) { + if (attribute.attributeType === AttributeType.attribute) { + this.setNotInterleavedAttribute(attribute); + } else { + this.setInterleavedAttribute(attribute); + } } - setNotInterleavedAttribute(e) { - this._attributes.has(e.name) || - ((e.shaderLocation = this.shaderLocation), - (this.shaderLocation += 1), - (e.offset = this.offset), - (this.offset += e.attributeByteSize), - this._attributes.set(e.name, e)); + setNotInterleavedAttribute(attribute) { + if (this._attributes.has(attribute.name)) return; + attribute.shaderLocation = this.shaderLocation; + this.shaderLocation += 1; + attribute.offset = this.offset; + this.offset += attribute.attributeByteSize; + this._attributes.set(attribute.name, attribute); } - setInterleavedAttribute(e) { - this._attributes.has(e.names.toString()) || this._attributes.set(e.names.toString(), e); + setInterleavedAttribute(attribute) { + if (this._attributes.has(attribute.names.toString())) return; + this._attributes.set(attribute.names.toString(), attribute); } getGPUAttributesDes() { - const e = []; - return ( - this._attributes.forEach((t) => { - e.push(...t.getGPUAttribute()); - }), - e - ); + const result = []; + this._attributes.forEach((attribute) => { + result.push(...attribute.getGPUAttribute()); + }); + return result; } getAtrributeValues() { - const e = []; - let t, - i = 0, - r = null; - const n = []; - this._attributes.forEach((s) => { - s.attributeType === Be.attribute - ? (e.push(s.itemSize), n.push(s.value), (i += s.itemSize)) - : (this.interleave || (this.interleave = !0), - (r = r ?? s.value), - (t = s?.buffer), - (i = s.itemSizes.reduce((e, t) => e + t, 0))); + const arrayStrides = []; + let arrayStride = 0; + let buffer = undefined; + let values = null; + const arrays = []; + this._attributes.forEach((attribute) => { + if (attribute.attributeType === AttributeType.attribute) { + arrayStrides.push(attribute.itemSize); + arrays.push(attribute.value); + arrayStride += attribute.itemSize; + } else { + if (!this.interleave) this.interleave = true; + values = values ?? attribute.value; + buffer = attribute?.buffer; + arrayStride = attribute.itemSizes.reduce((total, current) => (total += current), 0); + } }); - const s = this.interleave ? new Float32Array(r) : this.interleaveTypedArray(Float32Array, e, ...n); - return { arrayStride: i * s.BYTES_PER_ELEMENT, typeArray: s, buffer: t }; + const typeArray = this.interleave + ? new Float32Array(values) + : this.interleaveTypedArray(Float32Array, arrayStrides, ...arrays); + return { + arrayStride: arrayStride * typeArray.BYTES_PER_ELEMENT, + typeArray, + buffer + }; } destroy() { - this._attributes.forEach((e) => { - e.destroy(); + this._attributes.forEach((attribute) => { + attribute.destroy(); }); } - interleaveTypedArray(e, t, ...i) { - const r = i.reduce((e, t) => e + t.length, 0), - n = new e(r), - s = t.reduce((e, t) => e + t); - for (let e = 0; e < r; e++) { - let r = 0; - for (let a = 0; a < t.length; a++) for (let o = 0; o < t[a]; o++) (n[e * s + r] = i[a][t[a] * e + o]), r++; + /** + * Interleave n typed arrays + * @alias module:interleaveTypedArray + * @param {TypedArray} ResultConstructor Returned typed array constructor + * @param {Array} elements Number of elements to group for each typed array + * @param {...TypedArray} arrays Arrays to interleave + * @returns {TypedArray} + */ + interleaveTypedArray(ResultConstructor, elements, ...arrays) { + const totalLength = arrays.reduce((total, arr) => total + arr.length, 0); + const result = new ResultConstructor(totalLength); + const stride = elements.reduce((a, b) => a + b); + for (let i = 0; i < totalLength; i++) { + let offset = 0; + for (let j = 0; j < elements.length; j++) { + for (let k = 0; k < elements[j]; k++) { + result[i * stride + offset] = arrays[j][elements[j] * i + k]; + offset++; + } + } } - return n; + return result; } } -class Ct { - constructor(e) { - const { label: t, index: i, locationIndex: r = 0, stepMode: n = C.Vertex, arrayStride: s } = e; - (this.index = i || 0), - (this.attributes = new Lt(r)), - (this.stepMode = n), - (this.dirty = !0), - (this.label = t?.concat(`_${i}_VertexBuffer`)), - (this.arrayStride = s), - (this.defines = {}), - (this.locationIndex = r); + +class VertexBuffer { + // + constructor(params) { + const { label, index, locationIndex = 0, stepMode = InputStepMode.Vertex, arrayStride } = params; + this.index = index || 0; + this.attributes = new Attributes(locationIndex); + this.stepMode = stepMode; + this.dirty = true; + this.label = label?.concat(`_${index}_VertexBuffer`); + this.arrayStride = arrayStride; + this.defines = {}; + this.locationIndex = locationIndex; } getBufferDes() { - return { + const result = { arrayStride: this.arrayStride, stepMode: this.stepMode, attributes: this.attributes.getGPUAttributesDes() }; + return result; } - setAttribute(e) { - e.attributeType === Be.attribute - ? this.setLocationIndex(e.name) - : e?.names.forEach((e) => this.setLocationIndex(e)), - this.attributes.setAttribute(e), - (this.dirty = !0); + setAttribute(attribute) { + if (attribute.attributeType === AttributeType.attribute) { + this.setLocationIndex(attribute.name); + } else { + attribute?.names.forEach((name) => this.setLocationIndex(name)); + } + this.attributes.setAttribute(attribute); + this.dirty = true; } - getAttribute(e) { - return this.attributes.getAttribute(e); + getAttribute(name) { + return this.attributes.getAttribute(name); } - containAttribute(e) { - return null != this.defines[e?.concat("Location")]; + containAttribute(name) { + return this.defines[name?.concat("Location")] != undefined ? true : false; } - bind(e, t) { + bind(device, passEncoder) { if (this.attributes.dirty) { - this.attributes.dirty = !1; - const { arrayStride: t, typeArray: i, buffer: r } = this.attributes.getAtrributeValues(); - void 0 === this.arrayStride && (this.arrayStride = t), - this.buffer - ? i && this.buffer.setSubData(0, i) - : (this.buffer = r ?? $.createVertexBuffer(this.label, e, i)); + this.attributes.dirty = false; + const { arrayStride, typeArray, buffer } = this.attributes.getAtrributeValues(); + if (this.arrayStride === undefined) this.arrayStride = arrayStride; + if (!this.buffer) { + this.buffer = buffer ?? Buffer.createVertexBuffer(this.label, device, typeArray); + } else { + // update Buffer + if (typeArray) this.buffer.setSubData(0, typeArray); + } } - t.setVertexBuffer(this.index, this.buffer.gpuBuffer); + passEncoder.setVertexBuffer(this.index, this.buffer.gpuBuffer); } - setLocationIndex(e) { - !this.defines[e?.concat("Location")] && - e && - ((this.defines[e?.concat("Location")] = this.locationIndex), (this.locationIndex += 1)); + setLocationIndex(name) { + if (this.defines[name?.concat("Location")] || !name) return; + this.defines[name?.concat("Location")] = this.locationIndex; + this.locationIndex += 1; } destroy() { - this.buffer.destroy(), this.attributes.destroy(); - } -} -function Rt(e, t, i) { - i = ee(i, !1); - const r = {}, - n = pe(e), - s = pe(t); - let a, o, c; - if (n) - for (a in e) - e.hasOwnProperty(a) && - ((o = e[a]), - s && i && "object" == typeof o && t.hasOwnProperty(a) - ? ((c = t[a]), (r[a] = "object" == typeof c ? Rt(o, c, i) : o)) - : (r[a] = o)); - if (s) for (a in t) t.hasOwnProperty(a) && !r.hasOwnProperty(a) && ((c = t[a]), (r[a] = c)); - return r; -} -class At { + this.buffer.destroy(); + this.attributes.destroy(); + } +} + +/** + * Merges two objects, copying their properties onto a new combined object. When two objects have the same + * property, the value of the property on the first object is used. If either object is undefined, + * it will be treated as an empty object. + * + * @example + * const object1 = { + * propOne : 1, + * propTwo : { + * value1 : 10 + * } + * } + * const object2 = { + * propTwo : 2 + * } + * const final = combine(object1, object2); + * + * // final === { + * // propOne : 1, + * // propTwo : { + * // value1 : 10 + * // } + * // } + * + * @param {Object} [object1] The first object to merge. + * @param {Object} [object2] The second object to merge. + * @param {Boolean} [deep=false] Perform a recursive merge. + * @returns {Object} The combined object containing all properties from both objects. + * + * @function + */ +function combine(object1, object2, deep) { + deep = defaultValue(deep, false); + const result = {}; + const object1Defined = defined(object1); + const object2Defined = defined(object2); + let property; + let object1Value; + let object2Value; + if (object1Defined) { + for (property in object1) { + if (object1.hasOwnProperty(property)) { + object1Value = object1[property]; + if (object2Defined && deep && typeof object1Value === "object" && object2.hasOwnProperty(property)) { + object2Value = object2[property]; + if (typeof object2Value === "object") { + result[property] = combine(object1Value, object2Value, deep); + } else { + result[property] = object1Value; + } + } else { + result[property] = object1Value; + } + } + } + } + if (object2Defined) { + for (property in object2) { + if (object2.hasOwnProperty(property) && !result.hasOwnProperty(property)) { + object2Value = object2[property]; + result[property] = object2Value; + } + } + } + return result; +} + +class Geometry { get defines() { - return Object.assign({}, this._defines, ...this.vertexBuffers.map((e) => e.defines)); + return Object.assign({}, this._defines, ...this.vertexBuffers.map((vertexBuffer) => vertexBuffer.defines)); } - set defines(e) { - (this.definesDirty = !0), (this._defines = Rt(e, this._defines, !1)); + set defines(value) { + this.definesDirty = true; + this._defines = combine(value, this._defines, false); } get currentLocationIndex() { - return this?.vertexBuffers?.reduce((e, t) => (t.locationIndex > e ? (e = t.locationIndex) : e), 0); + return this?.vertexBuffers?.reduce( + (max, current) => (current.locationIndex > max ? (max = current.locationIndex) : max), + 0 + ); } get vertexBufferCount() { return this.vertexBuffers.length; } - constructor(e) { - (this.type = e.type || void 0), - (this.boundingSphere = void 0), - (this.dirty = !1), - (this.definesDirty = !0), - (this.defaultVertexBuffer = new Ct({ label: this.type, index: 0 })), - (this.vertexBuffers = [this.defaultVertexBuffer]), - (this._defines = {}), - (this.normals = []), - (this.uvs = []), - (this.positions = []), - (this.indices = []), - (this.tangents = []); - } - getAttribute(e) { - return this.defaultVertexBuffer.getAttribute(e); - } - setAttribute(e) { - this.defaultVertexBuffer.setAttribute(e); - } - setIndice(e) { - (this.indices = e), - this.indexBuffer || (this.indexBuffer = new _t(this.type + "IndexBuffer")), - this.indexBuffer.setIndices(e); - } - update(e) {} - computeBoundingSphere(e, t = 3) { - this.boundingSphere = mt.fromVertices(e, new Ue(0, 0, 0), t); + constructor(options) { + this.type = options.type || undefined; + this.boundingSphere = undefined; + this.dirty = false; + this.definesDirty = true; + this.defaultVertexBuffer = new VertexBuffer({ + label: this.type, + index: 0 + }); + this.vertexBuffers = [this.defaultVertexBuffer]; + this._defines = {}; + this.normals = []; + this.uvs = []; + this.positions = []; + this.indices = []; + this.tangents = []; + } + getAttribute(name) { + return this.defaultVertexBuffer.getAttribute(name); + } + setAttribute(attribute) { + this.defaultVertexBuffer.setAttribute(attribute); + } + setIndice(indices) { + this.indices = indices; + if (!this.indexBuffer) this.indexBuffer = new IndexBuffer(this.type + "IndexBuffer"); + this.indexBuffer.setIndices(indices); + } + update(frameState) { + // todo } + computeBoundingSphere(positions, stride = 3) { + this.boundingSphere = BoundingSphere.fromVertices(positions, new Vector3(0, 0, 0), stride); + } + /** + * Calculate mesh tangent. + * @remark need to set positions(with or not with indices), normals, uv before calculation. + * @remark based on http://foundationsofgameenginedev.com/FGED2-sample.pdf + */ calculateTangents() { - if (!this.normals || !this.uvs) throw "Set normal and uv before calculation."; - const { indices: e, positions: t, normals: i, uvs: r } = this, - n = new Ue(), - s = new Ue(), - a = new Ue(), - o = new Se(), - c = new Se(), - l = new Se(), - h = new Ue(), - u = new Ue(), - f = new Ue(), - d = new Ue(), - m = new Ue(), - p = this.indices.length, - g = e ? e.length / 3 : t.length / 3, - x = new Array(p), - v = new Array(p); + if (!this.normals || !this.uvs) { + throw "Set normal and uv before calculation."; + } + const { indices, positions, normals, uvs } = this; + const tempPos0 = new Vector3(), + tempPos1 = new Vector3(), + tempPos2 = new Vector3(), + tempUV0 = new Vector2(), + tempUV1 = new Vector2(), + tempUV2 = new Vector2(); + const e1 = new Vector3(), + e2 = new Vector3(), + t = new Vector3(), + b = new Vector3(), + temp = new Vector3(); + const vertexCount = this.indices.length; + const triangleCount = indices ? indices.length / 3 : positions.length / 3; + const tangents = new Array(vertexCount); + const biTangents = new Array(vertexCount); this.tangents = []; - for (let e = 0; e < p; e++) (x[e] = new We()), (v[e] = new Ue()); - for (let i = 0; i < g; i++) { - let p = 3 * i, - g = 3 * i + 1, - y = 3 * i + 2; - e && ((p = e[p]), (g = e[g]), (y = e[y])); - const S = n.set(t[p], t[p + 1], t[p + 2]), - b = s.set(t[g], t[g + 1], t[g + 2]), - w = a.set(t[y], t[y + 1], t[y + 2]), - T = o.set(r[p], r[p + 1]), - E = c.set(r[g], r[g + 1]), - M = l.set(r[y], r[y + 1]); - Ue.subtract(b, S, h), Ue.subtract(w, S, u); - const U = E.x - T.x, - _ = M.x - T.x, - L = E.y - T.y, - C = M.y - T.y, - R = 1 / (U * C - _ * L); - Ue.multiplyByScalar(h, C * R, f), - Ue.multiplyByScalar(u, L * R, m), - Ue.subtract(f, m, f), - Ue.multiplyByScalar(u, U * R, d), - Ue.multiplyByScalar(h, _ * R, m), - Ue.subtract(d, m, d); - let A = x[p]; - A.set(A.x + f.x, A.y + f.y, A.z + f.z, 1), - (A = x[g]), - A.set(A.x + f.x, A.y + f.y, A.z + f.z, 1), - (A = x[y]), - A.set(A.x + f.x, A.y + f.y, A.z + f.z, 1), - v[p].add(d), - v[g].add(d), - v[y].add(d); - } - for (let e = 0; e < p; e++) { - const t = new Ue(i[3 * e], i[3 * e + 1], i[3 * e + 2]), - r = v[e], - n = x[e]; - f.set(n.x, n.y, n.z), Ue.cross(f, r, m); - const s = Ue.dot(m, t) > 0 ? 1 : -1; - Ue.multiplyByScalar(t, Ue.dot(f, t), m), - Ue.subtract(f, m, f), - Ue.normalize(f, f), - n.set(f.x, f.y, f.z, s), - this.tangents.push(f.x, f.y, f.z, s); + for (let i = 0; i < vertexCount; i++) { + tangents[i] = new Vector4(); + biTangents[i] = new Vector3(); + } + // Calculate tangent and bi-tangent for each triangle and add to all three vertices. + for (let k = 0; k < triangleCount; k++) { + let i0 = 3 * k; + let i1 = 3 * k + 1; + let i2 = 3 * k + 2; + if (indices) { + i0 = indices[i0]; + i1 = indices[i1]; + i2 = indices[i2]; + } + const p0 = tempPos0.set(positions[i0], positions[i0 + 1], positions[i0 + 2]); + const p1 = tempPos1.set(positions[i1], positions[i1 + 1], positions[i1 + 2]); + const p2 = tempPos2.set(positions[i2], positions[i2 + 1], positions[i2 + 2]); + const w0 = tempUV0.set(uvs[i0], uvs[i0 + 1]); + const w1 = tempUV1.set(uvs[i1], uvs[i1 + 1]); + const w2 = tempUV2.set(uvs[i2], uvs[i2 + 1]); + Vector3.subtract(p1, p0, e1); + Vector3.subtract(p2, p0, e2); + const x1 = w1.x - w0.x; + const x2 = w2.x - w0.x; + const y1 = w1.y - w0.y; + const y2 = w2.y - w0.y; + const r = 1.0 / (x1 * y2 - x2 * y1); + Vector3.multiplyByScalar(e1, y2 * r, t); + Vector3.multiplyByScalar(e2, y1 * r, temp); + Vector3.subtract(t, temp, t); + Vector3.multiplyByScalar(e2, x1 * r, b); + Vector3.multiplyByScalar(e1, x2 * r, temp); + Vector3.subtract(b, temp, b); + let tangent = tangents[i0]; + tangent.set(tangent.x + t.x, tangent.y + t.y, tangent.z + t.z, 1.0); + tangent = tangents[i1]; + tangent.set(tangent.x + t.x, tangent.y + t.y, tangent.z + t.z, 1.0); + tangent = tangents[i2]; + tangent.set(tangent.x + t.x, tangent.y + t.y, tangent.z + t.z, 1.0); + biTangents[i0].add(b); + biTangents[i1].add(b); + biTangents[i2].add(b); } + // Orthonormalize each tangent and calculate the handedness. + for (let i = 0; i < vertexCount; i++) { + const n = new Vector3(normals[3 * i], normals[3 * i + 1], normals[3 * i + 2]); + const b = biTangents[i]; + const tangent = tangents[i]; + t.set(tangent.x, tangent.y, tangent.z); + Vector3.cross(t, b, temp); + const w = Vector3.dot(temp, n) > 0.0 ? 1 : -1; + Vector3.multiplyByScalar(n, Vector3.dot(t, n), temp); + Vector3.subtract(t, temp, t); + Vector3.normalize(t, t); + // t.normalize(); + tangent.set(t.x, t.y, t.z, w); + this.tangents.push(t.x, t.y, t.z, w); + } + // this.setTangents(tangents); } destroy() { - this?.indexBuffer.destroy(), - this.defaultVertexBuffer.destroy(), - (this.normals = null), - (this.uvs = null), - (this.positions = null), - (this.indices = null), - (this.tangents = null), - (this.boundingSphere = void 0); - } -} -class Dt extends At { - constructor(e = 10, t = 10) { - super({ type: "planeGeometry" }), - (this.width = e), - (this.height = t), - (this.defines = { HAS_NORMAL: !0 }), - this.init(); + this?.indexBuffer.destroy(); + this.defaultVertexBuffer.destroy(); + this.normals = null; + this.uvs = null; + this.positions = null; + this.indices = null; + this.tangents = null; + this.boundingSphere = undefined; + } +} + +class PlaneGeometry extends Geometry { + constructor(width = 10, height = 10) { + super({ + type: "planeGeometry" + }); + this.width = width; + this.height = height; + this.defines = { + HAS_NORMAL: true + }; + this.init(); } init() { - const { indices: e, normals: t, uvs: i, vertices: r } = this.createGrid(this.width, this.height); - this.computeBoundingSphere(r), - this.setAttribute(new Ie("position", r, 3)), - this.setAttribute(new Ie("normal", t, 3)), - this.setAttribute(new Ie("uv", i, 2)), - this.setIndice(e), - (this.count = e.length); - } - createGrid(e = 1, t = 1, i = 1, r = 1) { - const n = e / 2, - s = t / 2, - a = Math.floor(i), - o = Math.floor(r), - c = a + 1, - l = o + 1, - h = e / a, - u = t / o, - f = [], - d = [], - m = [], - p = []; - for (let e = 0; e < l; e++) { - const t = e * u - s; - for (let i = 0; i < c; i++) { - const r = i * h - n; - d.push(r, -t, 0), m.push(0, 0, 1), p.push(i / a), p.push(1 - e / o); + // generate pos uv normal so on + const { indices, normals, uvs, vertices } = this.createGrid(this.width, this.height); + this.computeBoundingSphere(vertices); + this.setAttribute(new Float32Attribute("position", vertices, 3)); + this.setAttribute(new Float32Attribute("normal", normals, 3)); + this.setAttribute(new Float32Attribute("uv", uvs, 2)); + this.setIndice(indices); + this.count = indices.length; + } + createGrid(width = 1, height = 1, widthSegments = 1, heightSegments = 1) { + const width_half = width / 2; + const height_half = height / 2; + const gridX = Math.floor(widthSegments); + const gridY = Math.floor(heightSegments); + const gridX1 = gridX + 1; + const gridY1 = gridY + 1; + const segment_width = width / gridX; + const segment_height = height / gridY; + // + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; + for (let iy = 0; iy < gridY1; iy++) { + const y = iy * segment_height - height_half; + for (let ix = 0; ix < gridX1; ix++) { + const x = ix * segment_width - width_half; + vertices.push(x, -y, 0); + normals.push(0, 0, 1); + uvs.push(ix / gridX); + uvs.push(1 - iy / gridY); } } - for (let e = 0; e < o; e++) - for (let t = 0; t < a; t++) { - const i = t + c * e, - r = t + c * (e + 1), - n = t + 1 + c * (e + 1), - s = t + 1 + c * e; - f.push(i, r, s), f.push(r, n, s); + for (let iy = 0; iy < gridY; iy++) { + for (let ix = 0; ix < gridX; ix++) { + const a = ix + gridX1 * iy; + const b = ix + gridX1 * (iy + 1); + const c = ix + 1 + gridX1 * (iy + 1); + const d = ix + 1 + gridX1 * iy; + indices.push(a, b, d); + indices.push(b, c, d); } - return { indices: f, normals: m, uvs: p, vertices: d }; + } + return { indices, normals, uvs, vertices }; } } -class zt { - constructor(e = 0, t = 0, i = 0, r = 1) { - (this.x = e), (this.y = t), (this.z = i), (this.w = r); - } - set(e, t, i, r) { - (this.x = e), (this.y = t), (this.z = i), (this.w = r); + +/** + * A set of 4-dimensional coordinates used to represent rotation in 3-dimensional space. + * @alias Quaternion + * @constructor + * + * @param {Number} [x=0.0] The X component. + * @param {Number} [y=0.0] The Y component. + * @param {Number} [z=0.0] The Z component. + * @param {Number} [w=0.0] The W component. + * + * @see PackableForInterpolation + */ +class Quaternion { + constructor(x = 0, y = 0, z = 0, w = 1) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + set(x, y, z, w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; } normalize() { - const e = 1 / zt.magnitude(this), - t = this.x * e, - i = this.y * e, - r = this.z * e, - n = this.w * e; - return (this.x = t), (this.y = i), (this.z = r), (this.w = n), this; + const inverseMagnitude = 1.0 / Quaternion.magnitude(this); + const x = this.x * inverseMagnitude; + const y = this.y * inverseMagnitude; + const z = this.z * inverseMagnitude; + const w = this.w * inverseMagnitude; + this.x = x; + this.y = y; + this.z = z; + this.w = w; + return this; } invert() { - return (this.x *= -1), (this.y *= -1), (this.z *= -1), this; - } - dot(e) { - return this.x * e.x + this.y * e.y + this.z * e.z + this.w * e.w; + this.x *= -1; + this.y *= -1; + this.z *= -1; + return this; } - setFromUnitVectors(e, t) { - let i = Ue.dot(e, t) + 1; - return ( - i < Number.EPSILON - ? ((i = 0), - Math.abs(e.x) > Math.abs(e.z) - ? ((this.x = -e.y), (this.y = e.x), (this.z = 0), (this.w = i)) - : ((this.x = 0), (this.y = -e.z), (this.z = e.y), (this.w = i))) - : ((this.x = e.y * t.z - e.z * t.y), - (this.y = e.z * t.x - e.x * t.z), - (this.z = e.x * t.y - e.y * t.x), - (this.w = i)), - this.normalize() - ); + dot(v) { + return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; } - setFromRotationMatrix(e) { - const t = e, - i = t[0], - r = t[4], - n = t[8], - s = t[1], - a = t[5], - o = t[9], - c = t[2], - l = t[6], - h = t[10], - u = i + a + h; - if (u > 0) { - const e = 0.5 / Math.sqrt(u + 1); - (this.w = 0.25 / e), (this.x = (l - o) * e), (this.y = (n - c) * e), (this.z = (s - r) * e); - } else if (i > a && i > h) { - const e = 2 * Math.sqrt(1 + i - a - h); - (this.w = (l - o) / e), (this.x = 0.25 * e), (this.y = (r + s) / e), (this.z = (n + c) / e); - } else if (a > h) { - const e = 2 * Math.sqrt(1 + a - i - h); - (this.w = (n - c) / e), (this.x = (r + s) / e), (this.y = 0.25 * e), (this.z = (o + l) / e); + setFromUnitVectors(vFrom, vTo) { + // assumes direction vectors vFrom and vTo are normalized + let r = Vector3.dot(vFrom, vTo) + 1; + if (r < Number.EPSILON) { + // vFrom and vTo point in opposite directions + r = 0; + if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) { + this.x = -vFrom.y; + this.y = vFrom.x; + this.z = 0; + this.w = r; + } else { + this.x = 0; + this.y = -vFrom.z; + this.z = vFrom.y; + this.w = r; + } + } else { + // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3 + this.x = vFrom.y * vTo.z - vFrom.z * vTo.y; + this.y = vFrom.z * vTo.x - vFrom.x * vTo.z; + this.z = vFrom.x * vTo.y - vFrom.y * vTo.x; + this.w = r; + } + return this.normalize(); + } + setFromRotationMatrix(matrix) { + const te = matrix, + m11 = te[0], + m12 = te[4], + m13 = te[8], + m21 = te[1], + m22 = te[5], + m23 = te[9], + m31 = te[2], + m32 = te[6], + m33 = te[10], + trace = m11 + m22 + m33; + if (trace > 0) { + const s = 0.5 / Math.sqrt(trace + 1.0); + this.w = 0.25 / s; + this.x = (m32 - m23) * s; + this.y = (m13 - m31) * s; + this.z = (m21 - m12) * s; + } else if (m11 > m22 && m11 > m33) { + const s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33); + this.w = (m32 - m23) / s; + this.x = 0.25 * s; + this.y = (m12 + m21) / s; + this.z = (m13 + m31) / s; + } else if (m22 > m33) { + const s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33); + this.w = (m13 - m31) / s; + this.x = (m12 + m21) / s; + this.y = 0.25 * s; + this.z = (m23 + m32) / s; } else { - const e = 2 * Math.sqrt(1 + h - i - a); - (this.w = (s - r) / e), (this.x = (n + c) / e), (this.y = (o + l) / e), (this.z = 0.25 * e); + const s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22); + this.w = (m21 - m12) / s; + this.x = (m13 + m31) / s; + this.y = (m23 + m32) / s; + this.z = 0.25 * s; } return this; } clone() { - return zt.clone(this, this); + return Quaternion.clone(this, this); } - equals(e) { - return zt.equals(this, e); + equals(right) { + return Quaternion.equals(this, right); } - equalsEpsilon(e, t = 0) { - return zt.equalsEpsilon(this, e, t); + equalsEpsilon(right, epsilon = 0) { + return Quaternion.equalsEpsilon(this, right, epsilon); } toArray() { - const { x: e, y: t, z: i, w: r } = this; - return [e, t, i, r]; - } - static fromAxisAngle(e, t) { - const i = t / 2, - r = Math.sin(i); - It = Ue.normalize(e, It); - const n = It.x * r, - s = It.y * r, - a = It.z * r, - o = Math.cos(i), - c = new zt(n, s, a, o); - return (c.x = n), (c.y = s), (c.z = a), (c.w = o), c; - } - static clone(e, t) { - if (pe(e)) return pe(t) ? ((t.x = e.x), (t.y = e.y), (t.z = e.z), (t.w = e.w), t) : new zt(e.x, e.y, e.z, e.w); - } - static conjugate(e, t) { - return (t.x = -e.x), (t.y = -e.y), (t.z = -e.z), (t.w = e.w), t; - } - static magnitudeSquared(e) { - return e.x * e.x + e.y * e.y + e.z * e.z + e.w * e.w; - } - static magnitude(e) { - return Math.sqrt(zt.magnitudeSquared(e)); - } - static normalize(e, t) { - const i = 1 / zt.magnitude(e), - r = e.x * i, - n = e.y * i, - s = e.z * i, - a = e.w * i; - return (t.x = r), (t.y = n), (t.z = s), (t.w = a), t; - } - static inverse(e, t) { - const i = zt.magnitudeSquared(e); - return (t = zt.conjugate(e, t)), zt.multiplyByScalar(t, 1 / i, t); - } - static add(e, t, i) { - return (i.x = e.x + t.x), (i.y = e.y + t.y), (i.z = e.z + t.z), (i.w = e.w + t.w), i; - } - static subtract(e, t, i) { - return (i.x = e.x - t.x), (i.y = e.y - t.y), (i.z = e.z - t.z), (i.w = e.w - t.w), i; - } - static negate(e, t) { - return (t.x = -e.x), (t.y = -e.y), (t.z = -e.z), (t.w = -e.w), t; - } - static dot(e, t) { - return e.x * t.x + e.y * t.y + e.z * t.z + e.w * t.w; - } - static multiply(e, t, i) { - const r = e.x, - n = e.y, - s = e.z, - a = e.w, - o = t.x, - c = t.y, - l = t.z, - h = t.w, - u = a * o + r * h + n * l - s * c, - f = a * c - r * l + n * h + s * o, - d = a * l + r * c - n * o + s * h, - m = a * h - r * o - n * c - s * l; - return (i.x = u), (i.y = f), (i.z = d), (i.w = m), i; - } - static multiplyByScalar(e, t, i) { - return (i.x = e.x * t), (i.y = e.y * t), (i.z = e.z * t), (i.w = e.w * t), i; - } - static divideByScalar(e, t, i) { - return (i.x = e.x / t), (i.y = e.y / t), (i.z = e.z / t), (i.w = e.w / t), i; - } - static computeAxis(e, t) { - const i = e.w; - if (Math.abs(i - 1) < ve.EPSILON6) return (t.x = t.y = t.z = 0), t; - const r = 1 / Math.sqrt(1 - i * i); - return (t.x = e.x * r), (t.y = e.y * r), (t.z = e.z * r), t; - } - static computeAngle(e) { - return Math.abs(e.w - 1) < ve.EPSILON6 ? 0 : 2 * Math.acos(e.w); - } - static lerp(e, t, i, r) { - return (Pt = zt.multiplyByScalar(t, i, Pt)), (r = zt.multiplyByScalar(e, 1 - i, r)), zt.add(Pt, r, r); - } - static slerp(e, t, i, r) { - let n = zt.dot(e, t), - s = t; - if ((n < 0 && ((n = -n), (s = Nt = zt.negate(t, Nt))), 1 - n < ve.EPSILON6)) return zt.lerp(e, s, i, r); - const a = Math.acos(n); + const { x, y, z, w } = this; + return [x, y, z, w]; + } + static fromAxisAngle(axis, angle) { + const halfAngle = angle / 2.0; + const s = Math.sin(halfAngle); + fromAxisAngleScratch = Vector3.normalize(axis, fromAxisAngleScratch); + const x = fromAxisAngleScratch.x * s; + const y = fromAxisAngleScratch.y * s; + const z = fromAxisAngleScratch.z * s; + const w = Math.cos(halfAngle); + // if (!defined(result)) { + // return + // } + const result = new Quaternion(x, y, z, w); + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; + } + // static fromRotationMatrix(matrix: Matrix3, result: Quaternion): Quaternion { + // let root; + // let x; + // let y; + // let z; + // let w; + // const m00 = matrix[Matrix3.COLUMN0ROW0]; + // const m11 = matrix[Matrix3.COLUMN1ROW1]; + // const m22 = matrix[Matrix3.COLUMN2ROW2]; + // const trace = m00 + m11 + m22; + // if (trace > 0.0) { + // // |w| > 1/2, may as well choose w > 1/2 + // root = Math.sqrt(trace + 1.0); // 2w + // w = 0.5 * root; + // root = 0.5 / root; // 1/(4w) + // x = (matrix[Matrix3.COLUMN1ROW2] - matrix[Matrix3.COLUMN2ROW1]) * root; + // y = (matrix[Matrix3.COLUMN2ROW0] - matrix[Matrix3.COLUMN0ROW2]) * root; + // z = (matrix[Matrix3.COLUMN0ROW1] - matrix[Matrix3.COLUMN1ROW0]) * root; + // } else { + // // |w| <= 1/2 + // const next = fromRotationMatrixNext; + // let i = 0; + // if (m11 > m00) { + // i = 1; + // } + // if (m22 > m00 && m22 > m11) { + // i = 2; + // } + // const j = next[i]; + // const k = next[j]; + // root = Math.sqrt( + // matrix[Matrix3.getElementIndex(i, i)] - + // matrix[Matrix3.getElementIndex(j, j)] - + // matrix[Matrix3.getElementIndex(k, k)] + + // 1.0 + // ); + // const quat = fromRotationMatrixQuat; + // quat[i] = 0.5 * root; + // root = 0.5 / root; + // w = (matrix[Matrix3.getElementIndex(k, j)] - matrix[Matrix3.getElementIndex(j, k)]) * root; + // quat[j] = (matrix[Matrix3.getElementIndex(j, i)] + matrix[Matrix3.getElementIndex(i, j)]) * root; + // quat[k] = (matrix[Matrix3.getElementIndex(k, i)] + matrix[Matrix3.getElementIndex(i, k)]) * root; + // x = -quat[0]; + // y = -quat[1]; + // z = -quat[2]; + // } + // if (!defined(result)) { + // return new Quaternion(x, y, z, w); + // } + // result.x = x; + // result.y = y; + // result.z = z; + // result.w = w; + // return result; + // } + static clone(quaternion, result) { + if (!defined(quaternion)) { + return undefined; + } + if (!defined(result)) { + return new Quaternion(quaternion.x, quaternion.y, quaternion.z, quaternion.w); + } + result.x = quaternion.x; + result.y = quaternion.y; + result.z = quaternion.z; + result.w = quaternion.w; + return result; + } + static conjugate(quaternion, result) { + result.x = -quaternion.x; + result.y = -quaternion.y; + result.z = -quaternion.z; + result.w = quaternion.w; + return result; + } + static magnitudeSquared(quaternion) { return ( - (Bt = zt.multiplyByScalar(e, Math.sin((1 - i) * a), Bt)), - (Ot = zt.multiplyByScalar(s, Math.sin(i * a), Ot)), - (r = zt.add(Bt, Ot, r)), - zt.multiplyByScalar(r, 1 / Math.sin(a), r) + quaternion.x * quaternion.x + + quaternion.y * quaternion.y + + quaternion.z * quaternion.z + + quaternion.w * quaternion.w ); } - static squad(e, t, i, r, n, s) { - const a = zt.slerp(e, t, n, Vt), - o = zt.slerp(i, r, n, Ft); - return zt.slerp(a, o, 2 * n * (1 - n), s); - } - static equals(e, t) { - return e === t || (pe(e) && pe(t) && e.x === t.x && e.y === t.y && e.z === t.z && e.w === t.w); - } - static equalsEpsilon(e, t, i = 0) { + static magnitude(quaternion) { + return Math.sqrt(Quaternion.magnitudeSquared(quaternion)); + } + static normalize(quaternion, result) { + const inverseMagnitude = 1.0 / Quaternion.magnitude(quaternion); + const x = quaternion.x * inverseMagnitude; + const y = quaternion.y * inverseMagnitude; + const z = quaternion.z * inverseMagnitude; + const w = quaternion.w * inverseMagnitude; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; + } + static inverse(quaternion, result) { + const magnitudeSquared = Quaternion.magnitudeSquared(quaternion); + result = Quaternion.conjugate(quaternion, result); + return Quaternion.multiplyByScalar(result, 1.0 / magnitudeSquared, result); + } + static add(left, right, result) { + result.x = left.x + right.x; + result.y = left.y + right.y; + result.z = left.z + right.z; + result.w = left.w + right.w; + return result; + } + static subtract(left, right, result) { + result.x = left.x - right.x; + result.y = left.y - right.y; + result.z = left.z - right.z; + result.w = left.w - right.w; + return result; + } + static negate(quaternion, result) { + result.x = -quaternion.x; + result.y = -quaternion.y; + result.z = -quaternion.z; + result.w = -quaternion.w; + return result; + } + static dot(left, right) { + return left.x * right.x + left.y * right.y + left.z * right.z + left.w * right.w; + } + static multiply(left, right, result) { + const leftX = left.x; + const leftY = left.y; + const leftZ = left.z; + const leftW = left.w; + const rightX = right.x; + const rightY = right.y; + const rightZ = right.z; + const rightW = right.w; + const x = leftW * rightX + leftX * rightW + leftY * rightZ - leftZ * rightY; + const y = leftW * rightY - leftX * rightZ + leftY * rightW + leftZ * rightX; + const z = leftW * rightZ + leftX * rightY - leftY * rightX + leftZ * rightW; + const w = leftW * rightW - leftX * rightX - leftY * rightY - leftZ * rightZ; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; + } + static multiplyByScalar(quaternion, scalar, result) { + result.x = quaternion.x * scalar; + result.y = quaternion.y * scalar; + result.z = quaternion.z * scalar; + result.w = quaternion.w * scalar; + return result; + } + static divideByScalar(quaternion, scalar, result) { + result.x = quaternion.x / scalar; + result.y = quaternion.y / scalar; + result.z = quaternion.z / scalar; + result.w = quaternion.w / scalar; + return result; + } + static computeAxis(quaternion, result) { + const w = quaternion.w; + if (Math.abs(w - 1.0) < GMath.EPSILON6) { + result.x = result.y = result.z = 0; + return result; + } + const scalar = 1.0 / Math.sqrt(1.0 - w * w); + result.x = quaternion.x * scalar; + result.y = quaternion.y * scalar; + result.z = quaternion.z * scalar; + return result; + } + static computeAngle(quaternion) { + if (Math.abs(quaternion.w - 1.0) < GMath.EPSILON6) { + return 0.0; + } + return 2.0 * Math.acos(quaternion.w); + } + static lerp(start, end, t, result) { + lerpScratch = Quaternion.multiplyByScalar(end, t, lerpScratch); + result = Quaternion.multiplyByScalar(start, 1.0 - t, result); + return Quaternion.add(lerpScratch, result, result); + } + static slerp(start, end, t, result) { + let dot = Quaternion.dot(start, end); + // The angle between start must be acute. Since q and -q represent + // the same rotation, negate q to get the acute angle. + let r = end; + if (dot < 0.0) { + dot = -dot; + r = slerpEndNegated = Quaternion.negate(end, slerpEndNegated); + } + // dot > 0, as the dot product approaches 1, the angle between the + // quaternions vanishes. use linear interpolation. + if (1.0 - dot < GMath.EPSILON6) { + return Quaternion.lerp(start, r, t, result); + } + const theta = Math.acos(dot); + slerpScaledP = Quaternion.multiplyByScalar(start, Math.sin((1 - t) * theta), slerpScaledP); + slerpScaledR = Quaternion.multiplyByScalar(r, Math.sin(t * theta), slerpScaledR); + result = Quaternion.add(slerpScaledP, slerpScaledR, result); + return Quaternion.multiplyByScalar(result, 1.0 / Math.sin(theta), result); + } + static squad(q0, q1, s0, s1, t, result) { + const slerp0 = Quaternion.slerp(q0, q1, t, squadScratchQuaternion0); + const slerp1 = Quaternion.slerp(s0, s1, t, squadScratchQuaternion1); + return Quaternion.slerp(slerp0, slerp1, 2.0 * t * (1.0 - t), result); + } + static equals(left, right) { return ( - (i = ee(i, 0)), - e === t || - (pe(e) && - pe(t) && - Math.abs(e.x - t.x) <= i && - Math.abs(e.y - t.y) <= i && - Math.abs(e.z - t.z) <= i && - Math.abs(e.w - t.w) <= i) + left === right || + (defined(left) && + defined(right) && + left.x === right.x && + left.y === right.y && + left.z === right.z && + left.w === right.w) ); } - static exp(e, t) { - const i = Ue.magnitude(e); - let r = 0; + static equalsEpsilon(left, right, epsilon = 0) { + epsilon = defaultValue(epsilon, 0); return ( - 0 !== i && (r = Math.sin(i) / i), (t.x = e.x * r), (t.y = e.y * r), (t.z = e.z * r), (t.w = Math.cos(i)), t + left === right || + (defined(left) && + defined(right) && + Math.abs(left.x - right.x) <= epsilon && + Math.abs(left.y - right.y) <= epsilon && + Math.abs(left.z - right.z) <= epsilon && + Math.abs(left.w - right.w) <= epsilon) ); } + static exp(cartesian, result) { + const theta = Vector3.magnitude(cartesian); + let sinThetaOverTheta = 0.0; + if (theta !== 0.0) { + sinThetaOverTheta = Math.sin(theta) / theta; + } + result.x = cartesian.x * sinThetaOverTheta; + result.y = cartesian.y * sinThetaOverTheta; + result.z = cartesian.z * sinThetaOverTheta; + result.w = Math.cos(theta); + return result; + } } -(zt.ZERO = Object.freeze(new zt(0, 0, 0, 0))), (zt.IDENTITY = Object.freeze(new zt(0, 0, 0, 1))); -let It = new Ue(); +Quaternion.ZERO = Object.freeze(new Quaternion(0.0, 0.0, 0.0, 0.0)); +Quaternion.IDENTITY = Object.freeze(new Quaternion(0.0, 0.0, 0.0, 1.0)); +let fromAxisAngleScratch = new Vector3(); new Array(3); -let Pt = new zt(), - Nt = new zt(), - Bt = new zt(), - Ot = new zt(); -new Ue(), new Ue(); -const Vt = new zt(), - Ft = new zt(); -class $t { +let lerpScratch = new Quaternion(); +let slerpEndNegated = new Quaternion(); +let slerpScaledP = new Quaternion(); +let slerpScaledR = new Quaternion(); +new Vector3(); +new Vector3(); +const squadScratchQuaternion0 = new Quaternion(); +const squadScratchQuaternion1 = new Quaternion(); + +class RenderObject { constructor() { - (this._position = new Ue()), - (this._scale = new Ue(1, 1, 1)), - (this._quaternion = new zt()), - (this.modelMatrix = et.clone(et.IDENTITY, new et())), - (this._normalMatrix = et.clone(et.IDENTITY, new et())), - (this.up = new Ue(0, 1, 0)), - (this._target = new Ue(0, 0, 0)); + this._position = new Vector3(); + this._scale = new Vector3(1, 1, 1); + this._quaternion = new Quaternion(); + this.modelMatrix = Matrix4.clone(Matrix4.IDENTITY, new Matrix4()); + this._normalMatrix = Matrix4.clone(Matrix4.IDENTITY, new Matrix4()); + this.up = new Vector3(0, 1, 0); + this._target = new Vector3(0, 0, 0); } get normalMatrix() { return this._normalMatrix; @@ -4579,73 +6212,82 @@ class $t { return this._quaternion; } updateNormalMatrix() { - et.inverse(this.modelMatrix, this._normalMatrix), et.transpose(this._normalMatrix, this._normalMatrix); - } - updateMatrix(e) { - this.modelMatrix.compose(this.position, this.quaternion, this.scale), - e && et.multiply(e, this.modelMatrix, this.modelMatrix), - this.updateNormalMatrix(); - } - lookAt(e, t, i) { - this._target.set(e, t, i), - this.type == Z.Camera || this.type == Z.Light - ? jt.lookAt(this.position, this._target, this.up) - : jt.lookAt(this._target, this.position, this.up), - this.quaternion.setFromRotationMatrix(jt); - } - rotateOnAxis(e, t) { - const i = zt.fromAxisAngle(e, t); - zt.multiply(this.quaternion, i, this.quaternion); - } - rotateX(e) { - return this.rotateOnAxis(Gt, e); - } - rotateY(e) { - return this.rotateOnAxis(kt, e); - } - rotateZ(e) { - return this.rotateOnAxis(qt, e); - } -} -const Gt = new Ue(1, 0, 0), - kt = new Ue(0, 1, 0), - qt = new Ue(0, 0, 1), - jt = new et(); -class Ht extends $t { - constructor(e, t) { - super(), - (this.type = Z.Light), - (this._color = Ue.multiplyByScalar(e, t, new Ue())), - (this._intensity = t), - (this._position = new Ue(0, 1, 0)), - (this._target = new Ue()), - (this.positionDirty = !0), - (this.targetDirty = !0), - (this.colorDirty = !0), - (this.shadowDirty = !0), - (this.intensityDirty = !0), - (this._shadow = null); + Matrix4.inverse(this.modelMatrix, this._normalMatrix); + Matrix4.transpose(this._normalMatrix, this._normalMatrix); + } + updateMatrix(matrix) { + this.modelMatrix.compose(this.position, this.quaternion, this.scale); + if (matrix) Matrix4.multiply(matrix, this.modelMatrix, this.modelMatrix); + this.updateNormalMatrix(); + } + lookAt(x, y, z) { + this._target.set(x, y, z); + if (this.type == RenderObjectType.Camera || this.type == RenderObjectType.Light) { + _m1.lookAt(this.position, this._target, this.up); + } else { + _m1.lookAt(this._target, this.position, this.up); + } + this.quaternion.setFromRotationMatrix(_m1); + } + rotateOnAxis(axis, angle) { + const quat = Quaternion.fromAxisAngle(axis, angle); + Quaternion.multiply(this.quaternion, quat, this.quaternion); + } + rotateX(angle) { + return this.rotateOnAxis(_xAxis, angle); + } + rotateY(angle) { + return this.rotateOnAxis(_yAxis, angle); + } + rotateZ(angle) { + return this.rotateOnAxis(_zAxis, angle); + } +} +const _xAxis = new Vector3(1, 0, 0); +const _yAxis = new Vector3(0, 1, 0); +const _zAxis = new Vector3(0, 0, 1); +const _m1 = new Matrix4(); + +class Light extends RenderObject { + constructor(color, intensity) { + super(); + this.type = RenderObjectType.Light; + this._color = Vector3.multiplyByScalar(color, intensity, new Vector3()); + this._intensity = intensity; + this._position = new Vector3(0, 1, 0); + this._target = new Vector3(); + this.positionDirty = true; + this.targetDirty = true; + this.colorDirty = true; + this.shadowDirty = true; + this.intensityDirty = true; + this._shadow = null; } get position() { return this._position; } - set position(e) { - (this.positionDirty = !0), (this._position = e); + set position(value) { + this.positionDirty = true; + this._position = value; } get target() { return this._target; } - set target(e) { - (this.targetDirty = !0), (this._target = e); + set target(value) { + this.targetDirty = true; + this._target = value; } get color() { return this._color; } - set color(e) { - (this.colorDirty = !0), (this._color = e); + set color(value) { + this.colorDirty = true; + this._color = value; } - set intensity(e) { - (this.color = Ue.multiplyByScalar(this.color, e, new Ue())), (this.intensityDirty = !0), (this._intensity = e); + set intensity(value) { + this.color = Vector3.multiplyByScalar(this.color, value, new Vector3()); + this.intensityDirty = true; + this._intensity = value; } get intensity() { return this._intensity; @@ -4653,579 +6295,924 @@ class Ht extends $t { get shadow() { return this._shadow; } - set shadow(e) { - (this.shadowDirty = !0), (this._shadow = e); + set shadow(value) { + this.shadowDirty = true; + this._shadow = value; } } -const Xt = /^#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])?$/i, - Yt = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i, - Wt = /^rgba?\(\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)(?:\s*,\s*([0-9.]+))?\s*\)$/i, - Zt = /^hsla?\(\s*([0-9.]+)\s*,\s*([0-9.]+%)\s*,\s*([0-9.]+%)(?:\s*,\s*([0-9.]+))?\s*\)$/i; -function Kt(e, t, i) { - return ( - i < 0 && (i += 1), - i > 1 && (i -= 1), - 6 * i < 1 ? e + 6 * (t - e) * i : 2 * i < 1 ? t : 3 * i < 2 ? e + (t - e) * (2 / 3 - i) * 6 : e - ); + +// #rgba +const rgbaMatcher = /^#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])?$/i; +// #rrggbbaa +const rrggbbaaMatcher = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i; +// rgb(), rgba(), or rgb%() +const rgbParenthesesMatcher = /^rgba?\(\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)\s*,\s*([0-9.]+%?)(?:\s*,\s*([0-9.]+))?\s*\)$/i; +// hsl() or hsla() +const hslParenthesesMatcher = /^hsla?\(\s*([0-9.]+)\s*,\s*([0-9.]+%)\s*,\s*([0-9.]+%)(?:\s*,\s*([0-9.]+))?\s*\)$/i; +function hue2rgb(m1, m2, h) { + if (h < 0) { + h += 1; + } + if (h > 1) { + h -= 1; + } + if (h * 6 < 1) { + return m1 + (m2 - m1) * 6 * h; + } + if (h * 2 < 1) { + return m2; + } + if (h * 3 < 2) { + return m1 + (m2 - m1) * (2 / 3 - h) * 6; + } + return m1; } -class Qt { - constructor(e = 1, t = 1, i = 1) { - (this.red = e), (this.green = t), (this.blue = i); - } - set(e) { - return "string" == typeof e && Qt.fromCssColorString(e, this), this; +class Color { + constructor(red = 1.0, green = 1.0, blue = 1.0) { + /** + * The red component. + * @type {Number} + * @default 1.0 + */ + this.red = red; + /** + * The green component. + * @type {Number} + * @default 1.0 + */ + this.green = green; + /** + * The blue component. + * @type {Number} + * @default 1.0 + */ + this.blue = blue; + } + set(value) { + if (typeof value === "string") { + Color.fromCssColorString(value, this); + } + return this; } toArray() { return [this.red, this.green, this.blue]; } - clone(e) { - return Qt.clone(this, e); + clone(result) { + return Color.clone(this, result); } - equals(e) { - return Qt.equals(this, e); + equals(other) { + return Color.equals(this, other); } toCssHexString() { - let e = Qt.floatToByte(this.red).toString(16); - e.length < 2 && (e = `0${e}`); - let t = Qt.floatToByte(this.green).toString(16); - t.length < 2 && (t = `0${t}`); - let i = Qt.floatToByte(this.blue).toString(16); - return i.length < 2 && (i = `0${i}`), `#${e}${t}${i}`; - } - toBytes(e) { - const t = Qt.floatToByte(this.red), - i = Qt.floatToByte(this.green), - r = Qt.floatToByte(this.blue); - return pe(e) ? ((e[0] = t), (e[1] = i), (e[2] = r), e) : [t, i, r]; - } - static fromBytes(e, t, i, r) { - return ( - (e = Qt.byteToFloat(ee(e, 255))), - (t = Qt.byteToFloat(ee(t, 255))), - (i = Qt.byteToFloat(ee(i, 255))), - pe(r) ? ((r.red = e), (r.green = t), (r.blue = i), r) : new Qt(e, t, i) - ); - } - static fromHsl(e, t, i, r) { - (e = ee(e, 0) % 1), (t = ee(t, 0)); - let n = (i = ee(i, 0)), - s = i, - a = i; - if (0 !== t) { - let r; - r = i < 0.5 ? i * (1 + t) : i + t - i * t; - const o = 2 * i - r; - (n = Kt(o, r, e + 1 / 3)), (s = Kt(o, r, e)), (a = Kt(o, r, e - 1 / 3)); - } - return pe(r) ? ((r.red = n), (r.green = s), (r.blue = a), r) : new Qt(n, s, a); - } - static fromRandom(e, t) { - let i = (e = ee(e, ee.EMPTY_OBJECT)).red; - if (!pe(i)) { - const t = ee(e.minimumRed, 0), - r = ee(e.maximumRed, 1); - i = t + ve.nextRandomNumber() * (r - t); - } - let r = e.green; - if (!pe(r)) { - const t = ee(e.minimumGreen, 0), - i = ee(e.maximumGreen, 1); - r = t + ve.nextRandomNumber() * (i - t); - } - let n = e.blue; - if (!pe(n)) { - const t = ee(e.minimumBlue, 0), - i = ee(e.maximumBlue, 1); - n = t + ve.nextRandomNumber() * (i - t); - } - return pe(t) ? ((t.red = i), (t.green = r), (t.blue = n), t) : new Qt(i, r, n); - } - static fromCssColorString(e, t = new Qt()) { - e = e.replace(/\s/g, ""); - const i = Qt[e.toUpperCase()]; - if (pe(i)) return Qt.clone(i, t), t; - let r = Xt.exec(e); - return null !== r - ? ((t.red = parseInt(r[1], 16) / 15), - (t.green = parseInt(r[2], 16) / 15), - (t.blue = parseInt(r[3], 16) / 15), - t) - : ((r = Yt.exec(e)), - null !== r - ? ((t.red = parseInt(r[1], 16) / 255), - (t.green = parseInt(r[2], 16) / 255), - (t.blue = parseInt(r[3], 16) / 255), - t) - : ((r = Wt.exec(e)), - null !== r - ? ((t.red = parseFloat(r[1]) / ("%" === r[1].substr(-1) ? 100 : 255)), - (t.green = parseFloat(r[2]) / ("%" === r[2].substr(-1) ? 100 : 255)), - (t.blue = parseFloat(r[3]) / ("%" === r[3].substr(-1) ? 100 : 255)), - t) - : ((r = Zt.exec(e)), - null !== r - ? Qt.fromHsl( - parseFloat(r[1]) / 360, - parseFloat(r[2]) / 100, - parseFloat(r[3]) / 100, - t - ) - : (t = void 0)))); - } - static byteToFloat(e) { - return e / 255; - } - static floatToByte(e) { - return 1 === e ? 255 : (256 * e) | 0; - } - static clone(e, t) { - if (pe(e)) - return pe(t) - ? ((t.red = e.red), (t.green = e.green), (t.blue = e.blue), t) - : new Qt(e.red, e.green, e.blue); - } - static equals(e, t) { - return e === t || (pe(e) && pe(t) && e.red === t.red && e.green === t.green && e.blue === t.blue); - } - static equalsArray(e, t, i) { - return e.red === t[i] && e.green === t[i + 1] && e.blue === t[i + 2]; - } -} -class Jt { - constructor(e = 0, t = 0, i = 0, r = 0) { - (this[0] = e), (this[1] = i), (this[2] = t), (this[3] = r); - } - static clone(e, t) { - if (pe(e)) - return pe(t) - ? ((t[0] = e[0]), (t[1] = e[1]), (t[2] = e[2]), (t[3] = e[3]), t) - : new Jt(e[0], e[2], e[1], e[3]); - } - static fromColumnMajorArray(e, t) { - return Jt.clone(e, t); - } - static fromRowMajorArray(e, t) { - return pe(t) ? ((t[0] = e[0]), (t[1] = e[2]), (t[2] = e[1]), (t[3] = e[3]), t) : new Jt(e[0], e[1], e[2], e[3]); - } - static fromScale(e, t) { - return pe(t) ? ((t[0] = e.x), (t[1] = 0), (t[2] = 0), (t[3] = e.y), t) : new Jt(e.x, 0, 0, e.y); - } - static fromRotation(e, t) { - const i = Math.cos(e), - r = Math.sin(e); - return pe(t) ? ((t[0] = i), (t[1] = r), (t[2] = -r), (t[3] = i), t) : new Jt(i, -r, r, i); - } - toArray() { - const e = []; - return Jt.toArray(this, e), e; - } - static toArray(e, t) { - return pe(t) ? ((t[0] = e[0]), (t[1] = e[1]), (t[2] = e[2]), (t[3] = e[3]), t) : [e[0], e[1], e[2], e[3]]; - } - static getElementIndex(e, t) { - return 2 * e + t; - } - static getColumn(e, t, i) { - const r = 2 * t, - n = e[r], - s = e[r + 1]; - return (i.x = n), (i.y = s), i; - } - static setColumn(e, t, i, r) { - const n = 2 * t; - return ((r = Jt.clone(e, r))[n] = i.x), (r[n + 1] = i.y), r; + let r = Color.floatToByte(this.red).toString(16); + if (r.length < 2) { + r = `0${r}`; + } + let g = Color.floatToByte(this.green).toString(16); + if (g.length < 2) { + g = `0${g}`; + } + let b = Color.floatToByte(this.blue).toString(16); + if (b.length < 2) { + b = `0${b}`; + } + return `#${r}${g}${b}`; + } + toBytes(result) { + const red = Color.floatToByte(this.red); + const green = Color.floatToByte(this.green); + const blue = Color.floatToByte(this.blue); + if (!defined(result)) { + return [red, green, blue]; + } + result[0] = red; + result[1] = green; + result[2] = blue; + return result; + } + static fromBytes(red, green, blue, result) { + red = Color.byteToFloat(defaultValue(red, 255.0)); + green = Color.byteToFloat(defaultValue(green, 255.0)); + blue = Color.byteToFloat(defaultValue(blue, 255.0)); + if (!defined(result)) { + return new Color(red, green, blue); + } + result.red = red; + result.green = green; + result.blue = blue; + return result; + } + static fromHsl(hue, saturation, lightness, result) { + hue = defaultValue(hue, 0.0) % 1.0; + saturation = defaultValue(saturation, 0.0); + lightness = defaultValue(lightness, 0.0); + let red = lightness; + let green = lightness; + let blue = lightness; + if (saturation !== 0) { + let m2; + if (lightness < 0.5) { + m2 = lightness * (1 + saturation); + } else { + m2 = lightness + saturation - lightness * saturation; + } + const m1 = 2.0 * lightness - m2; + red = hue2rgb(m1, m2, hue + 1 / 3); + green = hue2rgb(m1, m2, hue); + blue = hue2rgb(m1, m2, hue - 1 / 3); + } + if (!defined(result)) { + return new Color(red, green, blue); + } + result.red = red; + result.green = green; + result.blue = blue; + return result; + } + /** + * Creates a random color using the provided options. For reproducible random colors, you should + * call {@link GMath#setRandomNumberSeed} once at the beginning of your application. + * + * @param {Object} [options] Object with the following properties: + * @param {Number} [options.red] If specified, the red component to use instead of a randomized value. + * @param {Number} [options.minimumRed=0.0] The maximum red value to generate if none was specified. + * @param {Number} [options.maximumRed=1.0] The minimum red value to generate if none was specified. + * @param {Number} [options.green] If specified, the green component to use instead of a randomized value. + * @param {Number} [options.minimumGreen=0.0] The maximum green value to generate if none was specified. + * @param {Number} [options.maximumGreen=1.0] The minimum green value to generate if none was specified. + * @param {Number} [options.blue] If specified, the blue component to use instead of a randomized value. + * @param {Number} [options.minimumBlue=0.0] The maximum blue value to generate if none was specified. + * @param {Number} [options.maximumBlue=1.0] The minimum blue value to generate if none was specified. + * @param {Color} [result] The object to store the result in, if undefined a new instance will be created. + * @returns {Color} The modified result parameter or a new instance if result was undefined. + * + * @example + * //Create a completely random color + * const color = Color.fromRandom(); + * + * //Create a random shade of yellow. + * const color1 = Color.fromRandom({ + * red : 1.0, + * green : 1.0, + * }); + * + * //Create a random bright color. + * const color2 = Color.fromRandom({ + * minimumRed : 0.75, + * minimumGreen : 0.75, + * minimumBlue : 0.75, + * }); + */ + static fromRandom(options, result) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + let red = options.red; + if (!defined(red)) { + const minimumRed = defaultValue(options.minimumRed, 0); + const maximumRed = defaultValue(options.maximumRed, 1.0); + red = minimumRed + GMath.nextRandomNumber() * (maximumRed - minimumRed); + } + let green = options.green; + if (!defined(green)) { + const minimumGreen = defaultValue(options.minimumGreen, 0); + const maximumGreen = defaultValue(options.maximumGreen, 1.0); + green = minimumGreen + GMath.nextRandomNumber() * (maximumGreen - minimumGreen); + } + let blue = options.blue; + if (!defined(blue)) { + const minimumBlue = defaultValue(options.minimumBlue, 0); + const maximumBlue = defaultValue(options.maximumBlue, 1.0); + blue = minimumBlue + GMath.nextRandomNumber() * (maximumBlue - minimumBlue); + } + if (!defined(result)) { + return new Color(red, green, blue); + } + result.red = red; + result.green = green; + result.blue = blue; + return result; + } + static fromCssColorString(color, result = new Color()) { + // Remove all whitespaces from the color string + color = color.replace(/\s/g, ""); + const namedColor = Color[color.toUpperCase()]; + if (defined(namedColor)) { + Color.clone(namedColor, result); + return result; + } + let matches = rgbaMatcher.exec(color); + if (matches !== null) { + result.red = parseInt(matches[1], 16) / 15; + result.green = parseInt(matches[2], 16) / 15.0; + result.blue = parseInt(matches[3], 16) / 15.0; + return result; + } + matches = rrggbbaaMatcher.exec(color); + if (matches !== null) { + result.red = parseInt(matches[1], 16) / 255.0; + result.green = parseInt(matches[2], 16) / 255.0; + result.blue = parseInt(matches[3], 16) / 255.0; + return result; + } + matches = rgbParenthesesMatcher.exec(color); + if (matches !== null) { + result.red = parseFloat(matches[1]) / ("%" === matches[1].substr(-1) ? 100.0 : 255.0); + result.green = parseFloat(matches[2]) / ("%" === matches[2].substr(-1) ? 100.0 : 255.0); + result.blue = parseFloat(matches[3]) / ("%" === matches[3].substr(-1) ? 100.0 : 255.0); + return result; + } + matches = hslParenthesesMatcher.exec(color); + if (matches !== null) { + return Color.fromHsl( + parseFloat(matches[1]) / 360.0, + parseFloat(matches[2]) / 100.0, + parseFloat(matches[3]) / 100.0, + result + ); + } + result = undefined; + return result; } - static getRow(e, t, i) { - const r = e[t], - n = e[t + 2]; - return (i.x = r), (i.y = n), i; + static byteToFloat(value) { + return value / 255.0; } - static setRow(e, t, i, r) { - return ((r = Jt.clone(e, r))[t] = i.x), (r[t + 2] = i.y), r; + static floatToByte(value) { + return value === 1.0 ? 255.0 : (value * 256.0) | 0; } - static setScale(e, t, i) { - const r = Jt.getScale(e, ei), - n = t.x / r.x, - s = t.y / r.y; - return (i[0] = e[0] * n), (i[1] = e[1] * n), (i[2] = e[2] * s), (i[3] = e[3] * s), i; + static clone(color, result) { + if (!defined(color)) { + return undefined; + } + if (!defined(result)) { + return new Color(color.red, color.green, color.blue); + } + result.red = color.red; + result.green = color.green; + result.blue = color.blue; + return result; } - static getScale(e, t) { + static equals(left, right) { return ( - (t.x = Se.magnitude(Se.fromElements(e[0], e[1], ri))), - (t.y = Se.magnitude(Se.fromElements(e[2], e[3], ri))), - t + left === right || // + (defined(left) && // + defined(right) && // + left.red === right.red && // + left.green === right.green && // + left.blue === right.blue) ); } - static getMaximumScale(e) { - return Jt.getScale(e, ti), Se.maximumComponent(ti); - } - static setRotation(e, t, i) { - const r = Jt.getScale(e, ii); - return (i[0] = t[0] * r.x), (i[1] = t[1] * r.x), (i[2] = t[2] * r.y), (i[3] = t[3] * r.y), i; - } - static getRotation(e, t) { - const i = Jt.getScale(e, ni); - return (t[0] = e[0] / i.x), (t[1] = e[1] / i.x), (t[2] = e[2] / i.y), (t[3] = e[3] / i.y), t; + /** + * @private + */ + static equalsArray(color, array, offset) { + return color.red === array[offset] && color.green === array[offset + 1] && color.blue === array[offset + 2]; } - static multiply(e, t, i) { - const r = e[0] * t[0] + e[2] * t[1], - n = e[0] * t[2] + e[2] * t[3], - s = e[1] * t[0] + e[3] * t[1], - a = e[1] * t[2] + e[3] * t[3]; - return (i[0] = r), (i[1] = s), (i[2] = n), (i[3] = a), i; - } - static add(e, t, i) { - return (i[0] = e[0] + t[0]), (i[1] = e[1] + t[1]), (i[2] = e[2] + t[2]), (i[3] = e[3] + t[3]), i; - } - static subtract(e, t, i) { - return (i[0] = e[0] - t[0]), (i[1] = e[1] - t[1]), (i[2] = e[2] - t[2]), (i[3] = e[3] - t[3]), i; - } - static multiplyByVector(e, t, i) { - const r = e[0] * t.x + e[2] * t.y, - n = e[1] * t.x + e[3] * t.y; - return (i.x = r), (i.y = n), i; - } - static multiplyByScalar(e, t, i) { - return (i[0] = e[0] * t), (i[1] = e[1] * t), (i[2] = e[2] * t), (i[3] = e[3] * t), i; - } - static multiplyByScale(e, t, i) { - return (i[0] = e[0] * t.x), (i[1] = e[1] * t.x), (i[2] = e[2] * t.y), (i[3] = e[3] * t.y), i; - } - static negate(e, t) { - return (t[0] = -e[0]), (t[1] = -e[1]), (t[2] = -e[2]), (t[3] = -e[3]), t; - } - static transpose(e, t) { - const i = e[0], - r = e[2], - n = e[1], - s = e[3]; - return (t[0] = i), (t[1] = r), (t[2] = n), (t[3] = s), t; +} + +/** + * A 2x2 matrix, indexable as a column-major order array. + * @param {Number} [column0Row0=0.0] The value for column 0, row 0. + * @param {Number} [column1Row0=0.0] The value for column 1, row 0. + * @param {Number} [column0Row1=0.0] The value for column 0, row 1. + * @param {Number} [column1Row1=0.0] The value for column 1, row 1. + */ +class Matrix2 { + constructor(column0Row0 = 0, column1Row0 = 0, column0Row1 = 0, column1Row1 = 0) { + this[0] = column0Row0; + this[1] = column0Row1; + this[2] = column1Row0; + this[3] = column1Row1; + } + static clone(matrix, result) { + if (!defined(matrix)) { + return undefined; + } + if (!defined(result)) { + return new Matrix2(matrix[0], matrix[2], matrix[1], matrix[3]); + } + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[3]; + return result; + } + static fromColumnMajorArray(values, result) { + return Matrix2.clone(values, result); + } + static fromRowMajorArray(values, result) { + if (!defined(result)) { + return new Matrix2(values[0], values[1], values[2], values[3]); + } + result[0] = values[0]; + result[1] = values[2]; + result[2] = values[1]; + result[3] = values[3]; + return result; + } + static fromScale(scale, result) { + if (!defined(result)) { + return new Matrix2(scale.x, 0.0, 0.0, scale.y); + } + result[0] = scale.x; + result[1] = 0.0; + result[2] = 0.0; + result[3] = scale.y; + return result; + } + static fromRotation(angle, result) { + const cosAngle = Math.cos(angle); + const sinAngle = Math.sin(angle); + if (!defined(result)) { + return new Matrix2(cosAngle, -sinAngle, sinAngle, cosAngle); + } + result[0] = cosAngle; + result[1] = sinAngle; + result[2] = -sinAngle; + result[3] = cosAngle; + return result; } - static abs(e, t) { - return (t[0] = Math.abs(e[0])), (t[1] = Math.abs(e[1])), (t[2] = Math.abs(e[2])), (t[3] = Math.abs(e[3])), t; + toArray() { + const result = []; + Matrix2.toArray(this, result); + return result; } - static equals(e, t) { - return e === t || (pe(e) && pe(t) && e[0] === t[0] && e[1] === t[1] && e[2] === t[2] && e[3] === t[3]); + static toArray(matrix, result) { + if (!defined(result)) { + return [matrix[0], matrix[1], matrix[2], matrix[3]]; + } + result[0] = matrix[0]; + result[1] = matrix[1]; + result[2] = matrix[2]; + result[3] = matrix[3]; + return result; + } + static getElementIndex(column, row) { + return column * 2 + row; + } + static getColumn(matrix, index, result) { + const startIndex = index * 2; + const x = matrix[startIndex]; + const y = matrix[startIndex + 1]; + result.x = x; + result.y = y; + return result; + } + static setColumn(matrix, index, cartesian, result) { + result = Matrix2.clone(matrix, result); + const startIndex = index * 2; + result[startIndex] = cartesian.x; + result[startIndex + 1] = cartesian.y; + return result; + } + static getRow(matrix, index, result) { + const x = matrix[index]; + const y = matrix[index + 2]; + result.x = x; + result.y = y; + return result; + } + static setRow(matrix, index, cartesian, result) { + result = Matrix2.clone(matrix, result); + result[index] = cartesian.x; + result[index + 2] = cartesian.y; + return result; + } + static setScale(matrix, scale, result) { + const existingScale = Matrix2.getScale(matrix, scaleScratch1); + const scaleRatioX = scale.x / existingScale.x; + const scaleRatioY = scale.y / existingScale.y; + result[0] = matrix[0] * scaleRatioX; + result[1] = matrix[1] * scaleRatioX; + result[2] = matrix[2] * scaleRatioY; + result[3] = matrix[3] * scaleRatioY; + return result; + } + static getScale(matrix, result) { + result.x = Vector2.magnitude(Vector2.fromElements(matrix[0], matrix[1], scratchColumn)); + result.y = Vector2.magnitude(Vector2.fromElements(matrix[2], matrix[3], scratchColumn)); + return result; + } + static getMaximumScale(matrix) { + Matrix2.getScale(matrix, scaleScratch3); + return Vector2.maximumComponent(scaleScratch3); + } + static setRotation(matrix, rotation, result) { + const scale = Matrix2.getScale(matrix, scaleScratch4); + result[0] = rotation[0] * scale.x; + result[1] = rotation[1] * scale.x; + result[2] = rotation[2] * scale.y; + result[3] = rotation[3] * scale.y; + return result; + } + static getRotation(matrix, result) { + const scale = Matrix2.getScale(matrix, scaleScratch5); + result[0] = matrix[0] / scale.x; + result[1] = matrix[1] / scale.x; + result[2] = matrix[2] / scale.y; + result[3] = matrix[3] / scale.y; + return result; + } + static multiply(left, right, result) { + const column0Row0 = left[0] * right[0] + left[2] * right[1]; + const column1Row0 = left[0] * right[2] + left[2] * right[3]; + const column0Row1 = left[1] * right[0] + left[3] * right[1]; + const column1Row1 = left[1] * right[2] + left[3] * right[3]; + result[0] = column0Row0; + result[1] = column0Row1; + result[2] = column1Row0; + result[3] = column1Row1; + return result; + } + static add(left, right, result) { + result[0] = left[0] + right[0]; + result[1] = left[1] + right[1]; + result[2] = left[2] + right[2]; + result[3] = left[3] + right[3]; + return result; + } + static subtract(left, right, result) { + result[0] = left[0] - right[0]; + result[1] = left[1] - right[1]; + result[2] = left[2] - right[2]; + result[3] = left[3] - right[3]; + return result; + } + static multiplyByVector(matrix, cartesian, result) { + const x = matrix[0] * cartesian.x + matrix[2] * cartesian.y; + const y = matrix[1] * cartesian.x + matrix[3] * cartesian.y; + result.x = x; + result.y = y; + return result; + } + static multiplyByScalar(matrix, scalar, result) { + result[0] = matrix[0] * scalar; + result[1] = matrix[1] * scalar; + result[2] = matrix[2] * scalar; + result[3] = matrix[3] * scalar; + return result; + } + static multiplyByScale(matrix, scale, result) { + result[0] = matrix[0] * scale.x; + result[1] = matrix[1] * scale.x; + result[2] = matrix[2] * scale.y; + result[3] = matrix[3] * scale.y; + return result; + } + static negate(matrix, result) { + result[0] = -matrix[0]; + result[1] = -matrix[1]; + result[2] = -matrix[2]; + result[3] = -matrix[3]; + return result; + } + static transpose(matrix, result) { + const column0Row0 = matrix[0]; + const column0Row1 = matrix[2]; + const column1Row0 = matrix[1]; + const column1Row1 = matrix[3]; + result[0] = column0Row0; + result[1] = column0Row1; + result[2] = column1Row0; + result[3] = column1Row1; + return result; + } + static abs(matrix, result) { + result[0] = Math.abs(matrix[0]); + result[1] = Math.abs(matrix[1]); + result[2] = Math.abs(matrix[2]); + result[3] = Math.abs(matrix[3]); + return result; + } + static equals(left, right) { + return ( + left === right || + (defined(left) && + defined(right) && + left[0] === right[0] && + left[1] === right[1] && + left[2] === right[2] && + left[3] === right[3]) + ); } - static equalsArray(e, t, i) { - return e[0] === t[i] && e[1] === t[i + 1] && e[2] === t[i + 2] && e[3] === t[i + 3]; + /** + * @private + */ + static equalsArray(matrix, array, offset) { + return ( + matrix[0] === array[offset] && + matrix[1] === array[offset + 1] && + matrix[2] === array[offset + 2] && + matrix[3] === array[offset + 3] + ); } - static equalsEpsilon(e, t, i = 0) { + static equalsEpsilon(left, right, epsilon = 0) { + epsilon = defaultValue(epsilon, 0); return ( - (i = ee(i, 0)), - e === t || - (pe(e) && - pe(t) && - Math.abs(e[0] - t[0]) <= i && - Math.abs(e[1] - t[1]) <= i && - Math.abs(e[2] - t[2]) <= i && - Math.abs(e[3] - t[3]) <= i) + left === right || + (defined(left) && + defined(right) && + Math.abs(left[0] - right[0]) <= epsilon && + Math.abs(left[1] - right[1]) <= epsilon && + Math.abs(left[2] - right[2]) <= epsilon && + Math.abs(left[3] - right[3]) <= epsilon) ); } - clone(e) { - return Jt.clone(this, e); + clone(result) { + return Matrix2.clone(this, result); } - equals(e) { - return Jt.equals(this, e); + equals(right) { + return Matrix2.equals(this, right); } - equalsEpsilon(e, t = 0) { - return Jt.equalsEpsilon(this, e, t); + equalsEpsilon(right, epsilon = 0) { + return Matrix2.equalsEpsilon(this, right, epsilon); } toString() { - return `(${this[0]}, ${this[2]})\n(${this[1]}, ${this[3]})`; + return `(${this[0]}, ${this[2]})\n` + `(${this[1]}, ${this[3]})`; } } -(Jt.IDENTITY = Object.freeze(new Jt(1, 0, 0, 1))), (Jt.ZERO = Object.freeze(new Jt(0, 0, 0, 0))); -const ei = new Se(); -new Se(); -const ti = new Se(), - ii = new Se(), - ri = new Se(), - ni = new Se(); -class si { - constructor(e, t, i) { - (this.name = e), (this.cb = t), (this.offset = ee(i, 0)), (this.type = "number"); +Matrix2.IDENTITY = Object.freeze(new Matrix2(1.0, 0.0, 0.0, 1.0)); +Matrix2.ZERO = Object.freeze(new Matrix2(0.0, 0.0, 0.0, 0.0)); +const scaleScratch1 = new Vector2(); +new Vector2(); +const scaleScratch3 = new Vector2(); +const scaleScratch4 = new Vector2(); +const scratchColumn = new Vector2(); +const scaleScratch5 = new Vector2(); + +class Uniform { + constructor(uniformName, cb, offset) { + this.name = uniformName; + this.cb = cb; + this.offset = defaultValue(offset, 0); + this.type = "number"; + } + setBuffer(array, offset = 0) { + for (let i = 0; i < array.length; i++) { + this.buffer[i + offset] = array[i]; + } } - setBuffer(e, t = 0) { - for (let i = 0; i < e.length; i++) this.buffer[i + t] = e[i]; + set() { + return undefined; } - set() {} getValue() { - let e; - switch (typeof this.cb) { + let result; + const cbType = typeof this.cb; + switch (cbType) { case "object": - e = this.cb[this.name] || this.cb; + result = this.cb[this.name] || this.cb; break; case "function": - e = this.cb(); + // @ts-ignore + result = this.cb(); break; case "number": - e = this.cb; + result = this.cb; break; default: throw new Error("type is error"); } - return e; - } - equals(e) { - if (this._value.length !== e.length) return !1; - for (let t = 0; t < e.length; t++) if (e[t] !== this._value[t]) return !1; - return !0; + return result; + } + // compare array + equals(v) { + if (this._value.length !== v.length) return false; + for (let i = 0; i < v.length; i++) { + if (v[i] !== this._value[i]) { + return false; + } + } + return true; } } -class ai extends si { - constructor(e, t, i, r, n) { - super(e, r, n), - (this.value = void 0), - (this._value = 0), - (this.byteSize = 4), - (this.buffer = new Uint32Array(t.buffer, i, 1)), - (this.type = "uint"); +class UniformUint extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, offset) { + super(uniformName, cb, offset); + this.value = undefined; + this._value = 0; + this.byteSize = 4; + this.buffer = new Uint32Array(buffer.buffer, byteOffset, 1); + this.type = "uint"; } set() { - return ( - null != this.cb && (this.value = this.getValue()), - this.value !== this._value && ((this._value = this.value), (this.buffer[0] = this.value), !0) - ); + if (this.cb != undefined) this.value = this.getValue(); + if (this.value !== this._value) { + this._value = this.value; + this.buffer[0] = this.value; + return true; + } + return false; } } -ai.align = 4; -class oi extends si { - constructor(e, t, i, r, n) { - super(e, r, n), - (this.value = void 0), - (this._value = 0), - (this.byteSize = 4), - (this.buffer = new Float32Array(t.buffer, i, 1)), - (this.type = "vec1"); +UniformUint.align = 4; +class UniformFloat extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, offset) { + super(uniformName, cb, offset); + this.value = undefined; + this._value = 0; + this.byteSize = 4; + this.buffer = new Float32Array(buffer.buffer, byteOffset, 1); + this.type = "vec1"; } set() { - return ( - null != this.cb && (this.value = this.getValue()), - this.value !== this._value && ((this._value = this.value), (this.buffer[0] = this.value), !0) - ); + if (this.cb != undefined) this.value = this.getValue(); + if (this.value !== this._value) { + this._value = this.value; + this.buffer[0] = this.value; + return true; + } + return false; } } -oi.align = 4; -class ci extends si { - constructor(e, t, i, r, n) { - super(e, r, n), - (this.value = void 0), - (this._value = new Se()), - (this.buffer = new Float32Array(t.buffer, i, 2)), - (this.byteSize = 8), - (this.type = "vec2"); +UniformFloat.align = 4; +class UniformFloatVec2 extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, offset) { + super(uniformName, cb, offset); + this.value = undefined; + this._value = new Vector2(); + this.buffer = new Float32Array(buffer.buffer, byteOffset, 2); + this.byteSize = 8; + this.type = "vec2"; } set() { - null != this.cb && (this.value = this.getValue()); - const e = this.value; - return e instanceof Se - ? !Se.equals(e, this._value) && (Se.clone(e, this._value), this.setBuffer(this._value.toArray()), !0) - : !this.equals(e) && ((this._value = e), this.setBuffer(e), !0); - } -} -ci.align = 8; -class li extends si { - constructor(e, t, i, r, n) { - super(e, r, n), - (this.value = void 0), - (this._value = new Ue()), - (this.buffer = new Float32Array(t.buffer, i, 3)), - (this.byteSize = 12), - (this.type = "vec3"); + if (this.cb != undefined) this.value = this.getValue(); + const v = this.value; + if (v instanceof Vector2) { + if (Vector2.equals(v, this._value)) return false; + Vector2.clone(v, this._value); + this.setBuffer(this._value.toArray()); + return true; + } else { + if (this.equals(v)) return false; + this._value = v; + this.setBuffer(v); + return true; + } + } +} +UniformFloatVec2.align = 8; +class UniformFloatVec3 extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, offset) { + super(uniformName, cb, offset); + this.value = undefined; + this._value = new Vector3(); + this.buffer = new Float32Array(buffer.buffer, byteOffset, 3); + this.byteSize = 12; + this.type = "vec3"; } set() { - null != this.cb && (this.value = this.getValue()); - const e = this.value; - return e instanceof Ue - ? !Ue.equals(e, this._value) && (Ue.clone(e, this._value), this.setBuffer(this._value.toArray()), !0) - : !this.equals(e) && ((this._value = e), this.setBuffer(e), !0); - } -} -li.align = 16; -class hi extends si { - constructor(e, t, i, r, n) { - super(e, r, n), - (this.value = void 0), - (this._value = new We()), - (this.buffer = new Float32Array(t.buffer, i, 4)), - (this.byteSize = 16), - (this.type = "vec4"); + if (this.cb != undefined) this.value = this.getValue(); + const v = this.value; + if (v instanceof Vector3) { + if (Vector3.equals(v, this._value)) return false; + Vector3.clone(v, this._value); + this.setBuffer(this._value.toArray()); + return true; + } else { + if (this.equals(v)) return false; + this._value = v; + this.setBuffer(v); + return true; + } + } +} +UniformFloatVec3.align = 16; +class UniformFloatVec4 extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, offset) { + super(uniformName, cb, offset); + this.value = undefined; + this._value = new Vector4(); + this.buffer = new Float32Array(buffer.buffer, byteOffset, 4); + this.byteSize = 16; + this.type = "vec4"; } set() { - null != this.cb && (this.value = this.getValue()); - const e = this.value; - return e instanceof We - ? !We.equals(e, this._value) && (We.clone(e, this._value), this.setBuffer(this._value.toArray()), !0) - : !this.equals(e) && ((this._value = e), this.setBuffer(e), !0); - } -} -hi.align = 16; -class ui extends si { - constructor(e, t, i, r, n) { - super(e, r, n), - (this.value = void 0), - (this._value = new Qt()), - (this.buffer = new Float32Array(t.buffer, i, 3)), - (this.byteSize = 12), - (this.type = "vec3"); + if (this.cb != undefined) this.value = this.getValue(); + const v = this.value; + if (v instanceof Vector4) { + if (Vector4.equals(v, this._value)) return false; + Vector4.clone(v, this._value); + this.setBuffer(this._value.toArray()); + return true; + } else { + if (this.equals(v)) return false; + this._value = v; + this.setBuffer(v); + return true; + } + } +} +UniformFloatVec4.align = 16; +class UniformColor extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, offset) { + super(uniformName, cb, offset); + this.value = undefined; + this._value = new Color(); + this.buffer = new Float32Array(buffer.buffer, byteOffset, 3); + this.byteSize = 12; + this.type = "vec3"; } set() { - null != this.cb && (this.value = this.getValue()); - const e = this.value; - return e instanceof Qt - ? !Qt.equals(e, this._value) && (Qt.clone(e, this._value), this.setBuffer(this._value.toArray()), !0) - : !this.equals(e) && ((this._value = e), this.setBuffer(e), !0); - } -} -ui.align = 16; -class fi extends si { - constructor(e, t, i, r, n) { - super(e, r, n), - (this.value = void 0), - (this._value = new Jt()), - (this.buffer = new Float32Array(t.buffer, i, 4)), - (this.byteSize = 16), - (this.type = "mat2"); + if (this.cb != undefined) this.value = this.getValue(); + const v = this.value; + if (v instanceof Color) { + if (Color.equals(v, this._value)) return false; + Color.clone(v, this._value); + this.setBuffer(this._value.toArray()); + return true; + } else { + if (this.equals(v)) return false; + this._value = v; + this.setBuffer(v); + return true; + } + } +} +UniformColor.align = 16; +class UniformMat2 extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, offset) { + super(uniformName, cb, offset); + this.value = undefined; + this._value = new Matrix2(); + this.buffer = new Float32Array(buffer.buffer, byteOffset, 4); + this.byteSize = 16; + this.type = "mat2"; } set() { - null != this.cb && (this.value = this.getValue()); - const e = this.value; - return e instanceof Jt - ? !Jt.equals(e, this._value) && (Jt.clone(e, this._value), this.setBuffer(this._value.toArray()), !0) - : !this.equals(e) && ((this._value = e), this.setBuffer(e), !0); - } -} -fi.align = 8; -class di extends si { - constructor(e, t, i, r, n) { - super(e, r, n), - (this.value = void 0), - (this._value = new Ge()), - (this.buffer = new Float32Array(t.buffer, i, 9)), - (this.byteSize = 48), - (this.type = "mat3"); + if (this.cb != undefined) this.value = this.getValue(); + const v = this.value; + if (v instanceof Matrix2) { + if (Matrix2.equals(v, this._value)) return false; + Matrix2.clone(v, this._value); + this.setBuffer(this._value.toArray()); + return true; + } else { + if (this.equals(v)) return false; + this._value = v; + this.setBuffer(v); + return true; + } + } +} +UniformMat2.align = 8; +class UniformMat3 extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, offset) { + super(uniformName, cb, offset); + this.value = undefined; + this._value = new Matrix3(); + this.buffer = new Float32Array(buffer.buffer, byteOffset, 9); + this.byteSize = 48; + this.type = "mat3"; } set() { - null != this.cb && (this.value = this.getValue()); - const e = this.value; - return e instanceof Ge - ? !Ge.equals(e, this._value) && (Ge.clone(e, this._value), this.setBuffer(this._value.toArray()), !0) - : !this.equals(e) && ((this._value = e), this.setBuffer(e), !0); - } -} -di.align = 16; -class mi extends si { - constructor(e, t, i, r, n) { - super(e, r, n), - (this.value = void 0), - (this._value = new et()), - (this.buffer = new Float32Array(t.buffer, i, 16)), - (this.byteSize = 64), - (this.type = "mat4"); + if (this.cb != undefined) this.value = this.getValue(); + const v = this.value; + if (v instanceof Matrix3) { + if (Matrix3.equals(v, this._value)) return false; + Matrix3.clone(v, this._value); + this.setBuffer(this._value.toArray()); + return true; + } else { + if (this.equals(v)) return false; + this._value = v; + this.setBuffer(v); + return true; + } + } +} +UniformMat3.align = 16; +class UniformMat4 extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, offset) { + super(uniformName, cb, offset); + this.value = undefined; + this._value = new Matrix4(); + this.buffer = new Float32Array(buffer.buffer, byteOffset, 16); + this.byteSize = 64; + this.type = "mat4"; } set() { - null != this.cb && (this.value = this.getValue()); - const e = this.value; - return e instanceof et - ? !et.equals(e, this._value) && (et.clone(e, this._value), this.setBuffer(this._value.toArray()), !0) - : ((this._value = e), this.setBuffer(e), !0); + if (this.cb != undefined) this.value = this.getValue(); + const v = this.value; + if (v instanceof Matrix4) { + if (Matrix4.equals(v, this._value)) return false; + Matrix4.clone(v, this._value); + this.setBuffer(this._value.toArray()); + return true; + } else { + // if(this.equals(v)) return false; + this._value = v; + this.setBuffer(v); + return true; + } } } -mi.align = 16; -class pi extends si { - constructor(e, t, i, r, n) { - super(e, r, 0), - (this.byteSize = 64 * n), - (this.buffer = new Float32Array(t.buffer, i, this.byteSize / 4)), - (this.type = "mat4-array"); +UniformMat4.align = 16; +class UniformMatrix4Array extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, count) { + super(uniformName, cb, 0); + this.byteSize = count * 64; + this.buffer = new Float32Array(buffer.buffer, byteOffset, this.byteSize / 4); + this.type = "mat4-array"; } set() { - if (((this.value = this.getValue()), !this.value)) return !1; - for (let e = 0; e < this.value.length; e++) this.setBuffer(this.value[e].toArray(), 16 * e); - return !0; + this.value = this.getValue(); + if (!this.value) return false; + for (let i = 0; i < this.value.length; i++) { + this.setBuffer(this.value[i].toArray(), i * 16); + } + return true; } } -pi.align = 16; -class gi extends si { - constructor(e, t, i, r, n) { - super(e, r, 0), - (this.buffer = new Float32Array(t.buffer, i, n)), - (this.byteSize = 4 * n), - (this.type = "float-array"); +UniformMatrix4Array.align = 16; +class UniformFloatArray extends Uniform { + // cb: Function; + constructor(uniformName, buffer, byteOffset, cb, count) { + super(uniformName, cb, 0); + this.buffer = new Float32Array(buffer.buffer, byteOffset, count); + this.byteSize = 4 * count; + this.type = "float-array"; } set() { this.value = this.getValue(); - for (let e = 0; e < this.value.length; e++) this.buffer[e] = this.value[e]; - return !0; + for (let i = 0; i < this.value.length; i++) { + this.buffer[i] = this.value[i]; + } + return true; } } -gi.align = 4; -class xi extends si { - constructor(e, t, i, r, n) { - super(e, r, 0), - (this.byteSize = 8 * n), - (this.buffer = new Float32Array(t.buffer, i, this.byteSize / 4)), - (this.type = "vec2-array"); +UniformFloatArray.align = 4; +class UniformVec2Array extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, count) { + super(uniformName, cb, 0); + this.byteSize = count * 8; + this.buffer = new Float32Array(buffer.buffer, byteOffset, this.byteSize / 4); + this.type = "vec2-array"; } set() { + // this.value = this.cb(); this.value = this.getValue(); - let e = 0; - for (let t = 0; t < this.value.length; t++) - (this.buffer[e] = this.value[t].x), (this.buffer[e + 1] = this.value[t].y), (e += 2); - return !0; + let j = 0; + for (let i = 0; i < this.value.length; i++) { + this.buffer[j] = this.value[i].x; + this.buffer[j + 1] = this.value[i].y; + j += 2; + } + return true; } } -xi.align = 8; -class vi extends si { - constructor(e, t, i, r, n) { - super(e, r, 0), - (this.byteSize = 16 * n), - (this.buffer = new Float32Array(t.buffer, i, this.byteSize / 4)), - (this.type = "vec3-array"); +UniformVec2Array.align = 8; +class UniformVec3Array extends Uniform { + // cb: Function; + constructor(uniformName, buffer, byteOffset, cb, count) { + super(uniformName, cb, 0); + this.byteSize = count * 16; + this.buffer = new Float32Array(buffer.buffer, byteOffset, this.byteSize / 4); + this.type = "vec3-array"; } set() { + // this.value = this.cb(); this.value = this.getValue(); - let e = 0; - for (let t = 0; t < this.value.length; t++) - (this.buffer[e] = this.value[t].x), - (this.buffer[e + 1] = this.value[t].y), - (this.buffer[e + 2] = this.value[t].z), - (this.buffer[e + 3] = 0), - (e += 4); - return !0; - } -} -vi.align = 16; -class yi extends si { - constructor(e, t, i, r, n) { - super(e, r, 0), - (this.byteSize = 16 * n), - (this.buffer = new Float32Array(t.buffer, i, this.byteSize / 4)), - (this.type = "vec4-array"); + let j = 0; + for (let i = 0; i < this.value.length; i++) { + this.buffer[j] = this.value[i].x; + this.buffer[j + 1] = this.value[i].y; + this.buffer[j + 2] = this.value[i].z; + this.buffer[j + 3] = 0; + j += 4; + } + return true; + } +} +UniformVec3Array.align = 16; +class UniformVec4Array extends Uniform { + // cb: Function; + constructor(uniformName, buffer, byteOffset, cb, count) { + super(uniformName, cb, 0); + this.byteSize = count * 16; + this.buffer = new Float32Array(buffer.buffer, byteOffset, this.byteSize / 4); + this.type = "vec4-array"; } set() { this.value = this.getValue(); - let e = 0; - for (let t = 0; t < this.value.length; t++) - (this.buffer[e] = this.value[t].x), - (this.buffer[e + 1] = this.value[t].y), - (this.buffer[e + 2] = this.value[t].z), - (this.buffer[e + 3] = this.value[t].w), - (e += 4); - return !0; - } -} -yi.align = 16; -class Si extends si { - constructor(e, t, i, r, n, s) { - super(e, void 0, 0), - (this.binding = t), - (this.visibility = ee(n, d.Vertex | d.Fragment)), - (this.textureView = s), - (this.type = r ?? "texture"), - (this.isTexture = !0), - (this._texture = i); + let j = 0; + for (let i = 0; i < this.value.length; i++) { + this.buffer[j] = this.value[i].x; + this.buffer[j + 1] = this.value[i].y; + this.buffer[j + 2] = this.value[i].z; + this.buffer[j + 3] = this.value[i].w; + j += 4; + } + return true; + } +} +UniformVec4Array.align = 16; +class UniformTexture extends Uniform { + constructor(uniformName, binding, texture, type, visibility, textureView) { + super(uniformName, undefined, 0); + this.binding = binding; + this.visibility = defaultValue(visibility, ShaderStage.Vertex | ShaderStage.Fragment); + this.textureView = textureView; + this.type = type ?? "texture"; + this.isTexture = true; + this._texture = texture; } get layoutType() { return this.texture?.layoutType || "not yet bind"; @@ -5233,1610 +7220,1929 @@ class Si extends si { get storageTextureLayoutType() { return this.texture?.storageTextureLayoutType || "not yet bind"; } - bind(e) { - this._texture && - ((this.texture = this._texture instanceof Function ? this._texture() : this._texture), - this.texture.update(e)); + bind(device) { + if (!this._texture) return; + this.texture = this._texture instanceof Function ? this._texture() : this._texture; + this.texture.update(device); } } -class bi extends si { - constructor(e, t, i, r) { - super(e, void 0, 0), - (this.visibility = ee(r, d.Vertex | d.Fragment)), - (this.name = e), - (this.binding = t), - (this.type = "sampler"), - (this.isSampler = !0), - (this._sampler = i); +class UniformSampler extends Uniform { + constructor(uniformName, binding, sampler, visibility) { + super(uniformName, undefined, 0); + this.visibility = defaultValue(visibility, ShaderStage.Vertex | ShaderStage.Fragment); + this.name = uniformName; + this.binding = binding; + this.type = "sampler"; + this.isSampler = true; + this._sampler = sampler; } get layoutType() { return this.sampler?.layoutType || "not yet bind"; } - bind(e) { - (this.sampler = this._sampler instanceof Function ? this._sampler() : this._sampler), this.sampler.update(e); + bind(device) { + this.sampler = this._sampler instanceof Function ? this._sampler() : this._sampler; + this.sampler.update(device); } } -class wi extends si { - constructor(e, t, i, r, n) { - super(e, r, n), - (this.cb = r), - (this.type = "struct-array"), - (this.dirty = !1), - (this.byteOffset = i), - (this.sourceBuffer = t); +class UniformStructArray extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, offset) { + super(uniformName, cb, offset); + this.cb = cb; + this.type = "struct-array"; + this.dirty = false; + this.byteOffset = byteOffset; + this.sourceBuffer = buffer; } set() { - return ( - (this.structArray = this.getValue()), - (this.byteSize = this.getStructSize()), - (this.buffer = new Float32Array(this.sourceBuffer.buffer, this.byteOffset, this.byteSize / 4)), - this.setSubData(), - !0 - ); + // + this.structArray = this.getValue(); + this.byteSize = this.getStructSize(); + this.buffer = new Float32Array(this.sourceBuffer.buffer, this.byteOffset, this.byteSize / 4); + this.setSubData(); + return true; } setSubData() { - this.structArray.forEach((e) => { - Object.keys(e).forEach((t) => { - const i = Array.isArray(e[t]?.value) ? e[t]?.value : e[t]?.value.toArray(); - Ci(this.buffer, i, e[t].offset); + this.structArray.forEach((struct) => { + const keys = Object.keys(struct); + keys.forEach((key) => { + const data = Array.isArray(struct[key]?.value) ? struct[key]?.value : (struct[key]?.value).toArray(); + setDataToTypeArray(this.buffer, data, struct[key].offset); }); }); } getStructSize() { - let e = 0; - return ( - this.structArray.forEach((t) => { - Object.keys(t).forEach((i) => { - (e += Ri.checkUniformOffset(e, wi.aligns[t[i].type])), - (t[i].offset = e), - (this.byteOffset += wi.byteSizes[t[i].type]); - }); - }), - e - ); + let byteOffset = 0; + this.structArray.forEach((struct) => { + const keys = Object.keys(struct); + keys.forEach((key) => { + byteOffset += UniformBuffer.checkUniformOffset(byteOffset, UniformStructArray.aligns[struct[key].type]); + struct[key].offset = byteOffset; + this.byteOffset += UniformStructArray.byteSizes[struct[key].type]; + }); + }); + return byteOffset; } } -(wi.align = 16), - (wi.aligns = { - [Q.UniformUint]: 4, - [Q.Float]: 4, - [Q.FloatVec2]: 8, - [Q.FloatVec3]: 16, - [Q.FloatVec4]: 16, - [Q.Mat2]: 8, - [Q.Mat3]: 16, - [Q.Mat4]: 16, - [Q.Color]: 16 - }), - (wi.byteSizes = { - [Q.UniformUint]: 4, - [Q.Float]: 4, - [Q.FloatVec2]: 8, - [Q.FloatVec3]: 12, - [Q.FloatVec4]: 16, - [Q.Mat2]: 16, - [Q.Mat3]: 48, - [Q.Mat4]: 64, - [Q.Color]: 12 - }); -class Ti extends si { - constructor(e, t, i, r, n) { - super(e, r, 0), - (this.cb = r), - (this.byteSize = 64 * n), - (this.buffer = new Float32Array(t.buffer, i, this.byteSize / 4)), - (this.type = "spotsLight"), - (this.dirty = !1); +UniformStructArray.align = 16; +UniformStructArray.aligns = { + [UniformEnum.UniformUint]: 4, + [UniformEnum.Float]: 4, + [UniformEnum.FloatVec2]: 8, + [UniformEnum.FloatVec3]: 16, + [UniformEnum.FloatVec4]: 16, + [UniformEnum.Mat2]: 8, + [UniformEnum.Mat3]: 16, + [UniformEnum.Mat4]: 16, + [UniformEnum.Color]: 16 +}; +UniformStructArray.byteSizes = { + [UniformEnum.UniformUint]: 4, + [UniformEnum.Float]: 4, + [UniformEnum.FloatVec2]: 8, + [UniformEnum.FloatVec3]: 12, + [UniformEnum.FloatVec4]: 16, + [UniformEnum.Mat2]: 16, + [UniformEnum.Mat3]: 48, + [UniformEnum.Mat4]: 64, + [UniformEnum.Color]: 12 +}; +class UniformSpotLights extends Uniform { + // cb: Function; + constructor(uniformName, buffer, byteOffset, cb, count) { + super(uniformName, cb, 0); + this.cb = cb; + this.byteSize = count * 64; + this.buffer = new Float32Array(buffer.buffer, byteOffset, this.byteSize / 4); + this.type = "spotsLight"; + this.dirty = false; } set() { - return ( - (this.lights = this.getValue()), - this.lights.forEach((e, t) => { - this.setSubData(e, t); - }), - this.dirty - ); + this.lights = this.getValue(); + this.lights.forEach((spotLight, index) => { + this.setSubData(spotLight, index); + }); + return this.dirty; + } + setSubData(spotLight, index) { + const offset = index * 16; + if (spotLight.positionDirty) { + this.dirty = setDataToTypeArray(this.buffer, spotLight.position.toArray(), offset + 0); // byteOffset=0; + } + if (spotLight.distanceDirty) { + this.dirty = setDataToTypeArray(this.buffer, spotLight.distance, offset + 3); // byteOffset=12; + } + if (spotLight.dirtectDirty) { + this.dirty = setDataToTypeArray(this.buffer, spotLight.directional.toArray(), offset + 4); // byteOffset=16; + } + if (spotLight.coneCosDirty) { + this.dirty = setDataToTypeArray(this.buffer, spotLight.coneCos, offset + 7); // byteOffset=28; + } + if (spotLight.colorDirty) { + this.dirty = setDataToTypeArray(this.buffer, spotLight.color.toArray(), offset + 8); // byteOffset=32; + } + if (spotLight.penumbraCosDirty) { + this.dirty = setDataToTypeArray(this.buffer, spotLight.penumbraCos, offset + 11); // byteOffset=44; + } + if (spotLight.decayDirty) { + this.dirty = setDataToTypeArray(this.buffer, spotLight.decay, offset + 12); // byteOffset=48; + } + spotLight.positionDirty = false; + spotLight.distanceDirty = false; + spotLight.dirtectDirty = false; + spotLight.coneCosDirty = false; + spotLight.colorDirty = false; + spotLight.penumbraCosDirty = false; + spotLight.decayDirty = false; } - setSubData(e, t) { - const i = 16 * t; - e.positionDirty && (this.dirty = Ci(this.buffer, e.position.toArray(), i + 0)), - e.distanceDirty && (this.dirty = Ci(this.buffer, e.distance, i + 3)), - e.dirtectDirty && (this.dirty = Ci(this.buffer, e.directional.toArray(), i + 4)), - e.coneCosDirty && (this.dirty = Ci(this.buffer, e.coneCos, i + 7)), - e.colorDirty && (this.dirty = Ci(this.buffer, e.color.toArray(), i + 8)), - e.penumbraCosDirty && (this.dirty = Ci(this.buffer, e.penumbraCos, i + 11)), - e.decayDirty && (this.dirty = Ci(this.buffer, e.decay, i + 12)), - (e.positionDirty = !1), - (e.distanceDirty = !1), - (e.dirtectDirty = !1), - (e.coneCosDirty = !1), - (e.colorDirty = !1), - (e.penumbraCosDirty = !1), - (e.decayDirty = !1); - } -} -Ti.align = 16; -class Ei extends si { - constructor(e, t, i, r, n) { - super(e, r, 0); - const s = Float32Array.BYTES_PER_ELEMENT; - (this._subDataSize = Ei.uniformSize), - (this.byteSize = n * this._subDataSize * s), - (this.buffer = new Float32Array(t.buffer, i, this.byteSize / 4)), - (this.type = "spotLightShadows"), - (this._nearValue = null), - (this._farValue = null); +} +UniformSpotLights.align = 16; +class UniformSpotLightShadows extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, count) { + super(uniformName, cb, 0); + const bytesPerElement = Float32Array.BYTES_PER_ELEMENT; + this._subDataSize = UniformSpotLightShadows.uniformSize; + this.byteSize = count * this._subDataSize * bytesPerElement; + this.buffer = new Float32Array(buffer.buffer, byteOffset, this.byteSize / 4); + this.type = "spotLightShadows"; + this._nearValue = null; + this._farValue = null; } set() { - return ( - (this.lights = this.getValue()), - this.lights.forEach((e, t) => { - this.setSubData(e, t); - }), - this.dirty - ); + this.lights = this.getValue(); + this.lights.forEach((spotLight, index) => { + this.setSubData(spotLight, index); + }); + return this.dirty; } - setSubData(e, t) { - const i = t * this._subDataSize; - e.shadow.vpMatrixDirty && - ((e.shadow.vpMatrixDirty = !1), (this.dirty = Ci(this.buffer, e.shadow.camera.vpMatrix.toArray(), i + 0))); - const r = e.shadow.camera.near; - r != this._nearValue && ((this._nearValue = r), (this.dirty = Ci(this.buffer, this._nearValue, i + 16))); - const n = e.shadow.camera.far; - n != this._farValue && ((this._farValue = n), (this.dirty = Ci(this.buffer, this._farValue, i + 17))); + setSubData(spotLight, index) { + const offset = index * this._subDataSize; + if (spotLight.shadow.vpMatrixDirty) { + spotLight.shadow.vpMatrixDirty = false; + this.dirty = setDataToTypeArray(this.buffer, spotLight.shadow.camera.vpMatrix.toArray(), offset + 0); // byteOffset=0; + } + const nearValue = spotLight.shadow.camera.near; + if (nearValue != this._nearValue) { + this._nearValue = nearValue; + this.dirty = setDataToTypeArray(this.buffer, this._nearValue, offset + 16); // byteOffset=0; + } + const farValue = spotLight.shadow.camera.far; + if (farValue != this._farValue) { + this._farValue = farValue; + this.dirty = setDataToTypeArray(this.buffer, this._farValue, offset + 17); // byteOffset=0; + } } } -(Ei.align = 16), (Ei.uniformSize = 18); -class Mi extends si { - constructor(e, t, i, r, n) { - super(e, r, 0), - (this.byteSize = 32 * n), - (this.buffer = new Float32Array(t.buffer, i, this.byteSize / 4)), - (this.type = "pointsLight"); +UniformSpotLightShadows.align = 16; +UniformSpotLightShadows.uniformSize = 18; +class UniformPointLights extends Uniform { + // cb: Function; + constructor(uniformName, buffer, byteOffset, cb, count) { + super(uniformName, cb, 0); + this.byteSize = count * 32; + this.buffer = new Float32Array(buffer.buffer, byteOffset, this.byteSize / 4); + this.type = "pointsLight"; } set() { - return ( - (this.lights = this.getValue()), - this.lights.forEach((e, t) => { - this.setSubData(e, t); - }), - this.dirty - ); + this.lights = this.getValue(); + this.lights.forEach((pointLight, index) => { + this.setSubData(pointLight, index); + }); + return this.dirty; } - setSubData(e, t) { - const i = 8 * t; - e.positionDirty && ((e.positionDirty = !1), (this.dirty = Ci(this.buffer, e.position.toArray(), i + 0))), - e.distanceDirty && ((e.distanceDirty = !1), (this.dirty = Ci(this.buffer, e.distance, i + 3))), - e.colorDirty && ((e.colorDirty = !1), (this.dirty = Ci(this.buffer, e.color.toArray(), i + 4))), - e.decayDirty && ((e.decayDirty = !1), (this.dirty = Ci(this.buffer, e.decay, i + 7))); - } -} -Mi.align = 16; -class Ui extends si { - constructor(e, t, i, r, n) { - super(e, r, 0); - const s = Float32Array.BYTES_PER_ELEMENT; - (this._subDataSize = Ui.uniformSize), - (this.byteSize = n * s * this._subDataSize), - (this.buffer = new Float32Array(t.buffer, i, this.byteSize / 4)), - (this.type = "pointLightShadows"), - (this._nearValue = null), - (this._farValue = null); + setSubData(pointLight, index) { + const offset = index * 8; + if (pointLight.positionDirty) { + pointLight.positionDirty = false; + this.dirty = setDataToTypeArray(this.buffer, pointLight.position.toArray(), offset + 0); // byteOffset=0; + } + if (pointLight.distanceDirty) { + pointLight.distanceDirty = false; + this.dirty = setDataToTypeArray(this.buffer, pointLight.distance, offset + 3); // byteOffset=12; + } + if (pointLight.colorDirty) { + pointLight.colorDirty = false; + this.dirty = setDataToTypeArray(this.buffer, pointLight.color.toArray(), offset + 4); // byteOffset=32; + } + if (pointLight.decayDirty) { + pointLight.decayDirty = false; + this.dirty = setDataToTypeArray(this.buffer, pointLight.decay, offset + 7); // byteOffset=12; + } } - set() { - return ( - (this.lights = this.getValue()), - this.lights.forEach((e, t) => { - this.setSubData(e, t); - }), - this.dirty - ); +} +UniformPointLights.align = 16; +class UniformPointLightShadows extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, count) { + super(uniformName, cb, 0); + const bytesPerElement = Float32Array.BYTES_PER_ELEMENT; + this._subDataSize = UniformPointLightShadows.uniformSize; + this.byteSize = count * bytesPerElement * this._subDataSize; + this.buffer = new Float32Array(buffer.buffer, byteOffset, this.byteSize / 4); + this.type = "pointLightShadows"; + this._nearValue = null; + this._farValue = null; } - setSubData(e, t) { - const i = t * this._subDataSize; - if (e.shadow.vpMatrixArrayDirty) { - e.shadow.vpMatrixArrayDirty = !1; - const t = e.shadow.camera.vpMatrixArray; - for (let e = 0; e < t.length; e++) { - const r = t[e]; - this.dirty = Ci(this.buffer, r.toArray(), i + 0 + 16 * e); + set() { + this.lights = this.getValue(); + this.lights.forEach((pointLight, index) => { + this.setSubData(pointLight, index); + }); + return this.dirty; + } + setSubData(pointLight, index) { + const offset = index * this._subDataSize; + if (pointLight.shadow.vpMatrixArrayDirty) { + pointLight.shadow.vpMatrixArrayDirty = false; + const vpMatrixArray = pointLight.shadow.camera.vpMatrixArray; + for (let i = 0; i < vpMatrixArray.length; i++) { + const vpMatrix = vpMatrixArray[i]; + this.dirty = setDataToTypeArray(this.buffer, vpMatrix.toArray(), offset + 0 + 16 * i); // byteOffset=98 * 4; + } + } + if (pointLight.shadow.viewPortDirty) { + pointLight.shadow.viewPortDirty = false; + for (let i = 0; i < 6; i++) { + this.dirty = setDataToTypeArray( + this.buffer, + pointLight.shadow.viewports[i].toArray(), + offset + 96 + 4 * i + ); // byteOffset=0; } } - if (e.shadow.viewPortDirty) { - e.shadow.viewPortDirty = !1; - for (let t = 0; t < 6; t++) this.dirty = Ci(this.buffer, e.shadow.viewports[t].toArray(), i + 96 + 4 * t); + const nearValue = pointLight.shadow.camera.near; + if (nearValue != this._nearValue) { + this._nearValue = nearValue; + this.dirty = setDataToTypeArray(this.buffer, this._nearValue, offset + 120); // byteOffset=0; + } + const farValue = pointLight.shadow.camera.far; + if (farValue != this._farValue) { + this._farValue = farValue; + this.dirty = setDataToTypeArray(this.buffer, this._farValue, offset + 121); // byteOffset=1; } - const r = e.shadow.camera.near; - r != this._nearValue && ((this._nearValue = r), (this.dirty = Ci(this.buffer, this._nearValue, i + 120))); - const n = e.shadow.camera.far; - n != this._farValue && ((this._farValue = n), (this.dirty = Ci(this.buffer, this._farValue, i + 121))); } } -(Ui.align = 16), (Ui.uniformSize = 122); -class _i extends si { - constructor(e, t, i, r, n) { - super(e, r, 0), - (this.cb = r), - (this.byteSize = 32 * n), - (this.buffer = new Float32Array(t.buffer, i, this.byteSize / 4)), - (this.type = "dirtectLights"); +UniformPointLightShadows.align = 16; +UniformPointLightShadows.uniformSize = 122; +class UniformDirtectLights extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, count) { + super(uniformName, cb, 0); + this.cb = cb; + this.byteSize = count * 32; + this.buffer = new Float32Array(buffer.buffer, byteOffset, this.byteSize / 4); + this.type = "dirtectLights"; } set() { - return ( - (this.lights = this.getValue()), - this.lights.forEach((e, t) => { - this.setSubData(e, t); - }), - this.dirty - ); + this.lights = this.getValue(); + this.lights.forEach((directionalLight, index) => { + this.setSubData(directionalLight, index); + }); + return this.dirty; } - setSubData(e, t) { - const i = 8 * t; - e.dirtectDirty && ((e.dirtectDirty = !1), (this.dirty = Ci(this.buffer, e.directional.toArray(), i + 0))), - e.colorDirty && ((e.colorDirty = !1), (this.dirty = Ci(this.buffer, e.color.toArray(), i + 4))); + setSubData(directionalLight, index) { + const offset = index * 8; + if (directionalLight.dirtectDirty) { + directionalLight.dirtectDirty = false; + this.dirty = setDataToTypeArray(this.buffer, directionalLight.directional.toArray(), offset + 0); // byteOffset=16; + } + if (directionalLight.colorDirty) { + directionalLight.colorDirty = false; + this.dirty = setDataToTypeArray(this.buffer, directionalLight.color.toArray(), offset + 4); // byteOffset=32; + } } } -_i.align = 16; -class Li extends si { - constructor(e, t, i, r, n) { - super(e, r, 0); - const s = Float32Array.BYTES_PER_ELEMENT; - (this._subDataSize = Li.uniformSize), - (this.byteSize = n * s * this._subDataSize), - (this.buffer = new Float32Array(t.buffer, i, this.byteSize / 4)), - (this.type = "dirtectLightShadows"); +UniformDirtectLights.align = 16; +class UniformDirtectLightShadows extends Uniform { + constructor(uniformName, buffer, byteOffset, cb, count) { + super(uniformName, cb, 0); + const bytesPerElement = Float32Array.BYTES_PER_ELEMENT; + this._subDataSize = UniformDirtectLightShadows.uniformSize; + this.byteSize = count * bytesPerElement * this._subDataSize; + this.buffer = new Float32Array(buffer.buffer, byteOffset, this.byteSize / 4); + this.type = "dirtectLightShadows"; } set() { - return ( - (this.lights = this.getValue()), - this.lights.forEach((e, t) => { - this.setSubData(e, t); - }), - this.dirty - ); + this.lights = this.getValue(); + this.lights.forEach((directionalLight, index) => { + this.setSubData(directionalLight, index); + }); + return this.dirty; + } + setSubData(directionalLight, index) { + const offset = index * this._subDataSize; + if (directionalLight.shadow.vpMatrixDirty) { + directionalLight.shadow.vpMatrixDirty = false; + this.dirty = setDataToTypeArray(this.buffer, directionalLight.shadow.camera.vpMatrix.toArray(), offset + 0); // byteOffset=16; + } } - setSubData(e, t) { - const i = t * this._subDataSize; - e.shadow.vpMatrixDirty && - ((e.shadow.vpMatrixDirty = !1), (this.dirty = Ci(this.buffer, e.shadow.camera.vpMatrix.toArray(), i + 0))); +} +UniformDirtectLightShadows.align = 16; +UniformDirtectLightShadows.uniformSize = 16; +function setDataToTypeArray(buffer, data, offset) { + if (Array.isArray(data)) { + data.forEach((value, index) => { + buffer[index + offset] = value; + }); + } else { + buffer[offset] = data; } + return true; } -function Ci(e, t, i) { - return ( - Array.isArray(t) - ? t.forEach((t, r) => { - e[r + i] = t; - }) - : (e[i] = t), - !0 - ); -} -(Li.align = 16), (Li.uniformSize = 16); -class Ri { - constructor(e) { - (this.type = ee(e.type, "uniform")), - (this.label = ee(e.label, "")), - (this.name = ee(e.label, "")), - (this.hasDynamicOffset = e.hasDynamicOffset ?? !1), - (this.minBindingSize = e.minBindingSize ?? 0), - (this.binding = e.binding ?? 0), - (this.visibility = ee(e.visibility, d.Fragment | d.Vertex)), - (this.usage = ee(e.usage, r.Uniform | r.CopyDst)), - (this._uniformStruct = new Map()), - (this.uniformDirty = !0), - (this._bufferSize = e.size), - (this.buffer = e.buffer), - (this.offset = 0), - (this.dataBuffer = ee(e.dataBuffer, new Float32Array(ee(this._bufferSize, 400)))), - (this.byteOffset = 0), - (this.isUniformBuffer = !0), - (this.maxOffset = e.maxOffset ?? 0); + +class UniformBuffer { + constructor(options) { + this.type = defaultValue(options.type, "uniform"); + this.label = defaultValue(options.label, ""); + this.name = defaultValue(options.label, ""); + this.hasDynamicOffset = options.hasDynamicOffset ?? false; + this.minBindingSize = options.minBindingSize ?? 0; + this.binding = options.binding ?? 0; + this.visibility = defaultValue(options.visibility, ShaderStage.Fragment | ShaderStage.Vertex); + this.usage = defaultValue(options.usage, BufferUsage.Uniform | BufferUsage.CopyDst); + this._uniformStruct = new Map(); + this.uniformDirty = true; + this._bufferSize = options.size; + this.buffer = options.buffer; + this.offset = 0; + this.dataBuffer = defaultValue(options.dataBuffer, new Float32Array(defaultValue(this._bufferSize, 400))); + this.byteOffset = 0; + this.isUniformBuffer = true; + this.maxOffset = options.maxOffset ?? 0; } get layoutType() { - return { type: this.type, hasDynamicOffset: this.hasDynamicOffset, minBindingSize: this.minBindingSize }; + return { + type: this.type, + hasDynamicOffset: this.hasDynamicOffset, + minBindingSize: this.minBindingSize + }; } get bufferSize() { - return this._bufferSize ?? 4 * this.uniformsSize; + return this._bufferSize ?? this.uniformsSize * 4; } get uniformsSize() { - return null != this._bufferSize ? this._bufferSize / 4 : 16 * Math.ceil(this.byteOffset / 16); - } - bind(e) { - this._uniformStruct.forEach((e) => { - const t = e.set(); - null != e?.dirty && (e.dirty = !1), null != t && 0 == this.uniformDirty && (this.uniformDirty = t); - }), - this.uniformDirty && - ((this.uniformDirty = !1), - this.buffer || (this.buffer = $.createUniformBuffer(this.label, e, this.bufferSize, this.usage)), - this.type != m.Storage && - this.buffer.setSubData(0, this.dataBuffer.slice(0, ee(this?.bufferSize / 4, this.uniformsSize)))); + // https://gpuweb.github.io/gpuweb/wgsl/#address-space-layout-constraints + return this._bufferSize != undefined ? this._bufferSize / 4 : Math.ceil(this.byteOffset / 16) * 16; + } + bind(device) { + this._uniformStruct.forEach((uniform) => { + const result = uniform.set(); + if (uniform?.dirty != undefined) uniform.dirty = false; + if (result != undefined && this.uniformDirty == false) this.uniformDirty = result; + }); + if (this.uniformDirty) { + this.uniformDirty = false; + if (!this.buffer) this.buffer = Buffer.createUniformBuffer(this.label, device, this.bufferSize, this.usage); + if (this.type != BufferBindingType.Storage) + this.buffer.setSubData( + 0, + this.dataBuffer.slice(0, defaultValue(this?.bufferSize / 4, this.uniformsSize)) + ); + } } getUniformBufferStruct() { - let e = "struct MaterialUniform {\n "; - return ( - this._uniformStruct.forEach((t) => { - e += this.createUniformString(t); - }), - (e += "}\n"), - e - ); + let uniformStruct = `struct MaterialUniform {\n `; + this._uniformStruct.forEach((uniform) => { + uniformStruct += this.createUniformString(uniform); + }); + uniformStruct += `}\n`; + return uniformStruct; } - createUniformString(e) { - let t = ""; - switch (e.type) { + createUniformString(uniform) { + let result = ``; + switch (uniform.type) { case "vec1": - t = `${e.name} :f32,\n`; + result = `${uniform.name} :f32,\n`; break; case "vec2": - t = `${e.name} :vec2,\n`; + result = `${uniform.name} :vec2,\n`; break; case "vec3": - t = `${e.name} :vec3,\n`; + result = `${uniform.name} :vec3,\n`; break; case "vec4": - t = `${e.name} :vec4,\n`; + result = `${uniform.name} :vec4,\n`; break; case "mat2": - t = `${e.name} :mat2x2,\n`; + result = `${uniform.name} :mat2x2,\n`; break; case "mat3": - t = `${e.name} :mat3x3,\n`; + result = `${uniform.name} :mat3x3,\n`; break; case "mat4": - t = `${e.name} :mat4x4,\n`; + result = `${uniform.name} :mat4x4,\n`; + break; } - return t; - } - contains(e) { - return this._uniformStruct.get(e); - } - replaceUniformValue(e, t) { - const i = this._uniformStruct.get(e); - i && (i.cb = t); - } - setUniform(e, t, i, r) { - if (this._uniformStruct.get(e)) return; - const n = Ri.UniformType[i]; - this.byteOffset += Ri.checkUniformOffset(this.byteOffset, n.align); - const s = - null != r - ? new n(e, this.dataBuffer, this.byteOffset, t, r) - : new n(e, this.dataBuffer, this.byteOffset, t); - this._uniformStruct.set(e, s), (this.byteOffset += s.byteSize); - } - static checkUniformOffset(e, t) { - return Math.ceil(e / t) * t - e; + return result; + } + contains(name) { + return this._uniformStruct.get(name); + } + replaceUniformValue(name, value) { + const uniform = this._uniformStruct.get(name); + if (!uniform) return; + uniform.cb = value; + } + // uniformBuffer.setVec3Array('test',()=>{return [new Vector3(1,0,0),new Vector3(1,0.8,0.5)]},2); + // uniformBuffer.setFloatArray('test1',()=>{return [0.5,0.5,1.0]},3); + // uniformBuffer.setVec4Array('test4',()=>{return [new Vector4(0.5,0.6,0.2,1.0),new Vector4(0.5,0.8,0.8,1.0)]},2); + // uniformBuffer.setVec2Array('test2',()=>{return [new Vector2(0.5,0.6),new Vector2(0.5,0.8,)]},2); + setUniform(name, value, uniformType, count) { + if (this._uniformStruct.get(name)) return; + const TypeUniform = UniformBuffer.UniformType[uniformType]; + this.byteOffset += UniformBuffer.checkUniformOffset(this.byteOffset, TypeUniform.align); + const uniform = + count != undefined + ? new TypeUniform(name, this.dataBuffer, this.byteOffset, value, count) + : new TypeUniform(name, this.dataBuffer, this.byteOffset, value); + this._uniformStruct.set(name, uniform); + this.byteOffset += uniform.byteSize; + } + static checkUniformOffset(byteSize, Align) { + // from https://gpuweb.github.io/gpuweb/wgsl/#address-space-layout-constraints + // return this.hasDynamicOffset + // ? Math.ceil(byteSize / 256) * 256 - byteSize + // : Math.ceil(byteSize / Align) * Align - byteSize; + return Math.ceil(byteSize / Align) * Align - byteSize; } destroy() { this?.buffer?.destroy(); } } -Ri.UniformType = { - [Q.UniformUint]: ai, - [Q.Float]: oi, - [Q.FloatVec2]: ci, - [Q.FloatVec3]: li, - [Q.FloatVec4]: hi, - [Q.Mat2]: fi, - [Q.Mat3]: di, - [Q.Mat4]: mi, - [Q.Color]: ui, - [Q.FloatArray]: gi, - [Q.Vec2Array]: xi, - [Q.Vec3Array]: vi, - [Q.Vec4Array]: yi, - [Q.Mat4Array]: pi, - [Q.PointLights]: Mi, - [Q.SpotLights]: Ti, - [Q.DirtectLights]: _i, - [Q.PointLightShadows]: Ui, - [Q.SpotLightShadows]: Ei, - [Q.DirtectLightShadows]: Li, - [Q.UniformStructArray]: wi +UniformBuffer.UniformType = { + [UniformEnum.UniformUint]: UniformUint, + [UniformEnum.Float]: UniformFloat, + [UniformEnum.FloatVec2]: UniformFloatVec2, + [UniformEnum.FloatVec3]: UniformFloatVec3, + [UniformEnum.FloatVec4]: UniformFloatVec4, + [UniformEnum.Mat2]: UniformMat2, + [UniformEnum.Mat3]: UniformMat3, + [UniformEnum.Mat4]: UniformMat4, + [UniformEnum.Color]: UniformColor, + [UniformEnum.FloatArray]: UniformFloatArray, + [UniformEnum.Vec2Array]: UniformVec2Array, + [UniformEnum.Vec3Array]: UniformVec3Array, + [UniformEnum.Vec4Array]: UniformVec4Array, + [UniformEnum.Mat4Array]: UniformMatrix4Array, + [UniformEnum.PointLights]: UniformPointLights, + [UniformEnum.SpotLights]: UniformSpotLights, + [UniformEnum.DirtectLights]: UniformDirtectLights, + [UniformEnum.PointLightShadows]: UniformPointLightShadows, + [UniformEnum.SpotLightShadows]: UniformSpotLightShadows, + [UniformEnum.DirtectLightShadows]: UniformDirtectLightShadows, + [UniformEnum.UniformStructArray]: UniformStructArray }; -const Ai = /#([^\s]*)(\s*)/gm; -function Di(e, ...t) { - const i = []; - let r = { frag: "", elseIsValid: !1, expression: !0 }, - n = 1; - for (let s = 0; s < e.length; ++s) { - const a = e[s], - o = a.matchAll(Ai); - let c = 0, - l = !1; - for (const e of o) { - switch (((r.frag += a.substring(c, e.index)), e[1])) { + +// import Color from "../../math/Color"; +function colorFrag(defines) { + return ` + struct VertexOutput { + @builtin(position) position: vec4, + @location(0) color: vec4, + }; + @fragment + fn main(input:VertexOutput) -> @location(0) vec4 { + return input.color; + } + `; +} + +function colorVert(defines) { + return ` + struct VertexInput { + @location(${defines.positionLocation}) position: vec3, + @location(${defines.colorLocation}) color: vec4, + } + struct VertexOutput { + @builtin(position) position: vec4, + @location(0) color: vec4, + }; + struct SelfUniform { + modelMatrix: mat4x4, + } + struct SystemUniform { + projectionMatrix: mat4x4, + viewMatrix: mat4x4, + inverseViewMatrix: mat4x4, + cameraPosition: vec3, + }; + @binding(${defines.colorBinding}) @group(0) var selfUniform : SelfUniform; + @binding(${defines.cameraBinding}) @group(1) var systemUniform : SystemUniform; + @vertex + fn main(input: VertexInput) -> VertexOutput { + var output:VertexOutput; + output.color=input.color; + output.position = systemUniform.projectionMatrix * systemUniform.viewMatrix *selfUniform.modelMatrix*vec4(input.position,1.0); + return output; + } + `; +} + +const preprocessorSymbols = /#([^\s]*)(\s*)/gm; +// Template literal tag that handles simple preprocessor symbols for WGSL +// shaders. Supports #if/elif/else/endif statements. +function wgslParseDefines(strings, ...values) { + const stateStack = []; + let state = { frag: "", elseIsValid: false, expression: true }; + let depth = 1; + for (let i = 0; i < strings.length; ++i) { + const frag = strings[i]; + const matchedSymbols = frag.matchAll(preprocessorSymbols); + let lastIndex = 0; + let valueConsumed = false; + for (const match of matchedSymbols) { + state.frag += frag.substring(lastIndex, match.index); + switch (match[1]) { case "if": - if (e.index + e[0].length != a.length) + if (match.index + match[0].length != frag.length) { throw new Error("#if must be immediately followed by a template expression (ie: ${value})"); - (l = !0), i.push(r), n++, (r = { frag: "", elseIsValid: !0, expression: !!t[s] }); + } + valueConsumed = true; + stateStack.push(state); + depth++; + state = { frag: "", elseIsValid: true, expression: !!values[i] }; break; case "elif": - if (e.index + e[0].length != a.length) + if (match.index + match[0].length != frag.length) { throw new Error("#elif must be immediately followed by a template expression (ie: ${value})"); - if (!r.elseIsValid) throw new Error("#elif not preceeded by an #if or #elif"); - (l = !0), - r.expression && i.length != n && i.push(r), - (r = { frag: "", elseIsValid: !0, expression: !!t[s] }); + } else if (!state.elseIsValid) { + throw new Error("#elif not preceeded by an #if or #elif"); + } + valueConsumed = true; + if (state.expression && stateStack.length != depth) { + stateStack.push(state); + } + state = { frag: "", elseIsValid: true, expression: !!values[i] }; break; case "else": - if (!r.elseIsValid) throw new Error("#else not preceeded by an #if or #elif"); - r.expression && i.length != n && i.push(r), (r = { frag: e[2], elseIsValid: !1, expression: !0 }); + if (!state.elseIsValid) { + throw new Error("#else not preceeded by an #if or #elif"); + } + if (state.expression && stateStack.length != depth) { + stateStack.push(state); + } + state = { frag: match[2], elseIsValid: false, expression: true }; break; case "endif": - if (!i.length) throw new Error("#endif not preceeded by an #if"); - const o = i.length == n ? i.pop() : r; - (r = i.pop()), n--, o.expression && (r.frag += o.frag), (r.frag += e[2]); + if (!stateStack.length) { + throw new Error("#endif not preceeded by an #if"); + } + const branchState = stateStack.length == depth ? stateStack.pop() : state; + state = stateStack.pop(); + depth--; + if (branchState.expression) { + state.frag += branchState.frag; + } + state.frag += match[2]; break; default: - r.frag += e[0]; + // Unknown preprocessor symbol. Emit it back into the output frag unchanged. + state.frag += match[0]; + break; } - c = e.index + e[0].length; + lastIndex = match.index + match[0].length; + } + // If the frag didn't end on one of the preprocessor symbols append the rest of it here. + if (lastIndex != frag.length) { + state.frag += frag.substring(lastIndex, frag.length); + } + // If the next value wasn't consumed by the preprocessor symbol, append it here. + if (!valueConsumed && values.length > i) { + state.frag += values[i]; } - c != a.length && (r.frag += a.substring(c, a.length)), !l && t.length > s && (r.frag += t[s]); } - if (i.length) throw new Error("Mismatched #if/#endif count"); - return r.frag; -} -function zi(e) { - return `\n struct VertexInput {\n @location(${e.positionLocation}) position: vec2, \n }\n struct VertexOutput {\n @builtin(position) position: vec4,\n @location(0) uv: vec2,\n };\n @vertex\n fn main(input: VertexInput) -> VertexOutput {\n var output:VertexOutput;\n output.uv = input.position * 0.5 + 0.5;\n output.position = vec4(input.position, 0.0, 1.0);;\n return output;\n }\n `; + if (stateStack.length) { + throw new Error("Mismatched #if/#endif count"); + } + return state.frag; } -const Ii = { - light: function (e) { - return Di` - struct ReflectedLight { - ambient: vec3, - directDiffuse:vec3, - directSpecular:vec3, - indirectDiffuse:vec3, - indirectSpecular:vec3, - testColor: vec3, - }; - struct IncidentLight { - color: vec3, - direction: vec3, - visible: bool, - }; - struct Geometry { - position: vec3, - normal: vec3, - viewDir: vec3, - dotNV:f32, - #if ${e.USE_CLEARCOAT} - vec3 clearcoatNormal; - #endif - }; - #if ${e.spotLightsCount > 0} - struct SpotLight { - position: vec3, - distance: f32, - direction: vec3, - coneCos: f32, - color: vec3, - penumbraCos: f32, - decay: f32, - }; - fn getSpotLightInfo(spotLight:SpotLight,worldPos:vec3,shininess:f32,N:vec3,V:vec3)->ReflectedLight{ - var direction:vec3 = spotLight.position - worldPos; - var lightColor:ReflectedLight; - let lightDistance:f32 = length(direction); - direction = normalize(direction); - let angleCos:f32 = dot( direction, spotLight.direction ); - let decay:f32 = clamp(1.0 - pow(lightDistance/spotLight.distance, spotLight.decay), 0.0, 1.0); - let spotEffect:f32 = smoothstep( spotLight.penumbraCos, spotLight.coneCos, angleCos ); - let decayTotal:f32 = decay * spotEffect; - let d:f32 = max( dot( N, direction ), 0.0 ) * decayTotal; - lightColor.directDiffuse= spotLight.color * d; - let halfDir:vec3 = normalize( V + direction ); - let s:f32 = pow( clamp( dot( N, halfDir ), 0.0, 1.0 ), shininess ) * decayTotal; - lightColor.directSpecular= spotLight.color * s; - return lightColor; - } - fn getSpotLightIncidentLight(spotLight:SpotLight, geometry:Geometry)->IncidentLight { - var incidentLight:IncidentLight; - let lVector:vec3 = spotLight.position - geometry.position; - incidentLight.direction = normalize( lVector ); - - let lightDistance:f32 = length( lVector ); - let angleCos:f32 = dot( incidentLight.direction, spotLight.direction ); - - let spotEffect:f32 = smoothstep( spotLight.penumbraCos, spotLight.coneCos, angleCos ); - let decayEffect:f32 = clamp(1.0 - pow(lightDistance/spotLight.distance, 4.0), 0.0, 1.0); - - incidentLight.color=spotLight.color*spotEffect * decayEffect; - return incidentLight; - } - - #endif +function pbr_fs(defines) { + return wgslParseDefines` + // reference: https://github.com/KhronosGroup/glTF-WebGL-PBR/blob/master/shaders/pbr-frag.glsl + #include + #include + #include + #include + #include + #include + struct PhysicalMaterial { + diffuseColor:vec3, + roughness:f32, + specularColor:vec3, + #if ${defines.USE_CLEARCOAT} + clearcoat:f32, + clearcoatRoughness:f32, + clearcoatF0:vec3, + clearcoatF90:f32, + #endif - #if ${e.pointLightsCount > 0} - struct PointLight { - position: vec3, - distance: f32, - color: vec3, - decay: f32, - }; - fn getPointLightInfo(pointLight:PointLight,worldPos:vec3,shininess:f32,N:vec3,V:vec3)->ReflectedLight{ - var lightColor:ReflectedLight; - var direction:vec3 = worldPos - pointLight.position; - let dist:f32 = length( direction ); - direction = normalize(direction); - let decay = clamp(1.0 - pow(dist / pointLight.distance, pointLight.decay), 0.0, 1.0); - - let d = max( dot( N, -direction ), 0.0 ) * decay; - lightColor.directDiffuse = pointLight.color * d; - - let halfDir:vec3 = normalize( V - direction ); - let s:f32 = pow( clamp( dot( N, halfDir ), 0.0, 1.0 ), shininess ) * decay; - lightColor.directSpecular = pointLight.color * s; - return lightColor; - } - fn getPointLightIncidentLight(pointLight:PointLight, geometry:Geometry)->IncidentLight { - var incidentLight:IncidentLight; - let lVector:vec3 = pointLight.position-geometry.position; - incidentLight.direction= normalize( lVector ); - let lightDistance:f32 = length( lVector ); - // let weight:f32=1.0 - pow(lightDistance/pointLight.distance, 4.0); - incidentLight.color=pointLight.color*clamp(1.0 - pow(lightDistance/pointLight.distance, 4.0), 0.0, 1.0); - return incidentLight; - } - #endif - #if ${e.dirtectLightsCount > 0} - struct DirectionalLight { - direction: vec3, - color: vec3, - }; - fn getDirectLightInfo(directionalLight:DirectionalLight,shininess:f32,N:vec3,V:vec3)->ReflectedLight{ - var lightColor:ReflectedLight; - let d:f32 = max(dot(N, -directionalLight.direction), 0.0); - lightColor.directDiffuse += directionalLight.color * d; - - let halfDir:vec3 = normalize( V - directionalLight.direction ); - let s:f32 = pow( clamp( dot( N, halfDir ), 0.0, 1.0 ), shininess ); - lightColor.directSpecular += directionalLight.color * s; - return lightColor; - } - fn getDirectionalDirectLightIncidentLight(directionalLight:DirectionalLight,geometry:Geometry)->IncidentLight { - var incidentLight:IncidentLight; - incidentLight.color = directionalLight.color; - incidentLight.direction = normalize(directionalLight.direction); - return incidentLight; - } - #endif + #if ${defines.USE_IRIDESCENCE} + iridescence:f32, + iridescenceIOR:f32, + iridescenceThickness:f32, + iridescenceFresnel:vec3, + iridescenceF0:vec3, + #endif - #if ${e.openShadow} - struct LightInfo { - direction: vec3, - viewport: vec4, - }; - - fn linearizeDepth(depth: f32, near: f32, far: f32)->f32 { - return 2 * (near * far) / (far + near - depth * (far - near)); - } + #if ${defines.USE_SHEEN} + sheenColor:vec3, + sheenRoughness:f32, + #endif - fn getCubeFace(v : vec3) -> i32{ - let vAbs = abs(v); - - if (vAbs.z >= vAbs.x && vAbs.z >= vAbs.y) { - if (v.z < 0.0) { - return 3; - } - return 2; - } - - if (vAbs.y >= vAbs.x) { - if (v.y < 0.0) { - return 5; - } - return 4; - } - - if (v.x < 0.0) { - return 1; - } - return 0; - } + #if ${defines.IOR} + ior:f32, + #endif - fn getShadowValue(shadowMapArray:texture_depth_2d_array, shadowSampler:sampler_comparison, lightPos:vec4, geometry:Geometry, lightInfo:LightInfo, index:u32, isPointLight: bool, near: f32, far: f32)->f32 { - var visibility = 0.0; - var projectPos: vec3 = lightPos.xyz / lightPos.w; - var shadowPos: vec3 = vec3(projectPos.xy * vec2(0.5, -0.5) + vec2(0.5), projectPos.z); - var d:f32 = dot(geometry.normal, -lightInfo.direction); - var bias = max(0.012 * (1.0 - d), 0.001) / lightPos.w; - let oneOverShadowDepthTextureSize = 1.0 / 1024.0; - // var depth = select(shadowPos.z, (linearizeDepth(shadowPos.z, near, far) - near) / (far- near), isPerspectiveCamera); - var depth = shadowPos.z; + #if ${defines.USE_TRANSMISSION} + transmission:f32, + transmissionAlpha:f32, + thickness:f32, + attenuationDistance:f32, + attenuationColor:vec3, + #endif + }; + const M_PI:f32 = 3.141592653589793; + const c_MinRoughness:f32 = 0.04; + #include + #if ${defines.USE_IBL} + #include + #endif + @binding(${defines.pbrBinding}) @group(0) var materialUniform : MaterialUniform; + @binding(${defines.cameraBinding}) @group(1) var systemUniform : SystemUniform; + @fragment + fn main(input:FragInput) -> @location(0) vec4 + { + var perceptualRoughness:f32 = materialUniform.roughness; + var metallic:f32 = materialUniform.metallic; - if (isPointLight) { - shadowPos.x = shadowPos.x * lightInfo.viewport.z; - shadowPos.y = shadowPos.y * lightInfo.viewport.w; - var viewportX = lightInfo.viewport.x * lightInfo.viewport.z; - var viewportY = lightInfo.viewport.y * lightInfo.viewport.w; - var uvOffset = 1.5 / 1024.0; - shadowPos.x = clamp(shadowPos.x + viewportX, viewportX + uvOffset, viewportX + lightInfo.viewport.z - uvOffset); - shadowPos.y = clamp(shadowPos.y + viewportY, viewportY + uvOffset, viewportY + lightInfo.viewport.w - uvOffset); - } + #if ${defines.USE_METALNESSTEXTURE} + let mrSample:vec4 = textureSample(metalnessRoughnessTexture,metalnessRoughnessSampler, input.uv); + perceptualRoughness = mrSample.g * perceptualRoughness; + metallic = mrSample.b * metallic; + #endif + perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0); + metallic = clamp(metallic, 0.0, 1.0); + let alphaRoughness:f32 = perceptualRoughness * perceptualRoughness; - for (var y = -1; y <= 1; y++) { - for (var x = -1; x <= 1; x++) { - let offset = vec2(vec2(x, y)) * oneOverShadowDepthTextureSize; - - visibility += textureSampleCompare( - shadowMapArray, shadowSampler, - shadowPos.xy + offset, index, depth - bias); - } - } - visibility /= 9.0; - var inFrustum = shadowPos.x >= 0.0 && shadowPos.x <= 1.0 && shadowPos.y >= 0.0 && shadowPos.y <= 1.0; - if (!inFrustum || depth > 1.0) { - visibility = 1.0; - } - return visibility; - } - #endif - #if ${e.ambientLightCount || e.spotLightsCount || e.pointLightsCount || e.dirtectLightsCount} - struct LightUniforms{ - #if ${e.ambientLightCount} - ambient:vec4, - #endif - #if ${e.spotLightsCount} - spotLights:array, - #endif - #if ${e.pointLightsCount} - pointLights:array, - #endif - #if ${e.dirtectLightsCount} - dirtectLights:array, + // The albedo may be defined from a base texture or a flat color + #if ${defines.USE_TEXTURE} + let baseColor:vec4 = textureSample(baseColorTexture,baseColorSampler, input.uv) ; + #else + let baseColor:vec4 = vec4(materialUniform.color,1.0); #endif - } - @group(2) @binding(${e.lightBinding}) var lightUniforms: LightUniforms; - #if ${e.openShadow} - #if ${e.spotLightShadowMapsCount} - struct SpotLightShadow { - shadowCameraVPMatrix: mat4x4, - shadowCameraNear: f32, - shadowCameraFar: f32 - } + #if ${defines.USE_NORMALTEXTURE} + let n:vec3 = getNormalByNormalTexture(input); + #else + let n:vec3 = getNormal(input); #endif - #if ${e.pointLightShadowMapsCount} - struct PointLightShadow { - shadowCameraVPMatrixArray: array, 6>, - shadowCameraViewportArray: array, 6>, - shadowCameraNear: f32, - shadowCameraFar: f32, - // shadowCameraVPMatrix: mat4x4, - // shadowCameraVPMatrixArray: array, 6>, - // shadowCameraViewportArray: array, 6>, - } + var material:PhysicalMaterial; + material.diffuseColor=baseColor.rgb*( 1.0 - metallic ); + material.roughness=perceptualRoughness; + material.specularColor=mix( vec3( 0.04), baseColor.rgb, metallic ); + var geometry:Geometry; + geometry.normal=n; + geometry.viewDir=normalize(systemUniform.cameraPosition - input.worldPos); + geometry.position=input.worldPos; + geometry.dotNV = saturate(dot(geometry.normal, geometry.viewDir) ); + //light shading + var reflectedLight=parseLights(geometry,material); + var color=reflectedLight.directDiffuse+reflectedLight.directSpecular; + //IBL + #if ${defines.USE_IBL && defines.HAS_UV} + var reflectedLightDiffuse=indirectDiffuse_Physical(geometry,material); + var reflectedLightSpecular=indirectSpecular_Physical(geometry,material); + color+=reflectedLightDiffuse.indirectDiffuse; + color+=reflectedLightSpecular.indirectSpecular; #endif - #if ${e.directLightShadowMapsCount} - struct DirectLightShadow { - shadowCameraVPMatrix: mat4x4, - } + #if ${defines.USE_AOTEXTURE} + let ao:f32 = textureSample(aoTexture,aoSampler, input.uv).r; + color = mix(color, color * ao, materialUniform.occlusionStrength); #endif - struct ShadowUniforms{ - #if ${e.spotLightShadowMapsCount} - spotLightShadows:array, - #endif - #if ${e.pointLightShadowMapsCount} - pointLightShadows:array, - #endif - #if ${e.directLightShadowMapsCount} - directLightShadows:array, - #endif - } - @group(2) @binding(${e.shadowBinding}) var shadowUniforms: ShadowUniforms; - #if ${e.spotLightShadowMapTextureArrayBinding} - @group(2) @binding(${ - e.spotLightShadowMapTextureArrayBinding - }) var spotLightShadowMapTextureArray: texture_depth_2d_array; - #endif - #if ${e.pointLightShadowMapTextureArrayBinding} - @group(2) @binding(${ - e.pointLightShadowMapTextureArrayBinding - }) var pointLightShadowMapTextureArray: texture_depth_2d_array; + #if ${defines.USE_EMISSIVETEXTURE} + let emissive:vec3 = textureSample(emissiveTexture, emissiveSampler,input.uv).rgb ; + color += emissive; #endif - #if ${e.directLightShadowMapTextureArrayBinding} - @group(2) @binding(${ - e.directLightShadowMapTextureArrayBinding - }) var directLightShadowMapTextureArray: texture_depth_2d_array; - #endif - @group(2) @binding(${e.shadowSamplerBinding}) var shadowSampler: sampler_comparison; + return vec4(color, baseColor.a); + } + `; +} + +function pbr_vs(defines) { + return wgslParseDefines` + #include + #include + #include + #include + #include + #include + @binding(${defines.pbrBinding}) @group(0) var materialUniform : MaterialUniform; + @binding(${defines.cameraBinding}) @group(1) var systemUniform : SystemUniform; + @vertex + fn main(input: VertexInput)-> VertexOutput + { + var output: VertexOutput; + #if ${defines.HAS_UV} + output.uv = input.uv; #endif + var modelMatrix:mat4x4; + var vNormalView:vec3; + vNormalView = normalize(materialUniform.normalMatrix * vec4(input.normal,0.0)).xyz; + modelMatrix=materialUniform.modelMatrix; + #include + #include + output.normal = vNormalView.xyz; + output.position = systemUniform.projectionMatrix * systemUniform.viewMatrix *modelMatrix* vec4(input.position, 1.0); + let modelPos=modelMatrix *vec4(input.position,1.0); + output.worldPos = modelPos.xyz/modelPos.w; + return output; + } + `; +} +function pbrFrag(defines) { + return wgslParseDefines` + #include + #include + #include + #include + #include + #include + #include + #include + struct SystemUniform { + projectionMatrix: mat4x4, + viewMatrix: mat4x4, + inverseViewMatrix: mat4x4, + cameraPosition: vec3, + }; + // uniform vec3 lightProbe[9], +//////////////////////////////////// +struct VertexOutput { + @builtin(position) position: vec4, + @builtin(front_facing) is_front: bool, + @location(0) vUv: vec2, + @location(1) vViewPosition: vec3, // Vector from vertex to camera. + @location(2) vWorldPosition: vec3, + @location(3) vNormal: vec3, + // 可选 + #if ${defines.USE_LIGHTTEXTURE || defines.USE_AOTEXTURE} + @location(${defines.vUv2OutLocation}) vUv2: vec2, #endif - #if ${e.materialPhong} - fn parseLights(geometry:Geometry,shininess:f32)->ReflectedLight { - #elif ${e.materialPbr} - fn parseLights(geometry:Geometry,material:PhysicalMaterial)->ReflectedLight{ + + #if ${defines.USE_COLOR_ALPHA} + @location(${defines.vColorOutLocation}) vColor: vec4, + #elif ${defines.USE_COLOR || defines.USE_INSTANCING_COLOR} + @location(${defines.vColorOutLocation}) vColor: vec3, #endif - var reflectedLight:ReflectedLight; - var shadowValue:f32 = 1.0; - #if ${e.ambientLightCount > 0} - //处理环境光 - var ambientColor:vec3 = lightUniforms.ambient.xyz * lightUniforms.ambient.w; - reflectedLight.ambient += ambientColor; - #endif - #if ${e.spotLightsCount > 0} - //处理聚光灯 - var spotLight:SpotLight; - for (var k = 0u; k < ${e.spotLightsCount}; k = k + 1u) { - spotLight= lightUniforms.spotLights[k]; - #if ${e.materialPhong && e.openShadow && e.spotLightShadowMapsCount} - if k < textureNumLayers(spotLightShadowMapTextureArray) { - var spotLightShadow:SpotLightShadow = shadowUniforms.spotLightShadows[k]; - var lightPos: vec4 = spotLightShadow.shadowCameraVPMatrix * vec4(geometry.position,1.0); - var lightInfo:LightInfo; - lightInfo.direction = normalize(geometry.position - spotLight.position); + #if ${defines.USE_TANGENT} + @location(${defines.vTangentOutLocation}) vTangent: vec3, + @location(${defines.vBitangentOutLocation}) vBitangent: vec3, + #endif +}; + struct PhysicalMaterial { + diffuseColor:vec3, + roughness:f32, + specularColor:vec3, + specularF90:f32, + #if ${defines.USE_CLEARCOAT} + clearcoat:f32, + clearcoatRoughness:f32, + clearcoatF0:vec3, + clearcoatF90:f32, + #endif - shadowValue = getShadowValue(spotLightShadowMapTextureArray, shadowSampler, lightPos, geometry, lightInfo, k, false, - spotLightShadow.shadowCameraNear, spotLightShadow.shadowCameraFar); - } - spotLight.color *= shadowValue; - #endif - #if ${e.materialPhong} - let spReflectedLight=getSpotLightInfo(spotLight,geometry.position,shininess,geometry.normal,geometry.viewDir); - #elif ${e.materialPbr} - let incidentLight=getSpotLightIncidentLight(spotLight,geometry); - let spReflectedLight=direct_Physical(incidentLight, geometry, material); - #endif + #if ${defines.USE_IRIDESCENCE} + iridescence:f32, + iridescenceIOR:f32, + iridescenceThickness:f32, + iridescenceFresnel:vec3, + iridescenceF0:vec3, + #endif - reflectedLight.directDiffuse+=spReflectedLight.directDiffuse; - reflectedLight.directSpecular+=spReflectedLight.directSpecular; - } - #endif - #if ${e.pointLightsCount > 0} - //处理点光源 - var pointLight:PointLight; - for (var j = 0u; j < ${e.pointLightsCount};j = j + 1u) { - pointLight = lightUniforms.pointLights[j]; - #if ${e.materialPhong && e.openShadow && e.pointLightShadowMapsCount} - if j < textureNumLayers(pointLightShadowMapTextureArray) { - var pointLightShadow:PointLightShadow = shadowUniforms.pointLightShadows[j]; - var lightInfo:LightInfo; - lightInfo.direction = normalize(geometry.position - pointLight.position); - var cubeFace = getCubeFace(lightInfo.direction); - var lightPos: vec4 = pointLightShadow.shadowCameraVPMatrixArray[cubeFace] * vec4(geometry.position,1.0); - lightInfo.viewport = pointLightShadow.shadowCameraViewportArray[cubeFace]; + #if ${defines.USE_SHEEN} + sheenColor:vec3, + sheenRoughness:f32, + #endif - // var lightPos: vec4 = pointLightShadow.shadowCameraVPMatrix * vec4(geometry.position,1.0); + #if ${defines.IOR} + ior:f32, + #endif - shadowValue = getShadowValue(pointLightShadowMapTextureArray, shadowSampler, lightPos, geometry, lightInfo, j, true, - pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar); - - // reflectedLight.testColor = vec3(pointLightShadow.shadowCameraFar / 1000, - // pointLightShadow.shadowCameraVPMatrixArray[5][3][2] / 255, pointLightShadow.shadowCameraVPMatrixArray[5][3][3] / 255); - // reflectedLight.testColor = vec3(pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraNear); - } - pointLight.color *= shadowValue; - #endif - #if ${e.materialPhong} - let poiReflectedLight=getPointLightInfo(pointLight,geometry.position,shininess,geometry.normal,geometry.viewDir); - #elif ${e.materialPbr} - let incidentLight=getPointLightIncidentLight(pointLight,geometry); - let poiReflectedLight=direct_Physical(incidentLight, geometry, material); - #endif + #if ${defines.USE_TRANSMISSION} + transmission:f32, + transmissionAlpha:f32, + thickness:f32, + attenuationDistance:f32, + attenuationColor:vec3, + #endif + }; +@binding(0) @group(0) var materialUniform : MaterialUniform; +@binding(0) @group(1) var systemUniform : SystemUniform; +@fragment +fn main(input:VertexOutput)-> @location(0) vec4 { + var diffuseColor:vec4 = vec4(materialUniform.diffuse, materialUniform.opacity ); + // ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); + var reflectedLight:ReflectedLight; + var totalEmissiveRadiance:vec3 = materialUniform.emissive; + #if ${defines.USE_TEXTURE} + var sampledDiffuseColor:vec4 =textureSample(baseTexture, baseSampler, input.vUv); + #if ${defines.DECODE_VIDEO_TEXTURE} + sampledDiffuseColor = vec4( mix( pow( sampledDiffuseColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), sampledDiffuseColor.rgb * 0.0773993808, vec3( lessThanEqual( sampledDiffuseColor.rgb, vec3( 0.04045 ) ) ) ), sampledDiffuseColor.w ); + #endif - reflectedLight.directDiffuse+=poiReflectedLight.directDiffuse; - reflectedLight.directSpecular+=poiReflectedLight.directSpecular; - } + diffuseColor *= sampledDiffuseColor; #endif - #if ${e.dirtectLightsCount > 0} - //处理方向光 - var directionalLight:DirectionalLight; - for (var i= 0u; i <${e.dirtectLightsCount}; i = i + 1u) { - directionalLight = lightUniforms.dirtectLights[i]; - #if ${e.materialPhong && e.openShadow && e.directLightShadowMapsCount} - if i < textureNumLayers(directLightShadowMapTextureArray) { - var directLightShadow:DirectLightShadow = shadowUniforms.directLightShadows[i]; - var lightPos: vec4 = directLightShadow.shadowCameraVPMatrix * vec4(geometry.position,1.0); - var lightInfo:LightInfo; - lightInfo.direction = directionalLight.direction; - - shadowValue = getShadowValue(directLightShadowMapTextureArray, shadowSampler, lightPos, geometry, lightInfo, i, false, 0, 0); - } - directionalLight.color *= shadowValue; - #endif - - #if ${e.materialPhong} - let dirReflectedLight=getDirectLightInfo(directionalLight,shininess,geometry.normal,geometry.viewDir); - #elif ${e.materialPbr} - let incidentLight=getDirectionalDirectLightIncidentLight(directionalLight,geometry); - let dirReflectedLight=direct_Physical(incidentLight, geometry, material); - #endif - reflectedLight.directDiffuse+=dirReflectedLight.directDiffuse; - reflectedLight.directSpecular+=dirReflectedLight.directSpecular; - } + var roughnessFactor:f32 = materialUniform.roughness; + + #if ${defines.USE_ROUGHNESSTEXTURE} + let texelRoughness:vec4=textureSample(roughnessTexture, baseSampler, input.vUv); + roughnessFactor *= texelRoughness.g; #endif - return reflectedLight; - }`; - }, - brdf: function (e) { - return Di` - #if ${e.USE_SHEEN} - fn D_Charlie( roughness:f32,dotNH:f32 )->f32 { - let alpha:f32 = pow2( roughness ); - let invAlpha:f32 = 1.0 / alpha; - let cos2h:f32 = dotNH * dotNH; - let sin2h:f32 = max( 1.0 - cos2h, 0.0078125 ); - return ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI ); - } - fn V_Neubelt( dotNV:f32, dotNL:f32 )->f32 { - return saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) ); - } - fn BRDF_Sheen(lightDir:vec3, viewDir:vec3, normal:vec3,sheenColor:vec3,sheenRoughness:f32 )->vec3 { - let halfDir:vec3 = normalize( lightDir + viewDir ); - let dotNL:f32 = saturate( dot( normal, lightDir ) ); - let dotNV:f32 = saturate( dot( normal, viewDir ) ); - let dotNH:f32 = saturate( dot( normal, halfDir ) ); - let D:f32 = D_Charlie( sheenRoughness, dotNH ); - let V:f32 = V_Neubelt( dotNV, dotNL ); - return sheenColor * ( D * V ); - } + + var metalnessFactor:f32 = materialUniform.metalness; + + #if ${defines.USE_METALNESSTEXTURE} + let texelMetalness:vec4 =textureSample(metalnessTexture, baseSampler, input.vUv); + metalnessFactor *= texelMetalness.b; #endif - fn BRDF_Lambert(diffuseColor:vec3)->vec3 { - return RECIPROCAL_PI * diffuseColor; + let faceDirection:f32 =select(-1.0,1.0,input.is_front); + #if ${defines.FLAT_SHADED} + let fdx:vec3 = dpdx( input.vViewPosition ); + let fdy:vec3 = dpdy( input.vViewPosition ); + let normal:vec3 = normalize( cross( fdy, fdx ) ); + #else + let normal:vec3 = normalize( input.vNormal ); + #if ${defines.DOUBLE_SIDED} + normal = normal * faceDirection; + #endif + #if ${defines.USE_TANGENT} + let tangent:vec3 = normalize( input.vTangent ); + let bitangent:vec3 = normalize( input.vBitangent ); + #if ${defines.DOUBLE_SIDED} + tangent = tangent * faceDirection; + bitangent = bitangent * faceDirection; + #endif + #if ${defines.TANGENTSPACE_NORMALTEXTURE || defines.USE_CLEARCOAT_NORMALTEXTURE} + let vTBN:mat3x3 = mat3x3( tangent, bitangent, normal ); + #endif + #endif + #endif + + let geometryNormal:vec3 = normal; - } // validated + #if ${defines.OBJECTSPACE_NORMALTEXTURE} + normal =textureSample(normalTexture, baseSampler, input.vUv).xyz * 2.0 - 1.0; + #if ${defines.FLIP_SIDED} + normal = - normal; + #endif + #if ${defines.DOUBLE_SIDED} + normal = normal * faceDirection; + #endif - fn F_Schlick( f0:vec3, dotVH:f32 )->vec3 { + normal = normalize(materialUniform.normalMatrix * normal ); - // Original approximation by Christophe Schlick '94 - // float fresnel = pow( 1.0 - dotVH, 5.0 ); + #elif ${defines.TANGENTSPACE_NORMALTEXTURE} + let tempMapN:vec3 =textureSample(normalTexture, baseSampler, input.vUv).xyz * 2.0 - 1.0; + let mapN:vec3 =tempMapN.xy *= materialUniform.normalScale; + #if ${defines.USE_TANGENT} + normal = normalize( vTBN * mapN ); + #else + normal = perturbNormal2Arb( - input.vViewPosition, normal, mapN, faceDirection ); + #endif - // Optimized variant (presented by Epic at SIGGRAPH '13) - // https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf - let fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH ); - return ( 1.0 - f0 ) * fresnel + f0; + #elif ${defines.USE_BUMPTEXTURE} - } // validated + normal = perturbNormalArb( - input.vViewPosition, normal, dHdxy_fwd(), faceDirection ); + #endif - fn Schlick_to_F0(f:vec3, f90:f32, dotVH:f32 )->vec3 { - let x:f32 = clamp( 1.0 - dotVH, 0.0, 1.0 ); - let x2:f32 = x * x; - let x5:f32 = clamp( x * x2 * x2, 0.0, 0.9999 ); + #if ${defines.USE_CLEARCOAT} + var clearcoatNormal:vec3 = geometryNormal; + #endif + #if ${defines.USE_CLEARCOAT_NORMALTEXTURE} + var clearcoatMapN:vec3 =textureSample(clearcoatNormalTexture, baseSampler, input.vUv).xyz * 2.0 - 1.0; + clearcoatMapN.xy *= materialUniform.clearcoatNormalScale; + #if ${defines.USE_TANGENT} + clearcoatNormal = normalize( vTBN * clearcoatMapN ); + #else + clearcoatNormal = perturbNormal2Arb( - input.vViewPosition, clearcoatNormal, clearcoatMapN, faceDirection ); + #endif + #endif + #if ${defines.USE_EMISSIVETEXTURE} + let emissiveColor:vec4 =textureSample(emissiveTexture, baseSampler, input.vUv); + totalEmissiveRadiance *= emissiveColor.rgb; + #endif - return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 ); - } - fn V_GGX_SmithCorrelated( alpha:f32, dotNL:f32,dotNV:f32 )->f32 { + var material:PhysicalMaterial; + material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor ); + let dxy:vec3 = max( abs( dpdx( geometryNormal ) ), abs( dpdy( geometryNormal ) ) ); + let geometryRoughness:f32 = max( max( dxy.x, dxy.y ), dxy.z ); + material.roughness = max( roughnessFactor, 0.0525 ); + material.roughness += geometryRoughness; + material.roughness = min( material.roughness, 1.0 ); - let a2 :f32= pow2( alpha ); + #if ${defines.IOR} + material.ior = materialUniform.ior; + #if ${defines.SPECULAR} + let specularIntensityFactor:f32 = materialUniform.specularIntensity; + let specularColorFactor:vec3 = materialUniform.specularColor; + #if ${defines.USE_SPECULARINTENSITYTEXTURE} + specularIntensityFactor *=textureSample(specularIntensityTexture, baseSampler, input.vUv).a; + #endif - let gv:f32 = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) ); - let gl:f32 = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) ); + #if ${defines.USE_SPECULARCOLORTEXTURE} + specularColorFactor *=textureSample(specularColorTexture, baseSampler, input.vUv).rgb; + #endif - return 0.5 / max((gv + gl), 0.000000001 ); + material.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor ); + #else + let specularIntensityFactor:f32 = 1.0; + let specularColorFactor:vec3 = vec3( 1.0 ); + material.specularF90 = 1.0; + #endif + material.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor ); + #else + material.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor ); + material.specularF90 = 1.0; + #endif + #if ${defines.USE_CLEARCOAT} + material.clearcoat = materialUniform.clearcoat; + material.clearcoatRoughness = materialUniform.clearcoatRoughness; + material.clearcoatF0 = vec3( 0.04 ); + material.clearcoatF90 = 1.0; + #if ${defines.USE_CLEARCOATTEXTURE} + material.clearcoat *=textureSample(clearcoatTexture, baseSampler, input.vUv).x; + #endif + #if ${defines.USE_CLEARCOAT_ROUGHNESSTEXTURE} + material.clearcoatRoughness *=textureSample(clearcoatRoughnessTexture, baseSampler, input.vUv).y; + #endif + material.clearcoat = saturate( material.clearcoat ); + material.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 ); + material.clearcoatRoughness += geometryRoughness; + material.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 ); + #endif + #if ${defines.USE_IRIDESCENCE} + material.iridescence = materialUniform.iridescence; + material.iridescenceIOR = materialUniform.iridescenceIOR; + #if ${defines.USE_IRIDESCENCETEXTURE} + material.iridescence *=textureSample(iridescenceTexture, baseSampler, input.vUv).r; + #endif + #if ${defines.USE_IRIDESCENCE_THICKNESSTEXTURE} + material.iridescenceThickness = (materialUniform.iridescenceThicknessMaximum - materialUniform.iridescenceThicknessMinimum) * textureSample(iridescenceThicknessTexture, baseSampler, input.vUv).g + materialUniform.iridescenceThicknessMinimum; + #else + material.iridescenceThickness = materialUniform.iridescenceThicknessMaximum; + #endif + #endif + #if ${defines.USE_SHEEN} + material.sheenColor = materialUniform.sheenColor; + #if ${defines.USE_SHEENCOLORTEXTURE} + material.sheenColor *=textureSample(sheenColorTexture, baseSampler, input.vUv).rgb; + #endif + material.sheenRoughness = clamp( materialUniform.sheenRoughness, 0.07, 1.0 ); + #if ${defines.USE_SHEENROUGHNESSTEXTURE} + material.sheenRoughness *=textureSample(sheenRoughnessTexture, baseSampler, input.vUv).a; + #endif + #endif + + var geometry:GeometricContext; + geometry.position = - input.vViewPosition; + geometry.normal = normal; + // geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( input.vViewPosition ); + geometry.viewDir = normalize( input.vViewPosition); - } - fn D_GGX( alpha:f32, dotNH:f32 )->f32 { + #if ${defines.USE_CLEARCOAT} + geometry.clearcoatNormal = clearcoatNormal; + #endif - let a2:f32 = pow2( alpha ); + #if ${defines.USE_IRIDESCENCE} + let dotNVi:f32 = saturate( dot( normal, geometry.viewDir ) ); + if ( material.iridescenceThickness == 0.0 ) { + material.iridescence = 0.0; + } + else { + material.iridescence = saturate( material.iridescence ); + } + if ( material.iridescence > 0.0 ) { + material.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor ); + material.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi ); + } + #endif - let denom:f32 = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0; // avoid alpha = 0 with dotNH = 1 + var iblIrradiance:vec3 = vec3( 0.0 ); + var irradiance:vec3 = getAmbientLightIrradiance(commonLightsParms.ambient); + //irradiance += getLightProbeIrradiance( lightProbe, geometry.normal,systemUniform.viewMatrix ); - return RECIPROCAL_PI * a2 / pow2( denom ); + var radiance:vec3 = vec3( 0.0 ); + var clearcoatRadiance:vec3 = vec3( 0.0 ); - } - fn BRDF_GGX( lightDir:vec3, viewDir:vec3, normal:vec3, f0:vec3, roughness:f32 )->vec3 { + #if ${defines.USE_LIGHTTEXTURE} + let lightMapTexel:vec4 =textureSample(lightTexture, baseSampler, input.vUv2); + let lightMapIrradiance:vec3 = lightMapTexel.rgb * materialUniform.lightTextureIntensity; + irradiance += lightMapIrradiance; + #endif + //&& defines.STANDARD&&defines.ENVTEXTURE_TYPE_CUBE_UV + #if ${defines.USE_ENVTEXTURE} + iblIrradiance += getIBLIrradiance( geometry.normal,baseSampler,systemUniform.viewMatrix ); + #endif + #if ${defines.USE_ENVTEXTURE} + radiance += getIBLRadiance( geometry.viewDir,baseSampler,systemUniform.viewMatrix, geometry.normal, materialUniform.roughness ); + #if ${defines.USE_CLEARCOAT} + clearcoatRadiance += getIBLRadiance( geometry.viewDir,baseSampler,systemUniform.viewMatrix, geometry.clearcoatNormal, material.clearcoatRoughness ); + #endif + #endif + //直接光照 + let dirReflectedLight:ReflectedLight= parseLights(geometry,material); + reflectedLight.directDiffuse +=dirReflectedLight.directDiffuse; + reflectedLight.directSpecular +=dirReflectedLight.directSpecular; + //间接漫反射 + let indirectDiffuseLight:ReflectedLight= RE_IndirectDiffuse_Physical( irradiance, geometry, material); + reflectedLight.directDiffuse +=indirectDiffuseLight.indirectDiffuse; + reflectedLight.directSpecular +=indirectDiffuseLight.indirectSpecular; + //间接高光 + let indirectSpecularLight:ReflectedLight=RE_IndirectSpecular_Physical( radiance, iblIrradiance, clearcoatRadiance, geometry, material); + reflectedLight.directDiffuse +=indirectSpecularLight.indirectDiffuse; + reflectedLight.directSpecular +=indirectSpecularLight.indirectSpecular; + //环境光遮蔽 + #if ${defines.USE_AOTEXTURE} + let ambientOcclusion:f32 = (textureSample(aoTexture, baseSampler, input.vUv2).r - 1.0 ) * materialUniform.aoTextureIntensity + 1.0; - let alpha:f32 = pow2( roughness ); // UE4's roughness + reflectedLight.indirectDiffuse *= ambientOcclusion; + //&&defines.STANDARD + #if ${defines.USE_ENVTEXTURE} + let dotNV:f32 = saturate( dot( geometry.normal, geometry.viewDir ) ); + reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness ); + #endif + #endif - let halfDir = normalize( lightDir + viewDir ); + var totalDiffuse:vec3 = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse; + var totalSpecular:vec3 = reflectedLight.directSpecular + reflectedLight.indirectSpecular; + //透射 + #if ${defines.USE_TRANSMISSION} + material.transmission = materialUniform.transmission; + material.transmissionAlpha = 1.0; + material.thickness = materialUniform.thickness; + material.attenuationDistance = materialUniform.attenuationDistance; + material.attenuationColor = materialUniform.attenuationColor; + #if ${defines.USE_TRANSMISSIONTEXTURE} + material.transmission *=textureSample(transmissionTexture, baseSampler, input.vUv).r; + #endif + #if ${defines.USE_THICKNESSTEXTURE} + material.thickness *=textureSample(thicknessTexture, baseSampler, input.vUv).g; + #endif + let pos:vec3 = vWorldPosition; + let v:vec3 = normalize( cameraPosition - pos ); + let n:vec3 = inverseTransformDirection( normal, systemUniform.viewMatrix ); + let transmission:vec4 = getIBLVolumeRefraction( + n, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90, pos, modelMatrix, systemUniform.viewMatrix, systemUniform.projectionMatrix, material.ior, material.thickness, material.attenuationColor, material.attenuationDistance ); + material.transmissionAlpha = mix( material.transmissionAlpha, transmission.a, material.transmission ); + totalDiffuse = mix( totalDiffuse, transmission.rgb, material.transmission ); + #endif - let dotNL:f32 = saturate( dot( normal, lightDir ) ); - let dotNV:f32 = saturate( dot( normal, viewDir ) ); - let dotNH:f32 = saturate( dot( normal, halfDir ) ); - let dotVH:f32 = saturate( dot( lightDir, halfDir ) ); + let outgoingLight:vec3 = totalDiffuse + totalSpecular + totalEmissiveRadiance; - let F = F_Schlick( f0, dotVH ); + #if ${defines.USE_SHEEN} + let sheenEnergyComp:f32 = 1.0 - 0.157 * max3( material.sheenColor ); + outgoingLight = outgoingLight * sheenEnergyComp + sheenSpecular; + #endif - let V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV ); + #if ${defines.USE_CLEARCOAT} + let dotNVcc:f32 = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) ); + let Fcc:vec3 = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc ); + outgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + clearcoatSpecular * material.clearcoat; + #endif - let D = D_GGX( alpha, dotNH ); + #if ${defines.USE_TRANSMISSION} + diffuseColor.a *= material.transmissionAlpha + 0.1; + #endif - return F * ( V * D ); + var finnalColor:vec4; + finnalColor = vec4( outgoingLight, diffuseColor.a ); + #if ${defines.TONE_MAPPING} + finnalColor.rgb = toneMapping( finnalColor.rgb,materialUniform.toneMappingExposure ); + #endif - } - fn direct_Physical( directLight:IncidentLight, geometry:Geometry,material:PhysicalMaterial)->ReflectedLight { - var reflectedLight:ReflectedLight; - let dotNL:f32 = saturate(dot( geometry.normal,geometry.viewDir)); - let irradiance:vec3 = dotNL * directLight.color*3.1415926; - reflectedLight.directSpecular = irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.roughness ); - reflectedLight.directDiffuse = irradiance * BRDF_Lambert( material.diffuseColor ); - return reflectedLight; - } - `; - }, - phongFunction: function (e) { - return "\n fn G_BlinnPhong_Implicit( )->f32 {\n\n // geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v)\n return 0.25;\n\n }\n fn D_BlinnPhong( shininess:f32, dotNH:f32 )->f32 {\n\n return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow(dotNH, shininess);\n\n }\n fn BRDF_BlinnPhong( lightDir:vec3, viewDir:vec3, normal:vec3, specularColor:vec3, shininess:f32 )->vec3 {\n\n let halfDir = normalize( lightDir + viewDir );\n\n let dotNH:f32 = saturate( dot( normal, halfDir ) );\n let dotVH:f32 = saturate( dot( viewDir, halfDir ) );\n\n let F = F_Schlick( specularColor, 1.0, dotVH );\n\n let G:f32 = G_BlinnPhong_Implicit( );\n\n let D = D_BlinnPhong( shininess, dotNH );\n\n return F * ( G * D );\n\n } \n fn RE_Direct_BlinnPhong( directLight:IncidentLight,geometry:GeometricContext, material:BlinnPhongMaterial )->ReflectedLight{\n var reflectedLight:ReflectedLight; \n let dotNL:f32 = saturate(dot(geometry.normal, directLight.direction));\n let irradiance:vec3 = dotNL*directLight.color;\n\n reflectedLight.directDiffuse= irradiance * BRDF_Lambert( material.diffuseColor );\n\n reflectedLight.directSpecular= irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularShininess ) * material.specularStrength;\n return reflectedLight;\n }\n fn RE_IndirectDiffuse_BlinnPhong( irradiance:vec3, geometry:GeometricContext, material:BlinnPhongMaterial)->ReflectedLight {\n var reflectedLight:ReflectedLight; \n reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n return reflectedLight;\n }\n "; - }, - phongUtils: function (e) { - return "\n struct BlinnPhongMaterial {\n diffuseColor:vec3,\n specularColor:vec3,\n specularShininess:f32,\n specularStrength:f32,\n };\n const RECIPROCAL_PI:f32= 0.3183098861837907;\n fn pow2( x:f32 )->f32 { return x*x; }\n fn pow3( x:f32 )->f32 { return x*x*x; }\n fn pow4(x:f32 )->f32 { let x2 = x*x; return x2*x2; }\n fn max3( v:vec3 )->f32 { return max( max( v.x, v.y ), v.z ); }\n fn average(v:vec3 )->f32 { \n let result=vec3( 0.3333333, 0.3333333, 0.3333333);\n return dot( v,result ); \n }\n "; - }, - lightCommon: function (e) { - return Di` - struct ReflectedLight { - directDiffuse:vec3, - directSpecular:vec3, - indirectDiffuse:vec3, - indirectSpecular:vec3, - }; - struct Geometry { - position: vec3, - normal: vec3, - viewDir: vec3, - #if ${e.USE_CLEARCOAT} - vec3 clearcoatNormal; + finnalColor = linearToOutputTexel( finnalColor); + + #if ${defines.PREMULTIPLIED_ALPHA} + finnalColor.rgb *= finnalColor.a; #endif - }; - fn getAmbientLightIrradiance(ambientLightColor: vec3) -> vec3 { - let irradiance = ambientLightColor; - return irradiance; - } - fn getDistanceAttenuation(lightDistance: f32, cutoffDistance: f32, decayExponent: f32) -> f32 { - if (cutoffDistance > 0.0 && decayExponent > 0.0) { - let x:f32 = saturate(- lightDistance / cutoffDistance + 1.0); - return pow(x, decayExponent); - } - return 1.0; - } - fn getSpotAttenuation(coneCosine: f32, penumbraCosine: f32, angleCosine: f32) -> f32 { - return smoothstep(coneCosine, penumbraCosine, angleCosine); - } - fn shGetIrradianceAt( normal:vec3, shCoefficients:array,9>)->vec3 { - let x:f32 = normal.x; - let y:f32 = normal.y; - let z:f32 = normal.z; - var result:vec3 = shCoefficients[ 0 ] * 0.886227; - result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y; - result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z; - result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x; - result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y; - result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z; - result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 ); - result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z; - result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y ); - return result; - } - fn inverseTransformDirection( dir:vec3, matrix:mat4x4 )->vec3 { - return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz ); - } - `; - }, - pbrStruct: function (e) { - return Di` - struct MaterialUniform{ + #if ${defines.DITHERING} + finnalColor.rgb = dithering( finnalColor.rgb ); + #endif + return finnalColor; + }`; +} - modelMatrix: mat4x4, - - diffuse:vec3, - - opacity:f32, - - normalMatrix: mat3x3, - - emissive:vec3, - - roughness:f32, - - metalness:f32, - - #if ${e.TONE_MAPPING} - toneMappingExposure:f32, - #endif - - #if ${e.SPECULAR} - - specularColor:vec3, - - specularIntensity:f32, - #endif - - #if ${e.USE_SHEEN} - - sheenColor:vec3, - - sheenRoughness:f32, - #endif +function pbrVert(defines) { + return wgslParseDefines` + #include + struct VertexOutput { + @builtin(position) position: vec4, + @location(0) vUv: vec2, + @location(1) vViewPosition: vec3, // Vector from vertex to camera. + @location(2) vWorldPosition: vec3, + @location(3) vNormal: vec3, + // 可选 + #if ${defines.USE_LIGHTTEXTURE || defines.USE_AOTEXTURE} + @location(${defines.vUv2OutLocation}) vUv2: vec2, + #endif - #if ${e.USE_TRANSMISSION} - - attenuationColor:vec3, - - transmission:f32, - - transmissionSamplerSize:vec2, - - thickness:f32, - - attenuationDistance:f32, - - #endif + #if ${defines.USE_COLOR_ALPHA} + @location(${defines.vColorOutLocation}) vColor: vec4, + #elif ${defines.USE_COLOR || defines.USE_INSTANCING_COLOR} + @location(${defines.vColorOutLocation}) vColor: vec3, + #endif - #if ${e.USE_SKINNING} - - bindMatrix:mat4x4, - - bindMatrixInverse:mat4x4, - - boneTextureSize:u32, - #endif + #if ${defines.USE_TANGENT} + @location(${defines.vTangentOutLocation}) vTangent: vec3, + @location(${defines.vBitangentOutLocation}) vBitangent: vec3, + #endif + }; + struct GlobalUniform { + projectionMatrix: mat4x4, + viewMatrix: mat4x4, + inverseViewMatrix: mat4x4, + cameraPosition: vec3, + }; - #if ${e.USE_NORMALTEXTURE} - normalScale:vec2, - #endif - - #if ${e.IOR} - ior:f32, - #endif - - #if ${e.USE_CLEARCOAT} - - #if ${e.USE_CLEARCOAT_NORMALTEXTURE} - clearcoatNormalScale:vec2, - #endif - - clearcoat:f32, - - clearcoatRoughness:f32, - #endif - - #if ${e.USE_IRIDESCENCE} - iridescence:f32, - - iridescenceIOR:f32, - - iridescenceThicknessMinimum:f32, - - iridescenceThicknessMaximum:f32, - - #endif + //texture and sampler + // @group(0) @binding(${defines.samplerBinding}) var baseSampler: sampler; + #if ${defines.USE_SKINNING} + //uniform highp sampler2D boneTexture; + @group(0) @binding(${defines.boneTextureBinding}) var boneTexture: texture_2d; + #endif - #if ${e.USE_AOTEXTURE} - aoTextureIntensity:f32, - #endif + #if ${defines.USE_DISPLACEMENTTEXTURE} + //uniform sampler2D displacementMap; + @group(0) @binding(${defines.displacementTextureBinding}) var displacementMap: texture_2d; + #endif - #if ${e.USE_LIGHTTEXTURE} - lightTextureIntensity:f32, - #endif - - #if ${e.USE_ENVTEXTURE} - envTextureIntensity:f32, - - flipEnvTexture:f32, - #endif + #if ${defines.MORPHTARGETS_TEXTURE} + //uniform sampler2DArray morphTargetsTexture; + @group(0) @binding(${defines.morphTargetsTextureBinding}) var morphTargetsTexture: texture_2d_array; + #endif - #if ${e.USE_BUMPTEXTURE} - bumpScale:f32; - #endif + struct VertexInput { + @location(0) position: vec3, - #if ${e.USE_DISPLACEMENTTEXTURE} - - displacementScale:f32, - - displacementBias:f32, - #endif - - #if ${e.USE_MORPHTARGETS} - - morphTargetBaseInfluence:f32, - - #if ${e.MORPHTARGETS_TEXTURE} - - morphTargetsTextureSize:vec2, - - MORPHTARGETS_COUNT:u32, - - #endif - - morphTargetInfluences:array, - - #endif - } + @location(1) normal: vec3, - `; - }, - pbrFunction: function (e) { - return Di` + @location(2) uv: vec2, + #if ${defines.USE_LIGHTTEXTURE || defines.USE_AOTEXTURE} + @location(${defines.uv2Location}) uv2:vec2, + #endif + #if ${defines.USE_INSTANCING} + @location(${defines.instanceMatrixLocation}) instanceMatrix:mat4x4, + #endif + #if ${defines.USE_INSTANCING_COLOR} + @location(${defines.instanceColorLocation}) instanceColor:vec3, + #endif + + #if ${defines.USE_TANGENT} + @location(${defines.tangentLocation}) tangent:vec4, + #endif + #if ${defines.USE_COLOR_ALPHA} + @location(${defines.colorLocation}) color:vec4, + #elif ${defines.USE_COLOR} + @location(${defines.colorLocation}) color:vec3, + #endif - #if ${e.DITHERING} - fn dithering(color:vec3 )->vec3 { - let grid_position:f32 = rand( gl_FragCoord.xy ); - let dither_shift_RGB:vec3 = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 ); - dither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position ); - return color + dither_shift_RGB; - } - #endif + #if ${defines.USE_MORPHTARGETS && !defines.MORPHTARGETS_TEXTURE} + @location(${defines.morphTarget0Location}) morphTarget0:vec3, - #if ${e.USE_IRIDESCENCE} - fn BRDF_GGX_Iridescence( lightDir:vec3, viewDir:vec3,normal:vec3, f0:vec3, f90:f32,iridescence:f32, iridescenceFresnel:vec3,roughness:f32 )->vec3 { - let alpha:f32 = pow2( roughness ); - let halfDir:vec3 = normalize( lightDir + viewDir ); - let dotNL:f32 = saturate( dot( normal, lightDir ) ); - let dotNV:f32 = saturate( dot( normal, viewDir ) ); - let dotNH:f32 = saturate( dot( normal, halfDir ) ); - let dotVH:f32 = saturate( dot( viewDir, halfDir ) ); - let F:vec3 = mix( F_Schlick( f0, f90, dotVH ), iridescenceFresnel, iridescence ); - let V:f32 = V_GGX_SmithCorrelated( alpha, dotNL, dotNV ); - let D:f32 = D_GGX( alpha, dotNH ); - return F * ( V * D ); - } - #endif + @location(${defines.morphTarget1Location}) morphTarget1:vec3, - #if ${e.USE_SHEEN} - fn D_Charlie( roughness:f32,dotNH:f32 )->f32 { - let alpha:f32 = pow2( roughness ); - let invAlpha:f32 = 1.0 / alpha; - let cos2h:f32 = dotNH * dotNH; - let sin2h:f32 = max( 1.0 - cos2h, 0.0078125 ); - return ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI ); - } - fn V_Neubelt( dotNV:f32, dotNL:f32 )->f32 { - return saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) ); + @location(${defines.morphTarget2Location}) morphTarget2:vec3, + + @location(${defines.morphTarget3Location}) morphTarget3:vec3, + #if ${defines.USE_MORPHNORMALS} + @location(${defines.morphNormal0Location}) morphNormal0:vec3, + + @location(${defines.morphNormal1Location}) morphNormal1:vec3, + + @location(${defines.morphNormal2Location}) morphNormal2:vec3, + + @location(${defines.morphNormal3Location}) morphNormal3:vec3, + #else + @location(${defines.morphTarget4Location}) morphTarget4:vec3, + + @location(${defines.morphTarget5Location}) morphTarget5:vec3, + + @location(${defines.morphTarget6Location}) morphTarget6:vec3, + + @location(${defines.morphTarget7Location}) morphTarget7:vec3, + #endif + #endif + #if ${defines.USE_SKINNING} + @location(${defines.skinIndexLocation}) skinIndex:vec4, + @location(${defines.skinWeightLocation}) skinWeight:vec4, + #endif + } + + #if ${defines.MORPHTARGETS_TEXTURE} + fn getMorph( vertexIndex:u32, morphTargetIndex:u32,offset:u32 )->vec4 { + let texelIndex:u32 = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset; + let y:u32 = texelIndex / materialUniform.morphTargetsTextureSize.x; + let x:u32 = texelIndex - y * materialUniform.morphTargetsTextureSize.x; + let morphUV:vec3 = vec3( x, y, morphTargetIndex ); + //textureLoad + //return texelFetch( morphTargetsTexture, morphUV, 0 ); + return textureLoad( morphTargetsTexture, morphUV, 0 ); } - fn BRDF_Sheen(lightDir:vec3, viewDir:vec3, normal:vec3,sheenColor:vec3,sheenRoughness:f32 )->vec3 { - let halfDir:vec3 = normalize( lightDir + viewDir ); - let dotNL:f32 = saturate( dot( normal, lightDir ) ); - let dotNV:f32 = saturate( dot( normal, viewDir ) ); - let dotNH:f32 = saturate( dot( normal, halfDir ) ); - let D:f32 = D_Charlie( sheenRoughness, dotNH ); - let V:f32 = V_Neubelt( dotNV, dotNL ); - return sheenColor * ( D * V ); + #endif + #if ${defines.USE_SKINNING} + fn getBoneMatrix( i:f32 )->mat4x4 { + let j:f32 = i * 4.0; + let x:f32 = j%f32( materialUniform.boneTextureSize ); + let y:f32 = floor( j / f32( materialUniform.boneTextureSize ) ); + let dx:f32 = 1.0 / f32( materialUniform.boneTextureSize ); + let dy:f32 = 1.0 / f32( materialUniform.boneTextureSize ); + y = dy * ( y + 0.5 ); + + let v1:vec4 = textureSample(boneTexture, baseSampler, vec2( dx * ( x + 0.5 ), y ) ); + let v2:vec4 = textureSample(boneTexture, baseSampler, vec2( dx * ( x + 1.5 ), y ) ); + let v3:vec4 = textureSample(boneTexture, baseSampler, vec2( dx * ( x + 2.5 ), y ) ); + let v4:vec4 = textureSample(boneTexture, baseSampler, vec2( dx * ( x + 3.5 ), y ) ); + let bone:mat4x4 = mat4x4( v1, v2, v3, v4 ); + return bone; } #endif - #if ${e.USE_IRIDESCENCE} - let XYZ_TO_REC709: mat3x3 = mat3x3( - 3.2404542, -0.9692660, 0.0556434, -1.5371385, 1.8760108, -0.2040259, -0.4985314, 0.0415560, 1.0572252 - ); - fn Fresnel0ToIor( fresnel0:vec3 )->vec3 { - let sqrtF0:vec3 = sqrt( fresnel0 ); - return ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 ); - } - fn IorToFresnel0(transmittedIor:vec3,incidentIor:f32 )->vec3 { - return pow2Vector( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) ); - } - fn IorToFresnel0(transmittedIor:f32, incidentIor:f32 )->f32 { - return pow2Vector( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor )); - } - fn evalSensitivity(OPD:f32,shift:vec3 )->vec3 { - let phase:f32 = 2.0 * PI * OPD * 1.0e-9; - let val:vec3 = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 ); - let pos:vec3 = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 ); - let vart:vec3 = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 ); - let xyz:vec3 = val * sqrt( 2.0 * PI * vart ) * cos( pos * phase + shift ) * exp( - pow2( phase ) * vart ); - xyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[ 0 ] ) * exp( - 4.5282e+09 * pow2( phase ) ); - xyz /= 1.0685e-7; - let rgb:vec3 = XYZ_TO_REC709 * xyz; - return rgb; - } - fn evalIridescence(outsideIOR:f32, eta2:f32,cosTheta1:f32,thinFilmThickness:f32,baseF0:vec3 )->vec3 { - var I:vec3; - let iridescenceIOR:f32 = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) ); - let sinTheta2Sq:f32 = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) ); - let cosTheta2Sq:f32 = 1.0 - sinTheta2Sq; - if ( cosTheta2Sq < 0.0 ) { - return vec3( 1.0 ); + @binding(0) @group(0) var materialUniform : MaterialUniform; + @binding(0) @group(1) var globalUniform : GlobalUniform; + @vertex + fn main(input:VertexInput)->VertexOutput { + var vertexOutput:VertexOutput; + #if ${defines.USE_TEXTURE} + vertexOutput.vUv = input.uv; + #endif + #if ${defines.USE_LIGHTTEXTURE || defines.USE_AOTEXTURE} + vertexOutput.vUv2 input.uv2; + #endif + #if ${defines.USE_COLOR_ALPHA} + vertexOutput.vColor = vec4( 1.0 ); + #elif ${defines.USE_COLOR || defines.USE_INSTANCING_COLOR} + vertexOutput.vColor = vec3( 1.0 ); + #endif + #if ${defines.USE_COLOR} + vertexOutput.vColor *= input.color; + #endif + #if ${defines.USE_INSTANCING_COLOR} + vertexOutput.vColor.xyz *= input.instanceColor.xyz; + #endif + #if ${defines.USE_MORPHCOLORS && defines.MORPHTARGETS_TEXTURE} + vertexOutput.vColor *= materialUniform.morphTargetBaseInfluence; + for (let i : u32 = 0u; i < materialUniform.MORPHTARGETS_COUNT; i = i + 1u ) { + #if ${defines.USE_COLOR_ALPHA} + if ( materialUniform.morphTargetInfluences[ i ] ! = 0.0 ) vertexOutput.vColor += getMorph( gl_VertexID, i, 2 ) * materialUniform.morphTargetInfluences[ i ]; + #elif ${defines.USE_COLOR} + if ( materialUniform.morphTargetInfluences[ i ] ! = 0.0 ) vertexOutput.vColor += getMorph( gl_VertexID, i, 2 ).rgb * materialUniform.morphTargetInfluences[ i ]; + #endif } - let cosTheta2:f32 = sqrt( cosTheta2Sq ); - let R0:f32 = IorToFresnel0( iridescenceIOR, outsideIOR ); - let R12:f32 = F_Schlick( R0, 1.0, cosTheta1 ); - let R21:f32 = R12; - let T121:f32 = 1.0 - R12; - let phi12:f32 = 0.0; - if ( iridescenceIOR < outsideIOR ) phi12 = PI; - let phi21:f32 = PI - phi12; - let baseIOR:vec3 = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) ); - let R1:vec3 = IorToFresnel0( baseIOR, iridescenceIOR ); - let R23:vec3 = F_Schlick( R1, 1.0, cosTheta2 ); - let phi23:vec3 = vec3( 0.0 ); - if ( baseIOR[ 0 ] < iridescenceIOR ) phi23[ 0 ] = PI; - if ( baseIOR[ 1 ] < iridescenceIOR ) phi23[ 1 ] = PI; - if ( baseIOR[ 2 ] < iridescenceIOR ) phi23[ 2 ] = PI; - let OPD:f32 = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2; - let phi:vec3 = vec3( phi21 ) + phi23; - let R123:vec3 = clamp( R12 * R23, 1e-5, 0.9999 ); - let r123:vec3 = sqrt( R123 ); - let Rs:vec3 = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 ); - let C0:vec3 = R12 + Rs; - I = C0; - let Cm:vec3 = Rs - T121; - for ( let m : u32 = 1;m <= 2; ++ m ) { - Cm *= r123; - Sm:vec3 = 2.0 * evalSensitivity( f32( m ) * OPD, f32( m ) * phi ); - I += Cm * Sm; - } - return max( I, vec3( 0.0 ) ); - } + #endif + var objectNormal:vec3 = vec3(input.normal); + #if ${defines.USE_TANGENT} + let objectTangent:vec3 = vec3( input.tangent.xyz ); + #endif + #if ${defines.USE_MORPHNORMALS} + objectNormal *= materialUniform.morphTargetBaseInfluence; + #if ${defines.MORPHTARGETS_TEXTURE} + for ( let i : u32 = 0u; i < materialUniform.MORPHTARGETS_COUNT; i = i + 1u) { + if ( materialUniform.morphTargetInfluences[ i ] ! = 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * materialUniform.morphTargetInfluences[ i ]; + } + #else + objectNormal += morphNormal0 * materialUniform.morphTargetInfluences[ 0 ]; + objectNormal += morphNormal1 * materialUniform.morphTargetInfluences[ 1 ]; + objectNormal += morphNormal2 * materialUniform.morphTargetInfluences[ 2 ]; + objectNormal += morphNormal3 * materialUniform.morphTargetInfluences[ 3 ]; + #endif + #endif + #if ${defines.USE_SKINNING} + let boneMatX:mat4x4 = getBoneMatrix( input.skinIndex.x ); + let boneMatY:mat4x4 = getBoneMatrix( input.skinIndex.y ); + let boneMatZ:mat4x4 = getBoneMatrix( input.skinIndex.z ); + let boneMatW:mat4x4 = getBoneMatrix( input.skinIndex.w ); + #endif + #if ${defines.USE_SKINNING} + let skinMatrix:mat4x4 = mat4x4( 0.0 ); + skinMatrix += input.skinWeight.x * boneMatX; + skinMatrix += input.skinWeight.y * boneMatY; + skinMatrix += input.skinWeight.z * boneMatZ; + skinMatrix += input.skinWeight.w * boneMatW; + skinMatrix = materialUniform.bindMatrixInverse * skinMatrix * materialUniform.bindMatrix; + objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz; + #if ${defines.USE_TANGENT} + objectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz; + #endif + #endif + var transformedNormal:vec3 = objectNormal; + // transformedNormal+=vec3(0.0); + #if ${defines.USE_INSTANCING} + let m:mat3x3 = mat3x3( input.instanceMatrix ); + transformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) ); + transformedNormal = m * transformedNormal; + #endif + transformedNormal = materialUniform.normalMatrix * transformedNormal; + #if ${defines.FLIP_SIDED} + transformedNormal = - transformedNormal; + #endif + #if ${defines.USE_TANGENT} + let transformedTangent:vec3 = (globalUniform.viewMatrix*materialUniform.modelMatrix * vec4( objectTangent, 0.0 ) ).xyz; + #if ${defines.FLIP_SIDED} + transformedTangent = - transformedTangent; + #endif + #endif + vertexOutput.vNormal = normalize( transformedNormal ); + #if ${defines.FLAT_SHADED} + #if ${defines.USE_TANGENT} + vTangent = normalize( transformedTangent ); + vBitangent = normalize( cross( vNormal, vTangent ) * input.tangent.w ); + #endif + #endif + let transformed:vec3 = vec3( input.position ); + #if ${defines.USE_MORPHTARGETS} + transformed *= materialUniform.morphTargetBaseInfluence; + #if ${defines.MORPHTARGETS_TEXTURE} + for ( let i : u32 = 0u; i < materialUniform.MORPHTARGETS_COUNT; i = i + 1u ) { + if ( materialUniform.morphTargetInfluences[ i ] ! = 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ]; + } + #else + transformed += input.morphTarget0 * materialUniform.morphTargetInfluences[ 0 ]; + transformed += input.morphTarget1 * materialUniform.morphTargetInfluences[ 1 ]; + transformed += input.morphTarget2 * materialUniform.morphTargetInfluences[ 2 ]; + transformed += input.morphTarget3 * materialUniform.morphTargetInfluences[ 3 ]; + #if ${defines.USE_MORPHNORMALS} + transformed += input.morphTarget4 * materialUniform.morphTargetInfluences[ 4 ]; + transformed += input.morphTarget5 * materialUniform.morphTargetInfluences[ 5 ]; + transformed += input.morphTarget6 * materialUniform.morphTargetInfluences[ 6 ]; + transformed += input.morphTarget7 * materialUniform.morphTargetInfluences[ 7 ]; + #endif + #endif + #endif + #if ${defines.USE_SKINNING} + let skinVertex:vec4 = materialUniform.bindMatrix * vec4( transformed, 1.0 ); + let skinned:vec4 = vec4( 0.0 ); + skinned += boneMatX * skinVertex * input.skinWeight.x; + skinned += boneMatY * skinVertex * input.skinWeight.y; + skinned += boneMatZ * skinVertex * input.skinWeight.z; + skinned += boneMatW * skinVertex * input.skinWeight.w; + transformed = ( materialUniform.bindMatrixInverse * skinned ).xyz; + #endif + #if ${defines.USE_DISPLACEMENTTEXTURE} + transformed += normalize( objectNormal ) * (textureSample(displacementMap, baseSampler, vUv).x * materialUniform.displacementScale + materialUniform.displacementBias ); + #endif + var mvPosition:vec4 = vec4( transformed, 1.0 ); + #if ${defines.USE_INSTANCING} + mvPosition = input.instanceMatrix * mvPosition; + #endif + mvPosition = globalUniform.viewMatrix*materialUniform.modelMatrix * mvPosition; + vertexOutput.position = globalUniform.projectionMatrix * mvPosition; + vertexOutput.vViewPosition = - mvPosition.xyz/mvPosition.w; + #if ${defines.USE_ENVTEXTURE || defines.DISTANCE || defines.USE_TRANSMISSION} + var worldPosition:vec4 = vec4( transformed, 1.0 ); + #if ${defines.USE_INSTANCING} + worldPosition = input.instanceMatrix * worldPosition; + #endif + worldPosition = materialUniform.modelMatrix * worldPosition; + #endif + #if ${defines.USE_TRANSMISSION} + vertexOutput.vWorldPosition = worldPosition.xyz; + #endif + return vertexOutput; + } + `; +} + +function phongFrag(defines) { + return wgslParseDefines` + struct MaterialUniform { + modelMatrix: mat4x4, + color: vec3, + opacity:f32, + normalMatrix: mat4x4, + emissive:vec3, + shininess:f32, + specular:vec3, + } + #include + #include + #include + #include + @binding(${defines.phongBinding}) @group(0) var materialUniform : MaterialUniform; + @binding(${defines.cameraBinding}) @group(1) var systemUniform : SystemUniform; + @fragment + fn main(input:FragInput) -> @location(0) vec4 { + var totalEmissiveRadiance:vec3 = materialUniform.emissive; + var color:vec4; + #if${defines.USE_COLORTEXTURE} + color= vec4(textureSample(baseColorTexture, baseColorSampler, input.uv).rgb+materialUniform.color,materialUniform.opacity); + #else + color=vec4(materialUniform.color,materialUniform.opacity); + #endif + let V:vec3 = normalize( systemUniform.cameraPosition - input.worldPos); + #if ${defines.USE_NORMALTEXTURE} + let N:vec3 = getNormalByNormalTexture(input); + #else + let N:vec3 = getNormal(input); + #endif + var geometry:Geometry; + geometry.normal=N; + geometry.viewDir=V; + geometry.position=input.worldPos; + let lightColor:ReflectedLight=parseLights(geometry,materialUniform.shininess); + // var finnalColor:vec3=color.xyz + (lightColor.directDiffuse + lightColor.directSpecular + lightColor.ambient); + var finnalColor:vec3=color.xyz * (lightColor.directDiffuse + lightColor.directSpecular + lightColor.ambient); + + // finnalColor = lightColor.testColor.xyz; + + return vec4(finnalColor,color.a); + }`; +} + +function phongVert(defines) { + return wgslParseDefines` + struct MaterialUniform { + modelMatrix: mat4x4, + color: vec3, + opacity:f32, + normalMatrix: mat4x4, + emissive:vec3, + specular:vec3, + shininess:f32, + } + #include + #include + #include + @binding(${defines.phongBinding}) @group(0) var selfUniform : MaterialUniform; + @binding(${defines.cameraBinding}) @group(1) var systemUniform : SystemUniform; + @vertex + fn main(input: VertexInput) -> VertexOutput { + var output: VertexOutput; + #if ${defines.HAS_UV} + output.uv = input.uv; + #endif + let modelPos=selfUniform.modelMatrix *vec4(input.position,1.0); + output.worldPos = modelPos.xyz/modelPos.w; + let vNormalView = selfUniform.normalMatrix * vec4(input.normal,0.0); + output.normal = vNormalView.xyz; + output.view = systemUniform.cameraPosition.xyz - modelPos.xyz; + let viewPosition=systemUniform.viewMatrix * modelPos; + output.viewPosition = -viewPosition.xyz; + output.position = systemUniform.projectionMatrix * systemUniform.viewMatrix * modelPos; + return output; + }`; +} + +function point_fs(defines) { + return wgslParseDefines` + #include + struct SelfUniform { + modelMatrix: mat4x4, + color:vec3, + size:f32, + opacity:f32, + } + @binding(${defines.pointBinding}) @group(0) var selfUniform : SelfUniform; + #if${defines.USE_COLORTEXTURE} + @group(0) @binding(${defines.baseColorSamplerBinding}) var baseColorSampler: sampler; + @group(0) @binding(${defines.baseColorTextureBinding}) var baseColorTexture: texture_2d; + #endif + @fragment + fn main(input:PointFragInput) -> @location(0) vec4 { + var color:vec4=vec4(selfUniform.color,selfUniform.opacity); + #if${defines.USE_COLORTEXTURE} + color=textureSample(baseColorTexture, baseColorSampler, input.uv); #endif - const clearcoatSpecular:vec3 = vec3( 0.0 ); - const sheenSpecular:vec3 = vec3( 0.0 ); + #if${defines.HAS_COLOR} + color=vec4(input.color,selfUniform.opacity); + #endif + return color; + } + `; +} - fn IBLSheenBRDF( normal:vec3, viewDir:vec3, roughness:f32 )->f32 { - let dotNV:f32 = saturate( dot( normal, viewDir ) ); - let r2:f32 = roughness * roughness; - let a:f32 =select(-8.48 * r2 + 14.3 * roughness - 9.95,-339.2 * r2 + 161.4 * roughness - 25.9,roughness < 0.25); - //let a:f32 = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95; - let b:f32=select(1.97 * r2 - 3.27 * roughness + 0.72,44.0 * r2 - 23.7 * roughness + 3.26, roughness < 0.25); - //let b:f32 = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72; - //let DG:f32 = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) ); - let DG:f32 = exp( a * dotNV + b ) + select(0.1 * ( roughness - 0.25 ),0.0,roughness < 0.25); - return saturate( DG * RECIPROCAL_PI ); - } - fn DFGApprox( specularColor:vec3, roughness:f32,dotNV:f32 )->vec3 { - const c0:vec4 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); - let c1:vec4 = vec4( 1, 0.0425, 1.04, - 0.04 ); - let r:vec4 = roughness * c0 + c1; - let a004:f32 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; - let fab:vec2 = vec2( - 1.04, 1.04 ) * a004 + r.zw; - return specularColor * fab.x + fab.y; +function point_vs(defines) { + return wgslParseDefines` + #include + #include + #include + struct SelfUniform { + modelMatrix: mat4x4, + color:vec3, + size:f32, + opacity:f32, } - fn EnvironmentBRDF( normal:vec3,viewDir:vec3,specularColor:vec3, specularF90:f32,roughness:f32 )->vec3 { - let fab:vec2 = DFGApprox( normal, viewDir, roughness ); - return specularColor * fab.x + specularF90 * fab.y; + @binding(${defines.pointBinding}) @group(0) var selfUniform : SelfUniform; + @binding(${defines.cameraBinding}) @group(1) var systemUniform : SystemUniform; + @vertex + fn main(input: PointVertInput) -> PointVertOutput { + var output:PointVertOutput; + let mvPosition:vec4= ystemUniform.viewMatrix *selfUniform.modelMatrix*vec4(0.0,0.0,0.0, 1.0 ); + #if ${defines.HAS_UV} + output.uv=input.uv; + #endif + #if ${defines.HAS_COLOR} + output.color=input.color; + #endif + #if ${defines.HAS_SIZE} + output.size=input.size; + #endif + vec2 alignedPosition = input.position.xy* selfUniform.size; + mvPosition.xy += alignedPosition; + output.position = systemUniform.projectionMatrix * mvPosition; + return output; + } + `; +} + +function quadFrag(defines) { + return ` + @group(0) @binding(1) var baseSampler: sampler; + @group(0) @binding(0) var colorTexture: texture_2d; + struct VertexOutput { + @builtin(position) position: vec4, + @location(0) uv: vec2, + }; + @fragment + fn main(input:VertexOutput) -> @location(0) vec4 { + return textureSample(colorTexture, baseSampler, vec2(input.uv.x,1.0-input.uv.y)); } + `; +} +function quadVert(defines) { + return ` + struct VertexInput { + @location(${defines.positionLocation}) position: vec2, + } + struct VertexOutput { + @builtin(position) position: vec4, + @location(0) uv: vec2, + }; + @vertex + fn main(input: VertexInput) -> VertexOutput { + var output:VertexOutput; + output.uv = input.position * 0.5 + 0.5; + output.position = vec4(input.position, 0.0, 1.0);; + return output; + } + `; +} - fn computeSpecularOcclusion( dotNV:f32, ambientOcclusion:f32, roughness:f32 )->f32 { - return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion ); +function skyBoxFrag(defines) { + return ` + fn lessThanEqual(a:vec3,b:vec3)->vec3{ + let xValue:f32=select(b.x,a.x,a.x<=b.x); + let yValue:f32=select(b.y,a.y,a.y<=b.y); + let zValue:f32=select(b.z,a.z,a.z<=b.z); + return vec3(xValue,yValue,zValue); + } + fn LinearTosRGB( value:vec4 )->vec4 { + return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a ); } - #if ${e.USE_TRANSMISSION} + struct FragmentInput { + @location(0) texCoord : vec3 + }; + @group(0) @binding(2) var defaultSampler: sampler; + @group(0) @binding(1) var skyboxTexture: texture_cube; + @fragment + fn main(input : FragmentInput) -> @location(0) vec4 { + let color = textureSample(skyboxTexture, defaultSampler, input.texCoord); + return LinearTosRGB(color); + } +`; +} + +function skyBoxVert(defines) { + return ` + struct SystemUniform { + projectionMatrix: mat4x4, + viewMatrix: mat4x4, + inverseViewMatrix: mat4x4, + cameraPosition: vec3, + }; + struct MaterialUniform { + modelMatrix: mat4x4, + } + @binding(${defines.skyboxBinding}) @group(0) var selfUniform : MaterialUniform; + @binding(${defines.cameraBinding}) @group(1) var systemUniform : SystemUniform; + struct VertexInput { + @location(${defines.positionLocation}) position : vec3, + }; + struct VertexOutput { + @builtin(position) position : vec4, + @location(0) texCoord : vec3, + }; + @vertex + fn main(input : VertexInput) -> VertexOutput { + var output : VertexOutput; + output.texCoord = input.position.xyz; + var modelView = systemUniform.viewMatrix; + // Drop the translation portion of the modelView matrix + modelView[3] = vec4(0.0, 0.0, 0.0, modelView[3].w); + output.position = systemUniform.projectionMatrix * modelView * vec4(input.position,1.0); + output.position = output.position.xyww; + return output; + } + `; +} + +function sprite_fs(defines) { + return wgslParseDefines` + #include + struct SelfUniform { + modelMatrix: mat4x4, + color:vec3, + rotation:f32, + center:vec2, + opacity:f32, + } + @binding(${defines.spriteBinding}) @group(0) var selfUniform : SelfUniform; + #if${defines.USE_COLORTEXTURE} + @group(0) @binding(${defines.baseColorSamplerBinding}) var baseColorSampler: sampler; + @group(0) @binding(${defines.baseColorTextureBinding}) var baseColorTexture: texture_2d; + #endif + @fragment + fn main(input:VertexOutput) -> @location(0) vec4 { + #if${defines.USE_COLORTEXTURE} + return textureSample(baseColorTexture, baseColorSampler, input.uv); + #else + return vec4(selfUniform.color,selfUniform.opacity); + #endif + } + `; +} + +function sprite_vs(defines) { + return wgslParseDefines` + + #include + #include + #include + struct SelfUniform { + modelMatrix: mat4x4, + color:vec3, + rotation:f32, + center:vec2, + opacity:f32, + } + @binding(${defines.spriteBinding}) @group(0) var selfUniform : SelfUniform; + @binding(${defines.cameraBinding}) @group(1) var systemUniform : SystemUniform; + @vertex + fn main(input: VertexInput) -> VertexOutput { + var output:VertexOutput; + var mvPosition:vec4= systemUniform.viewMatrix *selfUniform.modelMatrix*vec4(0.0,0.0,0.0,1.0); + #if ${defines.HAS_UV} + output.uv=input.uv; + #endif + var scale:vec2; + scale.x = length(vec3(selfUniform.modelMatrix[0].x, selfUniform.modelMatrix[0].y, selfUniform.modelMatrix[0].z)); + scale.y = length(vec3(selfUniform.modelMatrix[1].x, selfUniform.modelMatrix[1].y, selfUniform.modelMatrix[1].z)); + // scale *= - mvPosition.z; + var alignedPosition:vec2 =(input.position.xy- (selfUniform.center - vec2(0.5,0.5))) * scale; + let rotatedPositionX = cos(selfUniform.rotation) * alignedPosition.x - sin( selfUniform.rotation ) * alignedPosition.y; + let rotatedPositionY = sin(selfUniform.rotation) * alignedPosition.x + cos( selfUniform.rotation ) * alignedPosition.y; + var rotatedPosition=vec2(rotatedPositionX,rotatedPositionY); + let newPoint =mvPosition.xy+ rotatedPosition; + output.position = systemUniform.projectionMatrix * vec4(newPoint.x,newPoint.y,mvPosition.z,mvPosition.w); + return output; + } + `; +} + +function blendFrag(defines) { + return ` + struct FragInput { + @location(0) uv: vec2, + }; + @group(0) @binding({{tDiffuseBinding}}) var tDiffuse: texture_2d; + @group(0) @binding({{baseColorTextureBinding}}) var baseColorTexture: texture_2d; + @group(0) @binding({{tSamplerBinding}}) var tSampler: sampler; + @fragment + fn main(input:FragInput) -> @location(0) vec4 { + let postColor:vec4 = textureSample(tDiffuse, tSampler, input.uv); + let baseColor:vec4 = textureSample(baseColorTexture, tSampler, input.uv); + return baseColor+postColor; + } + `; +} - fn getVolumeTransmissionRay( n:vec3, v:vec3, thickness:f32, ior:f32, modelMatrix:mat4x4:f32)->vec3 { - var refractionVector:vec3 = refract( - v, normalize( n ), 1.0 / ior ); - var modelScale:vec3; - modelScale.x = length( vec3( modelMatrix[0].xyz ) ); - modelScale.y = length( vec3( modelMatrix[1].xyz ) ); - modelScale.z = length( vec3( modelMatrix[2].xyz ) ); - return normalize( refractionVector ) * thickness * modelScale; +function Blur(defines) { + return ` + struct FragInput { + @location(0) uv: vec2, } - fn applyIorToRoughness(roughness:f32, ior:f32 )->f32 { - return roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 ); + struct BlurUniforms { + direction:vec2, } - fn getTransmissionSample( fragCoord:vec2, roughness:f32,ior:f32 )->vec4 { - let framebufferLod:f32 = log2( materialUniform.transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior ); - return textureSampleLevel(transmissionSamplerTexture,baseSampler,fragCoord.xy, framebufferLod); - + fn gaussianPdf(x:f32, sigma:f32)->f32 { + return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma; } - fn applyVolumeAttenuation( radiance:vec3, transmissionDistance:f32,attenuationColor:vec3,attenuationDistance:f32 )->vec3 { - if ( isinf( attenuationDistance ) ) { - return radiance; - } - else { - let attenuationCoefficient:vec3 = -log( attenuationColor ) / attenuationDistance; - let transmittance:vec3 = exp( - attenuationCoefficient * transmissionDistance ); - return transmittance * radiance; + @group(0) @binding(0) var blurUniforms : BlurUniforms; + @group(0) @binding({{tDiffuseBinding}}) var tDiffuse: texture_2d; + @group(0) @binding({{tSamplerBinding}}) var tSampler: sampler; + @fragment + fn main(input:FragInput) -> @location(0) vec4 { + let invSize:vec2 = vec2(1.0,1.0) / vec2(textureDimensions(tDiffuse)); + let fSigma:f32 =f32(${defines.SIGMA}); + var weightSum:f32 = gaussianPdf(0.0, fSigma); + let baseColor=textureSample(tDiffuse, tSampler, input.uv); + var diffuseSum:vec3 = baseColor.rgb * weightSum; + let uvOffset:vec2 = blurUniforms.direction * invSize; + for( var i : u32 = 1; i < ${defines.KERNEL_RADIUS};i = i + 1 ) { + let x:f32 = f32(i); + let w:f32 = gaussianPdf(x, fSigma); + let sample1:vec3=textureSample(tDiffuse, tSampler, input.uv+ uvOffset*x).rgb; + let sample2:vec3=textureSample(tDiffuse, tSampler, input.uv- uvOffset*x).rgb; + diffuseSum =diffuseSum+ (sample2+sample2)* w; + weightSum += 2.0 * w; } - - } - fn getIBLVolumeRefraction( n:vec3,v:vec3, roughness:f32, diffuseColor:vec3,specularColor:vec3, specularF90:f32,position:vec3, modelMatrix:mat4x4, viewMatrix:mat4x4,projMatrix:mat4x4,ior:f32, thickness:f32,attenuationColor:vec3,attenuationDistance:f32 )->vec4 { - let transmissionRay:vec3 = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix ); - let refractedRayExit:vec3 = position + transmissionRay; - let ndcPos:vec4 = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 ); - let refractionCoords:vec2 = ndcPos.xy / ndcPos.w; - refractionCoords += 1.0; - refractionCoords /= 2.0; - let transmittedLight:vec4 = getTransmissionSample( refractionCoords, roughness, ior ); - let attenuatedColor:vec3 = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance ); - let F:vec3 = EnvironmentBRDF( n, v, specularColor, specularF90, roughness ); - return vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a ); + diffuseSum/=weightSum; + return vec4(diffuseSum,baseColor.a); } - #endif - - #if ${e.USE_BUMPTEXTURE} - fn dHdxy_fwd()->vec2 { - let dSTdx:vec2 = dpdx( vUv ); - let dSTdy:vec2 = dpdy( vUv ); - - let Hll:f32 = materialUniform.bumpScale * textureSample(bumpTexture, baseSampler, vUv).x; - let dBx:f32 = materialUniform.bumpScale * textureSample(bumpTexture, baseSampler, vUv + dSTdx).x - Hll; - let dBy:f32 = materialUniform.bumpScale * textureSample(bumpTexture, baseSampler, vUv + dSTdy).x - Hll; - return vec2( dBx, dBy ); - } - fn perturbNormalArb( surf_pos:vec3, surf_norm:vec3, dHdxy:vec2, faceDirection:f32 )->vec3 { - let vSigmaX:vec3 = dpdx( surf_pos.xyz ); - let vSigmaY:vec3 = dpdy( surf_pos.xyz ); - let vN:vec3 = surf_norm; - let R1:vec3 = cross( vSigmaY, vN ); - let R2:vec3 = cross( vN, vSigmaX ); - let fDet:f32 = dot( vSigmaX, R1 ) * faceDirection; - let vGrad:vec3 = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 ); - return normalize( abs( fDet ) * surf_norm - vGrad ); - } - #endif + `; +} - //! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALTEXTURE ) || defined ( USE_CLEARCOAT_NORMALTEXTURE ) ) - #if ${(!e.USE_TANGENT && e.TANGENTSPACE_NORMALTEXTURE) || e.USE_CLEARCOAT_NORMALTEXTURE} - fn perturbNormal2Arb( eye_pos:vec3, surf_norm:vec3, textureN:vec3, faceDirection:f32 )->vec3 { - let q0:vec3 = dpdx( eye_pos.xyz ); - let q1:vec3 = dpdy( eye_pos.xyz ); - let st0:vec2 = dpdx( vUv.st ); - let st1:vec2 = dpdy( vUv.st ); - let N:vec3 = surf_norm; - let q1perp:vec3 = cross( q1, N ); - let q0perp:vec3 = cross( N, q0 ); - let T:vec3 = q1perp * st0.x + q0perp * st1.x; - let B:vec3 = q1perp * st0.y + q0perp * st1.y; - let det:f32 = max( dot( T, T ), dot( B, B ) ); - let scale:f32 = ( det == 0.0 ) ? 0.0 : faceDirection * inversesqrt( det ); - return normalize( T * ( textureN.x * scale ) + B * ( textureN.y * scale ) + N * textureN.z ); - } - #endif - struct MultiAndSingleScatter{ - multiScatter:vec3, - singleScatter:vec3 +function LuminosityHigh(defines) { + return ` + struct LuminosityUniforms{ + luminosityThreshold:f32, + smoothWidth:f32, + defaultColor:vec3, + defaultOpacity:f32, } - #if ${e.USE_IRIDESCENCE} - ////////inout vec3 singleScatter, inout vec3 multiScatter - fn computeMultiscatteringIridescence( normal:vec3, viewDir:vec3, specularColor:vec3, specularF90:f32, iridescence:f32,iridescenceF0:vec3, roughness:f32 )->MultiAndSingleScatter { - #else - ////////inout vec3 singleScatter, inout vec3 multiScatter - fn computeMultiscattering( normal:vec3,viewDir:vec3, specularColor:vec3, specularF90:f32, roughness:f32)->MultiAndSingleScatter { - #endif - let fab:vec2 = DFGApprox( normal, viewDir, roughness ); - - var multiAndSingleScatter:MultiAndSingleScatter; - - #if ${e.USE_IRIDESCENCE} - let Fr:vec3 = mix( specularColor, iridescenceF0, iridescence ); - #else - let Fr:vec3 = specularColor; - #endif - let FssEss:vec3 = Fr * fab.x + specularF90 * fab.y; - let Ess:f32 = fab.x + fab.y; - let Ems:f32 = 1.0 - Ess; - let Favg:vec3 = Fr + ( 1.0 - Fr ) * 0.047619; - let Fms:vec3 = FssEss * Favg / ( 1.0 - Ems * Favg ); - // singleScatter += FssEss; - // multiScatter += Fms * Ems; - multiAndSingleScatter.multiScatter=Fms * Ems; - multiAndSingleScatter.singleScatter=FssEss; - return multiAndSingleScatter; - } - //直接光照 - fn RE_Direct_Physical( directLight:IncidentLight, geometry:GeometricContext, material:PhysicalMaterial)->ReflectedLight { - var reflectedLight:ReflectedLight; - let dotNL:f32 = saturate(dot( geometry.normal, directLight.direction)); - let irradiance:vec3 = dotNL * directLight.color; - #if ${e.USE_CLEARCOAT} - let dotNLcc:f32 = saturate( dot( geometry.clearcoatNormal, directLight.direction ) ); - let ccIrradiance:vec3 = dotNLcc * directLight.color; - clearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness ); - #endif - - #if ${e.USE_SHEEN} - sheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness ); - #endif + struct FragInput { + @location(0) uv: vec2, + }; + @group(0) @binding(0) var luminosityUniforms : LuminosityUniforms; + @group(0) @binding({{tDiffuseBinding}}) var tDiffuse: texture_2d; + @group(0) @binding({{tSamplerBinding}}) var tSampler: sampler; + @fragment + fn main(input:FragInput)-> @location(0) vec4 { - #if ${e.USE_IRIDESCENCE} - reflectedLight.directSpecular = irradiance * BRDF_GGX_Iridescence( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness ); - #else - reflectedLight.directSpecular = irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness ); - #endif - reflectedLight.directDiffuse = irradiance * BRDF_Lambert( material.diffuseColor ); - return reflectedLight; - } - //间接光照 - fn RE_IndirectDiffuse_Physical( irradiance:vec3, geometry:GeometricContext, material:PhysicalMaterial )->ReflectedLight { - var reflectedLight:ReflectedLight; - reflectedLight.indirectDiffuse = irradiance * BRDF_Lambert( material.diffuseColor ); - return reflectedLight; - } - //间接高光 - fn RE_IndirectSpecular_Physical( radiance:vec3, irradiance:vec3, clearcoatRadiance:vec3, geometry:GeometricContext, material:PhysicalMaterial)->ReflectedLight { - var reflectedLight:ReflectedLight; - #if ${e.USE_CLEARCOAT} - clearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness ); - #endif - #if ${e.USE_SHEEN} - sheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness ); - #endif - var singleScattering:vec3; - var multiScattering:vec3; - let cosineWeightedIrradiance:vec3 = irradiance * RECIPROCAL_PI; - var tempMultiAndSingleScatter:MultiAndSingleScatter; - #if ${e.USE_IRIDESCENCE} - tempMultiAndSingleScatter=computeMultiscatteringIridescence( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness ); - #else - tempMultiAndSingleScatter= computeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness ); - #endif - singleScattering=tempMultiAndSingleScatter.singleScatter; - multiScattering=tempMultiAndSingleScatter.multiScatter; - let totalScattering:vec3 = singleScattering + multiScattering; - let diffuse:vec3 = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) ); - reflectedLight.indirectSpecular = radiance * singleScattering; - reflectedLight.indirectSpecular = multiScattering * cosineWeightedIrradiance; - reflectedLight.indirectDiffuse = diffuse * cosineWeightedIrradiance; - return reflectedLight; - } - `; - }, - pbrTexture: function (e) { - return Di` - #if ${e.USE_BUMPTEXTURE} - @group(0) @binding(${e.bumpTextureBinding}) var bumpTexture: texture_2d; - #endif - #if ${e.USE_TRANSMISSION} - #if ${e.USE_TRANSMISSIONTEXTURE} - @group(0) @binding(${e.transmissionTextureBinding}) var transmissionTexture: texture_2d; - #endif - #if ${e.USE_THICKNESSTEXTURE} - @group(0) @binding(${e.thicknessTextureBinding}) var thicknessTexture: texture_2d; - #endif - @group(0) @binding(${e.transmissionSamplerTextureBinding}) var transmissionSamplerTexture: texture_2d; - #endif - #if ${e.USE_ENVTEXTURE} - @group(0) @binding(${e.envTextureBinding}) var envTexture: texture_cube; - #endif - #if ${e.USE_NORMALTEXTURE} - @group(0) @binding(${e.normalTextureBinding}) var normalTexture: texture_2d; - #endif - - #if ${e.USE_CLEARCOATTEXTURE} - @group(0) @binding(${e.clearcoatTextureBinding}) var clearcoatTexture: texture_2d; - #endif - - #if ${e.USE_CLEARCOAT_ROUGHNESSTEXTURE} - @group(0) @binding(${e.clearcoatRclearcoatRoughnessTextureBinding}) var clearcoatRoughnessTexture: texture_2d; - #endif - - #if ${e.USE_CLEARCOAT_NORMALTEXTURE} - @group(0) @binding(${e.clearcoatNormalTextureBinding}) var clearcoatNormalTexture: texture_2d; - #endif - - #if ${e.USE_IRIDESCENCETEXTURE} - @group(0) @binding(${e.iridescenceTextureBinding}) var iridescenceTexture: texture_2d; - #endif - - #if ${e.USE_IRIDESCENCE_THICKNESSTEXTURE} - @group(0) @binding(${e.iridescenceThicknessTextureBinding}) var iridescenceThicknessTexture: texture_2d; - #endif - - #if ${e.USE_ROUGHNESSTEXTURE} - @group(0) @binding(${e.roughnessTextureBinding}) var roughnessTexture: texture_2d; - #endif - - #if ${e.USE_METALNESSTEXTURE} - @group(0) @binding(${e.metalnessTextureBinding}) var metalnessTexture: texture_2d; - #endif + let texel:vec4 = textureSample(tDiffuse, tSampler, input.uv); - #if ${e.SPECULAR} - #if ${e.USE_SPECULARINTENSITYTEXTURE} - @group(0) @binding(${e.specularIntensityTextureBinding}) var specularIntensityTexture: texture_2d; - #endif + let luma:vec3 = vec3( 0.299,0.587,0.114 ); - #if ${e.USE_SPECULARCOLORTEXTURE} - @group(0) @binding(${e.specularColorTextureBinding}) var specularColorTexture: texture_2d; - #endif - #endif + let v:f32 = dot( texel.xyz, luma ); - #if ${e.USE_SHEEN} - #if ${e.USE_SHEENCOLORTEXTURE} - @group(0) @binding(${e.sheenColorTextureBinding}) var sheenColorTexture: texture_2d; - #endif - #if ${e.USE_SHEENROUGHNESSTEXTURE} - @group(0) @binding(${e.sheenRoughnessTextureBinding}) var sheenRoughnessTexture: texture_2d; - #endif - #endif + let outputColor:vec4 = vec4( luminosityUniforms.defaultColor.rgb, luminosityUniforms.defaultOpacity ); - #if ${e.USE_TEXTURE} - @group(0) @binding(${e.baseSamplerBinding}) var baseSampler: sampler; - @group(0) @binding(${e.baseTextureBinding}) var baseTexture: texture_2d; - #endif + let alpha:f32 = smoothstep( luminosityUniforms.luminosityThreshold, luminosityUniforms.luminosityThreshold + luminosityUniforms.smoothWidth, v ); - #if ${e.USE_ALPHATEXTURE} - @group(0) @binding(${e.alphaTextureBinding}) var alphaTexture: texture_2d; - #endif + return mix( outputColor, texel, alpha ); + } + `; +} - #if ${e.USE_AOTEXTURE} - @group(0) @binding(${e.aoTextureBinding}) var aoTexture: texture_2d; - - #endif - #if ${e.USE_LIGHTTEXTURE} - @group(0) @binding(${e.lightTextureBinding}) var lightTexture: texture_2d; - #endif +function FragInput(defines) { + return wgslParseDefines` + struct FragInput { + @builtin(front_facing) frontFacing: bool, + @location(0) worldPos:vec3, + @location(1) normal:vec3, + @location(2) uv:vec2, + @location(3) view: vec3, // Vector from vertex to camera. + @location(4) color: vec4, + @location(5) viewPosition: vec3, + } + `; +} - #if ${e.USE_EMISSIVETEXTURE} - @group(0) @binding(${e.emissiveTextureBinding}) var emissiveTexture: texture_2d; - #endif - `; - }, - pbrUtils: function (e) { - return Di` - const PI:f32= 3.141592653589793; - const PI2:f32= 6.283185307179586; - const PI_HALF:f32= 1.5707963267948966; - const RECIPROCAL_PI:f32= 0.3183098861837907; - const RECIPROCAL_PI2:f32= 0.15915494309189535; - const EPSILON:f32= 1e-6; +function PointFragInput(defines) { + return ` + struct PointFragInput{ + @location(0) uv:vec2, + @location(1) color: vec4, + @location(2) size: f32, + } + `; +} - fn pow2(x:f32 )->f32 { - return x*x; - } - fn pow2Vector(x:vec3 )->vec3 { - return x*x; - } - fn pow3( x:f32 )->f32 { - return x*x*x; - } - fn pow4( x:f32 )->f32 { - let x2:f32 = x*x; - return x2*x2; - } - fn max3( v:vec3 )->f32 { - return max( max( v.x, v.y ), v.z ); - } - fn average(v:vec3 )->f32 { - return dot( v, vec3( 0.3333333 ) ); - } - fn rand( uv:vec2 )->f32 { - let a:f32 = 12.9898; - let b:f32 = 78.233; - let c:f32 = 43758.5453; - let dt:f32 = dot( uv.xy, vec2( a, b ) ); - let sn:f32 = dt % PI; - return fract( sin( sn ) * c ); - } - fn transformDirection( dir:vec3, matrix:mat4x4 )->vec3 { - return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); - } +function PointVertInput(defines) { + return wgslParseDefines` + struct PointVertInput { + @location(${defines.positionLocation}) position: vec3, + @location(${defines.uvLocation}) uv: vec2, + #if${defines.HAS_COLOR} + @location(${defines.colorLocation}) color: vec3, + #endif + #if ${defines.HAS_SIZE} + @location(${defines.sizeLocation}) size: f32, + #endif + #if ${defines.USE_INSTANCE} + @builtin(instance_index) instanceIdx : u32 + #endif + } + `; +} - fn transposeMat3( m:mat3x3 )->mat3x3 { - var tmp:mat3x3; - tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x ); - tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y ); - tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z ); - return tmp; - } - fn luminance( rgb:vec3 )->f32 { - let weights:vec3 = vec3(0.2126729, 0.7151522, 0.0721750 ); - return dot( weights, rgb ); - } - fn LinearToneMapping( color:vec3,toneMappingExposure:f32 )->vec3 { - return toneMappingExposure * color; +function PointVertOutput(defines) { + return ` + struct PointVertOutput{ + @builtin(position) position:vec4, + @location(0) uv:vec2, + @location(1) color: vec4, + @location(2) size: f32, } + `; +} - fn ReinhardToneMapping( color:vec3,toneMappingExposure:f32 )->vec3 { - var tempColor:vec3; - tempColor=color; - tempColor *= toneMappingExposure; - return saturate( tempColor / ( vec3( 1.0 ) + tempColor ) ); - } - fn CustomToneMapping( color:vec3 )->vec3 { - return color; - } - fn toneMapping( color:vec3,toneMappingExposure:f32 )->vec3 { - return ReinhardToneMapping( color,toneMappingExposure ); - } +function VertexInput(defines) { + return wgslParseDefines` + struct VertexInput { + @location(${defines.positionLocation}) position: vec3, + #if${defines.HAS_NORMAL} + @location(${defines.normalLocation}) normal: vec3, + #endif + #if${defines.HAS_COLOR} + @location(${defines.colorLocation}) color: vec3, + #endif + #if ${defines.HAS_UV} + @location(${defines.uvLocation}) uv: vec2, + #endif + #if${defines.HAS_SKIN} + @location(${defines.joint0Location}) joint0:vec4, + @location(${defines.weight0Location}) weight0:vec4, + #endif + #if ${defines.USE_INSTANCE} + @builtin(instance_index) instanceIdx : u32 + #endif + } + `; +} - fn LinearToLinear( value:vec4 )->vec4 { - return value; - } - fn lessThanEqual(a:vec3,b:vec3)->vec3{ - let xValue:f32=select(b.x,a.x,a.x<=b.x); - let yValue:f32=select(b.y,a.y,a.y<=b.y); - let zValue:f32=select(b.z,a.z,a.z<=b.z); - return vec3(xValue,yValue,zValue); - } - fn LinearTosRGB( value:vec4 )->vec4 { - return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a ); - } - fn linearToOutputTexel(value:vec4 )->vec4 { - return LinearTosRGB( value ); - } +function VertexOutput(defines) { + return wgslParseDefines` + struct VertexOutput { + @builtin(position) position:vec4, + @location(0) worldPos:vec3, + @location(1) normal:vec3, + @location(2) uv:vec2, + @location(3) view: vec3, // Vector from vertex to camera. + @location(4) color: vec4, + @location(5) viewPosition: vec3, + } `; - }, - environment: function (e) { - return Di` - #if ${e.ENVTEXTURE_TYPE_CUBE_UV} +} + +function SystemUniform(defines) { + return wgslParseDefines` + struct SystemUniform { + projectionMatrix: mat4x4, + viewMatrix: mat4x4, + inverseViewMatrix: mat4x4, + cameraPosition: vec3, + }; + `; +} + +function TextureAndSamplerDefine(defines) { + return wgslParseDefines` + #if ${defines.USE_IBL} + @group(0) @binding(${defines.specularEnvTextureBinding}) var specularEnvTexture: texture_cube; + @group(0) @binding(${defines.specularEnvSamplerBinding}) var specularEnvSampler: sampler; + #endif + #if ${defines.USE_TEXTURE} + @group(0) @binding(${defines.baseColorTextureBinding}) var baseColorTexture: texture_2d; + @group(0) @binding(${defines.baseColorSamplerBinding}) var baseColorSampler: sampler; + #endif + // normal map + #if ${defines.USE_NORMALTEXTURE} + @group(0) @binding(${defines.normalTextureBinding}) var normalTexture: texture_2d; + @group(0) @binding(${defines.normalSamplerBinding}) var normalSampler: sampler; + #endif + // emmisve map + #if ${defines.USE_EMISSIVETEXTURE} + @group(0) @binding(${defines.emissiveTextureBinding}) var emissiveTexture: texture_2d; + @group(0) @binding(${defines.emissiveSamplerBinding}) var emissiveSampler: sampler; + #endif + + // metal roughness + #if ${defines.USE_METALNESSTEXTURE} + @group(0) @binding(${defines.metalnessRoughnessTextureBinding}) var metalnessRoughnessTexture: texture_2d; + @group(0) @binding(${defines.metalnessRoughnessSamplerBinding}) var metalnessRoughnessSampler: sampler; + #endif + // occlusion texture + #if ${defines.USE_AOTEXTURE} + @group(0) @binding(${defines.aoTextureBinding}) var aoTexture: texture_2d; + @group(0) @binding(${defines.aoSamplerBinding}) var aoSampler: sampler; + #endif + #if ${defines.USE_NORMALTEXTURE} + #include + #include + #else + #include + #endif + `; +} + +function environment(defines) { + return wgslParseDefines` + #if ${defines.ENVTEXTURE_TYPE_CUBE_UV} const cubeUV_minMipLevel:f32= 4.0; const cubeUV_minTileSize:f32= 16.0; const CUBEUV_MAX_MIP:f32=6.0; @@ -6927,61 +9233,506 @@ const Ii = { else if ( roughness >= cubeUV_r5 ) { mip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4; } - else if ( roughness >= cubeUV_r6 ) { - mip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5; + else if ( roughness >= cubeUV_r6 ) { + mip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5; + } + else { + mip = - 2.0 * log2( 1.16 * roughness ); + } + return mip; + } + fn textureCubeUV(envTexture:texture_cube, baseSampler:sampler,sampleDir:vec3,roughness:f32 )->vec4 { + let mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP ); + let mipF = fract( mip ); + let mipInt = floor( mip ); + let color0:vec3 = bilinearCubeUV( envTexture,baseSampler,sampleDir, mipInt ); + if ( mipF == 0.0 ) { + return vec4(color0, 1.0 ); + } + else { + let color1:vec3 = bilinearCubeUV( envTexture,baseSampler, sampleDir, mipInt + 1.0 ); + return vec4(mix( color0, color1, mipF ), 1.0 ); + } + + } + #endif + #if ${defines.USE_ENVTEXTURE} + fn getIBLIrradiance( normal:vec3,baseSampler:sampler,viewMatrix:mat4x4)->vec3 { + #if ${defines.ENVTEXTURE_TYPE_CUBE_UV} + let worldNormal:vec3 = inverseTransformDirection( normal, viewMatrix ); + let envTextureColor:vec4 = textureCubeUV( envTexture,baseSampler, worldNormal, 1.0 ); + return PI * envTextureColor.rgb * materialUniform.envTextureIntensity; + #else + return vec3( 0.0 ); + #endif + } + fn getIBLRadiance( viewDir:vec3,baseSampler:sampler,viewMatrix:mat4x4,normal:vec3, roughness:f32 )->vec3 { + #if ${defines.ENVTEXTURE_TYPE_CUBE_UV} + var reflectVec:vec3 = reflect( - viewDir, normal ); + reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) ); + reflectVec = inverseTransformDirection( reflectVec, viewMatrix ); + let envTextureColor:vec4 = textureCubeUV( envTexture,baseSampler, reflectVec, roughness ); + return envTextureColor.rgb * materialUniform.envTextureIntensity; + #else + return vec3( 0.0 ); + #endif + } + #endif + `; +} + +function instanceVertHeader(defines) { + return wgslParseDefines` + #if ${defines.USE_INSTANCE} + struct InstancesUniform { + instanceMatrixs: array, ${defines.instanceCount}>, + }; + @group(0) @binding(${defines.instanceMatrixsBufferBinding}) var instancesUniform: InstancesUniform; + #endif + `; +} +function instanceVertMain(defines) { + return wgslParseDefines` + #if ${defines.USE_INSTANCE} + modelMatrix=instancesUniform.instanceMatrixs[input.instanceIdx]; + #endif + `; +} + +function light(defines) { + return wgslParseDefines` + struct ReflectedLight { + ambient: vec3, + directDiffuse:vec3, + directSpecular:vec3, + indirectDiffuse:vec3, + indirectSpecular:vec3, + testColor: vec3, + }; + struct IncidentLight { + color: vec3, + direction: vec3, + visible: bool, + }; + struct Geometry { + position: vec3, + normal: vec3, + viewDir: vec3, + dotNV:f32, + #if ${defines.USE_CLEARCOAT} + vec3 clearcoatNormal; + #endif + }; + + #if ${defines.spotLightsCount > 0} + struct SpotLight { + position: vec3, + distance: f32, + direction: vec3, + coneCos: f32, + color: vec3, + penumbraCos: f32, + decay: f32, + }; + fn getSpotLightInfo(spotLight:SpotLight,worldPos:vec3,shininess:f32,N:vec3,V:vec3)->ReflectedLight{ + var direction:vec3 = spotLight.position - worldPos; + var lightColor:ReflectedLight; + let lightDistance:f32 = length(direction); + direction = normalize(direction); + let angleCos:f32 = dot( direction, spotLight.direction ); + let decay:f32 = clamp(1.0 - pow(lightDistance/spotLight.distance, spotLight.decay), 0.0, 1.0); + let spotEffect:f32 = smoothstep( spotLight.penumbraCos, spotLight.coneCos, angleCos ); + let decayTotal:f32 = decay * spotEffect; + let d:f32 = max( dot( N, direction ), 0.0 ) * decayTotal; + lightColor.directDiffuse= spotLight.color * d; + let halfDir:vec3 = normalize( V + direction ); + let s:f32 = pow( clamp( dot( N, halfDir ), 0.0, 1.0 ), shininess ) * decayTotal; + lightColor.directSpecular= spotLight.color * s; + return lightColor; + } + fn getSpotLightIncidentLight(spotLight:SpotLight, geometry:Geometry)->IncidentLight { + var incidentLight:IncidentLight; + let lVector:vec3 = spotLight.position - geometry.position; + incidentLight.direction = normalize( lVector ); + + let lightDistance:f32 = length( lVector ); + let angleCos:f32 = dot( incidentLight.direction, spotLight.direction ); + + let spotEffect:f32 = smoothstep( spotLight.penumbraCos, spotLight.coneCos, angleCos ); + let decayEffect:f32 = clamp(1.0 - pow(lightDistance/spotLight.distance, 4.0), 0.0, 1.0); + + incidentLight.color=spotLight.color*spotEffect * decayEffect; + return incidentLight; + } + + #endif + + #if ${defines.pointLightsCount > 0} + struct PointLight { + position: vec3, + distance: f32, + color: vec3, + decay: f32, + }; + fn getPointLightInfo(pointLight:PointLight,worldPos:vec3,shininess:f32,N:vec3,V:vec3)->ReflectedLight{ + var lightColor:ReflectedLight; + var direction:vec3 = worldPos - pointLight.position; + let dist:f32 = length( direction ); + direction = normalize(direction); + let decay = clamp(1.0 - pow(dist / pointLight.distance, pointLight.decay), 0.0, 1.0); + + let d = max( dot( N, -direction ), 0.0 ) * decay; + lightColor.directDiffuse = pointLight.color * d; + + let halfDir:vec3 = normalize( V - direction ); + let s:f32 = pow( clamp( dot( N, halfDir ), 0.0, 1.0 ), shininess ) * decay; + lightColor.directSpecular = pointLight.color * s; + return lightColor; + } + fn getPointLightIncidentLight(pointLight:PointLight, geometry:Geometry)->IncidentLight { + var incidentLight:IncidentLight; + let lVector:vec3 = pointLight.position-geometry.position; + incidentLight.direction= normalize( lVector ); + let lightDistance:f32 = length( lVector ); + // let weight:f32=1.0 - pow(lightDistance/pointLight.distance, 4.0); + incidentLight.color=pointLight.color*clamp(1.0 - pow(lightDistance/pointLight.distance, 4.0), 0.0, 1.0); + return incidentLight; + } + #endif + #if ${defines.dirtectLightsCount > 0} + struct DirectionalLight { + direction: vec3, + color: vec3, + }; + fn getDirectLightInfo(directionalLight:DirectionalLight,shininess:f32,N:vec3,V:vec3)->ReflectedLight{ + var lightColor:ReflectedLight; + let d:f32 = max(dot(N, -directionalLight.direction), 0.0); + lightColor.directDiffuse += directionalLight.color * d; + + let halfDir:vec3 = normalize( V - directionalLight.direction ); + let s:f32 = pow( clamp( dot( N, halfDir ), 0.0, 1.0 ), shininess ); + lightColor.directSpecular += directionalLight.color * s; + return lightColor; + } + fn getDirectionalDirectLightIncidentLight(directionalLight:DirectionalLight,geometry:Geometry)->IncidentLight { + var incidentLight:IncidentLight; + incidentLight.color = directionalLight.color; + incidentLight.direction = normalize(directionalLight.direction); + return incidentLight; + } + #endif + + #if ${defines.openShadow} + struct LightInfo { + direction: vec3, + viewport: vec4, + }; + + fn linearizeDepth(depth: f32, near: f32, far: f32)->f32 { + return 2 * (near * far) / (far + near - depth * (far - near)); + } + + fn getCubeFace(v : vec3) -> i32{ + let vAbs = abs(v); + + if (vAbs.z >= vAbs.x && vAbs.z >= vAbs.y) { + if (v.z < 0.0) { + return 3; + } + return 2; + } + + if (vAbs.y >= vAbs.x) { + if (v.y < 0.0) { + return 5; + } + return 4; } - else { - mip = - 2.0 * log2( 1.16 * roughness ); + + if (v.x < 0.0) { + return 1; } - return mip; + return 0; } - fn textureCubeUV(envTexture:texture_cube, baseSampler:sampler,sampleDir:vec3,roughness:f32 )->vec4 { - let mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP ); - let mipF = fract( mip ); - let mipInt = floor( mip ); - let color0:vec3 = bilinearCubeUV( envTexture,baseSampler,sampleDir, mipInt ); - if ( mipF == 0.0 ) { - return vec4(color0, 1.0 ); + + fn getShadowValue(shadowMapArray:texture_depth_2d_array, shadowSampler:sampler_comparison, lightPos:vec4, geometry:Geometry, lightInfo:LightInfo, index:u32, isPointLight: bool, near: f32, far: f32)->f32 { + var visibility = 0.0; + var projectPos: vec3 = lightPos.xyz / lightPos.w; + var shadowPos: vec3 = vec3(projectPos.xy * vec2(0.5, -0.5) + vec2(0.5), projectPos.z); + var d:f32 = dot(geometry.normal, -lightInfo.direction); + var bias = max(0.012 * (1.0 - d), 0.001) / lightPos.w; + let oneOverShadowDepthTextureSize = 1.0 / 1024.0; + // var depth = select(shadowPos.z, (linearizeDepth(shadowPos.z, near, far) - near) / (far- near), isPerspectiveCamera); + var depth = shadowPos.z; + + if (isPointLight) { + shadowPos.x = shadowPos.x * lightInfo.viewport.z; + shadowPos.y = shadowPos.y * lightInfo.viewport.w; + var viewportX = lightInfo.viewport.x * lightInfo.viewport.z; + var viewportY = lightInfo.viewport.y * lightInfo.viewport.w; + var uvOffset = 1.5 / 1024.0; + shadowPos.x = clamp(shadowPos.x + viewportX, viewportX + uvOffset, viewportX + lightInfo.viewport.z - uvOffset); + shadowPos.y = clamp(shadowPos.y + viewportY, viewportY + uvOffset, viewportY + lightInfo.viewport.w - uvOffset); } - else { - let color1:vec3 = bilinearCubeUV( envTexture,baseSampler, sampleDir, mipInt + 1.0 ); - return vec4(mix( color0, color1, mipF ), 1.0 ); + + for (var y = -1; y <= 1; y++) { + for (var x = -1; x <= 1; x++) { + let offset = vec2(vec2(x, y)) * oneOverShadowDepthTextureSize; + + visibility += textureSampleCompare( + shadowMapArray, shadowSampler, + shadowPos.xy + offset, index, depth - bias); + } } - + visibility /= 9.0; + var inFrustum = shadowPos.x >= 0.0 && shadowPos.x <= 1.0 && shadowPos.y >= 0.0 && shadowPos.y <= 1.0; + if (!inFrustum || depth > 1.0) { + visibility = 1.0; + } + return visibility; } - #endif - #if ${e.USE_ENVTEXTURE} - fn getIBLIrradiance( normal:vec3,baseSampler:sampler,viewMatrix:mat4x4)->vec3 { - #if ${e.ENVTEXTURE_TYPE_CUBE_UV} - let worldNormal:vec3 = inverseTransformDirection( normal, viewMatrix ); - let envTextureColor:vec4 = textureCubeUV( envTexture,baseSampler, worldNormal, 1.0 ); - return PI * envTextureColor.rgb * materialUniform.envTextureIntensity; - #else - return vec3( 0.0 ); + #endif + + #if ${ + defines.ambientLightCount || defines.spotLightsCount || defines.pointLightsCount || defines.dirtectLightsCount + } + struct LightUniforms{ + #if ${defines.ambientLightCount} + ambient:vec4, + #endif + #if ${defines.spotLightsCount} + spotLights:array, + #endif + #if ${defines.pointLightsCount} + pointLights:array, + #endif + #if ${defines.dirtectLightsCount} + dirtectLights:array, #endif } - fn getIBLRadiance( viewDir:vec3,baseSampler:sampler,viewMatrix:mat4x4,normal:vec3, roughness:f32 )->vec3 { - #if ${e.ENVTEXTURE_TYPE_CUBE_UV} - var reflectVec:vec3 = reflect( - viewDir, normal ); - reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) ); - reflectVec = inverseTransformDirection( reflectVec, viewMatrix ); - let envTextureColor:vec4 = textureCubeUV( envTexture,baseSampler, reflectVec, roughness ); - return envTextureColor.rgb * materialUniform.envTextureIntensity; - #else - return vec3( 0.0 ); + @group(2) @binding(${defines.lightBinding}) var lightUniforms: LightUniforms; + + #if ${defines.openShadow} + #if ${defines.spotLightShadowMapsCount} + struct SpotLightShadow { + shadowCameraVPMatrix: mat4x4, + shadowCameraNear: f32, + shadowCameraFar: f32 + } + #endif + #if ${defines.pointLightShadowMapsCount} + struct PointLightShadow { + shadowCameraVPMatrixArray: array, 6>, + shadowCameraViewportArray: array, 6>, + shadowCameraNear: f32, + shadowCameraFar: f32, + // shadowCameraVPMatrix: mat4x4, + // shadowCameraVPMatrixArray: array, 6>, + // shadowCameraViewportArray: array, 6>, + } + #endif + #if ${defines.directLightShadowMapsCount} + struct DirectLightShadow { + shadowCameraVPMatrix: mat4x4, + } #endif + struct ShadowUniforms{ + #if ${defines.spotLightShadowMapsCount} + spotLightShadows:array, + #endif + #if ${defines.pointLightShadowMapsCount} + pointLightShadows:array, + #endif + #if ${defines.directLightShadowMapsCount} + directLightShadows:array, + #endif } + @group(2) @binding(${defines.shadowBinding}) var shadowUniforms: ShadowUniforms; + + #if ${defines.spotLightShadowMapTextureArrayBinding} + @group(2) @binding(${ + defines.spotLightShadowMapTextureArrayBinding + }) var spotLightShadowMapTextureArray: texture_depth_2d_array; + #endif + #if ${defines.pointLightShadowMapTextureArrayBinding} + @group(2) @binding(${ + defines.pointLightShadowMapTextureArrayBinding + }) var pointLightShadowMapTextureArray: texture_depth_2d_array; + #endif + #if ${defines.directLightShadowMapTextureArrayBinding} + @group(2) @binding(${ + defines.directLightShadowMapTextureArrayBinding + }) var directLightShadowMapTextureArray: texture_depth_2d_array; + #endif + @group(2) @binding(${defines.shadowSamplerBinding}) var shadowSampler: sampler_comparison; + #endif + #endif - `; - }, - blinn_phong: function (e) { - return "\n fn getPointLightInfo(pointLight:PointLight,worldPos:vec3,shininess:f32,N:vec3,V:vec3)->vec3{\n var color=vec3(0.0,0.0,0.0);\n var direction:vec3 = worldPos - pointLight.position;\n let dist:f32 = length( direction );\n direction = normalize(direction);\n let decay = clamp(1.0 - pow(dist / pointLight.distance, 4.0), 0.0, 1.0);\n\n let d = max( dot( N, -direction ), 0.0 ) * decay;\n color += pointLight.color * d;\n\n let halfDir:vec3 = normalize( V - direction );\n let s:f32 = pow( clamp( dot( N, halfDir ), 0.0, 1.0 ), shininess ) * decay;\n color += pointLight.color * s;\n return color;\n }\n fn getSpotLightInfo(spotLight:SpotLight,worldPos:vec3,shininess:f32,N:vec3,V:vec3)->vec3{\n var color=vec3(0.0,0.0,0.0);\n var direction:vec3 = spotLight.position - worldPos;\n let lightDistance:f32 = length(direction);\n direction = normalize(direction);\n let angleCos:f32 = dot( direction, -spotLight.direction );\n let decay:f32 = clamp(1.0 - pow(lightDistance/spotLight.distance, 4.0), 0.0, 1.0);\n let spotEffect:f32 = smoothstep( spotLight.penumbraCos, spotLight.coneCos, angleCos );\n let decayTotal:f32 = decay * spotEffect;\n let d:f32 = max( dot( N, direction ), 0.0 ) * decayTotal;\n color += spotLight.color * d;\n let halfDir:vec3 = normalize( V + direction );\n let s:f32 = pow( clamp( dot( N, halfDir ), 0.0, 1.0 ), shininess ) * decayTotal;\n color += spotLight.color * s;\n return color;\n }\n struct DirectionalLight {\n direction: vec3,\n color: vec3,\n };\n fn getDirectLightInfo(directionalLight:DirectionalLight,shininess:f32,N:vec3,V:vec3)->vec3{\n var color=vec3(0.0,0.0,0.0);\n let d:f32 = max(dot(N, -directionalLight.direction), 0.0);\n color += directionalLight.color * d;\n\n let halfDir:vec3 = normalize( V - directionalLight.direction );\n let s:f32 = pow( clamp( dot( N, halfDir ), 0.0, 1.0 ), shininess );\n color += directionalLight.color * s;\n return color;\n }\n "; - }, - getNormal: function (e) { - return Di` + #if ${defines.materialPhong} + fn parseLights(geometry:Geometry,shininess:f32)->ReflectedLight { + #elif ${defines.materialPbr} + fn parseLights(geometry:Geometry,material:PhysicalMaterial)->ReflectedLight{ + #endif + var reflectedLight:ReflectedLight; + var shadowValue:f32 = 1.0; + #if ${defines.ambientLightCount > 0} + //处理环境光 + var ambientColor:vec3 = lightUniforms.ambient.xyz * lightUniforms.ambient.w; + reflectedLight.ambient += ambientColor; + #endif + + #if ${defines.spotLightsCount > 0} + //处理聚光灯 + var spotLight:SpotLight; + for (var k = 0u; k < ${defines.spotLightsCount}; k = k + 1u) { + spotLight= lightUniforms.spotLights[k]; + #if ${defines.materialPhong && defines.openShadow && defines.spotLightShadowMapsCount} + if k < textureNumLayers(spotLightShadowMapTextureArray) { + var spotLightShadow:SpotLightShadow = shadowUniforms.spotLightShadows[k]; + var lightPos: vec4 = spotLightShadow.shadowCameraVPMatrix * vec4(geometry.position,1.0); + var lightInfo:LightInfo; + lightInfo.direction = normalize(geometry.position - spotLight.position); + + shadowValue = getShadowValue(spotLightShadowMapTextureArray, shadowSampler, lightPos, geometry, lightInfo, k, false, + spotLightShadow.shadowCameraNear, spotLightShadow.shadowCameraFar); + } + spotLight.color *= shadowValue; + #endif + #if ${defines.materialPhong} + let spReflectedLight=getSpotLightInfo(spotLight,geometry.position,shininess,geometry.normal,geometry.viewDir); + #elif ${defines.materialPbr} + let incidentLight=getSpotLightIncidentLight(spotLight,geometry); + let spReflectedLight=direct_Physical(incidentLight, geometry, material); + #endif + + reflectedLight.directDiffuse+=spReflectedLight.directDiffuse; + reflectedLight.directSpecular+=spReflectedLight.directSpecular; + } + #endif + #if ${defines.pointLightsCount > 0} + //处理点光源 + var pointLight:PointLight; + for (var j = 0u; j < ${defines.pointLightsCount};j = j + 1u) { + pointLight = lightUniforms.pointLights[j]; + #if ${defines.materialPhong && defines.openShadow && defines.pointLightShadowMapsCount} + if j < textureNumLayers(pointLightShadowMapTextureArray) { + var pointLightShadow:PointLightShadow = shadowUniforms.pointLightShadows[j]; + var lightInfo:LightInfo; + lightInfo.direction = normalize(geometry.position - pointLight.position); + var cubeFace = getCubeFace(lightInfo.direction); + var lightPos: vec4 = pointLightShadow.shadowCameraVPMatrixArray[cubeFace] * vec4(geometry.position,1.0); + lightInfo.viewport = pointLightShadow.shadowCameraViewportArray[cubeFace]; + + // var lightPos: vec4 = pointLightShadow.shadowCameraVPMatrix * vec4(geometry.position,1.0); + + shadowValue = getShadowValue(pointLightShadowMapTextureArray, shadowSampler, lightPos, geometry, lightInfo, j, true, + pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar); + + // reflectedLight.testColor = vec3(pointLightShadow.shadowCameraFar / 1000, + // pointLightShadow.shadowCameraVPMatrixArray[5][3][2] / 255, pointLightShadow.shadowCameraVPMatrixArray[5][3][3] / 255); + // reflectedLight.testColor = vec3(pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraNear); + } + pointLight.color *= shadowValue; + #endif + #if ${defines.materialPhong} + let poiReflectedLight=getPointLightInfo(pointLight,geometry.position,shininess,geometry.normal,geometry.viewDir); + #elif ${defines.materialPbr} + let incidentLight=getPointLightIncidentLight(pointLight,geometry); + let poiReflectedLight=direct_Physical(incidentLight, geometry, material); + #endif + + reflectedLight.directDiffuse+=poiReflectedLight.directDiffuse; + reflectedLight.directSpecular+=poiReflectedLight.directSpecular; + } + #endif + #if ${defines.dirtectLightsCount > 0} + //处理方向光 + var directionalLight:DirectionalLight; + for (var i= 0u; i <${defines.dirtectLightsCount}; i = i + 1u) { + directionalLight = lightUniforms.dirtectLights[i]; + #if ${defines.materialPhong && defines.openShadow && defines.directLightShadowMapsCount} + if i < textureNumLayers(directLightShadowMapTextureArray) { + var directLightShadow:DirectLightShadow = shadowUniforms.directLightShadows[i]; + var lightPos: vec4 = directLightShadow.shadowCameraVPMatrix * vec4(geometry.position,1.0); + var lightInfo:LightInfo; + lightInfo.direction = directionalLight.direction; + + shadowValue = getShadowValue(directLightShadowMapTextureArray, shadowSampler, lightPos, geometry, lightInfo, i, false, 0, 0); + } + directionalLight.color *= shadowValue; + #endif + + #if ${defines.materialPhong} + let dirReflectedLight=getDirectLightInfo(directionalLight,shininess,geometry.normal,geometry.viewDir); + #elif ${defines.materialPbr} + let incidentLight=getDirectionalDirectLightIncidentLight(directionalLight,geometry); + let dirReflectedLight=direct_Physical(incidentLight, geometry, material); + #endif + + reflectedLight.directDiffuse+=dirReflectedLight.directDiffuse; + reflectedLight.directSpecular+=dirReflectedLight.directSpecular; + } + #endif + return reflectedLight; + }`; +} + +function lightCommon(defines) { + return wgslParseDefines` + struct ReflectedLight { + directDiffuse:vec3, + directSpecular:vec3, + indirectDiffuse:vec3, + indirectSpecular:vec3, + }; + struct Geometry { + position: vec3, + normal: vec3, + viewDir: vec3, + #if ${defines.USE_CLEARCOAT} + vec3 clearcoatNormal; + #endif + }; + fn getAmbientLightIrradiance(ambientLightColor: vec3) -> vec3 { + let irradiance = ambientLightColor; + return irradiance; + } + fn getDistanceAttenuation(lightDistance: f32, cutoffDistance: f32, decayExponent: f32) -> f32 { + if (cutoffDistance > 0.0 && decayExponent > 0.0) { + let x:f32 = saturate(- lightDistance / cutoffDistance + 1.0); + return pow(x, decayExponent); + } + return 1.0; + } + fn getSpotAttenuation(coneCosine: f32, penumbraCosine: f32, angleCosine: f32) -> f32 { + return smoothstep(coneCosine, penumbraCosine, angleCosine); + } + fn shGetIrradianceAt( normal:vec3, shCoefficients:array,9>)->vec3 { + let x:f32 = normal.x; + let y:f32 = normal.y; + let z:f32 = normal.z; + var result:vec3 = shCoefficients[ 0 ] * 0.886227; + result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y; + result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z; + result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x; + result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y; + result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z; + result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 ); + result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z; + result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y ); + return result; + } + fn inverseTransformDirection( dir:vec3, matrix:mat4x4 )->vec3 { + return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz ); + } + `; +} + +function getNormal(defines) { + return wgslParseDefines` fn getNormal(input:FragInput)->vec3{ var normal:vec3; - #if ${e.HAS_NORMAL} + #if ${defines.HAS_NORMAL} normal= input.normal; #else let pos_dx = dpdx(input.worldPos); @@ -6991,38 +9742,9 @@ const Ii = { return normal*(f32(input.frontFacing) * 2.0 - 1.0); } `; - }, - getTBN: function (e) { - return Di` - fn getTBN(input:FragInput)->mat3x3{ - #if ${e.HAS_TANGENT} - let tbn:mat3x3 = input.tbn; - #else - let normal:vec3 =normalize(input.normal); - let uv:vec2 = select(-input.uv,input.uv,input.frontFacing); - // ref: http://www.thetenthplanet.de/archives/1180 - // get edge vectors of the pixel triangle - let dp1:vec3 = vec3(dpdx(input.worldPos.x), dpdx(input.worldPos.y), dpdx(input.worldPos.z)); - let dp2:vec3 = vec3(dpdy(input.worldPos.x), dpdy(input.worldPos.y), dpdy(input.worldPos.z)); - let duv1:vec2 = dpdx(uv); - let duv2:vec2 = dpdy(uv); - - // solve the linear system - let dp2perp:vec3 = cross(dp2, normal); - let dp1perp:vec3 = cross(normal, dp1); - let tangent:vec3 = dp2perp * duv1.x + dp1perp * duv2.x; - let binormal:vec3 = dp2perp * duv1.y + dp1perp * duv2.y; - // construct a scale-invariant frame - let result:f32=max(dot(tangent, tangent), dot(binormal, binormal)); - let invmax:f32 = 1.0/sqrt(result); - let tbn:mat3x3 = mat3x3(tangent * invmax, binormal * invmax, normal); - #endif - return tbn; - } - `; - }, - getNormalByNormalTexture: function (e) { - return Di` +} +function getNormalByNormalTexture(defines) { + return wgslParseDefines` fn getNormalByNormalTexture(input:FragInput)->vec3{ var n:vec3 = textureSample(normalTexture,normalSampler, input.uv).rgb; let tbn:mat3x3 =getTBN(input); @@ -7031,1193 +9753,1086 @@ const Ii = { return n; } `; - }, - ibl: function (e) { - return Di` - fn getLightProbeRadiance( viewDir:vec3,normal:vec3, roughness:f32 )->vec3{ - var reflectVec:vec3 = reflect( -viewDir, normal ); - reflectVec.x = -reflectVec.x; // TextureCube is left-hand,so x need inverse - let mipCount:f32 = 10.0; // resolution of 256x256 - let lod:f32 = roughness * mipCount; - let specularLight:vec3 = textureSampleLevel(specularEnvTexture,specularEnvSampler, reflectVec, lod).rgb; - return specularLight; - } - fn getLightProbeIrradiance( lightProbe:array,9>, normal:vec3)->vec3 { - var worldNormal:vec3 = normal; - worldNormal.x = -normal.x; - var irradiance:vec3 = lightProbe[0]; - irradiance+=lightProbe[1] * (normal.y); - irradiance+=lightProbe[2] * (normal.z) ; - irradiance+=lightProbe[3] * (normal.x) ; - - irradiance+=lightProbe[4] * (normal.y * normal.x) ; - irradiance+=lightProbe[5] * (normal.y * normal.z) ; - irradiance+=lightProbe[6] * (3.0 * normal.z * normal.z - 1.0); - irradiance+=lightProbe[7] * (normal.z * normal.x) ; - irradiance+=lightProbe[8] * (normal.x * normal.x - normal.y * normal.y); - - return max(irradiance, vec3(0.0,0.0,0.0)); - } - fn DFGApprox( specularColor:vec3, roughness:f32,dotNV:f32 )->vec3 { - const c0:vec4 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); - let c1:vec4 = vec4( 1, 0.0425, 1.04, - 0.04 ); - let r:vec4 = roughness * c0 + c1; - let a004:f32 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; - let fab:vec2 = vec2( - 1.04, 1.04 ) * a004 + r.zw; - return specularColor * fab.x + fab.y; - } - //间接光照 - fn indirectDiffuse_Physical(geometry:Geometry, material:PhysicalMaterial )->ReflectedLight { - var reflectedLight:ReflectedLight; - var irradiance:vec3 = lightUniforms.ambient.xyz*lightUniforms.ambient.w; - irradiance *= PI; - reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); - return reflectedLight; - } - //间接高光 - fn indirectSpecular_Physical(geometry:Geometry, material:PhysicalMaterial)->ReflectedLight { - var reflectedLight:ReflectedLight; - // IBL specular - let radiance:vec3 = getLightProbeRadiance(geometry.viewDir, geometry.normal, material.roughness); - let radianceAttenuation:f32 = 1.0; - reflectedLight.indirectSpecular += radianceAttenuation * radiance * DFGApprox(material.specularColor, material.roughness, geometry.dotNV ); - return reflectedLight; - } - `; - }, - skinVertMain: function (e) { - return Di` - #if ${e.HAS_SKIN} - modelMatrix =getSkinMatrix(input.joint0,input.weight0); - vNormalView = normalize((materialUniform.normalMatrix * modelMatrix * vec4(input.normal, 0.0)).xyz); - #endif - `; - }, - skinVertHeader: function (e) { - return Di` - #if ${e.HAS_SKIN} - struct JointsUniform{ - matrixs:array, - } - struct InverseBindMatricesUniform{ - matrixs:array, - } - @binding(${e.skinJointsBufferBinding}) @group(0) var jointsUniform : JointsUniform; - @binding(${e.invsBufferBinding}) @group(0) var inverseBindMatricesUniform : InverseBindMatricesUniform; - fn getSkinMatrix(joints: vec4f, weights: vec4f) -> mat4x4 { - let joint0 = jointsUniform.matrixs[u32(joints.x)] * inverseBindMatricesUniform.matrixs[u32(joints.x)]; - let joint1 = jointsUniform.matrixs[u32(joints.y)] * inverseBindMatricesUniform.matrixs[u32(joints.y)]; - let joint2 = jointsUniform.matrixs[u32(joints.z)] * inverseBindMatricesUniform.matrixs[u32(joints.z)]; - let joint3 = jointsUniform.matrixs[u32(joints.w)] * inverseBindMatricesUniform.matrixs[u32(joints.w)]; - - let skinMatrix = joint0 * weights.x + - joint1 * weights.y + - joint2 * weights.z + - joint3 * weights.w; - return skinMatrix; - } - #endif - `; - }, - FragInput: function (e) { - return Di` - struct FragInput { - @builtin(front_facing) frontFacing: bool, - @location(0) worldPos:vec3, - @location(1) normal:vec3, - @location(2) uv:vec2, - @location(3) view: vec3, // Vector from vertex to camera. - @location(4) color: vec4, - @location(5) viewPosition: vec3, - } - `; - }, - VertexInput: function (e) { - return Di` - struct VertexInput { - @location(${e.positionLocation}) position: vec3, - #if${e.HAS_NORMAL} - @location(${e.normalLocation}) normal: vec3, - #endif - #if${e.HAS_COLOR} - @location(${e.colorLocation}) color: vec3, - #endif - #if ${e.HAS_UV} - @location(${e.uvLocation}) uv: vec2, - #endif - #if${e.HAS_SKIN} - @location(${e.joint0Location}) joint0:vec4, - @location(${e.weight0Location}) weight0:vec4, - #endif - #if ${e.USE_INSTANCE} - @builtin(instance_index) instanceIdx : u32 - #endif - } - `; - }, - VertexOutput: function (e) { - return Di` - struct VertexOutput { - @builtin(position) position:vec4, - @location(0) worldPos:vec3, - @location(1) normal:vec3, - @location(2) uv:vec2, - @location(3) view: vec3, // Vector from vertex to camera. - @location(4) color: vec4, - @location(5) viewPosition: vec3, - } - `; - }, - PbrMaterialStruct: function (e) { - return Di` - struct MaterialUniform { - modelMatrix: mat4x4, - color: vec3, - opacity:f32, - normalMatrix: mat4x4, - emissive:vec3, - metallic:f32, - roughness:f32, - #if ${e.USE_NORMALTEXTURE} - normalTextureScale:vec2, - #endif - #if ${e.USE_AOTEXTURE} - occlusionStrength:f32, - #endif - } - `; - }, - SystemUniform: function (e) { - return Di` - struct SystemUniform { - projectionMatrix: mat4x4, - viewMatrix: mat4x4, - inverseViewMatrix: mat4x4, - cameraPosition: vec3, - }; - `; - }, - instanceVertMain: function (e) { - return Di` - #if ${e.USE_INSTANCE} - modelMatrix=instancesUniform.instanceMatrixs[input.instanceIdx]; - #endif - `; - }, - instanceVertHeader: function (e) { - return Di` - #if ${e.USE_INSTANCE} - struct InstancesUniform { - instanceMatrixs: array, ${e.instanceCount}>, - }; - @group(0) @binding(${e.instanceMatrixsBufferBinding}) var instancesUniform: InstancesUniform; - #endif - `; - }, - TextureAndSamplerDefine: function (e) { - return Di` - #if ${e.USE_IBL} - @group(0) @binding(${e.specularEnvTextureBinding}) var specularEnvTexture: texture_cube; - @group(0) @binding(${e.specularEnvSamplerBinding}) var specularEnvSampler: sampler; - #endif - #if ${e.USE_TEXTURE} - @group(0) @binding(${e.baseColorTextureBinding}) var baseColorTexture: texture_2d; - @group(0) @binding(${e.baseColorSamplerBinding}) var baseColorSampler: sampler; - #endif - // normal map - #if ${e.USE_NORMALTEXTURE} - @group(0) @binding(${e.normalTextureBinding}) var normalTexture: texture_2d; - @group(0) @binding(${e.normalSamplerBinding}) var normalSampler: sampler; - #endif - // emmisve map - #if ${e.USE_EMISSIVETEXTURE} - @group(0) @binding(${e.emissiveTextureBinding}) var emissiveTexture: texture_2d; - @group(0) @binding(${e.emissiveSamplerBinding}) var emissiveSampler: sampler; - #endif - - // metal roughness - #if ${e.USE_METALNESSTEXTURE} - @group(0) @binding(${e.metalnessRoughnessTextureBinding}) var metalnessRoughnessTexture: texture_2d; - @group(0) @binding(${e.metalnessRoughnessSamplerBinding}) var metalnessRoughnessSampler: sampler; - #endif - // occlusion texture - #if ${e.USE_AOTEXTURE} - @group(0) @binding(${e.aoTextureBinding}) var aoTexture: texture_2d; - @group(0) @binding(${e.aoSamplerBinding}) var aoSampler: sampler; - #endif - #if ${e.USE_NORMALTEXTURE} - #include - #include - #else - #include - #endif - `; - }, - PointVertInput: function (e) { - return Di` - struct PointVertInput { - @location(${e.positionLocation}) position: vec3, - @location(${e.uvLocation}) uv: vec2, - #if${e.HAS_COLOR} - @location(${e.colorLocation}) color: vec3, - #endif - #if ${e.HAS_SIZE} - @location(${e.sizeLocation}) size: f32, - #endif - #if ${e.USE_INSTANCE} - @builtin(instance_index) instanceIdx : u32 - #endif - } - `; - }, - PointVertOutput: function (e) { - return "\n struct PointVertOutput{\n @builtin(position) position:vec4,\n @location(0) uv:vec2,\n @location(1) color: vec4,\n @location(2) size: f32,\n }\n "; - }, - PointFragInput: function (e) { - return "\n struct PointFragInput{\n @location(0) uv:vec2,\n @location(1) color: vec4,\n @location(2) size: f32,\n }\n "; - } -}; -function Pi(e) { - return null != e ? Vi(e) : void 0; } -const Ni = /^[ \t]*#include +<([\w\d./]+)>/gm; -let Bi = {}; -const Oi = { - phong: { - frag: function (e) { - return Di` - struct MaterialUniform { - modelMatrix: mat4x4, - color: vec3, - opacity:f32, - normalMatrix: mat4x4, - emissive:vec3, - shininess:f32, - specular:vec3, - } - #include - #include - #include - #include - @binding(${e.phongBinding}) @group(0) var materialUniform : MaterialUniform; - @binding(${e.cameraBinding}) @group(1) var systemUniform : SystemUniform; - @fragment - fn main(input:FragInput) -> @location(0) vec4 { - var totalEmissiveRadiance:vec3 = materialUniform.emissive; - var color:vec4; - #if${e.USE_COLORTEXTURE} - color= vec4(textureSample(baseColorTexture, baseColorSampler, input.uv).rgb+materialUniform.color,materialUniform.opacity); - #else - color=vec4(materialUniform.color,materialUniform.opacity); - #endif - let V:vec3 = normalize( systemUniform.cameraPosition - input.worldPos); - #if ${e.USE_NORMALTEXTURE} - let N:vec3 = getNormalByNormalTexture(input); +function getTBN(defines) { + return wgslParseDefines` + fn getTBN(input:FragInput)->mat3x3{ + #if ${defines.HAS_TANGENT} + let tbn:mat3x3 = input.tbn; #else - let N:vec3 = getNormal(input); - #endif - var geometry:Geometry; - geometry.normal=N; - geometry.viewDir=V; - geometry.position=input.worldPos; - let lightColor:ReflectedLight=parseLights(geometry,materialUniform.shininess); - // var finnalColor:vec3=color.xyz + (lightColor.directDiffuse + lightColor.directSpecular + lightColor.ambient); - var finnalColor:vec3=color.xyz * (lightColor.directDiffuse + lightColor.directSpecular + lightColor.ambient); - - // finnalColor = lightColor.testColor.xyz; + let normal:vec3 =normalize(input.normal); + let uv:vec2 = select(-input.uv,input.uv,input.frontFacing); + // ref: http://www.thetenthplanet.de/archives/1180 + // get edge vectors of the pixel triangle + let dp1:vec3 = vec3(dpdx(input.worldPos.x), dpdx(input.worldPos.y), dpdx(input.worldPos.z)); + let dp2:vec3 = vec3(dpdy(input.worldPos.x), dpdy(input.worldPos.y), dpdy(input.worldPos.z)); + let duv1:vec2 = dpdx(uv); + let duv2:vec2 = dpdy(uv); - return vec4(finnalColor,color.a); - }`; - }, - vert: function (e) { - return Di` - struct MaterialUniform { - modelMatrix: mat4x4, - color: vec3, - opacity:f32, - normalMatrix: mat4x4, - emissive:vec3, - specular:vec3, - shininess:f32, + // solve the linear system + let dp2perp:vec3 = cross(dp2, normal); + let dp1perp:vec3 = cross(normal, dp1); + let tangent:vec3 = dp2perp * duv1.x + dp1perp * duv2.x; + let binormal:vec3 = dp2perp * duv1.y + dp1perp * duv2.y; + // construct a scale-invariant frame + let result:f32=max(dot(tangent, tangent), dot(binormal, binormal)); + let invmax:f32 = 1.0/sqrt(result); + let tbn:mat3x3 = mat3x3(tangent * invmax, binormal * invmax, normal); + #endif + return tbn; } - #include - #include - #include - @binding(${e.phongBinding}) @group(0) var selfUniform : MaterialUniform; - @binding(${e.cameraBinding}) @group(1) var systemUniform : SystemUniform; - @vertex - fn main(input: VertexInput) -> VertexOutput { - var output: VertexOutput; - #if ${e.HAS_UV} - output.uv = input.uv; - #endif - let modelPos=selfUniform.modelMatrix *vec4(input.position,1.0); - output.worldPos = modelPos.xyz/modelPos.w; - let vNormalView = selfUniform.normalMatrix * vec4(input.normal,0.0); - output.normal = vNormalView.xyz; - output.view = systemUniform.cameraPosition.xyz - modelPos.xyz; - let viewPosition=systemUniform.viewMatrix * modelPos; - output.viewPosition = -viewPosition.xyz; - output.position = systemUniform.projectionMatrix * systemUniform.viewMatrix * modelPos; - return output; - }`; - } - }, - color: { - frag: function (e) { - return "\n struct VertexOutput {\n @builtin(position) position: vec4,\n @location(0) color: vec4,\n };\n @fragment\n fn main(input:VertexOutput) -> @location(0) vec4 {\n return input.color;\n }\n "; - }, - vert: function (e) { - return `\n struct VertexInput {\n @location(${e.positionLocation}) position: vec3, \n @location(${e.colorLocation}) color: vec4,\n }\n struct VertexOutput {\n @builtin(position) position: vec4,\n @location(0) color: vec4,\n };\n struct SelfUniform {\n modelMatrix: mat4x4,\n }\n struct SystemUniform {\n projectionMatrix: mat4x4,\n viewMatrix: mat4x4,\n inverseViewMatrix: mat4x4,\n cameraPosition: vec3,\n }; \n @binding(${e.colorBinding}) @group(0) var selfUniform : SelfUniform;\n @binding(${e.cameraBinding}) @group(1) var systemUniform : SystemUniform;\n @vertex\n fn main(input: VertexInput) -> VertexOutput {\n var output:VertexOutput;\n output.color=input.color;\n output.position = systemUniform.projectionMatrix * systemUniform.viewMatrix *selfUniform.modelMatrix*vec4(input.position,1.0);\n return output;\n }\n `; - } - }, - pbr: { - frag: function (e) { - return Di` - #include - #include - #include - #include - #include - #include - #include - #include - struct SystemUniform { - projectionMatrix: mat4x4, - viewMatrix: mat4x4, - inverseViewMatrix: mat4x4, - cameraPosition: vec3, - }; - // uniform vec3 lightProbe[9], -//////////////////////////////////// -struct VertexOutput { - @builtin(position) position: vec4, - @builtin(front_facing) is_front: bool, - @location(0) vUv: vec2, - @location(1) vViewPosition: vec3, // Vector from vertex to camera. - @location(2) vWorldPosition: vec3, - @location(3) vNormal: vec3, - // 可选 - #if ${e.USE_LIGHTTEXTURE || e.USE_AOTEXTURE} - @location(${e.vUv2OutLocation}) vUv2: vec2, - #endif + `; +} - #if ${e.USE_COLOR_ALPHA} - @location(${e.vColorOutLocation}) vColor: vec4, - #elif ${e.USE_COLOR || e.USE_INSTANCING_COLOR} - @location(${e.vColorOutLocation}) vColor: vec3, - #endif +function brdf(defines) { + return wgslParseDefines` + #if ${defines.USE_SHEEN} + fn D_Charlie( roughness:f32,dotNH:f32 )->f32 { + let alpha:f32 = pow2( roughness ); + let invAlpha:f32 = 1.0 / alpha; + let cos2h:f32 = dotNH * dotNH; + let sin2h:f32 = max( 1.0 - cos2h, 0.0078125 ); + return ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI ); + } + fn V_Neubelt( dotNV:f32, dotNL:f32 )->f32 { + return saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) ); + } + fn BRDF_Sheen(lightDir:vec3, viewDir:vec3, normal:vec3,sheenColor:vec3,sheenRoughness:f32 )->vec3 { + let halfDir:vec3 = normalize( lightDir + viewDir ); + let dotNL:f32 = saturate( dot( normal, lightDir ) ); + let dotNV:f32 = saturate( dot( normal, viewDir ) ); + let dotNH:f32 = saturate( dot( normal, halfDir ) ); + let D:f32 = D_Charlie( sheenRoughness, dotNH ); + let V:f32 = V_Neubelt( dotNV, dotNL ); + return sheenColor * ( D * V ); + } + #endif + fn BRDF_Lambert(diffuseColor:vec3)->vec3 { - #if ${e.USE_TANGENT} - @location(${e.vTangentOutLocation}) vTangent: vec3, - @location(${e.vBitangentOutLocation}) vBitangent: vec3, - #endif -}; - struct PhysicalMaterial { - diffuseColor:vec3, - roughness:f32, - specularColor:vec3, - specularF90:f32, - #if ${e.USE_CLEARCOAT} - clearcoat:f32, - clearcoatRoughness:f32, - clearcoatF0:vec3, - clearcoatF90:f32, - #endif + return RECIPROCAL_PI * diffuseColor; - #if ${e.USE_IRIDESCENCE} - iridescence:f32, - iridescenceIOR:f32, - iridescenceThickness:f32, - iridescenceFresnel:vec3, - iridescenceF0:vec3, - #endif + } // validated - #if ${e.USE_SHEEN} - sheenColor:vec3, - sheenRoughness:f32, - #endif + fn F_Schlick( f0:vec3, dotVH:f32 )->vec3 { - #if ${e.IOR} - ior:f32, - #endif + // Original approximation by Christophe Schlick '94 + // float fresnel = pow( 1.0 - dotVH, 5.0 ); - #if ${e.USE_TRANSMISSION} - transmission:f32, - transmissionAlpha:f32, - thickness:f32, - attenuationDistance:f32, - attenuationColor:vec3, - #endif - }; -@binding(0) @group(0) var materialUniform : MaterialUniform; -@binding(0) @group(1) var systemUniform : SystemUniform; -@fragment -fn main(input:VertexOutput)-> @location(0) vec4 { - var diffuseColor:vec4 = vec4(materialUniform.diffuse, materialUniform.opacity ); - // ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); - var reflectedLight:ReflectedLight; - var totalEmissiveRadiance:vec3 = materialUniform.emissive; - #if ${e.USE_TEXTURE} - var sampledDiffuseColor:vec4 =textureSample(baseTexture, baseSampler, input.vUv); - #if ${e.DECODE_VIDEO_TEXTURE} - sampledDiffuseColor = vec4( mix( pow( sampledDiffuseColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), sampledDiffuseColor.rgb * 0.0773993808, vec3( lessThanEqual( sampledDiffuseColor.rgb, vec3( 0.04045 ) ) ) ), sampledDiffuseColor.w ); - #endif + // Optimized variant (presented by Epic at SIGGRAPH '13) + // https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf + let fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH ); + return ( 1.0 - f0 ) * fresnel + f0; - diffuseColor *= sampledDiffuseColor; - #endif + } // validated - var roughnessFactor:f32 = materialUniform.roughness; - - #if ${e.USE_ROUGHNESSTEXTURE} - let texelRoughness:vec4=textureSample(roughnessTexture, baseSampler, input.vUv); - roughnessFactor *= texelRoughness.g; - #endif + fn Schlick_to_F0(f:vec3, f90:f32, dotVH:f32 )->vec3 { + let x:f32 = clamp( 1.0 - dotVH, 0.0, 1.0 ); + let x2:f32 = x * x; + let x5:f32 = clamp( x * x2 * x2, 0.0, 0.9999 ); - var metalnessFactor:f32 = materialUniform.metalness; - - #if ${e.USE_METALNESSTEXTURE} - let texelMetalness:vec4 =textureSample(metalnessTexture, baseSampler, input.vUv); - metalnessFactor *= texelMetalness.b; - #endif + return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 ); + } + fn V_GGX_SmithCorrelated( alpha:f32, dotNL:f32,dotNV:f32 )->f32 { - let faceDirection:f32 =select(-1.0,1.0,input.is_front); - #if ${e.FLAT_SHADED} - let fdx:vec3 = dpdx( input.vViewPosition ); - let fdy:vec3 = dpdy( input.vViewPosition ); - let normal:vec3 = normalize( cross( fdy, fdx ) ); - #else - let normal:vec3 = normalize( input.vNormal ); - #if ${e.DOUBLE_SIDED} - normal = normal * faceDirection; - #endif - #if ${e.USE_TANGENT} - let tangent:vec3 = normalize( input.vTangent ); - let bitangent:vec3 = normalize( input.vBitangent ); - #if ${e.DOUBLE_SIDED} - tangent = tangent * faceDirection; - bitangent = bitangent * faceDirection; - #endif - #if ${e.TANGENTSPACE_NORMALTEXTURE || e.USE_CLEARCOAT_NORMALTEXTURE} - let vTBN:mat3x3 = mat3x3( tangent, bitangent, normal ); - #endif - #endif - #endif - - let geometryNormal:vec3 = normal; + let a2 :f32= pow2( alpha ); - #if ${e.OBJECTSPACE_NORMALTEXTURE} - normal =textureSample(normalTexture, baseSampler, input.vUv).xyz * 2.0 - 1.0; - #if ${e.FLIP_SIDED} - normal = - normal; - #endif - #if ${e.DOUBLE_SIDED} - normal = normal * faceDirection; - #endif + let gv:f32 = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) ); + let gl:f32 = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) ); - normal = normalize(materialUniform.normalMatrix * normal ); + return 0.5 / max((gv + gl), 0.000000001 ); - #elif ${e.TANGENTSPACE_NORMALTEXTURE} - let tempMapN:vec3 =textureSample(normalTexture, baseSampler, input.vUv).xyz * 2.0 - 1.0; - let mapN:vec3 =tempMapN.xy *= materialUniform.normalScale; - #if ${e.USE_TANGENT} - normal = normalize( vTBN * mapN ); - #else - normal = perturbNormal2Arb( - input.vViewPosition, normal, mapN, faceDirection ); - #endif + } + fn D_GGX( alpha:f32, dotNH:f32 )->f32 { + + let a2:f32 = pow2( alpha ); - #elif ${e.USE_BUMPTEXTURE} + let denom:f32 = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0; // avoid alpha = 0 with dotNH = 1 - normal = perturbNormalArb( - input.vViewPosition, normal, dHdxy_fwd(), faceDirection ); - #endif + return RECIPROCAL_PI * a2 / pow2( denom ); - #if ${e.USE_CLEARCOAT} - var clearcoatNormal:vec3 = geometryNormal; - #endif - #if ${e.USE_CLEARCOAT_NORMALTEXTURE} - var clearcoatMapN:vec3 =textureSample(clearcoatNormalTexture, baseSampler, input.vUv).xyz * 2.0 - 1.0; - clearcoatMapN.xy *= materialUniform.clearcoatNormalScale; - #if ${e.USE_TANGENT} - clearcoatNormal = normalize( vTBN * clearcoatMapN ); - #else - clearcoatNormal = perturbNormal2Arb( - input.vViewPosition, clearcoatNormal, clearcoatMapN, faceDirection ); - #endif - #endif - #if ${e.USE_EMISSIVETEXTURE} - let emissiveColor:vec4 =textureSample(emissiveTexture, baseSampler, input.vUv); - totalEmissiveRadiance *= emissiveColor.rgb; - #endif + } + fn BRDF_GGX( lightDir:vec3, viewDir:vec3, normal:vec3, f0:vec3, roughness:f32 )->vec3 { - var material:PhysicalMaterial; - material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor ); - let dxy:vec3 = max( abs( dpdx( geometryNormal ) ), abs( dpdy( geometryNormal ) ) ); - let geometryRoughness:f32 = max( max( dxy.x, dxy.y ), dxy.z ); - material.roughness = max( roughnessFactor, 0.0525 ); - material.roughness += geometryRoughness; - material.roughness = min( material.roughness, 1.0 ); + let alpha:f32 = pow2( roughness ); // UE4's roughness - #if ${e.IOR} - material.ior = materialUniform.ior; - #if ${e.SPECULAR} - let specularIntensityFactor:f32 = materialUniform.specularIntensity; - let specularColorFactor:vec3 = materialUniform.specularColor; - #if ${e.USE_SPECULARINTENSITYTEXTURE} - specularIntensityFactor *=textureSample(specularIntensityTexture, baseSampler, input.vUv).a; - #endif + let halfDir = normalize( lightDir + viewDir ); - #if ${e.USE_SPECULARCOLORTEXTURE} - specularColorFactor *=textureSample(specularColorTexture, baseSampler, input.vUv).rgb; - #endif + let dotNL:f32 = saturate( dot( normal, lightDir ) ); + let dotNV:f32 = saturate( dot( normal, viewDir ) ); + let dotNH:f32 = saturate( dot( normal, halfDir ) ); + let dotVH:f32 = saturate( dot( lightDir, halfDir ) ); - material.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor ); - #else - let specularIntensityFactor:f32 = 1.0; - let specularColorFactor:vec3 = vec3( 1.0 ); - material.specularF90 = 1.0; - #endif - material.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor ); - #else - material.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor ); - material.specularF90 = 1.0; - #endif - #if ${e.USE_CLEARCOAT} - material.clearcoat = materialUniform.clearcoat; - material.clearcoatRoughness = materialUniform.clearcoatRoughness; - material.clearcoatF0 = vec3( 0.04 ); - material.clearcoatF90 = 1.0; - #if ${e.USE_CLEARCOATTEXTURE} - material.clearcoat *=textureSample(clearcoatTexture, baseSampler, input.vUv).x; - #endif - #if ${e.USE_CLEARCOAT_ROUGHNESSTEXTURE} - material.clearcoatRoughness *=textureSample(clearcoatRoughnessTexture, baseSampler, input.vUv).y; - #endif - material.clearcoat = saturate( material.clearcoat ); - material.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 ); - material.clearcoatRoughness += geometryRoughness; - material.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 ); - #endif - #if ${e.USE_IRIDESCENCE} - material.iridescence = materialUniform.iridescence; - material.iridescenceIOR = materialUniform.iridescenceIOR; - #if ${e.USE_IRIDESCENCETEXTURE} - material.iridescence *=textureSample(iridescenceTexture, baseSampler, input.vUv).r; - #endif - #if ${e.USE_IRIDESCENCE_THICKNESSTEXTURE} - material.iridescenceThickness = (materialUniform.iridescenceThicknessMaximum - materialUniform.iridescenceThicknessMinimum) * textureSample(iridescenceThicknessTexture, baseSampler, input.vUv).g + materialUniform.iridescenceThicknessMinimum; - #else - material.iridescenceThickness = materialUniform.iridescenceThicknessMaximum; - #endif - #endif - #if ${e.USE_SHEEN} - material.sheenColor = materialUniform.sheenColor; - #if ${e.USE_SHEENCOLORTEXTURE} - material.sheenColor *=textureSample(sheenColorTexture, baseSampler, input.vUv).rgb; - #endif - material.sheenRoughness = clamp( materialUniform.sheenRoughness, 0.07, 1.0 ); - #if ${e.USE_SHEENROUGHNESSTEXTURE} - material.sheenRoughness *=textureSample(sheenRoughnessTexture, baseSampler, input.vUv).a; - #endif - #endif - - var geometry:GeometricContext; - geometry.position = - input.vViewPosition; - geometry.normal = normal; - // geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( input.vViewPosition ); - geometry.viewDir = normalize( input.vViewPosition); + let F = F_Schlick( f0, dotVH ); - #if ${e.USE_CLEARCOAT} - geometry.clearcoatNormal = clearcoatNormal; - #endif + let V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV ); - #if ${e.USE_IRIDESCENCE} - let dotNVi:f32 = saturate( dot( normal, geometry.viewDir ) ); - if ( material.iridescenceThickness == 0.0 ) { - material.iridescence = 0.0; - } - else { - material.iridescence = saturate( material.iridescence ); - } - if ( material.iridescence > 0.0 ) { - material.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor ); - material.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi ); - } - #endif + let D = D_GGX( alpha, dotNH ); - var iblIrradiance:vec3 = vec3( 0.0 ); - var irradiance:vec3 = getAmbientLightIrradiance(commonLightsParms.ambient); - //irradiance += getLightProbeIrradiance( lightProbe, geometry.normal,systemUniform.viewMatrix ); + return F * ( V * D ); - var radiance:vec3 = vec3( 0.0 ); - var clearcoatRadiance:vec3 = vec3( 0.0 ); + } + fn direct_Physical( directLight:IncidentLight, geometry:Geometry,material:PhysicalMaterial)->ReflectedLight { + var reflectedLight:ReflectedLight; + let dotNL:f32 = saturate(dot( geometry.normal,geometry.viewDir)); + let irradiance:vec3 = dotNL * directLight.color*3.1415926; + reflectedLight.directSpecular = irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.roughness ); + reflectedLight.directDiffuse = irradiance * BRDF_Lambert( material.diffuseColor ); + return reflectedLight; + } + `; +} - #if ${e.USE_LIGHTTEXTURE} - let lightMapTexel:vec4 =textureSample(lightTexture, baseSampler, input.vUv2); - let lightMapIrradiance:vec3 = lightMapTexel.rgb * materialUniform.lightTextureIntensity; - irradiance += lightMapIrradiance; - #endif - //&& defines.STANDARD&&defines.ENVTEXTURE_TYPE_CUBE_UV - #if ${e.USE_ENVTEXTURE} - iblIrradiance += getIBLIrradiance( geometry.normal,baseSampler,systemUniform.viewMatrix ); - #endif - #if ${e.USE_ENVTEXTURE} - radiance += getIBLRadiance( geometry.viewDir,baseSampler,systemUniform.viewMatrix, geometry.normal, materialUniform.roughness ); - #if ${e.USE_CLEARCOAT} - clearcoatRadiance += getIBLRadiance( geometry.viewDir,baseSampler,systemUniform.viewMatrix, geometry.clearcoatNormal, material.clearcoatRoughness ); - #endif - #endif - //直接光照 - let dirReflectedLight:ReflectedLight= parseLights(geometry,material); - reflectedLight.directDiffuse +=dirReflectedLight.directDiffuse; - reflectedLight.directSpecular +=dirReflectedLight.directSpecular; - //间接漫反射 - let indirectDiffuseLight:ReflectedLight= RE_IndirectDiffuse_Physical( irradiance, geometry, material); - reflectedLight.directDiffuse +=indirectDiffuseLight.indirectDiffuse; - reflectedLight.directSpecular +=indirectDiffuseLight.indirectSpecular; - //间接高光 - let indirectSpecularLight:ReflectedLight=RE_IndirectSpecular_Physical( radiance, iblIrradiance, clearcoatRadiance, geometry, material); - reflectedLight.directDiffuse +=indirectSpecularLight.indirectDiffuse; - reflectedLight.directSpecular +=indirectSpecularLight.indirectSpecular; - //环境光遮蔽 - #if ${e.USE_AOTEXTURE} - let ambientOcclusion:f32 = (textureSample(aoTexture, baseSampler, input.vUv2).r - 1.0 ) * materialUniform.aoTextureIntensity + 1.0; +function ibl(defines) { + return wgslParseDefines` + fn getLightProbeRadiance( viewDir:vec3,normal:vec3, roughness:f32 )->vec3{ + var reflectVec:vec3 = reflect( -viewDir, normal ); + reflectVec.x = -reflectVec.x; // TextureCube is left-hand,so x need inverse + let mipCount:f32 = 10.0; // resolution of 256x256 + let lod:f32 = roughness * mipCount; + let specularLight:vec3 = textureSampleLevel(specularEnvTexture,specularEnvSampler, reflectVec, lod).rgb; + return specularLight; + } + fn getLightProbeIrradiance( lightProbe:array,9>, normal:vec3)->vec3 { + var worldNormal:vec3 = normal; + worldNormal.x = -normal.x; + var irradiance:vec3 = lightProbe[0]; + irradiance+=lightProbe[1] * (normal.y); + irradiance+=lightProbe[2] * (normal.z) ; + irradiance+=lightProbe[3] * (normal.x) ; - reflectedLight.indirectDiffuse *= ambientOcclusion; - //&&defines.STANDARD - #if ${e.USE_ENVTEXTURE} - let dotNV:f32 = saturate( dot( geometry.normal, geometry.viewDir ) ); - reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness ); - #endif - #endif + irradiance+=lightProbe[4] * (normal.y * normal.x) ; + irradiance+=lightProbe[5] * (normal.y * normal.z) ; + irradiance+=lightProbe[6] * (3.0 * normal.z * normal.z - 1.0); + irradiance+=lightProbe[7] * (normal.z * normal.x) ; + irradiance+=lightProbe[8] * (normal.x * normal.x - normal.y * normal.y); - var totalDiffuse:vec3 = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse; - var totalSpecular:vec3 = reflectedLight.directSpecular + reflectedLight.indirectSpecular; - //透射 - #if ${e.USE_TRANSMISSION} - material.transmission = materialUniform.transmission; - material.transmissionAlpha = 1.0; - material.thickness = materialUniform.thickness; - material.attenuationDistance = materialUniform.attenuationDistance; - material.attenuationColor = materialUniform.attenuationColor; - #if ${e.USE_TRANSMISSIONTEXTURE} - material.transmission *=textureSample(transmissionTexture, baseSampler, input.vUv).r; - #endif - #if ${e.USE_THICKNESSTEXTURE} - material.thickness *=textureSample(thicknessTexture, baseSampler, input.vUv).g; - #endif - let pos:vec3 = vWorldPosition; - let v:vec3 = normalize( cameraPosition - pos ); - let n:vec3 = inverseTransformDirection( normal, systemUniform.viewMatrix ); - let transmission:vec4 = getIBLVolumeRefraction( - n, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90, pos, modelMatrix, systemUniform.viewMatrix, systemUniform.projectionMatrix, material.ior, material.thickness, material.attenuationColor, material.attenuationDistance ); - material.transmissionAlpha = mix( material.transmissionAlpha, transmission.a, material.transmission ); - totalDiffuse = mix( totalDiffuse, transmission.rgb, material.transmission ); - #endif + return max(irradiance, vec3(0.0,0.0,0.0)); + } + fn DFGApprox( specularColor:vec3, roughness:f32,dotNV:f32 )->vec3 { + const c0:vec4 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); + let c1:vec4 = vec4( 1, 0.0425, 1.04, - 0.04 ); + let r:vec4 = roughness * c0 + c1; + let a004:f32 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; + let fab:vec2 = vec2( - 1.04, 1.04 ) * a004 + r.zw; + return specularColor * fab.x + fab.y; + } + //间接光照 + fn indirectDiffuse_Physical(geometry:Geometry, material:PhysicalMaterial )->ReflectedLight { + var reflectedLight:ReflectedLight; + var irradiance:vec3 = lightUniforms.ambient.xyz*lightUniforms.ambient.w; + irradiance *= PI; + reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); + return reflectedLight; + } + //间接高光 + fn indirectSpecular_Physical(geometry:Geometry, material:PhysicalMaterial)->ReflectedLight { + var reflectedLight:ReflectedLight; + // IBL specular + let radiance:vec3 = getLightProbeRadiance(geometry.viewDir, geometry.normal, material.roughness); + let radianceAttenuation:f32 = 1.0; + reflectedLight.indirectSpecular += radianceAttenuation * radiance * DFGApprox(material.specularColor, material.roughness, geometry.dotNV ); + return reflectedLight; + } + `; +} - let outgoingLight:vec3 = totalDiffuse + totalSpecular + totalEmissiveRadiance; +function pbrFunction(defines) { + return wgslParseDefines` - #if ${e.USE_SHEEN} - let sheenEnergyComp:f32 = 1.0 - 0.157 * max3( material.sheenColor ); - outgoingLight = outgoingLight * sheenEnergyComp + sheenSpecular; - #endif + #if ${defines.DITHERING} + fn dithering(color:vec3 )->vec3 { + let grid_position:f32 = rand( gl_FragCoord.xy ); + let dither_shift_RGB:vec3 = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 ); + dither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position ); + return color + dither_shift_RGB; + } + #endif - #if ${e.USE_CLEARCOAT} - let dotNVcc:f32 = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) ); - let Fcc:vec3 = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc ); - outgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + clearcoatSpecular * material.clearcoat; - #endif + #if ${defines.USE_IRIDESCENCE} + fn BRDF_GGX_Iridescence( lightDir:vec3, viewDir:vec3,normal:vec3, f0:vec3, f90:f32,iridescence:f32, iridescenceFresnel:vec3,roughness:f32 )->vec3 { + let alpha:f32 = pow2( roughness ); + let halfDir:vec3 = normalize( lightDir + viewDir ); + let dotNL:f32 = saturate( dot( normal, lightDir ) ); + let dotNV:f32 = saturate( dot( normal, viewDir ) ); + let dotNH:f32 = saturate( dot( normal, halfDir ) ); + let dotVH:f32 = saturate( dot( viewDir, halfDir ) ); + let F:vec3 = mix( F_Schlick( f0, f90, dotVH ), iridescenceFresnel, iridescence ); + let V:f32 = V_GGX_SmithCorrelated( alpha, dotNL, dotNV ); + let D:f32 = D_GGX( alpha, dotNH ); + return F * ( V * D ); + } + #endif - #if ${e.USE_TRANSMISSION} - diffuseColor.a *= material.transmissionAlpha + 0.1; - #endif + #if ${defines.USE_SHEEN} + fn D_Charlie( roughness:f32,dotNH:f32 )->f32 { + let alpha:f32 = pow2( roughness ); + let invAlpha:f32 = 1.0 / alpha; + let cos2h:f32 = dotNH * dotNH; + let sin2h:f32 = max( 1.0 - cos2h, 0.0078125 ); + return ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI ); + } + fn V_Neubelt( dotNV:f32, dotNL:f32 )->f32 { + return saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) ); + } + fn BRDF_Sheen(lightDir:vec3, viewDir:vec3, normal:vec3,sheenColor:vec3,sheenRoughness:f32 )->vec3 { + let halfDir:vec3 = normalize( lightDir + viewDir ); + let dotNL:f32 = saturate( dot( normal, lightDir ) ); + let dotNV:f32 = saturate( dot( normal, viewDir ) ); + let dotNH:f32 = saturate( dot( normal, halfDir ) ); + let D:f32 = D_Charlie( sheenRoughness, dotNH ); + let V:f32 = V_Neubelt( dotNV, dotNL ); + return sheenColor * ( D * V ); + } + #endif - var finnalColor:vec4; - finnalColor = vec4( outgoingLight, diffuseColor.a ); - #if ${e.TONE_MAPPING} - finnalColor.rgb = toneMapping( finnalColor.rgb,materialUniform.toneMappingExposure ); - #endif + #if ${defines.USE_IRIDESCENCE} + let XYZ_TO_REC709: mat3x3 = mat3x3( + 3.2404542, -0.9692660, 0.0556434, -1.5371385, 1.8760108, -0.2040259, -0.4985314, 0.0415560, 1.0572252 + ); + fn Fresnel0ToIor( fresnel0:vec3 )->vec3 { + let sqrtF0:vec3 = sqrt( fresnel0 ); + return ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 ); + } + fn IorToFresnel0(transmittedIor:vec3,incidentIor:f32 )->vec3 { + return pow2Vector( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) ); + } + fn IorToFresnel0(transmittedIor:f32, incidentIor:f32 )->f32 { + return pow2Vector( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor )); + } + fn evalSensitivity(OPD:f32,shift:vec3 )->vec3 { + let phase:f32 = 2.0 * PI * OPD * 1.0e-9; + let val:vec3 = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 ); + let pos:vec3 = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 ); + let vart:vec3 = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 ); + let xyz:vec3 = val * sqrt( 2.0 * PI * vart ) * cos( pos * phase + shift ) * exp( - pow2( phase ) * vart ); + xyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[ 0 ] ) * exp( - 4.5282e+09 * pow2( phase ) ); + xyz /= 1.0685e-7; + let rgb:vec3 = XYZ_TO_REC709 * xyz; + return rgb; + } + fn evalIridescence(outsideIOR:f32, eta2:f32,cosTheta1:f32,thinFilmThickness:f32,baseF0:vec3 )->vec3 { + var I:vec3; + let iridescenceIOR:f32 = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) ); + let sinTheta2Sq:f32 = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) ); + let cosTheta2Sq:f32 = 1.0 - sinTheta2Sq; + if ( cosTheta2Sq < 0.0 ) { + return vec3( 1.0 ); + } + let cosTheta2:f32 = sqrt( cosTheta2Sq ); + let R0:f32 = IorToFresnel0( iridescenceIOR, outsideIOR ); + let R12:f32 = F_Schlick( R0, 1.0, cosTheta1 ); + let R21:f32 = R12; + let T121:f32 = 1.0 - R12; + let phi12:f32 = 0.0; + if ( iridescenceIOR < outsideIOR ) phi12 = PI; + let phi21:f32 = PI - phi12; + let baseIOR:vec3 = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) ); + let R1:vec3 = IorToFresnel0( baseIOR, iridescenceIOR ); + let R23:vec3 = F_Schlick( R1, 1.0, cosTheta2 ); + let phi23:vec3 = vec3( 0.0 ); + if ( baseIOR[ 0 ] < iridescenceIOR ) phi23[ 0 ] = PI; + if ( baseIOR[ 1 ] < iridescenceIOR ) phi23[ 1 ] = PI; + if ( baseIOR[ 2 ] < iridescenceIOR ) phi23[ 2 ] = PI; + let OPD:f32 = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2; + let phi:vec3 = vec3( phi21 ) + phi23; + let R123:vec3 = clamp( R12 * R23, 1e-5, 0.9999 ); + let r123:vec3 = sqrt( R123 ); + let Rs:vec3 = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 ); + let C0:vec3 = R12 + Rs; + I = C0; + let Cm:vec3 = Rs - T121; + for ( let m : u32 = 1;m <= 2; ++ m ) { + Cm *= r123; + Sm:vec3 = 2.0 * evalSensitivity( f32( m ) * OPD, f32( m ) * phi ); + I += Cm * Sm; + } + return max( I, vec3( 0.0 ) ); + } + #endif + const clearcoatSpecular:vec3 = vec3( 0.0 ); + const sheenSpecular:vec3 = vec3( 0.0 ); - finnalColor = linearToOutputTexel( finnalColor); + fn IBLSheenBRDF( normal:vec3, viewDir:vec3, roughness:f32 )->f32 { + let dotNV:f32 = saturate( dot( normal, viewDir ) ); + let r2:f32 = roughness * roughness; + let a:f32 =select(-8.48 * r2 + 14.3 * roughness - 9.95,-339.2 * r2 + 161.4 * roughness - 25.9,roughness < 0.25); + //let a:f32 = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95; + let b:f32=select(1.97 * r2 - 3.27 * roughness + 0.72,44.0 * r2 - 23.7 * roughness + 3.26, roughness < 0.25); + //let b:f32 = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72; + //let DG:f32 = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) ); + let DG:f32 = exp( a * dotNV + b ) + select(0.1 * ( roughness - 0.25 ),0.0,roughness < 0.25); + return saturate( DG * RECIPROCAL_PI ); + } + fn DFGApprox( specularColor:vec3, roughness:f32,dotNV:f32 )->vec3 { + const c0:vec4 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); + let c1:vec4 = vec4( 1, 0.0425, 1.04, - 0.04 ); + let r:vec4 = roughness * c0 + c1; + let a004:f32 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; + let fab:vec2 = vec2( - 1.04, 1.04 ) * a004 + r.zw; + return specularColor * fab.x + fab.y; + } + fn EnvironmentBRDF( normal:vec3,viewDir:vec3,specularColor:vec3, specularF90:f32,roughness:f32 )->vec3 { + let fab:vec2 = DFGApprox( normal, viewDir, roughness ); + return specularColor * fab.x + specularF90 * fab.y; + } - #if ${e.PREMULTIPLIED_ALPHA} - finnalColor.rgb *= finnalColor.a; - #endif - #if ${e.DITHERING} - finnalColor.rgb = dithering( finnalColor.rgb ); - #endif - return finnalColor; - }`; - }, - vert: function (e) { - return Di` - #include - struct VertexOutput { - @builtin(position) position: vec4, - @location(0) vUv: vec2, - @location(1) vViewPosition: vec3, // Vector from vertex to camera. - @location(2) vWorldPosition: vec3, - @location(3) vNormal: vec3, - // 可选 - #if ${e.USE_LIGHTTEXTURE || e.USE_AOTEXTURE} - @location(${e.vUv2OutLocation}) vUv2: vec2, - #endif - #if ${e.USE_COLOR_ALPHA} - @location(${e.vColorOutLocation}) vColor: vec4, - #elif ${e.USE_COLOR || e.USE_INSTANCING_COLOR} - @location(${e.vColorOutLocation}) vColor: vec3, - #endif + fn computeSpecularOcclusion( dotNV:f32, ambientOcclusion:f32, roughness:f32 )->f32 { + return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion ); + } + #if ${defines.USE_TRANSMISSION} - #if ${e.USE_TANGENT} - @location(${e.vTangentOutLocation}) vTangent: vec3, - @location(${e.vBitangentOutLocation}) vBitangent: vec3, - #endif - }; - struct GlobalUniform { - projectionMatrix: mat4x4, - viewMatrix: mat4x4, - inverseViewMatrix: mat4x4, - cameraPosition: vec3, - }; + fn getVolumeTransmissionRay( n:vec3, v:vec3, thickness:f32, ior:f32, modelMatrix:mat4x4:f32)->vec3 { + var refractionVector:vec3 = refract( - v, normalize( n ), 1.0 / ior ); + var modelScale:vec3; + modelScale.x = length( vec3( modelMatrix[0].xyz ) ); + modelScale.y = length( vec3( modelMatrix[1].xyz ) ); + modelScale.z = length( vec3( modelMatrix[2].xyz ) ); + return normalize( refractionVector ) * thickness * modelScale; + } + fn applyIorToRoughness(roughness:f32, ior:f32 )->f32 { + return roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 ); + } + fn getTransmissionSample( fragCoord:vec2, roughness:f32,ior:f32 )->vec4 { + let framebufferLod:f32 = log2( materialUniform.transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior ); + return textureSampleLevel(transmissionSamplerTexture,baseSampler,fragCoord.xy, framebufferLod); - //texture and sampler - // @group(0) @binding(${e.samplerBinding}) var baseSampler: sampler; - #if ${e.USE_SKINNING} - //uniform highp sampler2D boneTexture; - @group(0) @binding(${e.boneTextureBinding}) var boneTexture: texture_2d; + } + fn applyVolumeAttenuation( radiance:vec3, transmissionDistance:f32,attenuationColor:vec3,attenuationDistance:f32 )->vec3 { + if ( isinf( attenuationDistance ) ) { + return radiance; + } + else { + let attenuationCoefficient:vec3 = -log( attenuationColor ) / attenuationDistance; + let transmittance:vec3 = exp( - attenuationCoefficient * transmissionDistance ); + return transmittance * radiance; + } + + } + fn getIBLVolumeRefraction( n:vec3,v:vec3, roughness:f32, diffuseColor:vec3,specularColor:vec3, specularF90:f32,position:vec3, modelMatrix:mat4x4, viewMatrix:mat4x4,projMatrix:mat4x4,ior:f32, thickness:f32,attenuationColor:vec3,attenuationDistance:f32 )->vec4 { + let transmissionRay:vec3 = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix ); + let refractedRayExit:vec3 = position + transmissionRay; + let ndcPos:vec4 = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 ); + let refractionCoords:vec2 = ndcPos.xy / ndcPos.w; + refractionCoords += 1.0; + refractionCoords /= 2.0; + let transmittedLight:vec4 = getTransmissionSample( refractionCoords, roughness, ior ); + let attenuatedColor:vec3 = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance ); + let F:vec3 = EnvironmentBRDF( n, v, specularColor, specularF90, roughness ); + return vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a ); + } #endif - #if ${e.USE_DISPLACEMENTTEXTURE} - //uniform sampler2D displacementMap; - @group(0) @binding(${e.displacementTextureBinding}) var displacementMap: texture_2d; - #endif + #if ${defines.USE_BUMPTEXTURE} + fn dHdxy_fwd()->vec2 { + let dSTdx:vec2 = dpdx( vUv ); + let dSTdy:vec2 = dpdy( vUv ); - #if ${e.MORPHTARGETS_TEXTURE} - //uniform sampler2DArray morphTargetsTexture; - @group(0) @binding(${e.morphTargetsTextureBinding}) var morphTargetsTexture: texture_2d_array; + let Hll:f32 = materialUniform.bumpScale * textureSample(bumpTexture, baseSampler, vUv).x; + let dBx:f32 = materialUniform.bumpScale * textureSample(bumpTexture, baseSampler, vUv + dSTdx).x - Hll; + let dBy:f32 = materialUniform.bumpScale * textureSample(bumpTexture, baseSampler, vUv + dSTdy).x - Hll; + return vec2( dBx, dBy ); + } + fn perturbNormalArb( surf_pos:vec3, surf_norm:vec3, dHdxy:vec2, faceDirection:f32 )->vec3 { + let vSigmaX:vec3 = dpdx( surf_pos.xyz ); + let vSigmaY:vec3 = dpdy( surf_pos.xyz ); + let vN:vec3 = surf_norm; + let R1:vec3 = cross( vSigmaY, vN ); + let R2:vec3 = cross( vN, vSigmaX ); + let fDet:f32 = dot( vSigmaX, R1 ) * faceDirection; + let vGrad:vec3 = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 ); + return normalize( abs( fDet ) * surf_norm - vGrad ); + } #endif - struct VertexInput { - @location(0) position: vec3, + //! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALTEXTURE ) || defined ( USE_CLEARCOAT_NORMALTEXTURE ) ) + #if ${(!defines.USE_TANGENT && defines.TANGENTSPACE_NORMALTEXTURE) || defines.USE_CLEARCOAT_NORMALTEXTURE} + fn perturbNormal2Arb( eye_pos:vec3, surf_norm:vec3, textureN:vec3, faceDirection:f32 )->vec3 { + let q0:vec3 = dpdx( eye_pos.xyz ); + let q1:vec3 = dpdy( eye_pos.xyz ); + let st0:vec2 = dpdx( vUv.st ); + let st1:vec2 = dpdy( vUv.st ); + let N:vec3 = surf_norm; + let q1perp:vec3 = cross( q1, N ); + let q0perp:vec3 = cross( N, q0 ); + let T:vec3 = q1perp * st0.x + q0perp * st1.x; + let B:vec3 = q1perp * st0.y + q0perp * st1.y; + let det:f32 = max( dot( T, T ), dot( B, B ) ); + let scale:f32 = ( det == 0.0 ) ? 0.0 : faceDirection * inversesqrt( det ); + return normalize( T * ( textureN.x * scale ) + B * ( textureN.y * scale ) + N * textureN.z ); + } + #endif + struct MultiAndSingleScatter{ + multiScatter:vec3, + singleScatter:vec3 + } + #if ${defines.USE_IRIDESCENCE} + ////////inout vec3 singleScatter, inout vec3 multiScatter + fn computeMultiscatteringIridescence( normal:vec3, viewDir:vec3, specularColor:vec3, specularF90:f32, iridescence:f32,iridescenceF0:vec3, roughness:f32 )->MultiAndSingleScatter { + #else + ////////inout vec3 singleScatter, inout vec3 multiScatter + fn computeMultiscattering( normal:vec3,viewDir:vec3, specularColor:vec3, specularF90:f32, roughness:f32)->MultiAndSingleScatter { + #endif + let fab:vec2 = DFGApprox( normal, viewDir, roughness ); - @location(1) normal: vec3, + var multiAndSingleScatter:MultiAndSingleScatter; - @location(2) uv: vec2, - #if ${e.USE_LIGHTTEXTURE || e.USE_AOTEXTURE} - @location(${e.uv2Location}) uv2:vec2, - #endif - #if ${e.USE_INSTANCING} - @location(${e.instanceMatrixLocation}) instanceMatrix:mat4x4, - #endif - #if ${e.USE_INSTANCING_COLOR} - @location(${e.instanceColorLocation}) instanceColor:vec3, - #endif - - #if ${e.USE_TANGENT} - @location(${e.tangentLocation}) tangent:vec4, - #endif - #if ${e.USE_COLOR_ALPHA} - @location(${e.colorLocation}) color:vec4, - #elif ${e.USE_COLOR} - @location(${e.colorLocation}) color:vec3, - #endif + #if ${defines.USE_IRIDESCENCE} + let Fr:vec3 = mix( specularColor, iridescenceF0, iridescence ); + #else + let Fr:vec3 = specularColor; + #endif + let FssEss:vec3 = Fr * fab.x + specularF90 * fab.y; + let Ess:f32 = fab.x + fab.y; + let Ems:f32 = 1.0 - Ess; + let Favg:vec3 = Fr + ( 1.0 - Fr ) * 0.047619; + let Fms:vec3 = FssEss * Favg / ( 1.0 - Ems * Favg ); + // singleScatter += FssEss; + // multiScatter += Fms * Ems; + multiAndSingleScatter.multiScatter=Fms * Ems; + multiAndSingleScatter.singleScatter=FssEss; + return multiAndSingleScatter; + } + //直接光照 + fn RE_Direct_Physical( directLight:IncidentLight, geometry:GeometricContext, material:PhysicalMaterial)->ReflectedLight { + var reflectedLight:ReflectedLight; + let dotNL:f32 = saturate(dot( geometry.normal, directLight.direction)); + let irradiance:vec3 = dotNL * directLight.color; + #if ${defines.USE_CLEARCOAT} + let dotNLcc:f32 = saturate( dot( geometry.clearcoatNormal, directLight.direction ) ); + let ccIrradiance:vec3 = dotNLcc * directLight.color; + clearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness ); + #endif - #if ${e.USE_MORPHTARGETS && !e.MORPHTARGETS_TEXTURE} - @location(${e.morphTarget0Location}) morphTarget0:vec3, + #if ${defines.USE_SHEEN} + sheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness ); + #endif - @location(${e.morphTarget1Location}) morphTarget1:vec3, + #if ${defines.USE_IRIDESCENCE} + reflectedLight.directSpecular = irradiance * BRDF_GGX_Iridescence( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness ); + #else + reflectedLight.directSpecular = irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness ); + #endif + reflectedLight.directDiffuse = irradiance * BRDF_Lambert( material.diffuseColor ); + return reflectedLight; + } + //间接光照 + fn RE_IndirectDiffuse_Physical( irradiance:vec3, geometry:GeometricContext, material:PhysicalMaterial )->ReflectedLight { + var reflectedLight:ReflectedLight; + reflectedLight.indirectDiffuse = irradiance * BRDF_Lambert( material.diffuseColor ); + return reflectedLight; + } + //间接高光 + fn RE_IndirectSpecular_Physical( radiance:vec3, irradiance:vec3, clearcoatRadiance:vec3, geometry:GeometricContext, material:PhysicalMaterial)->ReflectedLight { + var reflectedLight:ReflectedLight; + #if ${defines.USE_CLEARCOAT} + clearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness ); + #endif + #if ${defines.USE_SHEEN} + sheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness ); + #endif + var singleScattering:vec3; + var multiScattering:vec3; + let cosineWeightedIrradiance:vec3 = irradiance * RECIPROCAL_PI; + var tempMultiAndSingleScatter:MultiAndSingleScatter; + #if ${defines.USE_IRIDESCENCE} + tempMultiAndSingleScatter=computeMultiscatteringIridescence( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness ); + #else + tempMultiAndSingleScatter= computeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness ); + #endif + singleScattering=tempMultiAndSingleScatter.singleScatter; + multiScattering=tempMultiAndSingleScatter.multiScatter; + let totalScattering:vec3 = singleScattering + multiScattering; + let diffuse:vec3 = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) ); + reflectedLight.indirectSpecular = radiance * singleScattering; + reflectedLight.indirectSpecular = multiScattering * cosineWeightedIrradiance; + reflectedLight.indirectDiffuse = diffuse * cosineWeightedIrradiance; + return reflectedLight; + } + `; +} - @location(${e.morphTarget2Location}) morphTarget2:vec3, +function pbrStruct(defines) { + return wgslParseDefines` + struct MaterialUniform{ - @location(${e.morphTarget3Location}) morphTarget3:vec3, - #if ${e.USE_MORPHNORMALS} - @location(${e.morphNormal0Location}) morphNormal0:vec3, + modelMatrix: mat4x4, + + diffuse:vec3, + + opacity:f32, + + normalMatrix: mat3x3, + + emissive:vec3, + + roughness:f32, + + metalness:f32, + + #if ${defines.TONE_MAPPING} + toneMappingExposure:f32, + #endif + + #if ${defines.SPECULAR} + + specularColor:vec3, + + specularIntensity:f32, + #endif + + #if ${defines.USE_SHEEN} + + sheenColor:vec3, + + sheenRoughness:f32, + #endif - @location(${e.morphNormal1Location}) morphNormal1:vec3, + #if ${defines.USE_TRANSMISSION} + + attenuationColor:vec3, + + transmission:f32, + + transmissionSamplerSize:vec2, + + thickness:f32, + + attenuationDistance:f32, + + #endif - @location(${e.morphNormal2Location}) morphNormal2:vec3, + #if ${defines.USE_SKINNING} + + bindMatrix:mat4x4, + + bindMatrixInverse:mat4x4, + + boneTextureSize:u32, + #endif - @location(${e.morphNormal3Location}) morphNormal3:vec3, - #else - @location(${e.morphTarget4Location}) morphTarget4:vec3, + #if ${defines.USE_NORMALTEXTURE} + normalScale:vec2, + #endif + + #if ${defines.IOR} + ior:f32, + #endif + + #if ${defines.USE_CLEARCOAT} + + #if ${defines.USE_CLEARCOAT_NORMALTEXTURE} + clearcoatNormalScale:vec2, + #endif + + clearcoat:f32, + + clearcoatRoughness:f32, + #endif + + #if ${defines.USE_IRIDESCENCE} + iridescence:f32, + + iridescenceIOR:f32, + + iridescenceThicknessMinimum:f32, + + iridescenceThicknessMaximum:f32, + + #endif - @location(${e.morphTarget5Location}) morphTarget5:vec3, + #if ${defines.USE_AOTEXTURE} + aoTextureIntensity:f32, + #endif - @location(${e.morphTarget6Location}) morphTarget6:vec3, + #if ${defines.USE_LIGHTTEXTURE} + lightTextureIntensity:f32, + #endif + + #if ${defines.USE_ENVTEXTURE} + envTextureIntensity:f32, + + flipEnvTexture:f32, + #endif - @location(${e.morphTarget7Location}) morphTarget7:vec3, + #if ${defines.USE_BUMPTEXTURE} + bumpScale:f32; #endif - #endif - #if ${e.USE_SKINNING} - @location(${e.skinIndexLocation}) skinIndex:vec4, - @location(${e.skinWeightLocation}) skinWeight:vec4, - #endif - } - #if ${e.MORPHTARGETS_TEXTURE} - fn getMorph( vertexIndex:u32, morphTargetIndex:u32,offset:u32 )->vec4 { - let texelIndex:u32 = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset; - let y:u32 = texelIndex / materialUniform.morphTargetsTextureSize.x; - let x:u32 = texelIndex - y * materialUniform.morphTargetsTextureSize.x; - let morphUV:vec3 = vec3( x, y, morphTargetIndex ); - //textureLoad - //return texelFetch( morphTargetsTexture, morphUV, 0 ); - return textureLoad( morphTargetsTexture, morphUV, 0 ); - } - #endif - #if ${e.USE_SKINNING} - fn getBoneMatrix( i:f32 )->mat4x4 { - let j:f32 = i * 4.0; - let x:f32 = j%f32( materialUniform.boneTextureSize ); - let y:f32 = floor( j / f32( materialUniform.boneTextureSize ) ); - let dx:f32 = 1.0 / f32( materialUniform.boneTextureSize ); - let dy:f32 = 1.0 / f32( materialUniform.boneTextureSize ); - y = dy * ( y + 0.5 ); + #if ${defines.USE_DISPLACEMENTTEXTURE} + + displacementScale:f32, + + displacementBias:f32, + #endif - let v1:vec4 = textureSample(boneTexture, baseSampler, vec2( dx * ( x + 0.5 ), y ) ); - let v2:vec4 = textureSample(boneTexture, baseSampler, vec2( dx * ( x + 1.5 ), y ) ); - let v3:vec4 = textureSample(boneTexture, baseSampler, vec2( dx * ( x + 2.5 ), y ) ); - let v4:vec4 = textureSample(boneTexture, baseSampler, vec2( dx * ( x + 3.5 ), y ) ); - let bone:mat4x4 = mat4x4( v1, v2, v3, v4 ); - return bone; + #if ${defines.USE_MORPHTARGETS} + + morphTargetBaseInfluence:f32, + + #if ${defines.MORPHTARGETS_TEXTURE} + + morphTargetsTextureSize:vec2, + + MORPHTARGETS_COUNT:u32, + + #endif + + morphTargetInfluences:array, + + #endif } - #endif - @binding(0) @group(0) var materialUniform : MaterialUniform; - @binding(0) @group(1) var globalUniform : GlobalUniform; - @vertex - fn main(input:VertexInput)->VertexOutput { - var vertexOutput:VertexOutput; - #if ${e.USE_TEXTURE} - vertexOutput.vUv = input.uv; - #endif - #if ${e.USE_LIGHTTEXTURE || e.USE_AOTEXTURE} - vertexOutput.vUv2 input.uv2; - #endif - #if ${e.USE_COLOR_ALPHA} - vertexOutput.vColor = vec4( 1.0 ); - #elif ${e.USE_COLOR || e.USE_INSTANCING_COLOR} - vertexOutput.vColor = vec3( 1.0 ); - #endif - #if ${e.USE_COLOR} - vertexOutput.vColor *= input.color; - #endif - #if ${e.USE_INSTANCING_COLOR} - vertexOutput.vColor.xyz *= input.instanceColor.xyz; - #endif - #if ${e.USE_MORPHCOLORS && e.MORPHTARGETS_TEXTURE} - vertexOutput.vColor *= materialUniform.morphTargetBaseInfluence; - for (let i : u32 = 0u; i < materialUniform.MORPHTARGETS_COUNT; i = i + 1u ) { - #if ${e.USE_COLOR_ALPHA} - if ( materialUniform.morphTargetInfluences[ i ] ! = 0.0 ) vertexOutput.vColor += getMorph( gl_VertexID, i, 2 ) * materialUniform.morphTargetInfluences[ i ]; - #elif ${e.USE_COLOR} - if ( materialUniform.morphTargetInfluences[ i ] ! = 0.0 ) vertexOutput.vColor += getMorph( gl_VertexID, i, 2 ).rgb * materialUniform.morphTargetInfluences[ i ]; + `; +} + +function pbrTexture(defines) { + return wgslParseDefines` + #if ${defines.USE_BUMPTEXTURE} + @group(0) @binding(${defines.bumpTextureBinding}) var bumpTexture: texture_2d; + #endif + #if ${defines.USE_TRANSMISSION} + #if ${defines.USE_TRANSMISSIONTEXTURE} + @group(0) @binding(${defines.transmissionTextureBinding}) var transmissionTexture: texture_2d; #endif - } - #endif - var objectNormal:vec3 = vec3(input.normal); - #if ${e.USE_TANGENT} - let objectTangent:vec3 = vec3( input.tangent.xyz ); - #endif - #if ${e.USE_MORPHNORMALS} - objectNormal *= materialUniform.morphTargetBaseInfluence; - #if ${e.MORPHTARGETS_TEXTURE} - for ( let i : u32 = 0u; i < materialUniform.MORPHTARGETS_COUNT; i = i + 1u) { - if ( materialUniform.morphTargetInfluences[ i ] ! = 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * materialUniform.morphTargetInfluences[ i ]; - } - #else - objectNormal += morphNormal0 * materialUniform.morphTargetInfluences[ 0 ]; - objectNormal += morphNormal1 * materialUniform.morphTargetInfluences[ 1 ]; - objectNormal += morphNormal2 * materialUniform.morphTargetInfluences[ 2 ]; - objectNormal += morphNormal3 * materialUniform.morphTargetInfluences[ 3 ]; + #if ${defines.USE_THICKNESSTEXTURE} + @group(0) @binding(${defines.thicknessTextureBinding}) var thicknessTexture: texture_2d; + #endif + @group(0) @binding(${defines.transmissionSamplerTextureBinding}) var transmissionSamplerTexture: texture_2d; #endif - #endif - #if ${e.USE_SKINNING} - let boneMatX:mat4x4 = getBoneMatrix( input.skinIndex.x ); - let boneMatY:mat4x4 = getBoneMatrix( input.skinIndex.y ); - let boneMatZ:mat4x4 = getBoneMatrix( input.skinIndex.z ); - let boneMatW:mat4x4 = getBoneMatrix( input.skinIndex.w ); - #endif - #if ${e.USE_SKINNING} - let skinMatrix:mat4x4 = mat4x4( 0.0 ); - skinMatrix += input.skinWeight.x * boneMatX; - skinMatrix += input.skinWeight.y * boneMatY; - skinMatrix += input.skinWeight.z * boneMatZ; - skinMatrix += input.skinWeight.w * boneMatW; - skinMatrix = materialUniform.bindMatrixInverse * skinMatrix * materialUniform.bindMatrix; - objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz; - #if ${e.USE_TANGENT} - objectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz; + #if ${defines.USE_ENVTEXTURE} + @group(0) @binding(${defines.envTextureBinding}) var envTexture: texture_cube; #endif - #endif - var transformedNormal:vec3 = objectNormal; - // transformedNormal+=vec3(0.0); - #if ${e.USE_INSTANCING} - let m:mat3x3 = mat3x3( input.instanceMatrix ); - transformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) ); - transformedNormal = m * transformedNormal; - #endif - transformedNormal = materialUniform.normalMatrix * transformedNormal; - #if ${e.FLIP_SIDED} - transformedNormal = - transformedNormal; - #endif - #if ${e.USE_TANGENT} - let transformedTangent:vec3 = (globalUniform.viewMatrix*materialUniform.modelMatrix * vec4( objectTangent, 0.0 ) ).xyz; - #if ${e.FLIP_SIDED} - transformedTangent = - transformedTangent; + #if ${defines.USE_NORMALTEXTURE} + @group(0) @binding(${defines.normalTextureBinding}) var normalTexture: texture_2d; #endif - #endif - vertexOutput.vNormal = normalize( transformedNormal ); - #if ${e.FLAT_SHADED} - #if ${e.USE_TANGENT} - vTangent = normalize( transformedTangent ); - vBitangent = normalize( cross( vNormal, vTangent ) * input.tangent.w ); + + #if ${defines.USE_CLEARCOATTEXTURE} + @group(0) @binding(${defines.clearcoatTextureBinding}) var clearcoatTexture: texture_2d; #endif - #endif - let transformed:vec3 = vec3( input.position ); - #if ${e.USE_MORPHTARGETS} - transformed *= materialUniform.morphTargetBaseInfluence; - #if ${e.MORPHTARGETS_TEXTURE} - for ( let i : u32 = 0u; i < materialUniform.MORPHTARGETS_COUNT; i = i + 1u ) { - if ( materialUniform.morphTargetInfluences[ i ] ! = 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ]; - } - #else - transformed += input.morphTarget0 * materialUniform.morphTargetInfluences[ 0 ]; - transformed += input.morphTarget1 * materialUniform.morphTargetInfluences[ 1 ]; - transformed += input.morphTarget2 * materialUniform.morphTargetInfluences[ 2 ]; - transformed += input.morphTarget3 * materialUniform.morphTargetInfluences[ 3 ]; - #if ${e.USE_MORPHNORMALS} - transformed += input.morphTarget4 * materialUniform.morphTargetInfluences[ 4 ]; - transformed += input.morphTarget5 * materialUniform.morphTargetInfluences[ 5 ]; - transformed += input.morphTarget6 * materialUniform.morphTargetInfluences[ 6 ]; - transformed += input.morphTarget7 * materialUniform.morphTargetInfluences[ 7 ]; - #endif + + #if ${defines.USE_CLEARCOAT_ROUGHNESSTEXTURE} + @group(0) @binding(${defines.clearcoatRclearcoatRoughnessTextureBinding}) var clearcoatRoughnessTexture: texture_2d; #endif - #endif - #if ${e.USE_SKINNING} - let skinVertex:vec4 = materialUniform.bindMatrix * vec4( transformed, 1.0 ); - let skinned:vec4 = vec4( 0.0 ); - skinned += boneMatX * skinVertex * input.skinWeight.x; - skinned += boneMatY * skinVertex * input.skinWeight.y; - skinned += boneMatZ * skinVertex * input.skinWeight.z; - skinned += boneMatW * skinVertex * input.skinWeight.w; - transformed = ( materialUniform.bindMatrixInverse * skinned ).xyz; - #endif - #if ${e.USE_DISPLACEMENTTEXTURE} - transformed += normalize( objectNormal ) * (textureSample(displacementMap, baseSampler, vUv).x * materialUniform.displacementScale + materialUniform.displacementBias ); - #endif - var mvPosition:vec4 = vec4( transformed, 1.0 ); - #if ${e.USE_INSTANCING} - mvPosition = input.instanceMatrix * mvPosition; - #endif - mvPosition = globalUniform.viewMatrix*materialUniform.modelMatrix * mvPosition; - vertexOutput.position = globalUniform.projectionMatrix * mvPosition; - vertexOutput.vViewPosition = - mvPosition.xyz/mvPosition.w; - #if ${e.USE_ENVTEXTURE || e.DISTANCE || e.USE_TRANSMISSION} - var worldPosition:vec4 = vec4( transformed, 1.0 ); - #if ${e.USE_INSTANCING} - worldPosition = input.instanceMatrix * worldPosition; + + #if ${defines.USE_CLEARCOAT_NORMALTEXTURE} + @group(0) @binding(${defines.clearcoatNormalTextureBinding}) var clearcoatNormalTexture: texture_2d; + #endif + + #if ${defines.USE_IRIDESCENCETEXTURE} + @group(0) @binding(${defines.iridescenceTextureBinding}) var iridescenceTexture: texture_2d; + #endif + + #if ${defines.USE_IRIDESCENCE_THICKNESSTEXTURE} + @group(0) @binding(${defines.iridescenceThicknessTextureBinding}) var iridescenceThicknessTexture: texture_2d; + #endif + + #if ${defines.USE_ROUGHNESSTEXTURE} + @group(0) @binding(${defines.roughnessTextureBinding}) var roughnessTexture: texture_2d; + #endif + + #if ${defines.USE_METALNESSTEXTURE} + @group(0) @binding(${defines.metalnessTextureBinding}) var metalnessTexture: texture_2d; + #endif + + #if ${defines.SPECULAR} + #if ${defines.USE_SPECULARINTENSITYTEXTURE} + @group(0) @binding(${defines.specularIntensityTextureBinding}) var specularIntensityTexture: texture_2d; + #endif + + #if ${defines.USE_SPECULARCOLORTEXTURE} + @group(0) @binding(${defines.specularColorTextureBinding}) var specularColorTexture: texture_2d; + #endif #endif - worldPosition = materialUniform.modelMatrix * worldPosition; - #endif - #if ${e.USE_TRANSMISSION} - vertexOutput.vWorldPosition = worldPosition.xyz; - #endif - return vertexOutput; + + #if ${defines.USE_SHEEN} + #if ${defines.USE_SHEENCOLORTEXTURE} + @group(0) @binding(${defines.sheenColorTextureBinding}) var sheenColorTexture: texture_2d; + #endif + #if ${defines.USE_SHEENROUGHNESSTEXTURE} + @group(0) @binding(${defines.sheenRoughnessTextureBinding}) var sheenRoughnessTexture: texture_2d; + #endif + #endif + + #if ${defines.USE_TEXTURE} + @group(0) @binding(${defines.baseSamplerBinding}) var baseSampler: sampler; + @group(0) @binding(${defines.baseTextureBinding}) var baseTexture: texture_2d; + #endif + + #if ${defines.USE_ALPHATEXTURE} + @group(0) @binding(${defines.alphaTextureBinding}) var alphaTexture: texture_2d; + #endif + + #if ${defines.USE_AOTEXTURE} + @group(0) @binding(${defines.aoTextureBinding}) var aoTexture: texture_2d; + + #endif + #if ${defines.USE_LIGHTTEXTURE} + @group(0) @binding(${defines.lightTextureBinding}) var lightTexture: texture_2d; + #endif + + #if ${defines.USE_EMISSIVETEXTURE} + @group(0) @binding(${defines.emissiveTextureBinding}) var emissiveTexture: texture_2d; + #endif + `; +} + +function pbrUtils(defines) { + return wgslParseDefines` + const PI:f32= 3.141592653589793; + const PI2:f32= 6.283185307179586; + const PI_HALF:f32= 1.5707963267948966; + const RECIPROCAL_PI:f32= 0.3183098861837907; + const RECIPROCAL_PI2:f32= 0.15915494309189535; + const EPSILON:f32= 1e-6; + + fn pow2(x:f32 )->f32 { + return x*x; + } + fn pow2Vector(x:vec3 )->vec3 { + return x*x; + } + fn pow3( x:f32 )->f32 { + return x*x*x; + } + fn pow4( x:f32 )->f32 { + let x2:f32 = x*x; + return x2*x2; + } + fn max3( v:vec3 )->f32 { + return max( max( v.x, v.y ), v.z ); + } + fn average(v:vec3 )->f32 { + return dot( v, vec3( 0.3333333 ) ); + } + fn rand( uv:vec2 )->f32 { + let a:f32 = 12.9898; + let b:f32 = 78.233; + let c:f32 = 43758.5453; + let dt:f32 = dot( uv.xy, vec2( a, b ) ); + let sn:f32 = dt % PI; + return fract( sin( sn ) * c ); + } + fn transformDirection( dir:vec3, matrix:mat4x4 )->vec3 { + return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); + } + + fn transposeMat3( m:mat3x3 )->mat3x3 { + var tmp:mat3x3; + tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x ); + tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y ); + tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z ); + return tmp; + } + fn luminance( rgb:vec3 )->f32 { + let weights:vec3 = vec3(0.2126729, 0.7151522, 0.0721750 ); + return dot( weights, rgb ); + } + fn LinearToneMapping( color:vec3,toneMappingExposure:f32 )->vec3 { + return toneMappingExposure * color; + } + + fn ReinhardToneMapping( color:vec3,toneMappingExposure:f32 )->vec3 { + var tempColor:vec3; + tempColor=color; + tempColor *= toneMappingExposure; + return saturate( tempColor / ( vec3( 1.0 ) + tempColor ) ); + } + fn CustomToneMapping( color:vec3 )->vec3 { + return color; + } + fn toneMapping( color:vec3,toneMappingExposure:f32 )->vec3 { + return ReinhardToneMapping( color,toneMappingExposure ); + } + + fn LinearToLinear( value:vec4 )->vec4 { + return value; + } + fn lessThanEqual(a:vec3,b:vec3)->vec3{ + let xValue:f32=select(b.x,a.x,a.x<=b.x); + let yValue:f32=select(b.y,a.y,a.y<=b.y); + let zValue:f32=select(b.z,a.z,a.z<=b.z); + return vec3(xValue,yValue,zValue); + } + fn LinearTosRGB( value:vec4 )->vec4 { + return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a ); + } + fn linearToOutputTexel(value:vec4 )->vec4 { + return LinearTosRGB( value ); } `; - } - }, - skybox: { - frag: function (e) { - return "\n fn lessThanEqual(a:vec3,b:vec3)->vec3{\n let xValue:f32=select(b.x,a.x,a.x<=b.x);\n let yValue:f32=select(b.y,a.y,a.y<=b.y);\n let zValue:f32=select(b.z,a.z,a.z<=b.z);\n return vec3(xValue,yValue,zValue); \n }\n fn LinearTosRGB( value:vec4 )->vec4 {\n return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n }\n struct FragmentInput {\n @location(0) texCoord : vec3\n };\n @group(0) @binding(2) var defaultSampler: sampler;\n @group(0) @binding(1) var skyboxTexture: texture_cube;\n @fragment\n fn main(input : FragmentInput) -> @location(0) vec4 {\n let color = textureSample(skyboxTexture, defaultSampler, input.texCoord);\n return LinearTosRGB(color);\n }\n"; - }, - vert: function (e) { - return `\n struct SystemUniform {\n projectionMatrix: mat4x4,\n viewMatrix: mat4x4,\n inverseViewMatrix: mat4x4,\n cameraPosition: vec3,\n }; \n struct MaterialUniform {\n modelMatrix: mat4x4,\n }\n @binding(${e.skyboxBinding}) @group(0) var selfUniform : MaterialUniform;\n @binding(${e.cameraBinding}) @group(1) var systemUniform : SystemUniform;\n struct VertexInput {\n @location(${e.positionLocation}) position : vec3,\n };\n struct VertexOutput {\n @builtin(position) position : vec4,\n @location(0) texCoord : vec3,\n };\n @vertex\n fn main(input : VertexInput) -> VertexOutput {\n var output : VertexOutput;\n output.texCoord = input.position.xyz;\n var modelView = systemUniform.viewMatrix;\n // Drop the translation portion of the modelView matrix\n modelView[3] = vec4(0.0, 0.0, 0.0, modelView[3].w);\n output.position = systemUniform.projectionMatrix * modelView * vec4(input.position,1.0);\n output.position = output.position.xyww;\n return output;\n }\n `; - } - }, - resolve: { - frag: function (e) { - return "\n @group(0) @binding(1) var baseSampler: sampler;\n @group(0) @binding(0) var colorTexture: texture_2d;\n struct VertexOutput {\n @builtin(position) position: vec4,\n @location(0) uv: vec2,\n };\n @fragment\n fn main(input:VertexOutput) -> @location(0) vec4 {\n return textureSample(colorTexture, baseSampler, vec2(input.uv.x,1.0-input.uv.y));\n }\n "; - }, - vert: zi - }, - pbr_mat: { - frag: function (e) { - return Di` - // reference: https://github.com/KhronosGroup/glTF-WebGL-PBR/blob/master/shaders/pbr-frag.glsl - #include - #include - #include - #include - #include - #include - struct PhysicalMaterial { - diffuseColor:vec3, - roughness:f32, - specularColor:vec3, - #if ${e.USE_CLEARCOAT} - clearcoat:f32, - clearcoatRoughness:f32, - clearcoatF0:vec3, - clearcoatF90:f32, - #endif +} - #if ${e.USE_IRIDESCENCE} - iridescence:f32, - iridescenceIOR:f32, - iridescenceThickness:f32, - iridescenceFresnel:vec3, - iridescenceF0:vec3, - #endif +function blinn_phong(defines) { + return ` + fn getPointLightInfo(pointLight:PointLight,worldPos:vec3,shininess:f32,N:vec3,V:vec3)->vec3{ + var color=vec3(0.0,0.0,0.0); + var direction:vec3 = worldPos - pointLight.position; + let dist:f32 = length( direction ); + direction = normalize(direction); + let decay = clamp(1.0 - pow(dist / pointLight.distance, 4.0), 0.0, 1.0); - #if ${e.USE_SHEEN} - sheenColor:vec3, - sheenRoughness:f32, - #endif + let d = max( dot( N, -direction ), 0.0 ) * decay; + color += pointLight.color * d; - #if ${e.IOR} - ior:f32, - #endif + let halfDir:vec3 = normalize( V - direction ); + let s:f32 = pow( clamp( dot( N, halfDir ), 0.0, 1.0 ), shininess ) * decay; + color += pointLight.color * s; + return color; + } + fn getSpotLightInfo(spotLight:SpotLight,worldPos:vec3,shininess:f32,N:vec3,V:vec3)->vec3{ + var color=vec3(0.0,0.0,0.0); + var direction:vec3 = spotLight.position - worldPos; + let lightDistance:f32 = length(direction); + direction = normalize(direction); + let angleCos:f32 = dot( direction, -spotLight.direction ); + let decay:f32 = clamp(1.0 - pow(lightDistance/spotLight.distance, 4.0), 0.0, 1.0); + let spotEffect:f32 = smoothstep( spotLight.penumbraCos, spotLight.coneCos, angleCos ); + let decayTotal:f32 = decay * spotEffect; + let d:f32 = max( dot( N, direction ), 0.0 ) * decayTotal; + color += spotLight.color * d; + let halfDir:vec3 = normalize( V + direction ); + let s:f32 = pow( clamp( dot( N, halfDir ), 0.0, 1.0 ), shininess ) * decayTotal; + color += spotLight.color * s; + return color; + } + struct DirectionalLight { + direction: vec3, + color: vec3, + }; + fn getDirectLightInfo(directionalLight:DirectionalLight,shininess:f32,N:vec3,V:vec3)->vec3{ + var color=vec3(0.0,0.0,0.0); + let d:f32 = max(dot(N, -directionalLight.direction), 0.0); + color += directionalLight.color * d; - #if ${e.USE_TRANSMISSION} - transmission:f32, - transmissionAlpha:f32, - thickness:f32, - attenuationDistance:f32, - attenuationColor:vec3, - #endif - }; - const M_PI:f32 = 3.141592653589793; - const c_MinRoughness:f32 = 0.04; - #include - #if ${e.USE_IBL} - #include + let halfDir:vec3 = normalize( V - directionalLight.direction ); + let s:f32 = pow( clamp( dot( N, halfDir ), 0.0, 1.0 ), shininess ); + color += directionalLight.color * s; + return color; + } + `; +} + +function phongFunction(defines) { + return ` + fn G_BlinnPhong_Implicit( )->f32 { + + // geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v) + return 0.25; + + } + fn D_BlinnPhong( shininess:f32, dotNH:f32 )->f32 { + + return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow(dotNH, shininess); + + } + fn BRDF_BlinnPhong( lightDir:vec3, viewDir:vec3, normal:vec3, specularColor:vec3, shininess:f32 )->vec3 { + + let halfDir = normalize( lightDir + viewDir ); + + let dotNH:f32 = saturate( dot( normal, halfDir ) ); + let dotVH:f32 = saturate( dot( viewDir, halfDir ) ); + + let F = F_Schlick( specularColor, 1.0, dotVH ); + + let G:f32 = G_BlinnPhong_Implicit( ); + + let D = D_BlinnPhong( shininess, dotNH ); + + return F * ( G * D ); + + } + fn RE_Direct_BlinnPhong( directLight:IncidentLight,geometry:GeometricContext, material:BlinnPhongMaterial )->ReflectedLight{ + var reflectedLight:ReflectedLight; + let dotNL:f32 = saturate(dot(geometry.normal, directLight.direction)); + let irradiance:vec3 = dotNL*directLight.color; + + reflectedLight.directDiffuse= irradiance * BRDF_Lambert( material.diffuseColor ); + + reflectedLight.directSpecular= irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularShininess ) * material.specularStrength; + return reflectedLight; + } + fn RE_IndirectDiffuse_BlinnPhong( irradiance:vec3, geometry:GeometricContext, material:BlinnPhongMaterial)->ReflectedLight { + var reflectedLight:ReflectedLight; + reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); + return reflectedLight; + } + `; +} + +function phongUtils(defines) { + return ` + struct BlinnPhongMaterial { + diffuseColor:vec3, + specularColor:vec3, + specularShininess:f32, + specularStrength:f32, + }; + const RECIPROCAL_PI:f32= 0.3183098861837907; + fn pow2( x:f32 )->f32 { return x*x; } + fn pow3( x:f32 )->f32 { return x*x*x; } + fn pow4(x:f32 )->f32 { let x2 = x*x; return x2*x2; } + fn max3( v:vec3 )->f32 { return max( max( v.x, v.y ), v.z ); } + fn average(v:vec3 )->f32 { + let result=vec3( 0.3333333, 0.3333333, 0.3333333); + return dot( v,result ); + } + `; +} + +function skinVertHeader(defines) { + return wgslParseDefines` + #if ${defines.HAS_SKIN} + struct JointsUniform{ + matrixs:array, + } + struct InverseBindMatricesUniform{ + matrixs:array, + } + @binding(${defines.skinJointsBufferBinding}) @group(0) var jointsUniform : JointsUniform; + @binding(${defines.invsBufferBinding}) @group(0) var inverseBindMatricesUniform : InverseBindMatricesUniform; + fn getSkinMatrix(joints: vec4f, weights: vec4f) -> mat4x4 { + let joint0 = jointsUniform.matrixs[u32(joints.x)] * inverseBindMatricesUniform.matrixs[u32(joints.x)]; + let joint1 = jointsUniform.matrixs[u32(joints.y)] * inverseBindMatricesUniform.matrixs[u32(joints.y)]; + let joint2 = jointsUniform.matrixs[u32(joints.z)] * inverseBindMatricesUniform.matrixs[u32(joints.z)]; + let joint3 = jointsUniform.matrixs[u32(joints.w)] * inverseBindMatricesUniform.matrixs[u32(joints.w)]; + + let skinMatrix = joint0 * weights.x + + joint1 * weights.y + + joint2 * weights.z + + joint3 * weights.w; + return skinMatrix; + } #endif - @binding(${e.pbrBinding}) @group(0) var materialUniform : MaterialUniform; - @binding(${e.cameraBinding}) @group(1) var systemUniform : SystemUniform; - @fragment - fn main(input:FragInput) -> @location(0) vec4 - { - var perceptualRoughness:f32 = materialUniform.roughness; - var metallic:f32 = materialUniform.metallic; + `; +} +function skinVertMain(defines) { + return wgslParseDefines` + #if ${defines.HAS_SKIN} + modelMatrix =getSkinMatrix(input.joint0,input.weight0); + vNormalView = normalize((materialUniform.normalMatrix * modelMatrix * vec4(input.normal, 0.0)).xyz); + #endif + `; +} - #if ${e.USE_METALNESSTEXTURE} - let mrSample:vec4 = textureSample(metalnessRoughnessTexture,metalnessRoughnessSampler, input.uv); - perceptualRoughness = mrSample.g * perceptualRoughness; - metallic = mrSample.b * metallic; - #endif - perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0); - metallic = clamp(metallic, 0.0, 1.0); - let alphaRoughness:f32 = perceptualRoughness * perceptualRoughness; +function PbrMaterialStruct(defines) { + return wgslParseDefines` + struct MaterialUniform { + modelMatrix: mat4x4, + color: vec3, + opacity:f32, + normalMatrix: mat4x4, + emissive:vec3, + metallic:f32, + roughness:f32, + #if ${defines.USE_NORMALTEXTURE} + normalTextureScale:vec2, + #endif + #if ${defines.USE_AOTEXTURE} + occlusionStrength:f32, + #endif + } + `; +} +const ShaderChunk = { + light, + brdf, + phongFunction, + phongUtils, + lightCommon, + pbrStruct, + pbrFunction, + pbrTexture, + pbrUtils, + environment, + blinn_phong, + getNormal, + getTBN, + getNormalByNormalTexture, + ibl, + skinVertMain, + skinVertHeader, + FragInput, + VertexInput, + VertexOutput, + PbrMaterialStruct, + SystemUniform, + instanceVertMain, + instanceVertHeader, + TextureAndSamplerDefine, + PointVertInput, + PointVertOutput, + PointFragInput +}; - // The albedo may be defined from a base texture or a flat color - #if ${e.USE_TEXTURE} - let baseColor:vec4 = textureSample(baseColorTexture,baseColorSampler, input.uv) ; - #else - let baseColor:vec4 = vec4(materialUniform.color,1.0); - #endif +function shadowMapDebuggerFrag(defines) { + return ` + @group(0) @binding(1) var shadowSampler: sampler; + @group(0) @binding(0) var shadowMap: texture_depth_2d; + + // @group(0) @binding(0) var shadowMap: texture_depth_2d_array; + // @group(0) @binding(0) var shadowMap: texture_2d; + + struct VertexOutput { + @builtin(position) position: vec4, + @location(0) uv: vec2, + }; + + fn linearizeDepth(depth: f32, near: f32, far: f32)->f32 { + return 2 * (near * far) / (far + near - depth * (far - near)); + } - #if ${e.USE_NORMALTEXTURE} - let n:vec3 = getNormalByNormalTexture(input); - #else - let n:vec3 = getNormal(input); - #endif - var material:PhysicalMaterial; - material.diffuseColor=baseColor.rgb*( 1.0 - metallic ); - material.roughness=perceptualRoughness; - material.specularColor=mix( vec3( 0.04), baseColor.rgb, metallic ); - var geometry:Geometry; - geometry.normal=n; - geometry.viewDir=normalize(systemUniform.cameraPosition - input.worldPos); - geometry.position=input.worldPos; - geometry.dotNV = saturate(dot(geometry.normal, geometry.viewDir) ); - //light shading - var reflectedLight=parseLights(geometry,material); - var color=reflectedLight.directDiffuse+reflectedLight.directSpecular; - //IBL - #if ${e.USE_IBL && e.HAS_UV} - var reflectedLightDiffuse=indirectDiffuse_Physical(geometry,material); - var reflectedLightSpecular=indirectSpecular_Physical(geometry,material); - color+=reflectedLightDiffuse.indirectDiffuse; - color+=reflectedLightSpecular.indirectSpecular; - #endif - #if ${e.USE_AOTEXTURE} - let ao:f32 = textureSample(aoTexture,aoSampler, input.uv).r; - color = mix(color, color * ao, materialUniform.occlusionStrength); - #endif + @fragment + fn main(input:VertexOutput) -> @location(0) vec4 { + let color: vec4 = textureGather(shadowMap, shadowSampler, vec2(input.uv.x,1.0-input.uv.y)); + let depth = (linearizeDepth(color.r, 0.1, 500) - 0.1) / (500 - 0.1); + return vec4(vec3(depth), 1.0); // PerspectiveCamera + // return color; + + // return textureSample(shadowMap, shadowSampler, vec2(input.uv.x,1.0-input.uv.y)); - #if ${e.USE_EMISSIVETEXTURE} - let emissive:vec3 = textureSample(emissiveTexture, emissiveSampler,input.uv).rgb ; - color += emissive; - #endif - return vec4(color, baseColor.a); } - `; - }, - vert: function (e) { - return Di` - #include - #include - #include - #include - #include - #include - @binding(${e.pbrBinding}) @group(0) var materialUniform : MaterialUniform; - @binding(${e.cameraBinding}) @group(1) var systemUniform : SystemUniform; + `; +} + +function shadowMapDebuggerVert(defines) { + return ` + struct VertexInput { + @location(${defines.positionLocation}) position: vec2, + } + struct VertexOutput { + @builtin(position) position: vec4, + @location(0) uv: vec2, + }; @vertex - fn main(input: VertexInput)-> VertexOutput - { - var output: VertexOutput; - #if ${e.HAS_UV} - output.uv = input.uv; - #endif - var modelMatrix:mat4x4; - var vNormalView:vec3; - vNormalView = normalize(materialUniform.normalMatrix * vec4(input.normal,0.0)).xyz; - modelMatrix=materialUniform.modelMatrix; - #include - #include - output.normal = vNormalView.xyz; - output.position = systemUniform.projectionMatrix * systemUniform.viewMatrix *modelMatrix* vec4(input.position, 1.0); - let modelPos=modelMatrix *vec4(input.position,1.0); - output.worldPos = modelPos.xyz/modelPos.w; - return output; - } - `; - } - }, - blur: { - frag: function (e) { - return `\n struct FragInput {\n @location(0) uv: vec2,\n }\n struct BlurUniforms {\n direction:vec2,\n }\n fn gaussianPdf(x:f32, sigma:f32)->f32 {\n return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;\n }\n @group(0) @binding(0) var blurUniforms : BlurUniforms;\n @group(0) @binding({{tDiffuseBinding}}) var tDiffuse: texture_2d;\n @group(0) @binding({{tSamplerBinding}}) var tSampler: sampler;\n @fragment\n fn main(input:FragInput) -> @location(0) vec4 {\n let invSize:vec2 = vec2(1.0,1.0) / vec2(textureDimensions(tDiffuse));\n let fSigma:f32 =f32(${e.SIGMA});\n var weightSum:f32 = gaussianPdf(0.0, fSigma);\n let baseColor=textureSample(tDiffuse, tSampler, input.uv);\n var diffuseSum:vec3 = baseColor.rgb * weightSum;\n let uvOffset:vec2 = blurUniforms.direction * invSize;\n for( var i : u32 = 1; i < ${e.KERNEL_RADIUS};i = i + 1 ) {\n let x:f32 = f32(i);\n let w:f32 = gaussianPdf(x, fSigma);\n let sample1:vec3=textureSample(tDiffuse, tSampler, input.uv+ uvOffset*x).rgb;\n let sample2:vec3=textureSample(tDiffuse, tSampler, input.uv- uvOffset*x).rgb;\n diffuseSum =diffuseSum+ (sample2+sample2)* w;\n weightSum += 2.0 * w;\n }\n diffuseSum/=weightSum;\n return vec4(diffuseSum,baseColor.a);\n }\n `; - }, - vert: zi - }, - luminosityHigh: { - frag: function (e) { - return "\n struct LuminosityUniforms{\n luminosityThreshold:f32,\n smoothWidth:f32,\n defaultColor:vec3,\n defaultOpacity:f32,\n }\n struct FragInput {\n @location(0) uv: vec2,\n };\n @group(0) @binding(0) var luminosityUniforms : LuminosityUniforms;\n @group(0) @binding({{tDiffuseBinding}}) var tDiffuse: texture_2d;\n @group(0) @binding({{tSamplerBinding}}) var tSampler: sampler;\n @fragment\n fn main(input:FragInput)-> @location(0) vec4 {\n\n let texel:vec4 = textureSample(tDiffuse, tSampler, input.uv);\n\n let luma:vec3 = vec3( 0.299,0.587,0.114 );\n\n let v:f32 = dot( texel.xyz, luma );\n\n let outputColor:vec4 = vec4( luminosityUniforms.defaultColor.rgb, luminosityUniforms.defaultOpacity );\n\n let alpha:f32 = smoothstep( luminosityUniforms.luminosityThreshold, luminosityUniforms.luminosityThreshold + luminosityUniforms.smoothWidth, v );\n\n return mix( outputColor, texel, alpha );\n }\n "; - }, - vert: zi - }, - blend: { - frag: function (e) { - return "\n struct FragInput {\n @location(0) uv: vec2,\n };\n @group(0) @binding({{tDiffuseBinding}}) var tDiffuse: texture_2d;\n @group(0) @binding({{baseColorTextureBinding}}) var baseColorTexture: texture_2d;\n @group(0) @binding({{tSamplerBinding}}) var tSampler: sampler;\n @fragment\n fn main(input:FragInput) -> @location(0) vec4 {\n let postColor:vec4 = textureSample(tDiffuse, tSampler, input.uv);\n let baseColor:vec4 = textureSample(baseColorTexture, tSampler, input.uv);\n return baseColor+postColor;\n } \n "; - }, - vert: zi - }, - shadowMapDebugger: { - frag: function (e) { - return "\n @group(0) @binding(1) var shadowSampler: sampler;\n @group(0) @binding(0) var shadowMap: texture_depth_2d;\n \n // @group(0) @binding(0) var shadowMap: texture_depth_2d_array;\n // @group(0) @binding(0) var shadowMap: texture_2d;\n\n struct VertexOutput {\n @builtin(position) position: vec4,\n @location(0) uv: vec2,\n };\n\n fn linearizeDepth(depth: f32, near: f32, far: f32)->f32 {\n return 2 * (near * far) / (far + near - depth * (far - near));\n }\n\n @fragment\n fn main(input:VertexOutput) -> @location(0) vec4 {\n\t\t\tlet color: vec4 = textureGather(shadowMap, shadowSampler, vec2(input.uv.x,1.0-input.uv.y));\n let depth = (linearizeDepth(color.r, 0.1, 500) - 0.1) / (500 - 0.1);\n return vec4(vec3(depth), 1.0); // PerspectiveCamera\n // return color;\n\n // return textureSample(shadowMap, shadowSampler, vec2(input.uv.x,1.0-input.uv.y));\n\n }\n "; - }, - vert: function (e) { - return `\n struct VertexInput {\n @location(${e.positionLocation}) position: vec2, \n }\n struct VertexOutput {\n @builtin(position) position: vec4,\n @location(0) uv: vec2,\n };\n @vertex\n fn main(input: VertexInput) -> VertexOutput {\n var output:VertexOutput;\n output.uv = input.position * 0.5 + 0.5;\n output.position = vec4(input.position, 0.0, 1.0);;\n return output;\n }\n `; - } - }, - shadowMap: { - vert: function (e) { - return Di` + fn main(input: VertexInput) -> VertexOutput { + var output:VertexOutput; + output.uv = input.position * 0.5 + 0.5; + output.position = vec4(input.position, 0.0, 1.0);; + return output; + } + `; +} + +// import Color from "../../math/Color"; +function shadowMapFrag(defines) { + return ` + struct VertexOutput { + @builtin(position) position: vec4, + @location(0) color: vec4, + }; + @fragment + fn main(input:VertexOutput) -> @location(0) vec4 { + return input.color; + } + `; +} + +function shadowMapVert(defines) { + return wgslParseDefines` struct VertexInput { - @location(${e.positionLocation}) position: vec3, + @location(${defines.positionLocation}) position: vec3, }; struct VertexOutput { @builtin(position) position: vec4, @@ -8232,21 +10847,21 @@ fn main(input:VertexOutput)-> @location(0) vec4 { cameraPosition: vec3, }; - #if ${e.isPointLightShadowMap} + #if ${defines.isPointLightShadowMap} struct PointLightUniform { vpMatrix: mat4x4, // vpMatrixArray: array, 6>, }; - @group(1) @binding(${e.pointLightShadowCameraBinding}) var pointLightUniform: PointLightUniform; + @group(1) @binding(${defines.pointLightShadowCameraBinding}) var pointLightUniform: PointLightUniform; #endif - @group(0) @binding(${e.selfBinding}) var selfUniform : SelfUniform; - @group(1) @binding(${e.cameraBinding}) var systemUniform : SystemUniform; + @group(0) @binding(${defines.selfBinding}) var selfUniform : SelfUniform; + @group(1) @binding(${defines.cameraBinding}) var systemUniform : SystemUniform; @vertex fn main(input: VertexInput) -> VertexOutput { var output:VertexOutput; - #if ${e.isPointLightShadowMap} + #if ${defines.isPointLightShadowMap} output.position = pointLightUniform.vpMatrix * selfUniform.modelMatrix * vec4(input.position,1.0); #else output.position = systemUniform.projectionMatrix * systemUniform.viewMatrix * selfUniform.modelMatrix * vec4(input.position,1.0); @@ -8254,286 +10869,384 @@ fn main(input:VertexOutput)-> @location(0) vec4 { return output; } `; - }, - frag: function (e) { - return "\n struct VertexOutput {\n @builtin(position) position: vec4,\n @location(0) color: vec4,\n };\n @fragment\n fn main(input:VertexOutput) -> @location(0) vec4 {\n return input.color;\n }\n "; - } +} + +function reduceComma(shader) { + // 对所有的include处理 + return shader != undefined ? resolveIncludes(shader) : undefined; +} +const includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm; +let currentDefines = {}; +const shaders = { + phong: { + frag: phongFrag, + vert: phongVert + }, + color: { + frag: colorFrag, + vert: colorVert + }, + pbr: { + frag: pbrFrag, + vert: pbrVert + }, + skybox: { + frag: skyBoxFrag, + vert: skyBoxVert + }, + resolve: { + frag: quadFrag, + vert: quadVert + }, + pbr_mat: { + frag: pbr_fs, + vert: pbr_vs + }, + blur: { + frag: Blur, + vert: quadVert + }, + luminosityHigh: { + frag: LuminosityHigh, + vert: quadVert + }, + blend: { + frag: blendFrag, + vert: quadVert + }, + shadowMapDebugger: { + frag: shadowMapDebuggerFrag, + vert: shadowMapDebuggerVert + }, + shadowMap: { + vert: shadowMapVert, + frag: shadowMapFrag }, sprite: { - vert: function (e) { - return Di` - - #include - #include - #include - struct SelfUniform { - modelMatrix: mat4x4, - color:vec3, - rotation:f32, - center:vec2, - opacity:f32, - } - @binding(${e.spriteBinding}) @group(0) var selfUniform : SelfUniform; - @binding(${e.cameraBinding}) @group(1) var systemUniform : SystemUniform; - @vertex - fn main(input: VertexInput) -> VertexOutput { - var output:VertexOutput; - var mvPosition:vec4= systemUniform.viewMatrix *selfUniform.modelMatrix*vec4(0.0,0.0,0.0,1.0); - #if ${e.HAS_UV} - output.uv=input.uv; - #endif - var scale:vec2; - scale.x = length(vec3(selfUniform.modelMatrix[0].x, selfUniform.modelMatrix[0].y, selfUniform.modelMatrix[0].z)); - scale.y = length(vec3(selfUniform.modelMatrix[1].x, selfUniform.modelMatrix[1].y, selfUniform.modelMatrix[1].z)); - // scale *= - mvPosition.z; - var alignedPosition:vec2 =(input.position.xy- (selfUniform.center - vec2(0.5,0.5))) * scale; - let rotatedPositionX = cos(selfUniform.rotation) * alignedPosition.x - sin( selfUniform.rotation ) * alignedPosition.y; - let rotatedPositionY = sin(selfUniform.rotation) * alignedPosition.x + cos( selfUniform.rotation ) * alignedPosition.y; - var rotatedPosition=vec2(rotatedPositionX,rotatedPositionY); - let newPoint =mvPosition.xy+ rotatedPosition; - output.position = systemUniform.projectionMatrix * vec4(newPoint.x,newPoint.y,mvPosition.z,mvPosition.w); - return output; - } - `; - }, - frag: function (e) { - return Di` - #include - struct SelfUniform { - modelMatrix: mat4x4, - color:vec3, - rotation:f32, - center:vec2, - opacity:f32, - } - @binding(${e.spriteBinding}) @group(0) var selfUniform : SelfUniform; - #if${e.USE_COLORTEXTURE} - @group(0) @binding(${e.baseColorSamplerBinding}) var baseColorSampler: sampler; - @group(0) @binding(${e.baseColorTextureBinding}) var baseColorTexture: texture_2d; - #endif - @fragment - fn main(input:VertexOutput) -> @location(0) vec4 { - #if${e.USE_COLORTEXTURE} - return textureSample(baseColorTexture, baseColorSampler, input.uv); - #else - return vec4(selfUniform.color,selfUniform.opacity); - #endif - } - `; - } + vert: sprite_vs, + frag: sprite_fs }, point: { - vert: function (e) { - return Di` - #include - #include - #include - struct SelfUniform { - modelMatrix: mat4x4, - color:vec3, - size:f32, - opacity:f32, - } - @binding(${e.pointBinding}) @group(0) var selfUniform : SelfUniform; - @binding(${e.cameraBinding}) @group(1) var systemUniform : SystemUniform; - @vertex - fn main(input: PointVertInput) -> PointVertOutput { - var output:PointVertOutput; - let mvPosition:vec4= ystemUniform.viewMatrix *selfUniform.modelMatrix*vec4(0.0,0.0,0.0, 1.0 ); - #if ${e.HAS_UV} - output.uv=input.uv; - #endif - #if ${e.HAS_COLOR} - output.color=input.color; - #endif - #if ${e.HAS_SIZE} - output.size=input.size; - #endif - vec2 alignedPosition = input.position.xy* selfUniform.size; - mvPosition.xy += alignedPosition; - output.position = systemUniform.projectionMatrix * mvPosition; - return output; - } - `; - }, - frag: function (e) { - return Di` - #include - struct SelfUniform { - modelMatrix: mat4x4, - color:vec3, - size:f32, - opacity:f32, - } - @binding(${e.pointBinding}) @group(0) var selfUniform : SelfUniform; - #if${e.USE_COLORTEXTURE} - @group(0) @binding(${e.baseColorSamplerBinding}) var baseColorSampler: sampler; - @group(0) @binding(${e.baseColorTextureBinding}) var baseColorTexture: texture_2d; - #endif - @fragment - fn main(input:PointFragInput) -> @location(0) vec4 { - var color:vec4=vec4(selfUniform.color,selfUniform.opacity); - #if${e.USE_COLORTEXTURE} - color=textureSample(baseColorTexture, baseColorSampler, input.uv); - #endif - #if${e.HAS_COLOR} - color=vec4(input.color,selfUniform.opacity); - #endif - return color; - } - `; - } + vert: point_vs, + frag: point_fs } }; -function Vi(e) { - return e.replace(Ni, Fi); -} -function Fi(e, t) { - const i = Ii[t]; - if (void 0 === i) throw new Error(`Can not resolve #include <${t}>`); - return Vi(i(Bi)); -} -function $i(e, t = {}) { - const i = Oi[e]; - return (Bi = t), { vert: Pi(i?.vert(Bi)), frag: Pi(i?.frag(Bi)) }; -} -class Gi { - constructor(e) { - (this.shaderId = e.shaderId), - (this.defines = e.defines || {}), - (this.render = e.render), - (this.compute = e.compute), - (this.dirty = !0); +function resolveIncludes(string) { + return string.replace(includePattern, includeReplacer); +} +function includeReplacer(match, include) { + const excute = ShaderChunk[include]; + if (excute === undefined) { + throw new Error(`Can not resolve #include <${include}>`); + } + const result = excute(currentDefines); + return resolveIncludes(result); +} +function getVertFrag(type, defines = {}) { + const excuteFunc = shaders[type]; + currentDefines = defines; + return { + vert: reduceComma(excuteFunc?.vert(currentDefines)), + frag: reduceComma(excuteFunc?.frag(currentDefines)) + }; +} + +class ShaderSource { + constructor(options) { + this.shaderId = options.shaderId; + this.defines = options.defines || {}; + this.render = options.render; + this.compute = options.compute; + this.dirty = true; } get uid() { - return (this._uid = this.shaderId.concat(JSON.stringify(this.defines))), this._uid; + this._uid = this.shaderId.concat(JSON.stringify(this.defines)); + return this._uid; } - setDefines(e) { - e && ((this.dirty = !0), (this.defines = Object.assign(this.defines, e))); + setDefines(defines) { + if (!defines) return; + this.dirty = true; + this.defines = Object.assign(this.defines, defines); } - getShaderModule(e) { + getShaderModule(device) { if (this.dirty) { - const { vert: t, frag: i, compute: r } = this.getShaderStr() || {}, - n = t ? e.createShaderModule({ code: t }) : void 0, - s = i ? e.createShaderModule({ code: i }) : void 0, - a = r ? e.createShaderModule({ code: r }) : void 0; - (this._shaderModule = { vert: n, frag: s, compute: a }), (this.dirty = !1); + const { vert, frag, compute } = this.getShaderStr() || {}; + const vertGPUModule = vert ? device.createShaderModule({ code: vert }) : undefined; + const fragGPUModule = frag ? device.createShaderModule({ code: frag }) : undefined; + const computeGPUModule = compute ? device.createShaderModule({ code: compute }) : undefined; + this._shaderModule = { + vert: vertGPUModule, + frag: fragGPUModule, + compute: computeGPUModule + }; + this.dirty = false; } return this._shaderModule; } destroy() { - (this.render = null), (this.compute = null), (this._shaderModule = null), (this.defines = null); + this.render = null; + this.compute = null; + this._shaderModule = null; + this.defines = null; } getShaderStr() { - const { fragShader: e, vertShader: t } = this.render || {}, - { computeShader: i } = this.compute || {}, - r = $i(this.shaderId, this.defines); + const { fragShader, vertShader } = this.render || {}; + const { computeShader } = this.compute || {}; + const source = getVertFrag(this.shaderId, this.defines); + const vert = source?.vert ?? (vertShader instanceof Function ? vertShader(this.defines) : vertShader); + const frag = source?.frag ?? (fragShader instanceof Function ? fragShader(this.defines) : fragShader); + const compute = computeShader instanceof Function ? computeShader(this.defines) : computeShader; return { - vert: r?.vert ?? (t instanceof Function ? t(this.defines) : t), - frag: r?.frag ?? (e instanceof Function ? e(this.defines) : e), - compute: i instanceof Function ? i(this.defines) : i + vert, + frag, + compute }; } - static replaceMain(e, t) { - return (t = `void ${t}()`), e.replace(/void\s+main\s*\(\s*(?:void)?\s*\)/g, t); + static replaceMain(source, renamedMain) { + renamedMain = `void ${renamedMain}()`; + return source.replace(/void\s+main\s*\(\s*(?:void)?\s*\)/g, renamedMain); } } -const ki = ["array", "array>", "array>", "array>"]; -function qi(e, t, i, r, n) { - const s = t?.value instanceof Function; - switch (t.type) { + +const uniformArrayNames = ["array", "array>", "array>", "array>"]; +function checkContainFloatType(uniforms) { + let result = 0; + let hasArraytype = false; + const uniformsNames = Object.getOwnPropertyNames(uniforms); + uniformsNames.map((uniformsName) => { + if (uniforms[uniformsName].type == "texture" || uniforms[uniformsName].type == "sampler") { + result += 0; + } else { + if ( + uniformArrayNames.find((name) => { + return name === uniforms[uniformsName].type; + }) + ) { + hasArraytype = true; + } else { + result += 1; + } + } + }); + return { + hasFloat: result, + hasArraytype + }; +} +function addUniformToShaderData(name, uniform, shaderData, mesh, uniformBuffer) { + const valueIsFunc = uniform?.value instanceof Function; + switch (uniform.type) { case "f32": - n.setUniform(e, s ? t.value : () => t.value, Q.Float); + uniformBuffer.setUniform( + name, + valueIsFunc + ? uniform.value + : () => { + return uniform.value; + }, + UniformEnum.Float + ); break; case "vec2": - n.setUniform(e, s ? t.value : () => t.value, Q.FloatVec2); + uniformBuffer.setUniform( + name, + valueIsFunc + ? uniform.value + : () => { + return uniform.value; + }, + UniformEnum.FloatVec2 + ); break; case "vec3": - n.setUniform(e, s ? t.value : () => t.value, Q.FloatVec3); + uniformBuffer.setUniform( + name, + valueIsFunc + ? uniform.value + : () => { + return uniform.value; + }, + UniformEnum.FloatVec3 + ); break; case "color": - n.setUniform(e, s ? t.value : () => t.value, Q.Color); + uniformBuffer.setUniform( + name, + valueIsFunc + ? uniform.value + : () => { + return uniform.value; + }, + UniformEnum.Color + ); break; case "vec4": - n.setUniform(e, s ? t.value : () => t.value, Q.FloatVec4); + uniformBuffer.setUniform( + name, + valueIsFunc + ? uniform.value + : () => { + return uniform.value; + }, + UniformEnum.FloatVec4 + ); break; case "mat2x2": - n.setUniform(e, s ? t.value : () => t.value, Q.Mat2); + uniformBuffer.setUniform( + name, + valueIsFunc + ? uniform.value + : () => { + return uniform.value; + }, + UniformEnum.Mat2 + ); break; case "mat3x3": - n.setUniform(e, s ? t.value : () => t.value, Q.Mat3); + uniformBuffer.setUniform( + name, + valueIsFunc + ? uniform.value + : () => { + return uniform.value; + }, + UniformEnum.Mat3 + ); break; case "mat4x4": - n.setUniform( - e, - s - ? t.value - : () => ("modelMatrix" == e ? r?.modelMatrix : "normalMatrix" === e ? r?.normalMatrix : t.value), - Q.Mat4 + uniformBuffer.setUniform( + name, + valueIsFunc + ? uniform.value + : () => + name == "modelMatrix" + ? mesh?.modelMatrix + : name === "normalMatrix" + ? mesh?.normalMatrix + : uniform.value, + UniformEnum.Mat4 ); break; case "array": - n.setUniform(e, s ? t.value : () => t.value, Q.FloatArray, t.value.length); + uniformBuffer.setUniform( + name, + valueIsFunc + ? uniform.value + : () => { + return uniform.value; + }, + UniformEnum.FloatArray, + uniform.value.length + ); break; case "array>": - n.setUniform(e, s ? t.value : () => t.value, Q.Vec2Array, t.value.length); + uniformBuffer.setUniform( + name, + valueIsFunc + ? uniform.value + : () => { + return uniform.value; + }, + UniformEnum.Vec2Array, + uniform.value.length + ); break; case "array>": - n.setUniform(e, s ? t.value : () => t.value, Q.Vec3Array, t.value.length); + uniformBuffer.setUniform( + name, + valueIsFunc + ? uniform.value + : () => { + return uniform.value; + }, + UniformEnum.Vec3Array, + uniform.value.length + ); break; case "array>": - n.setUniform(e, s ? t.value : () => t.value, Q.Vec4Array, t.value.length); + uniformBuffer.setUniform( + name, + valueIsFunc + ? uniform.value + : () => { + return uniform.value; + }, + UniformEnum.Vec4Array, + uniform.value.length + ); break; case "texture": case "storageTexture": - i.setTexture(e, s ? t.value : () => t.value, t?.binding, t?.type, t?.visibility, t?.textureView); + shaderData.setTexture( + name, + valueIsFunc + ? uniform.value + : () => { + return uniform.value; + }, + uniform?.binding, + uniform?.type, + uniform?.visibility, + uniform?.textureView + ); break; case "sampler": - i.setSampler(e, s ? t.value : () => t.value, t?.binding, t?.visibility); + shaderData.setSampler( + name, + valueIsFunc + ? uniform.value + : () => { + return uniform.value; + }, + uniform?.binding, + uniform?.visibility + ); break; default: throw new Error("not match unifrom type"); } } -const ji = new Map(); -class Hi { - constructor(e, t, i = [], r = 0) { - (this.entries = i), - (this.index = r || 0), - (this.gpuBindGroupLayout = e.createBindGroupLayout({ - label: t, - entries: i.map( - ({ visibility: e, buffer: t, sampler: i, texture: r, storageTexture: n, binding: s }) => ({ - binding: s, - visibility: e, - buffer: t, - sampler: i, - texture: r, - storageTexture: n - }) - ) - })); + +const layoutCache = new Map(); +class BindGroupLayout { + constructor(device, label, entries = [], index = 0) { + this.entries = entries; + this.index = index || 0; + this.gpuBindGroupLayout = device.createBindGroupLayout({ + label: label, + entries: entries.map(({ visibility, buffer, sampler, texture, storageTexture, binding }) => ({ + binding, + visibility, + buffer, + sampler, + texture, + storageTexture + })) + }); } - static getBindGroupLayoutFromCache(e, t, i, r) { - if (ji.has(t)) return ji.get(t); - { - const n = new Hi(e, t, i, r); - return ji.set(t, n), n; + static getBindGroupLayoutFromCache(device, label, entires, index) { + if (layoutCache.has(label)) { + return layoutCache.get(label); + } else { + const bindGroupLayout = new BindGroupLayout(device, label, entires, index); + layoutCache.set(label, bindGroupLayout); + return bindGroupLayout; } } - static removeBindGroupLayoutFromCache(e) { - ji.delete(e); + static removeBindGroupLayoutFromCache(bindGroupLayout) { + layoutCache.delete(bindGroupLayout); } } -class Xi { - constructor(e) { - (this.binding = e.binding), - (this.visibility = e.visibility), - (this.buffer = e.buffer), - (this.sampler = e.sampler), - (this.texture = e.texture), - (this.storageTexture = e.storageTexture), - (this.externalTexture = e.externalTexture); + +class BindGroupLayoutEntry { + constructor(options) { + this.binding = options.binding; + this.visibility = options.visibility; + this.buffer = options.buffer; + this.sampler = options.sampler; + this.texture = options.texture; + this.storageTexture = options.storageTexture; + this.externalTexture = options.externalTexture; } getGPULayoutEntity() { return { @@ -8546,2076 +11259,2918 @@ class Xi { storageTexture: this.storageTexture }; } -} -class Yi { - constructor(e, t, i, r) { - (this.label = e), - (this.currentBinding = 0), - (this.defineDirty = !0), - (this.defines = {}), - (this._uniforms = new Map()), - (this.groupIndex = ee(r, 0)), - (this.layoutIndex = ee(i, 0)); - } - getUniformBuffer(e) { - return this._uniforms.get(e); - } - getTexture(e) { - return this._uniforms.get(e); - } - getSampler(e) { - return this._uniforms.get(e); - } - setUniformBuffer(e, t, i) { - this._uniforms.get(e) || - ((t.binding = this.currentBinding), - this.setDefine(e.concat("Binding"), i ?? this.currentBinding), - (this.currentBinding += 1), - this._uniforms.set(e, t)); - } - setTexture(e, t, i, r, n, s) { - if (this._uniforms.get(e)) return; - const a = new Si(e, i ?? this.currentBinding, t, r, n, s); - this.setDefine(e.concat("Binding"), i ?? this.currentBinding), - (this.currentBinding += 1), - this._uniforms.set(e, a); - } - setSampler(e, t, i, r) { - if (this._uniforms.get(e)) return; - const n = new bi(e, i ?? this.currentBinding, t, r); - this.setDefine(e.concat("Binding"), i ?? this.currentBinding), - (this.currentBinding += 1), - this._uniforms.set(e, n); - } - setDefine(e, t) { - if (void 0 === this.defines[e]) (this.defineDirty = !0), (this.defines[e] = t); - else { - if (this.defines[e] === t) return; - (this.defineDirty = !0), (this.defines[e] = t); - } - } - replaceUniformBufferValue(e, t) { - this._uniforms.forEach((i) => { - i?.isUniformBuffer && i.replaceUniformValue(e, t); +} + +class ShaderData { + constructor(label, size, layoutIndex, groupIndex) { + this.label = label; + this.currentBinding = 0; + this.defineDirty = true; + this.defines = {}; + this._uniforms = new Map(); + this.groupIndex = defaultValue(groupIndex, 0); + this.layoutIndex = defaultValue(layoutIndex, 0); + } + getUniformBuffer(name) { + return this._uniforms.get(name); + } + getTexture(name) { + return this._uniforms.get(name); + } + getSampler(name) { + return this._uniforms.get(name); + } + setUniformBuffer(name, uniformBuffer, binding) { + if (this._uniforms.get(name)) return; + uniformBuffer.binding = this.currentBinding; + this.setDefine(name.concat("Binding"), binding ?? this.currentBinding); + this.currentBinding += 1; + this._uniforms.set(name, uniformBuffer); + } + setTexture(name, value, binding, type, visibility, textureView) { + if (this._uniforms.get(name)) return; + const uniform = new UniformTexture(name, binding ?? this.currentBinding, value, type, visibility, textureView); + this.setDefine(name.concat("Binding"), binding ?? this.currentBinding); + this.currentBinding += 1; + this._uniforms.set(name, uniform); + } + setSampler(name, value, binding, visibility) { + if (this._uniforms.get(name)) return; + const uniform = new UniformSampler(name, binding ?? this.currentBinding, value, visibility); + this.setDefine(name.concat("Binding"), binding ?? this.currentBinding); + this.currentBinding += 1; + this._uniforms.set(name, uniform); + } + setDefine(name, value) { + if (this.defines[name] === undefined) { + this.defineDirty = true; + this.defines[name] = value; + } else { + if (this.defines[name] === value) { + return; + } else { + this.defineDirty = true; + this.defines[name] = value; + } + } + } + replaceUniformBufferValue(name, value) { + this._uniforms.forEach((uniform) => { + if (uniform?.isUniformBuffer) { + uniform.replaceUniformValue(name, value); + } }); } - bind(e, t) { - this.uploadUniform(e), - this.groupLayout || (this.groupLayout = this.createBindGroupLayout(e, this.label, this.layoutIndex)), - this.bindGroup || (this.bindGroup = this.createBindGroup(e, this.label, this.groupIndex)), - this.bindGroup.bind(t); + bind(device, passEncoder) { + this.uploadUniform(device); + if (!this.groupLayout) this.groupLayout = this.createBindGroupLayout(device, this.label, this.layoutIndex); + if (!this.bindGroup) this.bindGroup = this.createBindGroup(device, this.label, this.groupIndex); + this.bindGroup.bind(passEncoder); } destroy() { - this._uniforms.forEach((e) => { - e.destroy && e?.destroy(); - }), - (this.label = void 0), - (this.currentBinding = 1), - (this.defineDirty = !0), - (this.defines = void 0), - this._uniforms.clear(), - Hi.removeBindGroupLayoutFromCache(this.groupLayout), - (this.bindGroup = void 0); - } - createBindGroup(e, t, i) { - const { entities: r, dynamic: n, alignedSize: s, maxOffset: a } = this.createBindGroupEntity(); - return new Ve({ - label: t, - entires: r, - device: e, + this._uniforms.forEach((uniform) => { + if (uniform.destroy) uniform?.destroy(); + }); + this.label = undefined; + this.currentBinding = 1; + this.defineDirty = true; + this.defines = undefined; + this._uniforms.clear(); + BindGroupLayout.removeBindGroupLayoutFromCache(this.groupLayout); + this.bindGroup = undefined; + } + createBindGroup(device, label, groupIndex) { + const { entities, dynamic, alignedSize, maxOffset } = this.createBindGroupEntity(); + const bindGroup = new BindGroup({ + label: label, + entires: entities, + device: device, layout: this.groupLayout, - index: i || 0, - dynamic: n, - alignedSize: s, - maxOffset: a + index: groupIndex || 0, + dynamic, + alignedSize, + maxOffset }); + return bindGroup; + } + createBindGroupLayout(device, label, layoutIndex) { + const result = this.createBindGroupLayoutEntry(); + const groupLayout = BindGroupLayout.getBindGroupLayoutFromCache( + device, + label + "-" + result.uid, + result.layouts, + layoutIndex || 0 + ); + return groupLayout; } - createBindGroupLayout(e, t, i) { - const r = this.createBindGroupLayoutEntry(); - return Hi.getBindGroupLayoutFromCache(e, t + "-" + r.uid, r.layouts, i || 0); - } - uploadUniform(e) { - this._uniforms.forEach((t) => { - t.bind(e); + uploadUniform(device) { + this._uniforms.forEach((uniform) => { + uniform.bind(device); }); } createBindGroupLayoutEntry() { - let e = ""; - const t = new Map(); - return ( - this._uniforms.forEach((i) => { - t.has(i.name) || - ((e = "" === e ? e.concat(i.name) : e.concat(", ").concat(i.name)), - t.set(i.name, this.createOneLayoutEntry(i))); - }), - (e = `uniforms[${e}]`), - { uid: e, layouts: [...t.values()] } - ); + let uid = ""; + const result = new Map(); + this._uniforms.forEach((uniform) => { + if (!result.has(uniform.name)) { + uid = uid === "" ? uid.concat(uniform.name) : uid.concat(", ").concat(uniform.name); + result.set(uniform.name, this.createOneLayoutEntry(uniform)); + } + }); + uid = `uniforms[${uid}]`; + return { uid, layouts: [...result.values()] }; } createBindGroupEntity() { - const e = new Map(); - let t = !1, - i = 0, - r = 0; - return ( - this._uniforms.forEach((n) => { - e.has(n.name) || - (n?.hasDynamicOffset && ((t = !0), (r = n.maxOffset), (i = 256 * Math.ceil(n.uniformsSize / 1024))), - e.set(n.name, this.creayeOneGroupEntity(n))); - }), - { entities: [...e.values()], dynamic: t, alignedSize: i, maxOffset: r } - ); - } - createOneLayoutEntry(e) { - let t; - return ( - e.isUniformBuffer - ? (t = new Xi({ binding: e.binding, buffer: e.layoutType, visibility: e.visibility })) - : e.isTexture - ? (t = new Xi({ - binding: e.binding, - visibility: e.visibility, - texture: "texture" == e.type ? e.layoutType : void 0, - storageTexture: "storageTexture" == e.type ? e.storageTextureLayoutType : void 0 - })) - : e.isSampler && (t = new Xi({ binding: e.binding, visibility: e.visibility, sampler: e.layoutType })), - t - ); + const result = new Map(); + let dynamic = false, + alignedSize = 0, + maxOffset = 0; + this._uniforms.forEach((uniform) => { + if (!result.has(uniform.name)) { + if (uniform?.hasDynamicOffset) { + dynamic = true; + maxOffset = uniform.maxOffset; + alignedSize = Math.ceil(uniform.uniformsSize / (4 * 256)) * 256; + } + result.set(uniform.name, this.creayeOneGroupEntity(uniform)); + } + }); + return { + entities: [...result.values()], + dynamic, + alignedSize, + maxOffset + }; } - creayeOneGroupEntity(e) { - let t; - return ( - e.isUniformBuffer - ? (t = new Fe({ - binding: e.binding, - resource: { buffer: e.buffer.gpuBuffer, offset: e.offset, size: e.bufferSize } - })) - : e.isTexture - ? (t = new Fe({ binding: e.binding, resource: e?.textureView ?? e.texture.textureView })) - : e.isSampler && (t = new Fe({ binding: e.binding, resource: e.sampler.gpuSampler })), - t - ); + createOneLayoutEntry(uniform) { + let layoutEntity; + if (uniform.isUniformBuffer) { + layoutEntity = new BindGroupLayoutEntry({ + binding: uniform.binding, + buffer: uniform.layoutType, + visibility: uniform.visibility + }); + } else if (uniform.isTexture) { + layoutEntity = new BindGroupLayoutEntry({ + binding: uniform.binding, + visibility: uniform.visibility, + texture: uniform.type == "texture" ? uniform.layoutType : undefined, + storageTexture: uniform.type == "storageTexture" ? uniform.storageTextureLayoutType : undefined + }); + } else if (uniform.isSampler) { + layoutEntity = new BindGroupLayoutEntry({ + binding: uniform.binding, + visibility: uniform.visibility, + sampler: uniform.layoutType + }); + } + return layoutEntity; + } + creayeOneGroupEntity(uniform) { + let groupEntity; + if (uniform.isUniformBuffer) { + groupEntity = new BindGroupEntity({ + binding: uniform.binding, + resource: { + buffer: uniform.buffer.gpuBuffer, + offset: uniform.offset, + size: uniform.bufferSize + } + }); + } else if (uniform.isTexture) { + groupEntity = new BindGroupEntity({ + binding: uniform.binding, + resource: uniform?.textureView ?? uniform.texture.textureView + }); + } else if (uniform.isSampler) { + groupEntity = new BindGroupEntity({ + binding: uniform.binding, + resource: uniform.sampler.gpuSampler + }); + } + return groupEntity; } } -class Wi { + +class Material { constructor() { - (this.label = void 0), - (this.type = void 0), - (this.baseTexture = void 0), - (this.baseSampler = void 0), - (this._diffuse = new Qt(0, 0, 0)), - (this._opacity = 1), - (this.shaderData = void 0), - (this.shaderSource = void 0), - (this.dirty = !0), - (this._emissive = new Qt(0, 0, 0)), - (this._emissiveIntensity = 1), - (this._doubleSided = !0), - (this.light = !1), - (this.ready = !1), - this.init(); - } - set wireframe(e) { - this.renderState.primitive.topology = e ? S.LineList : S.TriangleList; - } - set topology(e) { - this.renderState.primitive.topology = e; + this.label = undefined; + this.type = undefined; + this.baseTexture = undefined; + this.baseSampler = undefined; + this._diffuse = new Color(0.0, 0.0, 0.0); + this._opacity = 1.0; + // Buffer + this.shaderData = undefined; + this.shaderSource = undefined; + this.dirty = true; + this._emissive = new Color(0.0, 0.0, 0); + this._emissiveIntensity = 1.0; + this._doubleSided = true; + this.light = false; + this.ready = false; + this.init(); + } + set wireframe(value) { + this.renderState.primitive.topology = value ? PrimitiveTopology.LineList : PrimitiveTopology.TriangleList; + } + set topology(value) { + this.renderState.primitive.topology = value; } get doubleSided() { return this._doubleSided; } - set doubleSided(e) { - (this._renderState.primitive.cullMode = e ? w.None : w.Back), (this._doubleSided = e); + set doubleSided(value) { + this._renderState.primitive.cullMode = value ? CullMode.None : CullMode.Back; + this._doubleSided = value; } get renderState() { return this._renderState; } - set renderState(e) { - this._renderState = e; + set renderState(value) { + this._renderState = value; } get diffuse() { return this._diffuse; } - set diffuse(e) { - this._diffuse = e; + set diffuse(v) { + this._diffuse = v; } get emissive() { return this._emissive; } - set emissive(e) { - this._emissive = e; + set emissive(v) { + this._emissive = v; } get emissiveIntensity() { return this._emissiveIntensity; } - set emissiveIntensity(e) { - this._emissiveIntensity = e; + set emissiveIntensity(v) { + this._emissiveIntensity = v; } get opacity() { return this._opacity; } - set opacity(e) { - this._opacity = e; + set opacity(v) { + this._opacity = v; + } + onBeforeRender() { + // callback + } + onBeforeCompile() { + // callback } - onBeforeRender() {} - onBeforeCompile() {} clone() { return null; } - update(e, t) {} + update(frameState, mesh) { + // update material + } createShaderData() { - this.shaderData && this.shaderData.destroy(), (this.shaderData = new Yi(this.type, 0)), (this.ready = !0); + if (this.shaderData) this.shaderData.destroy(); + this.shaderData = new ShaderData(this.type, 0); + this.ready = true; } init() { - const e = new ae(), - t = new ce(), - i = new oe(); - (this._renderState = new te()), - (this._renderState.primitive = e), - (this._renderState.targets = [t]), - (this._renderState.depthStencil = i); + // 默认渲染状态 + const primitive = new Primitive(); + const target = new Target(); + const depthStencil = new DepthStencil(); + this._renderState = new RenderState(); + this._renderState.primitive = primitive; + this._renderState.targets = [target]; + this._renderState.depthStencil = depthStencil; } destroy() { - (this.label = void 0), - (this.type = void 0), - (this.baseTexture = void 0), - (this.baseSampler = void 0), - (this.color = void 0); + this.label = undefined; + this.type = undefined; + this.baseTexture = undefined; + this.baseSampler = undefined; + this.color = undefined; } } -class Zi extends Wi { - constructor(e) { + +class ShaderMaterial extends Material { + constructor(options) { super(); - const { type: t, frag: i, vert: r, defines: n, light: s } = e; - (this.type = t), - (this.shaderMaterialParms = e), - (this.shaderSource = new Gi({ shaderId: t, render: { fragShader: i, vertShader: r }, defines: ee(n, {}) })), - (this.uniforms = e.uniforms), - (this.uniformBuffer = void 0), - (this.light = s || !1); + const { type, frag, vert, defines, light } = options; + this.type = type; + this.shaderMaterialParms = options; + this.shaderSource = new ShaderSource({ + shaderId: type, + render: { + fragShader: frag, + vertShader: vert + }, + defines: defaultValue(defines, {}) + }); + this.uniforms = options.uniforms; + this.uniformBuffer = undefined; + this.light = light || false; } - update(e, t) { - (this.shaderData && !this.dirty) || this.createShaderData(t); + update(frameState, mesh) { + if (!this.shaderData || this.dirty) this.createShaderData(mesh); } clone() { - return new Zi(this.shaderMaterialParms); + return new ShaderMaterial(this.shaderMaterialParms); } - createShaderData(e) { + createShaderData(mesh) { super.createShaderData(); - const t = (function (e) { - let t = 0, - i = !1; - return ( - Object.getOwnPropertyNames(e).map((r) => { - "texture" == e[r].type || "sampler" == e[r].type - ? (t += 0) - : ki.find((t) => t === e[r].type) - ? (i = !0) - : (t += 1); - }), - { hasFloat: t, hasArraytype: i } + const result = checkContainFloatType(this.uniforms); + if (result.hasFloat) { + this.uniformBuffer = result.hasArraytype + ? new UniformBuffer({ + label: this.type + "UniformBuffer", + type: BufferBindingType.ReadOnlyStorage, + usage: BufferUsage.Storage | BufferUsage.CopyDst + }) + : new UniformBuffer({ label: this.type + "UniformBuffer" }); + this.shaderData.setUniformBuffer(this.type, this.uniformBuffer); + } + const uniformsNames = Object.getOwnPropertyNames(this.uniforms); + uniformsNames.map((uniformsName) => { + addUniformToShaderData( + uniformsName, + this.uniforms[uniformsName], + this.shaderData, + mesh, + this.uniformBuffer ); - })(this.uniforms); - t.hasFloat && - ((this.uniformBuffer = t.hasArraytype - ? new Ri({ label: this.type + "UniformBuffer", type: m.ReadOnlyStorage, usage: r.Storage | r.CopyDst }) - : new Ri({ label: this.type + "UniformBuffer" })), - this.shaderData.setUniformBuffer(this.type, this.uniformBuffer)); - Object.getOwnPropertyNames(this.uniforms).map((t) => { - qi(t, this.uniforms[t], this.shaderData, e, this.uniformBuffer); }); } } -function Ki() { - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (e) { - const t = (16 * Math.random()) | 0; - return ("x" === e ? t : (3 & t) | 8).toString(16); + +function createGuid() { + // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { + const r = (Math.random() * 16) | 0; + const v = c === "x" ? r : (r & 0x3) | 0x8; + return v.toString(16); }); } -class Qi extends $t { - constructor(e, t) { - super(), - (this.geometry = e), - (this.material = t), - (this.type = Z.Mesh), - (this.frustumCull = !0), - (this.uid = Ki()), - (this.subCommands = {}); + +class Mesh extends RenderObject { + constructor(geometry, material) { + super(); + this.geometry = geometry; + this.material = material; + this.type = RenderObjectType.Mesh; + this.frustumCull = true; + this.uid = createGuid(); + this.subCommands = {}; } get ready() { return this.material.ready; } - update(e, t) { - if ( - (this.updateMatrix(this?.parent?.modelMatrix), - this.geometry.update(e), - this.material.update(e, this), - this.geometry.boundingSphere.update(this.modelMatrix), - this.material.shaderSource.setDefines(e.defines), - this.type == Z.Debug) - ) - return void e.renderQueue.debugQueue.push(this); - this.distanceToCamera = this.geometry.boundingSphere.distanceToCamera(t); - e.cullingVolume.computeVisibility(this.geometry.boundingSphere) !== F.OUTSIDE && - this.frustumCull && - (this.material.transparent ? e.renderQueue.transparent.push(this) : e.renderQueue.opaque.push(this)); - } - beforeRender() {} - afterRender() {} - getDrawCommand(e, t, i) { - if ( - ((this.drawCommand && !this.material.dirty) || - (this.material.shaderSource.setDefines( - Object.assign({}, this.material.shaderData.defines, this.geometry.defines) - ), - this.material.dirty && (this.material.dirty = !1), - (this.drawCommand = new Y({ - vertexBuffers: this.geometry.vertexBuffers, - indexBuffer: this.geometry.indexBuffer, - shaderData: this.material.shaderData, - instances: this.instanceCount, - count: this.geometry.count, - renderState: this.material.renderState, - shaderSource: this.material.shaderSource, - lightShaderData: this.material.light ? i?.lightShaderData : void 0, - useLight: this.material.light - }))), - e) - ) { - if (!this.subCommands[t]) { - const i = e.clone(); - i.update(void 0, this), - i.dirty && (i.dirty = !1), - (this.subCommands[t] = this.drawCommand.shallowClone(i)); + update(frameState, camera) { + // update matrix + this.updateMatrix(this?.parent?.modelMatrix); + // create + this.geometry.update(frameState); + this.material.update(frameState, this); + // update boundingSphere + this.geometry.boundingSphere.update(this.modelMatrix); + this.material.shaderSource.setDefines(frameState.defines); + if (this.type == RenderObjectType.Debug) { + frameState.renderQueue.debugQueue.push(this); + return; + } + this.distanceToCamera = this.geometry.boundingSphere.distanceToCamera(camera); + const visibility = frameState.cullingVolume.computeVisibility(this.geometry.boundingSphere); + // 视锥剔除 + if (visibility === Intersect.OUTSIDE || !this.frustumCull) return; + if (this.material.transparent) { + frameState.renderQueue.transparent.push(this); + } else { + frameState.renderQueue.opaque.push(this); + } + } + beforeRender() { + // before render + } + afterRender() { + // after render + } + getDrawCommand(overrideMaterial, commandSubType, lightManger) { + if (!this.drawCommand || this.material.dirty) { + this.material.shaderSource.setDefines( + Object.assign({}, this.material.shaderData.defines, this.geometry.defines) + ); + if (this.material.dirty) this.material.dirty = false; + this.drawCommand = new DrawCommand({ + vertexBuffers: this.geometry.vertexBuffers, + indexBuffer: this.geometry.indexBuffer, + shaderData: this.material.shaderData, + instances: this.instanceCount, + count: this.geometry.count, + renderState: this.material.renderState, + shaderSource: this.material.shaderSource, + lightShaderData: this.material.light ? lightManger?.lightShaderData : undefined, + useLight: this.material.light + }); + } + if (overrideMaterial) { + if (!this.subCommands[commandSubType]) { + const copyMat = overrideMaterial.clone(); + copyMat.update(undefined, this); + if (copyMat.dirty) copyMat.dirty = false; + this.subCommands[commandSubType] = this.drawCommand.shallowClone(copyMat); } - return this.subCommands[t]; + return this.subCommands[commandSubType]; } return this.drawCommand; } destroy() { - this.geometry.destroy(), this.material.destroy(); + this.geometry.destroy(); + this.material.destroy(); } } -class Ji { - constructor(e, t) { - if (!(e && e instanceof Ht)) throw new Error("The parameter must be Light instance"); - (this.light = e), - (this.scene = t), - (this.debuggerSize = { width: 256, height: 256 }), - (this.mesh = this._createShadowMapMesh()); - const i = this.light.shadow.getShadowMapTexture(); - (this.material.uniforms.texture.value = i), (this.mesh.type = Z.Debug), this.scene.add(this.mesh); + +class ShadowMapDebugger { + constructor(light, scene) { + if (!light || !(light instanceof Light)) throw new Error("The parameter must be Light instance"); + this.light = light; + this.scene = scene; + this.debuggerSize = { + width: 256, + height: 256 + }; + this.mesh = this._createShadowMapMesh(); + const shadowMap = this.light.shadow.getShadowMapTexture(); + this.material.uniforms.texture.value = shadowMap; + this.mesh.type = RenderObjectType.Debug; + this.scene.add(this.mesh); } _createShadowMapMesh() { - const e = $i("shadowMapDebugger", { positionLocation: 0 }); - return ( - (this.geometry = new Dt(2, 2)), - (this.material = new Zi({ - type: "shadowMapDebugger", - frag: e.frag, - vert: e.vert, - uniforms: { - texture: { type: "texture", value: void 0 }, - sampler: { type: "sampler", value: new de({ magFilter: "linear", minFilter: "linear" }) } + const shader = getVertFrag("shadowMapDebugger", { + positionLocation: 0 + }); + this.geometry = new PlaneGeometry(2, 2); + this.material = new ShaderMaterial({ + type: "shadowMapDebugger", + frag: shader.frag, + vert: shader.vert, + uniforms: { + texture: { + type: "texture", + value: undefined + }, + sampler: { + type: "sampler", + value: new Sampler({ + magFilter: "linear", + minFilter: "linear" + }) } - })), - (this.material.renderState.viewport = new se(0, 0, this.debuggerSize.width, this.debuggerSize.height)), - new Qi(this.geometry, this.material) - ); + } + }); + this.material.renderState.viewport = new ViewPort(0, 0, this.debuggerSize.width, this.debuggerSize.height); + return new Mesh(this.geometry, this.material); } - setSize(e, t) { - e && t && ((this.debuggerSize.width = e), (this.debuggerSize.height = t), this.update()); + setSize(width, height) { + if (!width || !height) return; + this.debuggerSize.width = width; + this.debuggerSize.height = height; + this.update(); } update() { - this.material.renderState.viewport = new se(0, 0, this.debuggerSize.width, this.debuggerSize.height); + this.material.renderState.viewport = new ViewPort(0, 0, this.debuggerSize.width, this.debuggerSize.height); } } -class er extends Wi { + +class ColorMaterial extends Material { constructor() { - super(), (this.type = "color"), (this.shaderSource = new Gi({ shaderId: this.type, defines: {} })); + super(); + this.type = "color"; + this.shaderSource = new ShaderSource({ + shaderId: this.type, + defines: {} + }); } - update(e, t) { - (this.shaderData && !this.dirty) || this.createShaderData(); - const i = new Ri({ label: "color" }); - i.setUniform("modelMatrix", () => t.modelMatrix, Q.Mat4), this.shaderData.setUniformBuffer("color", i); + update(frameState, mesh) { + if (!this.shaderData || this.dirty) this.createShaderData(); + const uniformBuffer = new UniformBuffer({ label: "color" }); + uniformBuffer.setUniform( + "modelMatrix", + () => { + return mesh.modelMatrix; + }, + UniformEnum.Mat4 + ); + this.shaderData.setUniformBuffer("color", uniformBuffer); } } -class tr extends Qi { + +class Axes extends Mesh { constructor() { - super(), - (this.type = Z.Axes), - (this.distanceToCamera = 10), - (this.material = new er()), - (this.material.wireframe = !0), - this.init(); + super(); + this.type = RenderObjectType.Axes; + this.distanceToCamera = 10; + this.material = new ColorMaterial(); + this.material.wireframe = true; + this.init(); } - update(e) { - this.updateMatrix(), this.material.update(e, this), e.renderQueue.opaque.push(this); + update(frameState) { + this.updateMatrix(); + this.material.update(frameState, this); + frameState.renderQueue.opaque.push(this); } init() { - const e = [0, 1, 2, 3, 4, 5]; - (this.geometry = new At({})), - this.geometry.setAttribute(new Ie("position", [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1], 3)), - this.geometry.setAttribute( - new Ie("color", [1, 0, 0, 1, 1, 0.5, 0.5, 1, 0, 1, 0, 1, 0.5, 1, 0.5, 1, 0, 0, 1, 1, 0.5, 0.5, 1, 1], 4) - ), - this.geometry.setIndice(e), - (this.geometry.count = e.length); + const position = [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1]; + const colors = [1, 0, 0, 1, 1, 0.5, 0.5, 1, 0, 1, 0, 1, 0.5, 1, 0.5, 1, 0, 0, 1, 1, 0.5, 0.5, 1, 1]; + const indices = [0, 1, 2, 3, 4, 5]; + this.geometry = new Geometry({}); + this.geometry.setAttribute(new Float32Attribute("position", position, 3)); + this.geometry.setAttribute(new Float32Attribute("color", colors, 4)); + this.geometry.setIndice(indices); + this.geometry.count = indices.length; } } -class ir extends At { + +class SkyBoxGeometry extends Geometry { constructor() { - super({ type: "skyBoxGeometry" }), this.init(); + super({ + type: "skyBoxGeometry" + }); + this.init(); } init() { - const e = [ - 0, 2, 4, 6, 4, 2, 5, 3, 1, 3, 5, 7, 4, 1, 0, 1, 4, 5, 2, 3, 6, 7, 6, 3, 0, 1, 2, 3, 2, 1, 6, 5, 4, 5, 6, 7 + const positions = [ + 1.0, + 1.0, + 1.0, + -1.0, + 1.0, + 1.0, + 1.0, + -1.0, + 1.0, + -1.0, + -1.0, + 1.0, + 1.0, + 1.0, + -1.0, + -1.0, + 1.0, + -1.0, + 1.0, + -1.0, + -1.0, + -1.0, + -1.0, + -1.0 // 7 ]; - this.setAttribute( - new Ie("position", [1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1], 3) - ), - this.setIndice(e), - (this.count = e.length); + const indices = [ + // PosX (Right) + 0, 2, 4, 6, 4, 2, + // NegX (Left) + 5, 3, 1, 3, 5, 7, + // PosY (Top) + 4, 1, 0, 1, 4, 5, + // NegY (Bottom) + 2, 3, 6, 7, 6, 3, + // PosZ (Front) + 0, 1, 2, 3, 2, 1, + // NegZ (Back) + 6, 5, 4, 5, 6, 7 + ]; + this.setAttribute(new Float32Attribute("position", positions, 3)); + this.setIndice(indices); + this.count = indices.length; } } -function rr() { - return !0; + +function returnTrue() { + return true; +} +function destroyObject(object) { + // message =message||"This object was destroyed, i.e., destroy() was called."; + function throwOnDestroyed() { + throw new Error("This object was destroyed, i.e., destroy() was called."); + } + for (const key in object) { + if (typeof object[key] === "function") { + object[key] = throwOnDestroyed; + } + } + object.isDestroyed = returnTrue; + return undefined; } -const nr = new (class { + +class TextureCache { constructor() { - (this._numberOfTextures = 0), - (this._textures = new Map()), - (this._numberOfTextures = 0), - (this._texturesToRelease = new Map()), - (this.defaultSampler = new de({ - magFilter: "linear", - minFilter: "linear", - addressModeU: "repeat", - addressModeV: "repeat" - })); + this._numberOfTextures = 0; + this._textures = new Map(); + this._numberOfTextures = 0; + this._texturesToRelease = new Map(); + this.defaultSampler = new Sampler({ + magFilter: "linear", + minFilter: "linear", + addressModeU: "repeat", + addressModeV: "repeat" + }); } get numberOfTextures() { return this._numberOfTextures; } - getTexture(e) { - const t = this._textures.get(e); - if (pe(t)) return delete this._texturesToRelease[e], ++t.count, t.texture; - } - addTexture(e, t) { - const i = { texture: t, count: 1 }; - (t.finalDestroy = t.destroy), - (t.destroy = () => { - 0 == --i.count && this._texturesToRelease.set(e, i); - }), - this._textures.set(e, i), - ++this._numberOfTextures; + getTexture(keyword) { + const cachedTexture = this._textures.get(keyword); + if (!defined(cachedTexture)) { + return undefined; + } + // No longer want to release this if it was previously released. + delete this._texturesToRelease[keyword]; + ++cachedTexture.count; + return cachedTexture.texture; + } + addTexture(keyword, texture) { + const cachedTexture = { + texture: texture, + count: 1 + }; + texture.finalDestroy = texture.destroy; + // const that = this; + texture.destroy = () => { + if (--cachedTexture.count === 0) { + this._texturesToRelease.set(keyword, cachedTexture); + } + }; + this._textures.set(keyword, cachedTexture); + ++this._numberOfTextures; } releasedTextures() { - this._texturesToRelease.forEach((e) => { - e.texture?.finalDestroy(), --this._numberOfTextures; - }), - this._texturesToRelease.clear(); + this._texturesToRelease.forEach((cacheTexture) => { + cacheTexture.texture?.finalDestroy(); + --this._numberOfTextures; + }); + this._texturesToRelease.clear(); } destroy() { - return ( - this._textures.forEach((e) => { - e.texture?.finalDestroy(); - }), - (function (e) { - function t() { - throw new Error("This object was destroyed, i.e., destroy() was called."); - } - for (const i in e) "function" == typeof e[i] && (e[i] = t); - e.isDestroyed = rr; - })(this) - ); + this._textures.forEach((cachedTexture) => { + cachedTexture.texture?.finalDestroy(); + }); + return destroyObject(this); } -})(); -async function sr(e) { - const t = e.map((e) => { - const t = document.createElement("img"); - return (t.src = e), t.decode().then(() => createImageBitmap(t)); - }), - i = await Promise.all(t); - await Promise.all(i); - const r = new de({ magFilter: "linear", minFilter: "linear" }), - n = i.map((e, t) => ({ source: e, width: e.width, height: e.height, depth: 1, x: 0, y: 0, z: t })); +} +const textureCache = new TextureCache(); + +async function CubeTextureLoader(urls) { + const promises = urls.map((src) => { + const img = document.createElement("img"); + img.src = src; + return img.decode().then(() => createImageBitmap(img)); + }); + const images = await Promise.all(promises); + await Promise.all(images); + const baseSampler = new Sampler({ + magFilter: "linear", + minFilter: "linear" + }); + const data = images.map((image, i) => { + return { + source: image, + width: image.width, + height: image.height, + depth: 1, + x: 0, + y: 0, + z: i + }; + }); + const baseTexture = new Texture({ + size: { + width: images[0].width, + height: images[0].height, + depth: 6 + }, + format: "rgba8unorm", + usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT, + data, + viewFormats: "cube", + mipLevelCount: 6, + needMipMap: true + }); return { - texture: new fe({ - size: { width: i[0].width, height: i[0].height, depth: 6 }, - format: "rgba8unorm", - usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT, - data: n, - viewFormats: "cube", - mipLevelCount: 6, - needMipMap: !0 - }), - sampler: r + texture: baseTexture, + sampler: baseSampler }; } -class ar extends Wi { + +class SkyBoxMaterial extends Material { constructor() { - super(), - (this.type = "skybox"), - (this.shaderSource = new Gi({ shaderId: this.type, defines: {} })), - (this.loadFish = !1), - (this.renderState.depthStencil.depthWriteEnabled = !1), - (this.renderState.depthStencil.depthCompare = f.LessEqual); - } - async loadTexture(e) { - const t = await sr(e); - (this.loadFish = !0), - nr.addTexture("specular", t.texture), - (this.baseTexture = t.texture), - (this.baseSampler = t.sampler); - } - update(e, t) { - this.loadFish && (this.shaderData || this.createShaderData(t)); - } - createShaderData(e) { + super(); + this.type = "skybox"; + this.shaderSource = new ShaderSource({ + shaderId: this.type, + defines: {} + }); + this.loadFish = false; + this.renderState.depthStencil.depthWriteEnabled = false; + this.renderState.depthStencil.depthCompare = CompareFunction.LessEqual; + } + async loadTexture(urls) { + const result = await CubeTextureLoader(urls); + this.loadFish = true; + textureCache.addTexture("specular", result.texture); + this.baseTexture = result.texture; + this.baseSampler = result.sampler; + } + update(frameState, mesh) { + if (!this.loadFish) return; + if (!this.shaderData) { + this.createShaderData(mesh); + } + } + createShaderData(mesh) { super.createShaderData(); - const t = new Ri({ label: "skybox" }); - t.setUniform("modelMatrix", () => e.modelMatrix, Q.Mat4), - this.shaderData.setUniformBuffer("skybox", t), - this.shaderData.setTexture("baseTexture", this.baseTexture), - this.shaderData.setSampler("baseSampler", this.baseSampler); - } -} -class or extends Qi { - constructor(e) { - super(), - (this.type = Z.Skybox), - (this.visibility = !0), - (this.material = new ar()), - e && this.material.loadTexture(e), - (this.geometry = new ir()), - (this.isSkyBox = !0); - } - update(e) { - this.updateMatrix(), - this.geometry.update(e), - this.material.update(e, this), - this.visibility && e.renderQueue.pre.push(this); - } -} -class cr extends $t { + const uniformBuffer = new UniformBuffer({ label: "skybox" }); + uniformBuffer.setUniform( + "modelMatrix", + () => { + return mesh.modelMatrix; + }, + UniformEnum.Mat4 + ); + this.shaderData.setUniformBuffer("skybox", uniformBuffer); + this.shaderData.setTexture("baseTexture", this.baseTexture); + this.shaderData.setSampler("baseSampler", this.baseSampler); + } +} + +class SkyBox extends Mesh { + constructor(urls) { + super(); + this.type = RenderObjectType.Skybox; + this.visibility = true; + this.material = new SkyBoxMaterial(); + if (urls) this.material.loadTexture(urls); + this.geometry = new SkyBoxGeometry(); + this.isSkyBox = true; + } + update(frameState) { + this.updateMatrix(); + this.geometry.update(frameState); + this.material.update(frameState, this); + if (this.visibility) frameState.renderQueue.pre.push(this); + } +} + +class Instance extends RenderObject { constructor() { - super(), (this._notUpdateMatrix = !1), (this.visiblity = !1), (this.id = Ki()); + super(); + this._notUpdateMatrix = false; + this.visiblity = false; + this.id = createGuid(); } - setMatrix4(e) { - this.modelMatrix.set(e), (this._notUpdateMatrix = !0); + setMatrix4(mat4) { + this.modelMatrix.set(mat4); + this._notUpdateMatrix = true; } - updateMatrix(e) { - this._notUpdateMatrix || super.updateMatrix(e); + updateMatrix(matrix) { + if (this._notUpdateMatrix) return; + super.updateMatrix(matrix); } } -class lr extends Qi { - constructor(e, t) { - super(e, t), (this.instances = new Map()), (this.renderInstances = []), (this.hasAddInstances = !1); - } - update(e, t) { - this.checkInstancesVisiblity({ frameState: e, camera: t }), - this.geometry.update(e), - this.material.update(e, this), - this.hasAddInstances || this.addUniformsToMaterial(), - (this.instanceCount = this.renderInstances.length), - this.renderInstances.length < 1 || - (this.material.transparent ? e.renderQueue.transparent.push(this) : e.renderQueue.opaque.push(this)); + +class InstanceMesh extends Mesh { + constructor(geo, mat) { + super(geo, mat); + this.instances = new Map(); + this.renderInstances = []; + this.hasAddInstances = false; + } + update(frameState, camera) { + // update instances visiblity + this.checkInstancesVisiblity({ frameState, camera }); + this.geometry.update(frameState); + this.material.update(frameState, this); + if (!this.hasAddInstances) this.addUniformsToMaterial(); + this.instanceCount = this.renderInstances.length; + if (this.renderInstances.length < 1) return; + if (this.material.transparent) { + frameState.renderQueue.transparent.push(this); + } else { + frameState.renderQueue.opaque.push(this); + } } - addInstance(e) { - this.instances.get(e.id) || this.instances.set(e.id, e); + addInstance(instance) { + if (this.instances.get(instance.id)) return; + this.instances.set(instance.id, instance); } - removeInstance(e) { - return this.instances.delete(e); + removeInstance(key) { + return this.instances.delete(key); } - getInstance(e) { - return this.instances.get(e); + getInstance(key) { + return this.instances.get(key); } - checkInstancesVisiblity(e) { - const { frameState: t, camera: i } = e, - r = this.renderInstances.length; - (this.renderInstances = []), - this.instances.forEach((e) => { - e.updateMatrix(this?.parent?.modelMatrix), - (e.visiblity = this.getInstanceVisiblity({ instance: e, frameState: t, camera: i })), - e.visiblity && this.renderInstances.push(e); - }), - (this.material.dirty = this.renderInstances.length === r), - this.material.dirty && (this.hasAddInstances = !1); + checkInstancesVisiblity(options) { + const { frameState, camera } = options; + const preFrameInstanceCount = this.renderInstances.length; + this.renderInstances = []; + this.instances.forEach((instance) => { + instance.updateMatrix(this?.parent?.modelMatrix); + instance.visiblity = this.getInstanceVisiblity({ instance, frameState, camera }); + if (instance.visiblity) this.renderInstances.push(instance); + }); + this.material.dirty = this.renderInstances.length === preFrameInstanceCount; + // rebuild instanceMatrixsBuffer + if (this.material.dirty) this.hasAddInstances = false; } - getInstanceVisiblity(e) { - const { instance: t, frameState: i, camera: r } = e; - this.geometry.boundingSphere.update(t.modelMatrix), - (this.distanceToCamera = this.geometry.boundingSphere.distanceToCamera(r)); - const n = i.cullingVolume.computeVisibility(this.geometry.boundingSphere); - return n === F.INTERSECTING || n === F.INSIDE; + getInstanceVisiblity(options) { + const { instance, frameState, camera } = options; + this.geometry.boundingSphere.update(instance.modelMatrix); + this.distanceToCamera = this.geometry.boundingSphere.distanceToCamera(camera); + const visibility = frameState.cullingVolume.computeVisibility(this.geometry.boundingSphere); + return visibility === Intersect.INTERSECTING || visibility === Intersect.INSIDE; } addUniformsToMaterial() { if (!this.material.shaderData) return; - this.hasAddInstances = !0; - const e = new Ri({ + this.hasAddInstances = true; + const instanceMatrixsBuffer = new UniformBuffer({ label: "instanceMatrixsBuffer", - type: m.ReadOnlyStorage, - usage: r.Storage | r.CopyDst, - size: 64 * this.instances.size + type: BufferBindingType.ReadOnlyStorage, + usage: BufferUsage.Storage | BufferUsage.CopyDst, + size: this.instances.size * 64 }); - e.setUniform( + instanceMatrixsBuffer.setUniform( "instanceMatrixs", - () => this?.renderInstances?.map((e) => e.modelMatrix), - Q.Mat4Array, + () => { + return this?.renderInstances?.map((renderInstance) => renderInstance.modelMatrix); + }, + UniformEnum.Mat4Array, this?.renderInstances?.length - ), - this.material.shaderData.setUniformBuffer("instanceMatrixsBuffer", e), - this.material.shaderData.setDefine("USE_INSTANCE", !0), - this.material.shaderData.setDefine("instanceCount", this?.renderInstances?.length); + ); + this.material.shaderData.setUniformBuffer("instanceMatrixsBuffer", instanceMatrixsBuffer); + this.material.shaderData.setDefine("USE_INSTANCE", true); + this.material.shaderData.setDefine("instanceCount", this?.renderInstances?.length); } } -class hr { - constructor(e) { - (this.dispatch = e.dispatch), (this.shaderData = e.shaderData), (this.shaderSource = e.shaderSource); - } - render(e) { - const { device: t, passEncoder: i } = e; - this.shaderData?.bind?.(t, i); - H.getComputePipelineFromCache(t, this, [this.shaderData.groupLayout]).bind(i); - const { x: r, y: n, z: s } = this.dispatch; - i.dispatchWorkgroups(r, n, s); + +class ComputeCommand { + constructor(options) { + this.dispatch = options.dispatch; + this.shaderData = options.shaderData; + this.shaderSource = options.shaderSource; + } + render(params) { + const { device, passEncoder } = params; + this.shaderData?.bind?.(device, passEncoder); + const pipeline = Pipeline.getComputePipelineFromCache(device, this, [this.shaderData.groupLayout]); + pipeline.bind(passEncoder); + const { x, y, z } = this.dispatch; + passEncoder.dispatchWorkgroups(x, y, z); } } -class ur { - constructor(e) { - (this.modelParams = e), - (this.renderType = null != this.modelParams.compute ? "compute" : "render"), - (this.vertexBuffers = new Map()); - } - render(e) { - const { device: t, passEncoder: i } = e; - this.command || - (this.command = "render" === this.renderType ? this.createDrawCommand() : this.createComputeCommand()), - this.renderType, - this.command.render({ device: t, passEncoder: i }); + +class Model { + constructor(params) { + this.modelParams = params; + this.renderType = this.modelParams.compute != undefined ? "compute" : "render"; + this.vertexBuffers = new Map(); + } + render(params) { + const { device, passEncoder } = params; + if (!this.command) + this.command = this.renderType === "render" ? this.createDrawCommand() : this.createComputeCommand(); + if (this.renderType === "render") { + this.command.render({ + device, + passEncoder: passEncoder + }); + } else { + this.command.render({ + device, + passEncoder: passEncoder + }); + } } - compute(e) { - const { device: t, passEncoder: i } = e; - this.command || (this.command = this.createComputeCommand()), - this.command.render({ device: t, passEncoder: i }); + compute(params) { + const { device, passEncoder } = params; + if (!this.command) this.command = this.createComputeCommand(); + this.command.render({ + device, + passEncoder: passEncoder + }); } - getVertexBufferByUid(e) { - return this.vertexBuffers.get(e); + getVertexBufferByUid(uid) { + return this.vertexBuffers.get(uid); } - getUniformBufferByUid(e) { - return this.shaderData.getUniformBuffer(e); + getUniformBufferByUid(uid) { + return this.shaderData.getUniformBuffer(uid); } - getTextureByName(e) { - return this.shaderData.getTexture(e); + getTextureByName(name) { + return this.shaderData.getTexture(name); } - getSamplerByName(e) { - return this.shaderData.getSampler(e); + getSamplerByName(name) { + return this.shaderData.getSampler(name); } destroy() { - this?.vertexBuffers.clear(), this?.shaderData.destroy(), (this.command = null), (this.modelParams = null); + this?.vertexBuffers.clear(); + this?.shaderData.destroy(); + this.command = null; + this.modelParams = null; } createDrawCommand() { - const { count: e, instances: t } = this.modelParams, - i = this.createVertexBuffer(); + const { count, instances } = this.modelParams; + const vertexBuffers = this.createVertexBuffer(); this.shaderData = this.createShaderData(); - const r = this.createIndexBuffer(), - n = this.createShaderSource(), - s = this.createRenderState(); - return new Y({ - vertexBuffers: i, + const indexBuffer = this.createIndexBuffer(); + const shaderSource = this.createShaderSource(); + const renderState = this.createRenderState(); + return new DrawCommand({ + vertexBuffers, shaderData: this.shaderData, - indexBuffer: r, - shaderSource: n, - renderState: s, - count: e, - instances: t + indexBuffer, + shaderSource, + renderState, + count, + instances }); } createComputeCommand() { - const { dispatch: e } = this.modelParams, - t = this.createShaderData(), - i = this.createShaderSource(); - return new hr({ dispatch: e, shaderData: t, shaderSource: i }); + const { dispatch } = this.modelParams; + const shaderData = this.createShaderData(); + const shaderSource = this.createShaderSource(); + return new ComputeCommand({ + dispatch, + shaderData, + shaderSource + }); } createVertexBuffer() { - const { vertexBuffers: e, shaderId: t } = this.modelParams; - let i = 0; + const { vertexBuffers, shaderId } = this.modelParams; + let locationIndex = 0; return ( - e?.map((e, r) => { - const { attributes: n, stepMode: s, uid: a, arrayStride: o } = e, - c = new Ct({ label: t, index: r, locationIndex: i, stepMode: s, arrayStride: o }); - return ( - Object.keys(n).forEach((e) => { - const { size: t, value: r, names: s, itemSizes: a, buffer: o } = n[e]; - c.setAttribute(s?.length > 0 ? (o ? new Ne(s, o, a) : new Pe(s, r, a)) : new Ie(e, r, t)); - i += s?.length > 0 ? s?.length : 1; - }), - this.vertexBuffers.set(a, c), - c - ); + vertexBuffers?.map((vertexBufferObject, index) => { + const { attributes, stepMode, uid, arrayStride } = vertexBufferObject; + const vertexBuffer = new VertexBuffer({ + label: shaderId, + index, + locationIndex, + stepMode: stepMode, + arrayStride + }); + const attributeKeys = Object.keys(attributes); + attributeKeys.forEach((key) => { + const { size, value, names, itemSizes, buffer } = attributes[key]; + vertexBuffer.setAttribute( + names?.length > 0 + ? buffer + ? new BufferFloat32Attribute(names, buffer, itemSizes) + : new InterleavedFloat32Attribute(names, value, itemSizes) + : new Float32Attribute(key, value, size) + ); + const count = names?.length > 0 ? names?.length : 1; + locationIndex += count; + }); + this.vertexBuffers.set(uid, vertexBuffer); + return vertexBuffer; }) || [] ); } createShaderSource() { - const { vert: e, frag: t, compute: i, shaderId: r } = this.modelParams; - return new Gi({ shaderId: r, render: { vertShader: e, fragShader: t }, compute: { computeShader: i } }); + const { vert, frag, compute, shaderId } = this.modelParams; + return new ShaderSource({ + shaderId, + render: { + vertShader: vert, + fragShader: frag + }, + compute: { + computeShader: compute + } + }); } createShaderData() { - const { shaderId: e, uniformBuffers: t, uniformTextureAndSampler: i } = this.modelParams, - r = new Yi(e); - return t.forEach((t) => this.createUniformBuffer(t, r, e)), this.addUniformToShaderData(i, r, void 0), r; + const { shaderId, uniformBuffers, uniformTextureAndSampler } = this.modelParams; + const shaderData = new ShaderData(shaderId); + // fill uniformBuffer + uniformBuffers.forEach((uniformBuffer) => this.createUniformBuffer(uniformBuffer, shaderData, shaderId)); + // fill texture and sampler + this.addUniformToShaderData(uniformTextureAndSampler, shaderData, undefined); + return shaderData; } createRenderState() { const { - blendConstant: e, - depthStencil: t, - viewPort: i, - scissorTest: r, - targets: n, - multiSample: s, - primitive: a, - stencilReference: o + blendConstant, + depthStencil, + viewPort, + scissorTest, + targets, + multiSample, + primitive, + stencilReference } = this.modelParams.renderState; - return new te({ - scissorTest: r ? new ne(r.x, r.y, r.width, r.height) : void 0, - viewport: i ? new se(i.x, i.y, i.width, i.height) : void 0, - targets: n?.map((e) => new ce(e)), - depthStencil: t ? new oe(t) : void 0, - blendConstant: e ? new ie(e.r, e.g, e.b, e.a) : void 0, - stencilReference: o || 0, - multisample: s ? new re(s.count, s.mask, s.alphaToCoverageEnabled) : void 0, - primitive: a ? new ae(a.topology, a.cullMode, a.frontFace, a.unclippedDepth) : void 0, - stencilEnabled: !1, - scissorTestEnabled: !1 + return new RenderState({ + scissorTest: scissorTest + ? new ScissorTest(scissorTest.x, scissorTest.y, scissorTest.width, scissorTest.height) + : undefined, + viewport: viewPort ? new ViewPort(viewPort.x, viewPort.y, viewPort.width, viewPort.height) : undefined, + targets: targets?.map((target) => { + return new Target(target); + }), + depthStencil: depthStencil ? new DepthStencil(depthStencil) : undefined, + blendConstant: blendConstant + ? new BlendConstant(blendConstant.r, blendConstant.g, blendConstant.b, blendConstant.a) + : undefined, + stencilReference: stencilReference || 0, + multisample: multiSample + ? new MultiSample(multiSample.count, multiSample.mask, multiSample.alphaToCoverageEnabled) + : undefined, + primitive: primitive + ? new Primitive(primitive.topology, primitive.cullMode, primitive.frontFace, primitive.unclippedDepth) + : undefined, + stencilEnabled: false, + scissorTestEnabled: false }); } createIndexBuffer() { - const { indices: e, shaderId: t } = this.modelParams; - let i; - return e && ((i = new _t(t + "IndexBuffer")), i.setIndices(e)), i; + const { indices, shaderId } = this.modelParams; + let indexBuffer = undefined; + if (indices) { + indexBuffer = new IndexBuffer(shaderId + "IndexBuffer"); + indexBuffer.setIndices(indices); + } + return indexBuffer; } - createUniformBuffer(e, t, i) { + createUniformBuffer(uniformBufferParams, shaderData, shaderId) { const { - type: n = "uniform", - usage: s = r.Uniform | r.CopyDst, - uniforms: a, - uid: o, - binding: c, - buffer: l, - bufferSize: h, - visibility: u - } = e, - f = new Ri({ - label: o + "_UniformBuffer", - type: n, - usage: s, - binding: c, - buffer: l, - visibility: u, - size: l?.size ?? h - }); - t.setUniformBuffer(o, f), l || this.addUniformToShaderData(a, t, f); - } - addUniformToShaderData(e, t, i) { - if (!e) return; - Object.getOwnPropertyNames(e).map((r) => { - qi(r, e[r], t, void 0, i); + type = "uniform", + usage = BufferUsage.Uniform | BufferUsage.CopyDst, + uniforms, + uid, + binding, + buffer, + bufferSize, + visibility + } = uniformBufferParams; + const uniformBuffer = new UniformBuffer({ + label: uid + "_UniformBuffer", + type: type, + usage: usage, + binding, + buffer, + visibility, + size: buffer?.size ?? bufferSize + }); + shaderData.setUniformBuffer(uid, uniformBuffer); + if (!buffer) this.addUniformToShaderData(uniforms, shaderData, uniformBuffer); + } + addUniformToShaderData(uniforms, shaderData, uniformBuffer) { + if (!uniforms) return; + const uniformsNames = Object.getOwnPropertyNames(uniforms); + uniformsNames.map((uniformsName) => { + addUniformToShaderData(uniformsName, uniforms[uniformsName], shaderData, undefined, uniformBuffer); }); } } -class fr extends At { + +class SpriteGeometry extends Geometry { constructor() { - super({ type: "spriteGeometry" }), this.init(); + super({ + type: "spriteGeometry" + }); + this.init(); } init() { - const e = [-0.5, -0.5, 0, 0, 0, 0.5, -0.5, 0, 1, 0, 0.5, 0.5, 0, 1, 1, -0.5, 0.5, 0, 0, 1], - t = [0, 1, 2, 0, 2, 3]; - this.computeBoundingSphere(e, 5), - this.setAttribute(new Pe(["position", "uv"], e, [3, 2])), - this.setIndice(t), - (this.count = t.length); + // xyz、uv + const vertices = [-0.5, -0.5, 0, 0, 0, 0.5, -0.5, 0, 1, 0, 0.5, 0.5, 0, 1, 1, -0.5, 0.5, 0, 0, 1]; + const indices = [0, 1, 2, 0, 2, 3]; + this.computeBoundingSphere(vertices, 5); + this.setAttribute(new InterleavedFloat32Attribute(["position", "uv"], vertices, [3, 2])); + this.setIndice(indices); + this.count = indices.length; } } -class dr extends Wi { + +class SpriteMaterial extends Material { constructor() { - super(), - (this.type = "sprite"), - (this.shaderSource = new Gi({ shaderId: this.type, defines: { HAS_UV: !0 } })), - (this.rotation = Math.PI), - (this.opacity = 1), - (this.center = new Se(0, 0)), - (this.color = new Qt(1, 0, 0)); - } - update(e, t) { - (this.shaderData && !this.dirty) || this.createShaderData(t); - } - createShaderData(e) { + super(); + this.type = "sprite"; + this.shaderSource = new ShaderSource({ + shaderId: this.type, + defines: { + HAS_UV: true + } + }); + this.rotation = Math.PI; + this.opacity = 1; + this.center = new Vector2(0, 0); + this.color = new Color(1, 0, 0); + } + update(frameState, mesh) { + if (!this.shaderData || this.dirty) this.createShaderData(mesh); + } + createShaderData(mesh) { super.createShaderData(); - const t = new Ri({ label: "sprite" }); - t.setUniform("modelMatrix", () => e.modelMatrix, Q.Mat4), - t.setUniform("color", this, Q.Color), - t.setUniform("rotation", this, Q.Float), - t.setUniform("center", this, Q.FloatVec2), - t.setUniform("opacity", this, Q.Float), - this.shaderData.setUniformBuffer("sprite", t), - this.baseTexture && - (this.shaderData.setDefine("USE_COLORTEXTURE", !0), - this.shaderData.setTexture("baseColorTexture", this.baseTexture), - this.shaderData.setSampler("baseColorSampler", this.baseSampler || nr.defaultSampler)); + const uniformBuffer = new UniformBuffer({ label: "sprite" }); + uniformBuffer.setUniform( + "modelMatrix", + () => { + return mesh.modelMatrix; + }, + UniformEnum.Mat4 + ); + uniformBuffer.setUniform("color", this, UniformEnum.Color); + uniformBuffer.setUniform("rotation", this, UniformEnum.Float); + uniformBuffer.setUniform("center", this, UniformEnum.FloatVec2); + uniformBuffer.setUniform("opacity", this, UniformEnum.Float); + this.shaderData.setUniformBuffer("sprite", uniformBuffer); + if (this.baseTexture) { + this.shaderData.setDefine("USE_COLORTEXTURE", true); + this.shaderData.setTexture("baseColorTexture", this.baseTexture); + this.shaderData.setSampler("baseColorSampler", this.baseSampler || textureCache.defaultSampler); + } } destroy() { - this?.baseTexture?.destroy(), super.destroy(); + this?.baseTexture?.destroy(); + super.destroy(); } } -class mr extends Qi { + +class Sprite extends Mesh { constructor() { - super(), (this.material = new dr()), (this.geometry = new fr()); + super(); + this.material = new SpriteMaterial(); + this.geometry = new SpriteGeometry(); + } + setTexture(texture) { + this.material.baseTexture = texture; } - setTexture(e) { - this.material.baseTexture = e; + setSampler(sampler) { + this.material.baseSampler = sampler; } - setSampler(e) { - this.material.baseSampler = e; +} + +/** + * Ensure first argument passed to the primitive functions is an object + * @param {...*} args + */ +function createBox(options) { + options = options || {}; + const dimensions = options.dimensions || [1, 1, 1]; + const position = options.position || [-dimensions[0] / 2, -dimensions[1] / 2, -dimensions[2] / 2]; + const x = position[0]; + const y = position[1]; + const z = position[2]; + const width = dimensions[0]; + const height = dimensions[1]; + const depth = dimensions[2]; + const fbl = { x: x, y: y, z: z + depth }; + const fbr = { x: x + width, y: y, z: z + depth }; + const ftl = { x: x, y: y + height, z: z + depth }; + const ftr = { x: x + width, y: y + height, z: z + depth }; + const bbl = { x: x, y: y, z: z }; + const bbr = { x: x + width, y: y, z: z }; + const btl = { x: x, y: y + height, z: z }; + const btr = { x: x + width, y: y + height, z: z }; + const positions = [ + // front + fbl.x, + fbl.y, + fbl.z, + fbr.x, + fbr.y, + fbr.z, + ftl.x, + ftl.y, + ftl.z, + ftl.x, + ftl.y, + ftl.z, + fbr.x, + fbr.y, + fbr.z, + ftr.x, + ftr.y, + ftr.z, + // right + fbr.x, + fbr.y, + fbr.z, + bbr.x, + bbr.y, + bbr.z, + ftr.x, + ftr.y, + ftr.z, + ftr.x, + ftr.y, + ftr.z, + bbr.x, + bbr.y, + bbr.z, + btr.x, + btr.y, + btr.z, + // back + fbr.x, + bbr.y, + bbr.z, + bbl.x, + bbl.y, + bbl.z, + btr.x, + btr.y, + btr.z, + btr.x, + btr.y, + btr.z, + bbl.x, + bbl.y, + bbl.z, + btl.x, + btl.y, + btl.z, + // left + bbl.x, + bbl.y, + bbl.z, + fbl.x, + fbl.y, + fbl.z, + btl.x, + btl.y, + btl.z, + btl.x, + btl.y, + btl.z, + fbl.x, + fbl.y, + fbl.z, + ftl.x, + ftl.y, + ftl.z, + // top + ftl.x, + ftl.y, + ftl.z, + ftr.x, + ftr.y, + ftr.z, + btl.x, + btl.y, + btl.z, + btl.x, + btl.y, + btl.z, + ftr.x, + ftr.y, + ftr.z, + btr.x, + btr.y, + btr.z, + // bottom + bbl.x, + bbl.y, + bbl.z, + bbr.x, + bbr.y, + bbr.z, + fbl.x, + fbl.y, + fbl.z, + fbl.x, + fbl.y, + fbl.z, + bbr.x, + bbr.y, + bbr.z, + fbr.x, + fbr.y, + fbr.z + ]; + const uvs = [ + // front + 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, + // right + 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, + // back + 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, + // left + 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, + // top + 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, + // bottom + 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 + ]; + const normals = [ + // front + 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, + // right + 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, + // back + 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, + // left + -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, + // top + 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, + // bottom + 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0 + ]; + return { + positions: positions, + normals: normals, + uvs: uvs + }; +} +function createSphere(options) { + options = options || {}; + const longBands = options.longBands || 32; + const latBands = options.latBands || 32; + const radius = options.radius || 1; + const lat_step = Math.PI / latBands; + const long_step = (2 * Math.PI) / longBands; + const num_positions = longBands * latBands * 4; + const num_indices = longBands * latBands * 6; + let lat_angle, long_angle; + const positions = new Array(num_positions * 3); + const normals = new Array(num_positions * 3); + const uvs = new Array(num_positions * 2); + const indices = new Array(num_indices); + let x1, x2, x3, x4, y1, y2, z1, z2, z3, z4, u1, u2, v1, v2; + let i, j; + let k = 0, + l = 0; + let vi, ti; + for (i = 0; i < latBands; i++) { + lat_angle = i * lat_step; + y1 = Math.cos(lat_angle); + y2 = Math.cos(lat_angle + lat_step); + for (j = 0; j < longBands; j++) { + long_angle = j * long_step; + x1 = Math.sin(lat_angle) * Math.cos(long_angle); + x2 = Math.sin(lat_angle) * Math.cos(long_angle + long_step); + x3 = Math.sin(lat_angle + lat_step) * Math.cos(long_angle); + x4 = Math.sin(lat_angle + lat_step) * Math.cos(long_angle + long_step); + z1 = Math.sin(lat_angle) * Math.sin(long_angle); + z2 = Math.sin(lat_angle) * Math.sin(long_angle + long_step); + z3 = Math.sin(lat_angle + lat_step) * Math.sin(long_angle); + z4 = Math.sin(lat_angle + lat_step) * Math.sin(long_angle + long_step); + u1 = 1 - j / longBands; + u2 = 1 - (j + 1) / longBands; + v1 = 1 - i / latBands; + v2 = 1 - (i + 1) / latBands; + vi = k * 3; + ti = k * 2; + positions[vi] = x1 * radius; + positions[vi + 1] = y1 * radius; + positions[vi + 2] = z1 * radius; // v0 + positions[vi + 3] = x2 * radius; + positions[vi + 4] = y1 * radius; + positions[vi + 5] = z2 * radius; // v1 + positions[vi + 6] = x3 * radius; + positions[vi + 7] = y2 * radius; + positions[vi + 8] = z3 * radius; // v2 + positions[vi + 9] = x4 * radius; + positions[vi + 10] = y2 * radius; + positions[vi + 11] = z4 * radius; // v3 + normals[vi] = x1; + normals[vi + 1] = y1; + normals[vi + 2] = z1; + normals[vi + 3] = x2; + normals[vi + 4] = y1; + normals[vi + 5] = z2; + normals[vi + 6] = x3; + normals[vi + 7] = y2; + normals[vi + 8] = z3; + normals[vi + 9] = x4; + normals[vi + 10] = y2; + normals[vi + 11] = z4; + uvs[ti] = u1; + uvs[ti + 1] = v1; + uvs[ti + 2] = u2; + uvs[ti + 3] = v1; + uvs[ti + 4] = u1; + uvs[ti + 5] = v2; + uvs[ti + 6] = u2; + uvs[ti + 7] = v2; + indices[l] = k; + indices[l + 1] = k + 1; + indices[l + 2] = k + 2; + indices[l + 3] = k + 2; + indices[l + 4] = k + 1; + indices[l + 5] = k + 3; + k += 4; + l += 6; + } } + return { + positions: positions, + normals: normals, + uvs: uvs, + indices: indices + }; } -class pr extends At { - constructor(e) { - super({ type: "sphereGeometry" }), (this.defines = { HAS_NORMAL: !0 }), (this.radius = e), this.init(); + +class SphereGeometry extends Geometry { + constructor(radius) { + super({ + type: "sphereGeometry" + }); + this.defines = { + HAS_NORMAL: true + }; + this.radius = radius; + this.init(); } init() { - const { - positions: e, - normals: t, - uvs: i, - indices: r - } = (function (e) { - const t = (e = e || {}).longBands || 32, - i = e.latBands || 32, - r = e.radius || 1, - n = Math.PI / i, - s = (2 * Math.PI) / t, - a = t * i * 4, - o = t * i * 6; - let c, l; - const h = new Array(3 * a), - u = new Array(3 * a), - f = new Array(2 * a), - d = new Array(o); - let m, - p, - g, - x, - v, - y, - S, - b, - w, - T, - E, - M, - U, - _, - L, - C, - R, - A, - D = 0, - z = 0; - for (L = 0; L < i; L++) - for (c = L * n, v = Math.cos(c), y = Math.cos(c + n), C = 0; C < t; C++) - (l = C * s), - (m = Math.sin(c) * Math.cos(l)), - (p = Math.sin(c) * Math.cos(l + s)), - (g = Math.sin(c + n) * Math.cos(l)), - (x = Math.sin(c + n) * Math.cos(l + s)), - (S = Math.sin(c) * Math.sin(l)), - (b = Math.sin(c) * Math.sin(l + s)), - (w = Math.sin(c + n) * Math.sin(l)), - (T = Math.sin(c + n) * Math.sin(l + s)), - (E = 1 - C / t), - (M = 1 - (C + 1) / t), - (U = 1 - L / i), - (_ = 1 - (L + 1) / i), - (R = 3 * D), - (A = 2 * D), - (h[R] = m * r), - (h[R + 1] = v * r), - (h[R + 2] = S * r), - (h[R + 3] = p * r), - (h[R + 4] = v * r), - (h[R + 5] = b * r), - (h[R + 6] = g * r), - (h[R + 7] = y * r), - (h[R + 8] = w * r), - (h[R + 9] = x * r), - (h[R + 10] = y * r), - (h[R + 11] = T * r), - (u[R] = m), - (u[R + 1] = v), - (u[R + 2] = S), - (u[R + 3] = p), - (u[R + 4] = v), - (u[R + 5] = b), - (u[R + 6] = g), - (u[R + 7] = y), - (u[R + 8] = w), - (u[R + 9] = x), - (u[R + 10] = y), - (u[R + 11] = T), - (f[A] = E), - (f[A + 1] = U), - (f[A + 2] = M), - (f[A + 3] = U), - (f[A + 4] = E), - (f[A + 5] = _), - (f[A + 6] = M), - (f[A + 7] = _), - (d[z] = D), - (d[z + 1] = D + 1), - (d[z + 2] = D + 2), - (d[z + 3] = D + 2), - (d[z + 4] = D + 1), - (d[z + 5] = D + 3), - (D += 4), - (z += 6); - return { positions: h, normals: u, uvs: f, indices: d }; - })({ radius: this.radius }); - this.computeBoundingSphere(e), - this.setAttribute(new Ie("position", e, 3)), - this.setAttribute(new Ie("normal", t, 3)), - this.setAttribute(new Ie("uv", i, 2)), - this.setIndice(r), - (this.count = r.length); - } -} -class gr extends At { - constructor(e = 10, t = 10, i = 10) { - super({ type: "boxGeometry" }), - (this.width = e), - (this.height = t), - (this.depth = i), - (this.defines = { HAS_NORMAL: !0 }), - this.init(); + const { positions, normals, uvs, indices } = createSphere({ radius: this.radius }); + // this.positions = positions; + // this.normals = normals; + // this.uvs = uvs; + // this.indices = indices; + this.computeBoundingSphere(positions); + this.setAttribute(new Float32Attribute("position", positions, 3)); + this.setAttribute(new Float32Attribute("normal", normals, 3)); + this.setAttribute(new Float32Attribute("uv", uvs, 2)); + this.setIndice(indices); + this.count = indices.length; + } +} + +class BoxGeometry extends Geometry { + constructor(width = 10, height = 10, depth = 10) { + super({ + type: "boxGeometry" + }); + this.width = width; + this.height = height; + this.depth = depth; + this.defines = { + HAS_NORMAL: true + }; + this.init(); } init() { - const { - positions: e, - normals: t, - uvs: i - } = (function (e) { - const t = (e = e || {}).dimensions || [1, 1, 1], - i = e.position || [-t[0] / 2, -t[1] / 2, -t[2] / 2], - r = i[0], - n = i[1], - s = i[2], - a = t[0], - o = t[1], - c = t[2], - l = { x: r, y: n, z: s + c }, - h = { x: r + a, y: n, z: s + c }, - u = { x: r, y: n + o, z: s + c }, - f = { x: r + a, y: n + o, z: s + c }, - d = { x: r, y: n, z: s }, - m = { x: r + a, y: n, z: s }, - p = { x: r, y: n + o, z: s }, - g = { x: r + a, y: n + o, z: s }; - return { - positions: [ - l.x, - l.y, - l.z, - h.x, - h.y, - h.z, - u.x, - u.y, - u.z, - u.x, - u.y, - u.z, - h.x, - h.y, - h.z, - f.x, - f.y, - f.z, - h.x, - h.y, - h.z, - m.x, - m.y, - m.z, - f.x, - f.y, - f.z, - f.x, - f.y, - f.z, - m.x, - m.y, - m.z, - g.x, - g.y, - g.z, - h.x, - m.y, - m.z, - d.x, - d.y, - d.z, - g.x, - g.y, - g.z, - g.x, - g.y, - g.z, - d.x, - d.y, - d.z, - p.x, - p.y, - p.z, - d.x, - d.y, - d.z, - l.x, - l.y, - l.z, - p.x, - p.y, - p.z, - p.x, - p.y, - p.z, - l.x, - l.y, - l.z, - u.x, - u.y, - u.z, - u.x, - u.y, - u.z, - f.x, - f.y, - f.z, - p.x, - p.y, - p.z, - p.x, - p.y, - p.z, - f.x, - f.y, - f.z, - g.x, - g.y, - g.z, - d.x, - d.y, - d.z, - m.x, - m.y, - m.z, - l.x, - l.y, - l.z, - l.x, - l.y, - l.z, - m.x, - m.y, - m.z, - h.x, - h.y, - h.z - ], - normals: [ - 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, - 1, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, -1, 0, 0, -1, 0, 0, -1, 0, 0, - -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, - 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0 - ], - uvs: [ - 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, - 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 1 - ] - }; - })({ dimensions: [this.depth, this.width, this.height] }); - this.computeBoundingSphere(e), - this.setAttribute(new Ie("position", e, 3)), - this.setAttribute(new Ie("normal", t, 3)), - this.setAttribute(new Ie("uv", i, 2)), - (this.count = 36); - } -} -class xr extends At { - constructor(e = 1, t = 0.4, i = 64, r = 8, n = 2, s = 3) { - super({ type: "torusKnotGeometry" }), - (this.defines = { HAS_NORMAL: !0 }), - (this.radius = e), - (this.tube = t), - (this.tubularSegments = i), - (this.radialSegments = r), - (this.p = n), - (this.q = s), - this.init(); + // generate pos uv normal so on + const { positions, normals, uvs } = createBox({ + dimensions: [this.depth, this.width, this.height] + }); + this.computeBoundingSphere(positions); + this.setAttribute(new Float32Attribute("position", positions, 3)); + this.setAttribute(new Float32Attribute("normal", normals, 3)); + this.setAttribute(new Float32Attribute("uv", uvs, 2)); + this.count = 36; + } +} + +class TorusKnotGeometry extends Geometry { + constructor(radius = 1, tube = 0.4, tubularSegments = 64, radialSegments = 8, p = 2, q = 3) { + super({ + type: "torusKnotGeometry" + }); + this.defines = { + HAS_NORMAL: true + }; + this.radius = radius; + this.tube = tube; + this.tubularSegments = tubularSegments; + this.radialSegments = radialSegments; + this.p = p; + this.q = q; + this.init(); } init() { - const { normals: e, uvs: t, positions: i, indices: r } = this.createGeometry(); - this.computeBoundingSphere(i), - this.setAttribute(new Ie("position", i, 3)), - this.setAttribute(new Ie("normal", e, 3)), - this.setAttribute(new Ie("uv", t, 2)), - this.setIndice(r), - (this.count = r.length); + const { normals, uvs, positions, indices } = this.createGeometry(); + this.computeBoundingSphere(positions); + this.setAttribute(new Float32Attribute("position", positions, 3)); + this.setAttribute(new Float32Attribute("normal", normals, 3)); + this.setAttribute(new Float32Attribute("uv", uvs, 2)); + this.setIndice(indices); + this.count = indices.length; } createGeometry() { - const e = [], - t = [], - i = [], - r = [], - n = Math.floor(this.tubularSegments), - s = Math.floor(this.radialSegments), - a = new Ue(), - o = new Ue(), - c = new Ue(), - l = new Ue(), - h = new Ue(), - u = new Ue(), - f = new Ue(); - for (let r = 0; r <= n; ++r) { - const d = (r / n) * this.p * Math.PI * 2; - vr(d, this.p, this.q, this.radius, c), - vr(d + 0.01, this.p, this.q, this.radius, l), - Ue.subtract(l, c, u), - Ue.add(l, c, f), - Ue.cross(u, f, h), - Ue.cross(h, u, f), - h.normalize(), - f.normalize(); - for (let l = 0; l <= s; ++l) { - const u = (l / s) * Math.PI * 2, - d = -this.tube * Math.cos(u), - m = this.tube * Math.sin(u); - (a.x = c.x + (d * f.x + m * h.x)), - (a.y = c.y + (d * f.y + m * h.y)), - (a.z = c.z + (d * f.z + m * h.z)), - e.push(a.x, a.y, a.z), - Ue.subtract(a, c, o), - o.normalize(), - t.push(o.x, o.y, o.z), - i.push(r / n), - i.push(l / s); + const positions = [], + normals = [], + uvs = [], + indices = []; + const tubularSegments = Math.floor(this.tubularSegments); + const radialSegments = Math.floor(this.radialSegments); + // helper variables + const vertex = new Vector3(); + const normal = new Vector3(); + const P1 = new Vector3(); + const P2 = new Vector3(); + const B = new Vector3(); + const T = new Vector3(); + const N = new Vector3(); + // generate vertices, normals and uvs + for (let i = 0; i <= tubularSegments; ++i) { + // the radian "u" is used to calculate the position on the torus curve of the current tubular segment + const u = (i / tubularSegments) * this.p * Math.PI * 2; + // now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead. + // these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions + calculatePositionOnCurve(u, this.p, this.q, this.radius, P1); + calculatePositionOnCurve(u + 0.01, this.p, this.q, this.radius, P2); + // calculate orthonormal basis + Vector3.subtract(P2, P1, T); + // T.subVectors( P2, P1 ); + Vector3.add(P2, P1, N); + // N.addVectors( P2, P1 ); + Vector3.cross(T, N, B); + // B.crossVectors( T, N ); + Vector3.cross(B, T, N); + // N.crossVectors( B, T ); + // normalize B, N. T can be ignored, we don't use it + B.normalize(); + N.normalize(); + for (let j = 0; j <= radialSegments; ++j) { + // now calculate the vertices. they are nothing more than an extrusion of the torus curve. + // because we extrude a shape in the xy-plane, there is no need to calculate a z-value. + const v = (j / radialSegments) * Math.PI * 2; + const cx = -this.tube * Math.cos(v); + const cy = this.tube * Math.sin(v); + // now calculate the final vertex position. + // first we orient the extrusion with our basis vectors, then we add it to the current position on the curve + vertex.x = P1.x + (cx * N.x + cy * B.x); + vertex.y = P1.y + (cx * N.y + cy * B.y); + vertex.z = P1.z + (cx * N.z + cy * B.z); + positions.push(vertex.x, vertex.y, vertex.z); + // normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal) + Vector3.subtract(vertex, P1, normal); + normal.normalize(); + normals.push(normal.x, normal.y, normal.z); + // uv + uvs.push(i / tubularSegments); + uvs.push(j / radialSegments); } } - for (let e = 1; e <= n; e++) - for (let t = 1; t <= s; t++) { - const i = (s + 1) * (e - 1) + (t - 1), - n = (s + 1) * e + (t - 1), - a = (s + 1) * e + t, - o = (s + 1) * (e - 1) + t; - r.push(i, n, o), r.push(n, a, o); + // generate indices + for (let j = 1; j <= tubularSegments; j++) { + for (let i = 1; i <= radialSegments; i++) { + // indices + const a = (radialSegments + 1) * (j - 1) + (i - 1); + const b = (radialSegments + 1) * j + (i - 1); + const c = (radialSegments + 1) * j + i; + const d = (radialSegments + 1) * (j - 1) + i; + // faces + indices.push(a, b, d); + indices.push(b, c, d); } - return { normals: t, uvs: i, positions: e, indices: r }; + } + return { + normals, + uvs, + positions, + indices + }; } } -function vr(e, t, i, r, n) { - const s = Math.cos(e), - a = Math.sin(e), - o = (i / t) * e, - c = Math.cos(o); - (n.x = r * (2 + c) * 0.5 * s), (n.y = r * (2 + c) * a * 0.5), (n.z = r * Math.sin(o) * 0.5); +function calculatePositionOnCurve(u, p, q, radius, position) { + const cu = Math.cos(u); + const su = Math.sin(u); + const quOverP = (q / p) * u; + const cs = Math.cos(quOverP); + position.x = radius * (2 + cs) * 0.5 * cu; + position.y = radius * (2 + cs) * su * 0.5; + position.z = radius * Math.sin(quOverP) * 0.5; } -class yr extends Wi { + +class BlinnPhongMaterial extends Material { constructor() { - super(), - (this.type = "phong"), - (this.color = new Qt(1, 0, 0)), - (this.shaderSource = new Gi({ shaderId: this.type, defines: { materialPhong: !0 } })), - (this.light = !0), - (this.specular = new Qt(1, 1, 1)), - (this.shininess = 30), - (this.baseTexture = void 0), - (this.baseSampler = void 0); - } - update(e, t) { - (this.shaderData && !this.dirty) || this.createShaderData(t); - } - createShaderData(e) { + super(); + this.type = "phong"; + this.color = new Color(1.0, 0.0, 0.0); + this.shaderSource = new ShaderSource({ + shaderId: this.type, + defines: { + materialPhong: true + } + }); + this.light = true; + this.specular = new Color(1.0, 1.0, 1.0); + this.shininess = 30.0; + this.baseTexture = undefined; + this.baseSampler = undefined; + } + update(frameState, mesh) { + if (!this.shaderData || this.dirty) this.createShaderData(mesh); + } + createShaderData(mesh) { super.createShaderData(); - const t = new Ri({ label: "phong" }); - t.setUniform("modelMatrix", () => e.modelMatrix, Q.Mat4), - t.setUniform("color", this, Q.Color), - t.setUniform("opacity", this, Q.Float), - t.setUniform("normalMtrix", () => e.normalMatrix, Q.Mat4), - t.setUniform("emissive", this, Q.Color), - t.setUniform("shininess", this, Q.Float), - t.setUniform("specular", this, Q.Color), - this.shaderData.setUniformBuffer("phong", t), - this.baseTexture && - (this.shaderData.setDefine("USE_COLORTEXTURE", !0), - this.shaderData.setTexture("baseColorTexture", this.baseTexture), - this.shaderData.setSampler("baseColorSampler", this.baseSampler || nr.defaultSampler)), - this.normalTexture && - (this.shaderData.setDefine("USE_NORMALTEXTURE", !0), - this.shaderData.setTexture("normalTexture", this.normalTexture), - this.shaderData.setSampler("normalSampler", this.normalSampler || nr.defaultSampler)); + const uniformBuffer = new UniformBuffer({ label: "phong" }); + uniformBuffer.setUniform( + "modelMatrix", + () => { + return mesh.modelMatrix; + }, + UniformEnum.Mat4 + ); + uniformBuffer.setUniform("color", this, UniformEnum.Color); + uniformBuffer.setUniform("opacity", this, UniformEnum.Float); + uniformBuffer.setUniform( + "normalMtrix", + () => { + return mesh.normalMatrix; + }, + UniformEnum.Mat4 + ); + uniformBuffer.setUniform("emissive", this, UniformEnum.Color); + uniformBuffer.setUniform("shininess", this, UniformEnum.Float); + uniformBuffer.setUniform("specular", this, UniformEnum.Color); + this.shaderData.setUniformBuffer("phong", uniformBuffer); + if (this.baseTexture) { + this.shaderData.setDefine("USE_COLORTEXTURE", true); + this.shaderData.setTexture("baseColorTexture", this.baseTexture); + this.shaderData.setSampler("baseColorSampler", this.baseSampler || textureCache.defaultSampler); + } + if (this.normalTexture) { + this.shaderData.setDefine("USE_NORMALTEXTURE", true); + this.shaderData.setTexture("normalTexture", this.normalTexture); + this.shaderData.setSampler("normalSampler", this.normalSampler || textureCache.defaultSampler); + } } destroy() { - this?.baseTexture?.destroy(), super.destroy(); + this?.baseTexture?.destroy(); + super.destroy(); } } -class Sr extends Wi { + +class PbrMaterial extends Material { get roughness() { return this._roughness; } - set roughness(e) { - this._roughness = e; + set roughness(value) { + this._roughness = value; } get metalness() { return this._metalness; } - set metalness(e) { - this._metalness = e; + set metalness(v) { + this._metalness = v; } get aoTextureIntensity() { return this._aoTextureIntensity; } - set aoTextureIntensity(e) { - this._aoTextureIntensity = e; + set aoTextureIntensity(v) { + this._aoTextureIntensity = v; } get normalScale() { - return this.renderState && this.renderState.primitive && this.renderState.primitive.cullMode == w.Back - ? Se.negate(this._normalScale, new Se()) - : this._normalScale; + if (this.renderState && this.renderState.primitive) { + if (this.renderState.primitive.cullMode == CullMode.Back) { + return Vector2.negate(this._normalScale, new Vector2()); + } + } + return this._normalScale; } - set normalScale(e) { - this._normalScale = e; + set normalScale(v) { + this._normalScale = v; } - set IBLRender(e) { - (this._IBLRender = e), this.shaderSource.setDefines({ USE_IBL: this._IBLRender }), (this.dirty = !0); + set IBLRender(value) { + this._IBLRender = value; + this.shaderSource.setDefines({ + USE_IBL: this._IBLRender + }); + this.dirty = true; } constructor() { - super(), - (this.type = "pbr_mat"), - (this._roughness = 0.1), - (this._metalness = 0.1), - (this._aoTextureIntensity = 1), - (this.light = !0), - (this._normalScale = new Se(1, 1)), - (this._IBLRender = !0), - (this.shaderSource = new Gi({ - shaderId: this.type, - defines: { materialPbr: !0, USE_IBL: this._IBLRender } - })); - } - update(e, t) { - nr.getTexture("specular") && ((this.shaderData && !this.dirty) || this.createShaderData(t)); - } - createShaderData(e) { + super(); + this.type = "pbr_mat"; + this._roughness = 0.1; + this._metalness = 0.1; + this._aoTextureIntensity = 1.0; + this.light = true; + this._normalScale = new Vector2(1, 1); + this._IBLRender = true; + this.shaderSource = new ShaderSource({ + shaderId: this.type, + defines: { + materialPbr: true, + USE_IBL: this._IBLRender + } + }); + } + update(frameState, mesh) { + if (!textureCache.getTexture("specular")) return; + if (!this.shaderData || this.dirty) { + this.createShaderData(mesh); + } + } + createShaderData(mesh) { super.createShaderData(); - const t = new Ri({ label: "pbr" }); - t.setUniform("modelMatrix", () => e.modelMatrix, Q.Mat4), - t.setUniform("color", this, Q.Color), - t.setUniform("opacity", this, Q.Float), - t.setUniform("normalMtrix", () => e.normalMatrix, Q.Mat4), - t.setUniform("emissive", this, Q.Color), - t.setUniform("metalness", this, Q.Float), - t.setUniform("roughness", this, Q.Float), - this.shaderData.setUniformBuffer("pbr", t), - (this.specularEnvTexture = nr.getTexture("specular")), - this.baseTexture && - (this.shaderData.setDefine("USE_TEXTURE", !0), - this.shaderData.setTexture("baseColorTexture", this.baseTexture), - this.shaderData.setSampler("baseColorSampler", this.baseSampler || nr.defaultSampler)), - this.metalnessRoughnessTexture && - (this.shaderData.setDefine("USE_METALNESSTEXTURE", !0), - this.shaderData.setTexture("metalnessRoughnessTexture", this.metalnessRoughnessTexture), - this.shaderData.setSampler( - "metalnessRoughnessSampler", - this.metalnessRoughnessSampler || nr.defaultSampler - )), - this.normalTexture && - (t.setUniform("normalScale", this, Q.FloatVec2), - this.shaderData.setDefine("USE_NORMALTEXTURE", !0), - this.shaderData.setTexture("normalTexture", this.normalTexture), - this.shaderData.setSampler("normalSampler", this.normalSampler || nr.defaultSampler)), - this.aoTexture && - (this.shaderData.setDefine("USE_AOTEXTURE", !0), - this.shaderData.setTexture("aoTexture", this.aoTexture), - this.shaderData.setSampler("aoSampler", this.aoSampler || nr.defaultSampler), - t.setUniform("aoTextureIntensity", this, Q.Float)), - this.emissiveTexture && - (this.shaderData.setDefine("USE_EMISSIVETEXTURE", !0), - this.shaderData.setTexture("emissiveTexture", this.emissiveTexture), - this.shaderData.setSampler("emissiveSampler", this.emissiveSampler || nr.defaultSampler)), - this.specularEnvTexture && - this._IBLRender && - (this.shaderData.setTexture("specularEnvTexture", this.specularEnvTexture), - this.shaderData.setSampler("specularEnvSampler", this.specularEnvSampler || nr.defaultSampler)); + const uniformBuffer = new UniformBuffer({ label: "pbr" }); + uniformBuffer.setUniform( + "modelMatrix", + () => { + return mesh.modelMatrix; + }, + UniformEnum.Mat4 + ); + uniformBuffer.setUniform("color", this, UniformEnum.Color); + uniformBuffer.setUniform("opacity", this, UniformEnum.Float); + uniformBuffer.setUniform( + "normalMtrix", + () => { + return mesh.normalMatrix; + }, + UniformEnum.Mat4 + ); + uniformBuffer.setUniform("emissive", this, UniformEnum.Color); + uniformBuffer.setUniform("metalness", this, UniformEnum.Float); + uniformBuffer.setUniform("roughness", this, UniformEnum.Float); + this.shaderData.setUniformBuffer("pbr", uniformBuffer); + this.specularEnvTexture = textureCache.getTexture("specular"); + if (this.baseTexture) { + this.shaderData.setDefine("USE_TEXTURE", true); + this.shaderData.setTexture("baseColorTexture", this.baseTexture); + this.shaderData.setSampler("baseColorSampler", this.baseSampler || textureCache.defaultSampler); + } + if (this.metalnessRoughnessTexture) { + this.shaderData.setDefine("USE_METALNESSTEXTURE", true); + this.shaderData.setTexture("metalnessRoughnessTexture", this.metalnessRoughnessTexture); + this.shaderData.setSampler( + "metalnessRoughnessSampler", + this.metalnessRoughnessSampler || textureCache.defaultSampler + ); + } + if (this.normalTexture) { + uniformBuffer.setUniform("normalScale", this, UniformEnum.FloatVec2); + this.shaderData.setDefine("USE_NORMALTEXTURE", true); + this.shaderData.setTexture("normalTexture", this.normalTexture); + this.shaderData.setSampler("normalSampler", this.normalSampler || textureCache.defaultSampler); + } + if (this.aoTexture) { + this.shaderData.setDefine("USE_AOTEXTURE", true); + this.shaderData.setTexture("aoTexture", this.aoTexture); + this.shaderData.setSampler("aoSampler", this.aoSampler || textureCache.defaultSampler); + uniformBuffer.setUniform("aoTextureIntensity", this, UniformEnum.Float); + } + if (this.emissiveTexture) { + this.shaderData.setDefine("USE_EMISSIVETEXTURE", true); + this.shaderData.setTexture("emissiveTexture", this.emissiveTexture); + this.shaderData.setSampler("emissiveSampler", this.emissiveSampler || textureCache.defaultSampler); + } + if (this.specularEnvTexture && this._IBLRender) { + this.shaderData.setTexture("specularEnvTexture", this.specularEnvTexture); + this.shaderData.setSampler("specularEnvSampler", this.specularEnvSampler || textureCache.defaultSampler); + } } destroy() { - this?.aoTexture?.destroy(), - this?.baseTexture?.destroy(), - this?.emissiveTexture?.destroy(), - this?.normalTexture?.destroy(), - (this.specularEnvTexture = void 0); + this?.aoTexture?.destroy(); + this?.baseTexture?.destroy(); + this?.emissiveTexture?.destroy(); + this?.normalTexture?.destroy(); + this.specularEnvTexture = undefined; } } -class br { + +class EventDispatcher { constructor() { this._listeners = {}; } - addEventListener(e, t) { - void 0 === this._listeners && (this._listeners = {}); - const i = this._listeners; - void 0 === i[e] && (i[e] = []), -1 === i[e].indexOf(t) && i[e].push(t); - } - hasEventListener(e, t) { - if (void 0 === this._listeners) return !1; - const i = this._listeners; - return void 0 !== i[e] && -1 !== i[e].indexOf(t); + addEventListener(type, listener) { + if (this._listeners === undefined) this._listeners = {}; + const listeners = this._listeners; + if (listeners[type] === undefined) { + listeners[type] = []; + } + if (listeners[type].indexOf(listener) === -1) { + listeners[type].push(listener); + } } - removeEventListener(e, t) { - if (void 0 === this._listeners) return; - const i = this._listeners[e]; - if (void 0 !== i) { - const e = i.indexOf(t); - -1 !== e && i.splice(e, 1); + hasEventListener(type, listener) { + if (this._listeners === undefined) return false; + const listeners = this._listeners; + return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1; + } + removeEventListener(type, listener) { + if (this._listeners === undefined) return; + const listeners = this._listeners; + const listenerArray = listeners[type]; + if (listenerArray !== undefined) { + const index = listenerArray.indexOf(listener); + if (index !== -1) { + listenerArray.splice(index, 1); + } } } - dispatchEvent(e) { - if (void 0 === this._listeners) return; - const t = this._listeners[e.type]; - if (void 0 !== t) { - e.target = this; - const i = t.slice(0); - for (let t = 0, r = i.length; t < r; t++) i[t].call(this, e); - e.target = null; + dispatchEvent(event) { + if (this._listeners === undefined) return; + const listeners = this._listeners; + const listenerArray = listeners[event.type]; + if (listenerArray !== undefined) { + event.target = this; + const array = listenerArray.slice(0); + for (let i = 0, l = array.length; i < l; i++) { + array[i].call(this, event); + } + event.target = null; } } } -class wr { + +class RenderQueue { constructor() { - (this.pre = []), (this.opaque = []), (this.transparent = []), (this.computes = []), (this.debugQueue = []); + this.pre = []; + this.opaque = []; + this.transparent = []; + this.computes = []; + this.debugQueue = []; } sort() { - wr.sort(this.opaque, 0, this.opaque.length, wr._compareFromNearToFar), - wr.sort(this.transparent, 0, this.transparent.length, wr._compareFromFarToNear); - } - opaqueRender(e, t, i, r, n, s) { - this.opaque.map((a) => { - a.ready && (a.beforeRender(), wr.excuteCommand(a.getDrawCommand(r, n, s), t, i, e), a.afterRender()); + RenderQueue.sort(this.opaque, 0, this.opaque.length, RenderQueue._compareFromNearToFar); + RenderQueue.sort(this.transparent, 0, this.transparent.length, RenderQueue._compareFromFarToNear); + } + opaqueRender(camera, context, passEncoder, replaceMaterial, commandSubType, lightManger) { + this.opaque.map((mesh) => { + if (!mesh.ready) return; + mesh.beforeRender(); + RenderQueue.excuteCommand( + mesh.getDrawCommand(replaceMaterial, commandSubType, lightManger), + context, + passEncoder, + camera + ); + mesh.afterRender(); }); } - transparentRender(e, t, i, r, n, s) { - this.transparent.map((a) => { - a.ready && (a.beforeRender(), wr.excuteCommand(a.getDrawCommand(r, n, s), t, i, e), a.afterRender()); + transparentRender(camera, context, passEncoder, replaceMaterial, commandSubType, lightManger) { + this.transparent.map((mesh) => { + if (!mesh.ready) return; + mesh.beforeRender(); + RenderQueue.excuteCommand( + mesh.getDrawCommand(replaceMaterial, commandSubType, lightManger), + context, + passEncoder, + camera + ); + mesh.afterRender(); }); } - computeRender(e, t) { - this.computes.map((i) => { - wr.excuteCompute(i.getCommand(), e, t); + computeRender(context, passEncoder) { + this.computes.map((compute) => { + RenderQueue.excuteCompute(compute.getCommand(), context, passEncoder); }); } - debugQueueRender(e, t, i, r, n) { - this.debugQueue.map((s) => { - s.ready && (s.beforeRender(), wr.excuteCommand(s.getDrawCommand(r, n), t, i, e), s.afterRender()); + debugQueueRender(camera, context, passEncoder, replaceMaterial, commandSubType) { + this.debugQueue.map((mesh) => { + if (!mesh.ready) return; + mesh.beforeRender(); + RenderQueue.excuteCommand( + mesh.getDrawCommand(replaceMaterial, commandSubType), + context, + passEncoder, + camera + ); + mesh.afterRender(); }); } - preRender(e, t, i, r) { - this.pre.map((r) => { - r.ready && (r.beforeRender(), wr.excuteCommand(r.getDrawCommand(), t, i, e), r.afterRender()); + preRender(camera, context, passEncoder, replaceMaterial) { + this.pre.map((mesh) => { + if (!mesh.ready) return; + mesh.beforeRender(); + RenderQueue.excuteCommand(mesh.getDrawCommand(), context, passEncoder, camera); + mesh.afterRender(); }); } - static excuteCommand(e, t, i, r) { - e.render({ device: t.device, passEncoder: i, camera: r, viewPort: t?.viewPort, scissorTest: t?.scissorTest }); + static excuteCommand(command, context, passEncoder, camera) { + command.render({ + device: context.device, + passEncoder, + camera, + viewPort: context?.viewPort, + scissorTest: context?.scissorTest + }); } - static excuteCompute(e, t, i) { - e.render({ device: t.device, passEncoder: i }); + static excuteCompute(command, context, passEncoder) { + command.render({ device: context.device, passEncoder }); } reset() { - (this.pre = []), (this.opaque = []), (this.transparent = []), (this.computes = []), (this.debugQueue = []); - } - static _compareFromNearToFar(e, t) { - return e.priority - t.priority || e.distanceToCamera - t.distanceToCamera; - } - static _compareFromFarToNear(e, t) { - return e.priority - t.priority || t.distanceToCamera - e.distanceToCamera; - } - static sort(e, t, i, r) { - wr._quickSort(e, t, i, r); - } - static _quickSort(e, t, i, r) { - for (;;) { - if (i - t <= 10) return void wr._insertionSort(e, t, i, r); - const n = (t + i) >> 1; - let s = e[t], - a = e[i - 1], - o = e[n]; - if (r(s, a) > 0) { - const e = s; - (s = a), (a = e); + this.pre = []; + this.opaque = []; + this.transparent = []; + this.computes = []; + this.debugQueue = []; + } + static _compareFromNearToFar(a, b) { + return a.priority - b.priority || a.distanceToCamera - b.distanceToCamera; + } + static _compareFromFarToNear(a, b) { + return a.priority - b.priority || b.distanceToCamera - a.distanceToCamera; + } + // according to camera distance + static sort(insatnce, from, to, compareFunc) { + RenderQueue._quickSort(insatnce, from, to, compareFunc); + } + // from https://github.com/oasis-engine/engine/blob/main/packages/core/src/RenderPipeline/RenderQueue.ts + static _quickSort(a, from, to, compareFunc) { + while (true) { + // Insertion sort is faster for short arrays. + if (to - from <= 10) { + RenderQueue._insertionSort(a, from, to, compareFunc); + return; } - if (r(s, o) >= 0) { - const e = s; - (s = o), (o = a), (a = e); + const third_index = (from + to) >> 1; + // Find a pivot as the median of first, last and middle element. + let v0 = a[from]; + let v1 = a[to - 1]; + let v2 = a[third_index]; + const c01 = compareFunc(v0, v1); + if (c01 > 0) { + // v1 < v0, so swap them. + const tmp = v0; + v0 = v1; + v1 = tmp; + } // v0 <= v1. + const c02 = compareFunc(v0, v2); + if (c02 >= 0) { + // v2 <= v0 <= v1. + const tmp = v0; + v0 = v2; + v2 = v1; + v1 = tmp; } else { - if (r(a, o) > 0) { - const e = a; - (a = o), (o = e); + // v0 <= v1 && v0 < v2 + const c12 = compareFunc(v1, v2); + if (c12 > 0) { + // v0 <= v2 < v1 + const tmp = v1; + v1 = v2; + v2 = tmp; } } - (e[t] = s), (e[i - 1] = o); - const c = a; - let l = t + 1, - h = i - 1; - (e[n] = e[l]), (e[l] = c); - e: for (let t = l + 1; t < h; t++) { - let i = e[t], - n = r(i, c); - if (n < 0) (e[t] = e[l]), (e[l] = i), l++; - else if (n > 0) { + // v0 <= v1 <= v2 + a[from] = v0; + a[to - 1] = v2; + const pivot = v1; + let low_end = from + 1; // Upper bound of elements lower than pivot. + let high_start = to - 1; // Lower bound of elements greater than pivot. + a[third_index] = a[low_end]; + a[low_end] = pivot; + // From low_end to i are elements equal to pivot. + // From i to high_start are elements that haven't been compared yet. + partition: for (let i = low_end + 1; i < high_start; i++) { + let element = a[i]; + let order = compareFunc(element, pivot); + if (order < 0) { + a[i] = a[low_end]; + a[low_end] = element; + low_end++; + } else if (order > 0) { do { - if ((h--, h == t)) break e; - n = r(e[h], c); - } while (n > 0); - (e[t] = e[h]), (e[h] = i), n < 0 && ((i = e[t]), (e[t] = e[l]), (e[l] = i), l++); + high_start--; + if (high_start == i) break partition; + const top_elem = a[high_start]; + order = compareFunc(top_elem, pivot); + } while (order > 0); + a[i] = a[high_start]; + a[high_start] = element; + if (order < 0) { + element = a[i]; + a[i] = a[low_end]; + a[low_end] = element; + low_end++; + } } } - i - h < l - t ? (this._quickSort(e, h, i, r), (i = l)) : (this._quickSort(e, t, l, r), (t = h)); + if (to - high_start < low_end - from) { + this._quickSort(a, high_start, to, compareFunc); + to = low_end; + } else { + this._quickSort(a, from, low_end, compareFunc); + from = high_start; + } } } - static _insertionSort(e, t, i, r) { - for (let n = t + 1; n < i; n++) { - let i; - const s = e[n]; - for (i = n - 1; i >= t; i--) { - const t = e[i]; - if (!(r(t, s) > 0)) break; - e[i + 1] = t; + static _insertionSort(a, from, to, compareFunc) { + for (let i = from + 1; i < to; i++) { + let j; + const element = a[i]; + for (j = i - 1; j >= from; j--) { + const tmp = a[j]; + const order = compareFunc(tmp, element); + if (order > 0) { + a[j + 1] = tmp; + } else { + break; + } } - e[i + 1] = s; + a[j + 1] = element; } } } -class Tr { - constructor(e, t, i = {}) { - (this.context = e), - (this.lightManger = t), - (this.background = i.background), - (this.renderQueue = new wr()), - (this.geometryMemory = 0), - (this.textureMemory = 0), - (this.frameNumber = 0), - (this._defines = {}), - (this.definesDirty = !0); + +class FrameState { + constructor(context, lightManger, options = {}) { + this.context = context; + this.lightManger = lightManger; + this.background = options.background; + this.renderQueue = new RenderQueue(); + this.geometryMemory = 0; + this.textureMemory = 0; + this.frameNumber = 0; + this._defines = {}; + this.definesDirty = true; } get defines() { return this._defines; } - set defines(e) { - (this.definesDirty = !0), (this._defines = Rt(e, this._defines, !1)); + set defines(value) { + this.definesDirty = true; + this._defines = combine(value, this._defines, false); } - update(e, t = {}) { - (this.background = t.background), - this.renderQueue.reset(), - this?.lightManger?.update?.(this, e), - (this.cullingVolume = e.getCullingVolume()), - (this.frameNumber += 1); + update(camera, options = {}) { + this.background = options.background; + this.renderQueue.reset(); + this?.lightManger?.update?.(this, camera); + this.cullingVolume = camera.getCullingVolume(); + this.frameNumber += 1; } - resetCullingVolume(e) { - this.cullingVolume = e.getCullingVolume(); + resetCullingVolume(camera) { + this.cullingVolume = camera.getCullingVolume(); } - static getFrameStateOptionsByScene(e) { - return { background: e.background }; + static getFrameStateOptionsByScene(sceneInstance) { + return { + background: sceneInstance.background + }; } } -class Er extends Ht { - constructor(e, t) { - super(e, t), (this.lightType = K.AmbientLight), (this._colorAndIntensity = new We(e.x, e.y, e.z, t)); + +class AmbientLight extends Light { + constructor(color, intensity) { + super(color, intensity); + this.lightType = LightType.AmbientLight; + this._colorAndIntensity = new Vector4(color.x, color.y, color.z, intensity); } - get ColorAndIntensity() { - return ( - this._colorAndIntensity.set(this.color.x, this.color.y, this.color.z, this.intensity), - this._colorAndIntensity - ); + get ColorAndIntensity() { + this._colorAndIntensity.set(this.color.x, this.color.y, this.color.z, this.intensity); + return this._colorAndIntensity; } } -class Mr { - constructor(e) { - (this.spotLights = []), - (this.pointLights = []), - (this.directLights = []), - (this.ambientLight = new Er(new Ue(1, 1, 1), 0.2)), - (this.lightCountDirty = !0), - (this.openShadow = e.openShadow); - } - update(e, t) { - this.checkLightShadowState(), this.updateLight(t); - } - add(e) { - (this.lightCountDirty = !0), - e.lightType == K.AmbientLight - ? (this.ambientLight = e) - : e.lightType == K.DirectionalLight - ? this.directLights.push(e) - : e.lightType == K.PointLight - ? this.pointLights.push(e) - : e.lightType == K.SpotLight && this.spotLights.push(e); - } - remove(e) { - (this.lightCountDirty = !0), - e.lightType == K.AmbientLight - ? (this.ambientLight = new Er(new Ue(1, 1, 1), 1)) - : e.lightType == K.DirectionalLight - ? this.directLights.splice(this.directLights.indexOf(e), 1) - : e.lightType == K.PointLight - ? this.pointLights.splice(this.pointLights.indexOf(e), 1) - : e.lightType == K.SpotLight && this.spotLights.splice(this.spotLights.indexOf(e), 1); +// light.color ).multiplyScalar( light.intensity * scaleFactor ); + +class LightManger { + constructor(options) { + this.spotLights = []; + this.pointLights = []; + this.directLights = []; + this.ambientLight = new AmbientLight(new Vector3(1.0, 1.0, 1.0), 0.2); + this.lightCountDirty = true; + this.openShadow = options.openShadow; + } + update(frameState, camera) { + this.checkLightShadowState(); + this.updateLight(camera); + } + add(light) { + this.lightCountDirty = true; + if (light.lightType == LightType.AmbientLight) { + this.ambientLight = light; + } else if (light.lightType == LightType.DirectionalLight) { + this.directLights.push(light); + } else if (light.lightType == LightType.PointLight) { + this.pointLights.push(light); + } else if (light.lightType == LightType.SpotLight) { + this.spotLights.push(light); + } + } + remove(light) { + this.lightCountDirty = true; + if (light.lightType == LightType.AmbientLight) { + this.ambientLight = new AmbientLight(new Vector3(1.0, 1.0, 1.0), 1.0); + } else if (light.lightType == LightType.DirectionalLight) { + this.directLights.splice(this.directLights.indexOf(light), 1); + } else if (light.lightType == LightType.PointLight) { + this.pointLights.splice(this.pointLights.indexOf(light), 1); + } else if (light.lightType == LightType.SpotLight) { + this.spotLights.splice(this.spotLights.indexOf(light), 1); + } } checkLightShadowState() { - const e = this.getAllLights(); - for (let t = 0; t < e.length; t++) { - const i = e[t]; - i.shadowDirty && ((i.shadowDirty = !1), (this.lightCountDirty = !0)); + const lights = this.getAllLights(); + for (let i = 0; i < lights.length; i++) { + const light = lights[i]; + if (light.shadowDirty) { + light.shadowDirty = false; + this.lightCountDirty = true; + } } } updateLightShadow() { - this.spotLightShadowMapTextureArray && (this.spotLightShadowMapTextureArray.dirty = !0), - this.pointLightShadowMapTextureArray && (this.pointLightShadowMapTextureArray.dirty = !0), - this.directLightShadowMapTextureArray && (this.directLightShadowMapTextureArray.dirty = !0); - } - updateLight(e) { - this.lightCountDirty && - ((this.lightCountDirty = !1), - this.lightShaderData && this.lightShaderData.destroy(), - this.createLightShaderData()); + if (this.spotLightShadowMapTextureArray) this.spotLightShadowMapTextureArray.dirty = true; + if (this.pointLightShadowMapTextureArray) this.pointLightShadowMapTextureArray.dirty = true; + if (this.directLightShadowMapTextureArray) this.directLightShadowMapTextureArray.dirty = true; + } + updateLight(camera) { + if (this.lightCountDirty) { + this.lightCountDirty = false; + if (this.lightShaderData) this.lightShaderData.destroy(); + this.createLightShaderData(); + } } createLightShaderData() { - (this.lightShaderData = new Yi("light", 0, 2, 2)), - (this.lightUniformBuffer = new Ri({ - label: "light", - type: m.ReadOnlyStorage, - usage: r.Storage | r.CopyDst - })), - this.lightShaderData.setDefine("spotLightsCount", this.spotLights.length), - this.lightShaderData.setDefine("pointLightsCount", this.pointLights.length), - this.lightShaderData.setDefine("dirtectLightsCount", this.directLights.length), - this.lightShaderData.setDefine("ambientLightCount", 1), - this.ambientLight && - this.lightUniformBuffer.setUniform( - "ambientLight", - () => this.ambientLight.ColorAndIntensity, - Q.FloatVec4 - ), - this.spotLights.length && - this.lightUniformBuffer.setUniform( - "spotLights", - () => this.spotLights, - Q.SpotLights, - this.spotLights.length - ), - this.pointLights.length && - this.lightUniformBuffer.setUniform( - "pointLights", - () => this.pointLights, - Q.PointLights, - this.pointLights.length - ), - this.directLights.length && - this.lightUniformBuffer.setUniform( - "directLights", - () => this.directLights, - Q.DirtectLights, - this.directLights.length - ); - e: if (this.openShadow) { - const e = (this.spotLightShadowMapTextureArray = this.createShadowMapTextureArray(this.spotLights)), - t = (this.pointLightShadowMapTextureArray = this.createShadowMapTextureArray(this.pointLights)), - i = (this.directLightShadowMapTextureArray = this.createShadowMapTextureArray(this.directLights)); - if (!e && !t && !i) break e; - this.lightShaderData.setDefine("openShadow", this.openShadow), - (this.shadowUniformBuffer = new Ri({ + this.lightShaderData = new ShaderData("light", 0, 2, 2); + this.lightUniformBuffer = new UniformBuffer({ + label: "light", + type: BufferBindingType.ReadOnlyStorage, + usage: BufferUsage.Storage | BufferUsage.CopyDst + }); + this.lightShaderData.setDefine("spotLightsCount", this.spotLights.length); + this.lightShaderData.setDefine("pointLightsCount", this.pointLights.length); + this.lightShaderData.setDefine("dirtectLightsCount", this.directLights.length); + this.lightShaderData.setDefine("ambientLightCount", 1); + if (this.ambientLight) + this.lightUniformBuffer.setUniform( + "ambientLight", + () => { + return this.ambientLight.ColorAndIntensity; + }, + UniformEnum.FloatVec4 + ); + if (this.spotLights.length) { + // 初始化聚光灯 + this.lightUniformBuffer.setUniform( + "spotLights", + () => { + return this.spotLights; + }, + UniformEnum.SpotLights, + this.spotLights.length + ); + } + if (this.pointLights.length) { + // 点光源 + this.lightUniformBuffer.setUniform( + "pointLights", + () => { + return this.pointLights; + }, + UniformEnum.PointLights, + this.pointLights.length + ); + } + if (this.directLights.length) { + // 方向光 + this.lightUniformBuffer.setUniform( + "directLights", + () => { + return this.directLights; + }, + UniformEnum.DirtectLights, + this.directLights.length + ); + } + shadowShaderData: { + if (this.openShadow) { + const spotLightShadowMapTextureArray = (this.spotLightShadowMapTextureArray = + this.createShadowMapTextureArray(this.spotLights)); + const pointLightShadowMapTextureArray = (this.pointLightShadowMapTextureArray = + this.createShadowMapTextureArray(this.pointLights)); + const directLightShadowMapTextureArray = (this.directLightShadowMapTextureArray = + this.createShadowMapTextureArray(this.directLights)); + if ( + !spotLightShadowMapTextureArray && + !pointLightShadowMapTextureArray && + !directLightShadowMapTextureArray + ) + break shadowShaderData; + // define + this.lightShaderData.setDefine("openShadow", this.openShadow); + // shadowUniformBuffer + this.shadowUniformBuffer = new UniformBuffer({ label: "shadow", - type: m.ReadOnlyStorage, - usage: r.Storage | r.CopyDst - })); - const n = this.setShadowUniform("spotLightShadows", this.spotLights, Q.SpotLightShadows), - s = this.setShadowUniform("pointLightShadows", this.pointLights, Q.PointLightShadows), - a = this.setShadowUniform("directLightShadows", this.directLights, Q.DirtectLightShadows); - this.lightShaderData.setUniformBuffer("shadow", this.shadowUniformBuffer), - this.lightShaderData.setDefine("spotLightShadowMapsCount", n), - this.lightShaderData.setDefine("pointLightShadowMapsCount", s), - this.lightShaderData.setDefine("directLightShadowMapsCount", a), - void 0 !== e && - (e.textureProp.size.depth != n && console.warn("spotLightShadowMap align has problem"), - this.lightShaderData.setTexture("spotLightShadowMapTextureArray", e)), - void 0 !== t && - (t.textureProp.size.depth != s && console.warn("pointLightShadowMap align has problem"), - this.lightShaderData.setTexture("pointLightShadowMapTextureArray", t)), - void 0 !== i && - (i.textureProp.size.depth != a && console.warn("directLightShadowMap align has problem"), - this.lightShaderData.setTexture("directLightShadowMapTextureArray", i)), - this.lightShaderData.setSampler("shadowSampler", new de({ compare: f.Less }, { type: p.Comparison })); + type: BufferBindingType.ReadOnlyStorage, + usage: BufferUsage.Storage | BufferUsage.CopyDst + }); + // matrix,near,far... + const spotLightWithShadowCount = this.setShadowUniform( + "spotLightShadows", + this.spotLights, + UniformEnum.SpotLightShadows + ); + const pointLightWithShadowCount = this.setShadowUniform( + "pointLightShadows", + this.pointLights, + UniformEnum.PointLightShadows + ); + const directLightWithShadowCount = this.setShadowUniform( + "directLightShadows", + this.directLights, + UniformEnum.DirtectLightShadows + ); + this.lightShaderData.setUniformBuffer("shadow", this.shadowUniformBuffer); + this.lightShaderData.setDefine("spotLightShadowMapsCount", spotLightWithShadowCount); + this.lightShaderData.setDefine("pointLightShadowMapsCount", pointLightWithShadowCount); + this.lightShaderData.setDefine("directLightShadowMapsCount", directLightWithShadowCount); + // texture,sample + if (spotLightShadowMapTextureArray !== undefined) { + if (spotLightShadowMapTextureArray.textureProp.size.depth != spotLightWithShadowCount) + console.warn("spotLightShadowMap align has problem"); + this.lightShaderData.setTexture("spotLightShadowMapTextureArray", spotLightShadowMapTextureArray); + // this._testTexture = spotLightShadowMapTextureArray + } + if (pointLightShadowMapTextureArray !== undefined) { + if (pointLightShadowMapTextureArray.textureProp.size.depth != pointLightWithShadowCount) + console.warn("pointLightShadowMap align has problem"); + this.lightShaderData.setTexture("pointLightShadowMapTextureArray", pointLightShadowMapTextureArray); + // this._testTexture = pointLightShadowMapTextureArray; + } + if (directLightShadowMapTextureArray !== undefined) { + if (directLightShadowMapTextureArray.textureProp.size.depth != directLightWithShadowCount) + console.warn("directLightShadowMap align has problem"); + this.lightShaderData.setTexture( + "directLightShadowMapTextureArray", + directLightShadowMapTextureArray + ); + // this._testTexture = directLightShadowMapTextureArray + } + this.lightShaderData.setSampler( + "shadowSampler", + new Sampler({ compare: CompareFunction.Less }, { type: SamplerBindingType.Comparison }) + ); + // this.lightShaderData.setSampler("shadowSampler", new Sampler()); + } } this.lightShaderData.setUniformBuffer("light", this.lightUniformBuffer); } getAllLights() { - return [].concat(this.spotLights, this.pointLights, this.directLights); + const result = []; + return result.concat(this.spotLights, this.pointLights, this.directLights); } destroy() { - this.lightShaderData.destroy(), this.lightUniformBuffer.destroy(); - } - createShadowMapTextureArray(e) { - if (e.length <= 0) return; - const t = []; - for (let i = 0; i < e.length; i++) { - const r = e[i]; - if (r.shadow) { - const e = r.shadow.getShadowMapTexture(), - n = { - source: e, - width: e.textureProp.size.width, - height: e.textureProp.size.height, - depth: 1, - x: 0, - y: 0, - z: i - }; - t.push(n); + this.lightShaderData.destroy(); + this.lightUniformBuffer.destroy(); + } + createShadowMapTextureArray(lights) { + if (lights.length <= 0) return undefined; + const shadowMapSources = []; + for (let i = 0; i < lights.length; i++) { + const light = lights[i]; + if (light.shadow) { + const shadowMapTexture = light.shadow.getShadowMapTexture(); + const shadowMapSource = { + source: shadowMapTexture, + width: shadowMapTexture.textureProp.size.width, + height: shadowMapTexture.textureProp.size.height, + depth: 1, + x: 0, + y: 0, + z: i + }; + shadowMapSources.push(shadowMapSource); } } - if (t.length <= 0) return; - return new fe({ - size: { width: t[0].width, height: t[0].height, depth: t.length }, - fixedSize: !0, - sampleType: g.Depth, - format: l.Depth24Plus, - usage: a.TextureBinding | a.CopyDst, - data: t, - viewFormats: o.E2dArray + if (shadowMapSources.length <= 0) return undefined; + const shadowMapTextureArray = new Texture({ + size: { + width: shadowMapSources[0].width, + height: shadowMapSources[0].height, + depth: shadowMapSources.length + }, + fixedSize: true, + sampleType: TextureSampleType.Depth, + format: TextureFormat.Depth24Plus, + usage: TextureUsage.TextureBinding | TextureUsage.CopyDst, + data: shadowMapSources, + viewFormats: TextureViewDimension.E2dArray }); - } - setShadowUniform(e, t, i) { - if (t.length) { - const r = []; - for (let e = 0; e < t.length; e++) { - const i = t[e]; - i.shadow && r.push(i); + return shadowMapTextureArray; + } + setShadowUniform(uniformName, lights, uniformType) { + if (lights.length) { + const lightWithShadowArray = []; + for (let i = 0; i < lights.length; i++) { + const light = lights[i]; + if (!light.shadow) continue; + lightWithShadowArray.push(light); } - return this.shadowUniformBuffer.setUniform(e, () => r, i, r.length), r.length; + this.shadowUniformBuffer.setUniform( + uniformName, + () => { + return lightWithShadowArray; + }, + uniformType, + lightWithShadowArray.length + ); + return lightWithShadowArray.length; } } } -class Ur { + +class MeshManger { constructor() { this._list = new Map(); } get length() { return this._list.size; } - update(e, t) { - this._list.forEach((i) => { - i.update(e, t); + update(frameState, camera) { + this._list.forEach((instance) => { + instance.update(frameState, camera); }); } - add(e) { - return this._list.get(e.uid) ? this._list.get(e.uid) : (this._list.set(e.uid, e), e); + add(instance) { + if (this._list.get(instance.uid)) return this._list.get(instance.uid); + this._list.set(instance.uid, instance); + return instance; } - remove(e) { - return !!this._list.get(e.uid) && (e.destroy(), this._list.delete(e.uid), !0); + remove(instance) { + if (this._list.get(instance.uid)) { + instance.destroy(); + this._list.delete(instance.uid); + return true; + } + return false; } - contains(e) { - return !!this._list.get(e.uid); + contains(instance) { + return !!this._list.get(instance.uid); } } -class _r { + +class ResolveFrame { constructor() { - (this.geometry = new At({})), - this.geometry.setAttribute(new Ie("position", [-1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1], 2)), - (this.geometry.count = 6); - const e = $i("resolve", { positionLocation: 0 }); - (this.material = new Zi({ + this.geometry = new Geometry({}); + this.geometry.setAttribute( + new Float32Attribute("position", [-1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0], 2) + ); + this.geometry.count = 6; + const shader = getVertFrag("resolve", { positionLocation: 0 }); + this.material = new ShaderMaterial({ type: "resolve", - frag: e.frag, - vert: e.vert, + frag: shader.frag, + vert: shader.vert, uniforms: { - texture: { type: "texture", value: void 0 }, - sampler: { type: "sampler", value: new de({ magFilter: "linear", minFilter: "linear" }) } + texture: { + type: "texture", + value: undefined + }, + sampler: { + type: "sampler", + value: new Sampler({ + magFilter: "linear", + minFilter: "linear" + }) + } } - })), - (this.quadMesh = new Qi(this.geometry, this.material)); - } - setSize(e, t) { - this.canvasRenderTarget.setSize(e, t), (this.material.dirty = !0); - } - render(e, t) { - this.canvasRenderTarget || this.initRenderTarget(e), - (this.material.uniforms.texture.value = t), - this.material.update(void 0, this.quadMesh); - const i = this.quadMesh.getDrawCommand(), - r = this.canvasRenderTarget.beginRenderPass(e.device); - i.render({ device: e.device, passEncoder: r }), this.canvasRenderTarget.endRenderPass(); - } - initRenderTarget(e) { - const { width: t, height: i, depth: r } = e.presentationSize, - n = new me({ r: 0, g: 0, b: 0, a: 0 }, { textureView: () => e.context.getCurrentTexture().createView() }), - s = new fe({ - label: "resolveDepth", - size: { width: t, height: i, depth: r }, - format: l.Depth24Plus, - usage: a.RenderAttachment - }), - o = new me(1, { texture: s }); - this.canvasRenderTarget = new $e("render", [n], o); + }); + this.quadMesh = new Mesh(this.geometry, this.material); + } + setSize(width, height) { + this.canvasRenderTarget.setSize(width, height); + this.material.dirty = true; + } + render(context, colorTexture) { + if (!this.canvasRenderTarget) this.initRenderTarget(context); + // this.material + this.material.uniforms.texture.value = colorTexture; + this.material.update(undefined, this.quadMesh); + const drawComand = this.quadMesh.getDrawCommand(); + const currentRenderPassEncoder = this.canvasRenderTarget.beginRenderPass(context.device); + drawComand.render({ device: context.device, passEncoder: currentRenderPassEncoder }); + this.canvasRenderTarget.endRenderPass(); + } + initRenderTarget(context) { + const { width, height, depth } = context.presentationSize; + const colorAttachment = new Attachment( + { r: 0.0, g: 0.0, b: 0.0, a: 0 }, + { + textureView: () => { + return context.context.getCurrentTexture().createView(); + } + } + ); + const depthTexture = new Texture({ + label: "resolveDepth", + size: { width, height, depth }, + format: TextureFormat.Depth24Plus, + usage: TextureUsage.RenderAttachment + }); + const depthAttachment = new Attachment(1.0, { texture: depthTexture }); + this.canvasRenderTarget = new RenderTarget("render", [colorAttachment], depthAttachment); } } -class Lr { + +class PostEffectCollection { constructor() { - (this._postEffects = new Map()), (this.currentColorTexture = void 0), (this.resolveFrame = new _r()); + this._postEffects = new Map(); + this.currentColorTexture = undefined; + this.resolveFrame = new ResolveFrame(); } - add(e) { - this._postEffects.set(e.id, e); + add(postEffect) { + this._postEffects.set(postEffect.id, postEffect); } - remove(e) { - this._postEffects.delete(e.id), e.destroy(); + remove(postEffect) { + this._postEffects.delete(postEffect.id); + postEffect.destroy(); } - render(e, t) { - (this.currentColorTexture = t), - this._postEffects.forEach((t) => { - this.currentColorTexture = t.render(e, this.currentColorTexture); - }), - this.resolveFrame.render(e, this.currentColorTexture); + render(context, colorTexture) { + this.currentColorTexture = colorTexture; + this._postEffects.forEach((postEffect) => { + this.currentColorTexture = postEffect.render(context, this.currentColorTexture); + }); + this.resolveFrame.render(context, this.currentColorTexture); + } + setSize(width, height) { + this._postEffects.forEach((postEffect) => postEffect.setSize(width, height)); + this.resolveFrame.setSize(width, height); } - setSize(e, t) { - this._postEffects.forEach((i) => i.setSize(e, t)), this.resolveFrame.setSize(e, t); + postEffectsSort() { + // this._postEffects.sort() } - postEffectsSort() {} } -class Cr { - constructor(e) { - this.context = e; + +class Pass { + constructor(context) { + this.context = context; + } + update(frameState) { + // todo; } - update(e) {} - setSize(e, t) {} - beforeRender(e) { - (this.passRenderEncoder = this.renderTarget.beginRenderPass(this.context.device)), - this.computeTarget && - (this.passComputeEncoder = this.computeTarget.beginComputePassEncoder(this.context.device)); + setSize(width, height) { + // todo ; } - getColorTexture(e = 0) { - return this.renderTarget.getColorTexture(e); + beforeRender(options) { + this.passRenderEncoder = this.renderTarget.beginRenderPass(this.context.device); + if (this.computeTarget) + this.passComputeEncoder = this.computeTarget.beginComputePassEncoder(this.context.device); + } + getColorTexture(index = 0) { + return this.renderTarget.getColorTexture(index); } getDepthTexture() { return this.renderTarget.getDepthTexture(); } afterRender() { - this.renderTarget.endRenderPass(), this.computeTarget && this.computeTarget.endComputePassEncoder(); - } -} -class Rr extends Cr { - constructor(e) { - super(e), this.init(e); - } - beforeRender(e) { - this.updateRenderTarget(e), super.beforeRender(); - } - render(e, t) { - const { renderQueue: i, lightManger: r } = e; - i.sort(), - i.preRender(t, this.context, this.passRenderEncoder), - i.transparentRender(t, this.context, this.passRenderEncoder, void 0, void 0, r), - i.opaqueRender(t, this.context, this.passRenderEncoder, void 0, void 0, r), - i.debugQueueRender(t, this.context, this.passRenderEncoder); - } - init(e) { - this.createRenderTarget(e); - } - createRenderTarget(e) { - const { width: t, height: i, depth: r } = e.presentationSize, - n = new fe({ - label: "basicPassColor", - size: { width: t, height: i, depth: r }, - format: this.context.presentationFormat, - usage: a.RenderAttachment | a.TextureBinding - }), - s = new fe({ - label: "basicPassDepth", - size: { width: t, height: i, depth: r }, - format: l.Depth24Plus, - usage: a.RenderAttachment - }), - o = new me({ r: 0, g: 0, b: 0, a: 0 }, { texture: n }), - c = new me(1, { texture: s }); - this.renderTarget = new $e("render", [o], c); - } - setSize(e, t) { - this.renderTarget.setSize(e, t, 1); + this.renderTarget.endRenderPass(); + if (this.computeTarget) this.computeTarget.endComputePassEncoder(); } - updateRenderTarget(e) { - if (e?.background?.value instanceof Qt) { - const { red: t, green: i, blue: r } = e.background.value, - n = e.background?.opacity, - s = { r: t, g: i, b: r, a: n ?? 1 }; - this.renderTarget.colorAttachments[0].value = s; +} + +class BasicPass extends Pass { + constructor(context) { + super(context); + this.init(context); + } + beforeRender(frameState) { + this.updateRenderTarget(frameState); + super.beforeRender(); + } + render(frameState, camera) { + const { renderQueue, lightManger } = frameState; + renderQueue.sort(); + renderQueue.preRender(camera, this.context, this.passRenderEncoder); + renderQueue.transparentRender(camera, this.context, this.passRenderEncoder, undefined, undefined, lightManger); + renderQueue.opaqueRender(camera, this.context, this.passRenderEncoder, undefined, undefined, lightManger); + renderQueue.debugQueueRender(camera, this.context, this.passRenderEncoder); + } + init(context) { + this.createRenderTarget(context); + } + createRenderTarget(context) { + const { width, height, depth } = context.presentationSize; + const colorTexture = new Texture({ + label: "basicPassColor", + size: { width, height, depth }, + format: this.context.presentationFormat, + usage: TextureUsage.RenderAttachment | TextureUsage.TextureBinding + }); + const depthTexture = new Texture({ + label: "basicPassDepth", + size: { width, height, depth }, + format: TextureFormat.Depth24Plus, + usage: TextureUsage.RenderAttachment + }); + const colorAttachment = new Attachment({ r: 0.0, g: 0.0, b: 0.0, a: 0.0 }, { texture: colorTexture }); + const depthAttachment = new Attachment(1.0, { texture: depthTexture }); + this.renderTarget = new RenderTarget("render", [colorAttachment], depthAttachment); + } + setSize(width, height) { + this.renderTarget.setSize(width, height, 1); + } + updateRenderTarget(frameState) { + if (frameState?.background?.value instanceof Color) { + const { red, green, blue } = frameState.background.value; + const opacity = frameState.background?.opacity; + const clearValue = { + r: red, + g: green, + b: blue, + a: opacity ?? 1.0 + }; + this.renderTarget.colorAttachments[0].value = clearValue; } } } -class Ar { - constructor(e, t) { - (this.normal = Ue.clone(e)), (this.distance = t); + +/** + * A plane in Hessian Normal Form defined by + *
+ * ax + by + cz + d = 0
+ * 
+ * where (a, b, c) is the plane's normal, d is the signed + * distance to the plane, and (x, y, z) is any point on + * the plane. + * + * @alias Plane + * @constructor + * + * @param {Vector3} normal The plane's normal (normalized). + * @param {Number} distance The shortest distance from the origin to the plane. The sign of + * @example + * // The plane x=0 + * const plane = new Plane(Vector3.UNIT_X, 0.0); + * + * @exception {DeveloperError} Normal must be normalized + */ +class Plane { + constructor(normal, distance) { + this.normal = Vector3.clone(normal); + this.distance = distance; } normalize() { - const e = 1 / this.normal.length(); - return (this.normal = Ue.multiplyByScalar(this.normal, e, this.normal)), (this.distance *= e), this; - } - static fromPointNormal(e, t, i) { - if (!ve.equalsEpsilon(Ue.magnitude(t), 1, ve.EPSILON6)) throw new Error("normal must be normalized."); - const r = -Ue.dot(t, e); - return pe(i) ? (Ue.clone(t, i.normal), (i.distance = r), i) : new Ar(t, r); - } - static fromVector4(e, t) { - const i = Ue.fromVector4(e, Dr), - r = e.w; - if (!ve.equalsEpsilon(Ue.magnitude(i), 1, ve.EPSILON6)) throw new Error("normal must be normalized."); - return pe(t) ? (Ue.clone(i, t.normal), (t.distance = r), t) : new Ar(i, r); - } - static getPointDistance(e, t) { - return Ue.dot(e.normal, t) + e.distance; - } - static projectPointOntoPlane(e, t, i) { - pe(i) || (i = new Ue()); - const r = Ar.getPointDistance(e, t), - n = Ue.multiplyByScalar(e.normal, r, zr); - return Ue.subtract(t, n, i); - } - static transform(e, t, i) { - const r = e.normal, - n = e.distance, - s = et.inverseTranspose(t, Ir); - let a = We.fromElements(r.x, r.y, r.z, n, Pr); - a = et.multiplyByVector(s, a, a); - const o = Ue.fromVector4(a, Nr); - return (a = We.divideByScalar(a, Ue.magnitude(o), a)), Ar.fromVector4(a, i); - } - static clone(e, t) { - return pe(t) ? (Ue.clone(e.normal, t.normal), (t.distance = e.distance), t) : new Ar(e.normal, e.distance); - } - static equals(e, t) { - return e.distance === t.distance && Ue.equals(e.normal, t.normal); - } -} -(Ar.ORIGIN_XY_PLANE = Object.freeze(new Ar(Ue.UNIT_Z, 0))), - (Ar.ORIGIN_YZ_PLANE = Object.freeze(new Ar(Ue.UNIT_X, 0))), - (Ar.ORIGIN_ZX_PLANE = Object.freeze(new Ar(Ue.UNIT_Y, 0))); -const Dr = new Ue(), - zr = new Ue(), - Ir = new et(), - Pr = new We(), - Nr = new Ue(); -class Br { - constructor(e) { - this.planes = ee(e, [ - new Ar(Ue.UNIT_Z, 0), - new Ar(Ue.UNIT_Z, 0), - new Ar(Ue.UNIT_Z, 0), - new Ar(Ue.UNIT_Z, 0), - new Ar(Ue.UNIT_Z, 0), - new Ar(Ue.UNIT_Z, 0) + const inverseNormalLength = 1.0 / this.normal.length(); + this.normal = Vector3.multiplyByScalar(this.normal, inverseNormalLength, this.normal); + this.distance *= inverseNormalLength; + return this; + } + static fromPointNormal(point, normal, result) { + if (!GMath.equalsEpsilon(Vector3.magnitude(normal), 1.0, GMath.EPSILON6)) { + throw new Error("normal must be normalized."); + } + // >>includeEnd('debug'); + const distance = -Vector3.dot(normal, point); + if (!defined(result)) { + return new Plane(normal, distance); + } + Vector3.clone(normal, result.normal); + result.distance = distance; + return result; + } + static fromVector4(coefficients, result) { + const normal = Vector3.fromVector4(coefficients, scratchNormal); + const distance = coefficients.w; + // >>includeStart('debug', pragmas.debug); + if (!GMath.equalsEpsilon(Vector3.magnitude(normal), 1.0, GMath.EPSILON6)) { + throw new Error("normal must be normalized."); + } + // >>includeEnd('debug'); + if (!defined(result)) { + return new Plane(normal, distance); + } + Vector3.clone(normal, result.normal); + result.distance = distance; + return result; + } + static getPointDistance(plane, point) { + return Vector3.dot(plane.normal, point) + plane.distance; + } + static projectPointOntoPlane(plane, point, result) { + if (!defined(result)) { + result = new Vector3(); + } + // projectedPoint = point - (normal.point + scale) * normal + const pointDistance = Plane.getPointDistance(plane, point); + const scaledNormal = Vector3.multiplyByScalar(plane.normal, pointDistance, scratchCartesian); + return Vector3.subtract(point, scaledNormal, result); + } + static transform(plane, transform, result) { + const normal = plane.normal; + const distance = plane.distance; + const inverseTranspose = Matrix4.inverseTranspose(transform, scratchInverseTranspose); + let planeAsCartesian4 = Vector4.fromElements(normal.x, normal.y, normal.z, distance, scratchPlaneCartesian4); + planeAsCartesian4 = Matrix4.multiplyByVector(inverseTranspose, planeAsCartesian4, planeAsCartesian4); + // Convert the transformed plane to Hessian Normal Form + const transformedNormal = Vector3.fromVector4(planeAsCartesian4, scratchTransformNormal); + planeAsCartesian4 = Vector4.divideByScalar( + planeAsCartesian4, + Vector3.magnitude(transformedNormal), + planeAsCartesian4 + ); + return Plane.fromVector4(planeAsCartesian4, result); + } + static clone(plane, result) { + if (!defined(result)) { + return new Plane(plane.normal, plane.distance); + } + Vector3.clone(plane.normal, result.normal); + result.distance = plane.distance; + return result; + } + static equals(left, right) { + return left.distance === right.distance && Vector3.equals(left.normal, right.normal); + } +} +Plane.ORIGIN_XY_PLANE = Object.freeze(new Plane(Vector3.UNIT_Z, 0.0)); +Plane.ORIGIN_YZ_PLANE = Object.freeze(new Plane(Vector3.UNIT_X, 0.0)); +Plane.ORIGIN_ZX_PLANE = Object.freeze(new Plane(Vector3.UNIT_Y, 0.0)); +const scratchNormal = new Vector3(); +const scratchCartesian = new Vector3(); +const scratchInverseTranspose = new Matrix4(); +const scratchPlaneCartesian4 = new Vector4(); +const scratchTransformNormal = new Vector3(); + +/** + * The culling volume defined by planes. + * + * @alias CullingVolume + * @constructor + * + * @param {Vector4[]} [planes] An array of clipping planes. + */ +class CullingVolume { + constructor(planes) { + this.planes = defaultValue(planes, [ + new Plane(Vector3.UNIT_Z, 0.0), + new Plane(Vector3.UNIT_Z, 0.0), + new Plane(Vector3.UNIT_Z, 0.0), + new Plane(Vector3.UNIT_Z, 0.0), + new Plane(Vector3.UNIT_Z, 0.0), + new Plane(Vector3.UNIT_Z, 0.0) ]); } - static fromBoundingSphere(e, t) { - if (!pe(e)) throw new Error("boundingSphere is required."); - pe(t) || (t = new Br()); - const i = Or.length, - r = t.planes; - r.length = 2 * i; - const n = e.center, - s = e.radius; - let a = 0; - for (let e = 0; e < i; ++e) { - const t = Or[e]; - let i = r[a], - o = r[a + 1]; - pe(i) || (i = r[a] = new We()), - pe(o) || (o = r[a + 1] = new We()), - Ue.multiplyByScalar(t, -s, Vr), - Ue.add(n, Vr, Vr), - (i.x = t.x), - (i.y = t.y), - (i.z = t.z), - (i.w = -Ue.dot(t, Vr)), - Ue.multiplyByScalar(t, s, Vr), - Ue.add(n, Vr, Vr), - (o.x = -t.x), - (o.y = -t.y), - (o.z = -t.z), - (o.w = -Ue.dot(Ue.negate(t, Fr), Vr)), - (a += 2); - } - return t; - } - computeVisibility(e) { - if (!pe(e)) throw new Error("boundingVolume is required."); - const t = this.planes; - let i = !1; - for (let r = 0, n = t.length; r < n; ++r) { - const n = e.intersectPlane(t[r]); - if (n === F.OUTSIDE) return F.OUTSIDE; - n === F.INTERSECTING && (i = !0); - } - return i ? F.INTERSECTING : F.INSIDE; - } -} -(Br.MASK_OUTSIDE = 4294967295), (Br.MASK_INSIDE = 0), (Br.MASK_INDETERMINATE = 2147483647); -const Or = [new Ue(), new Ue(), new Ue()]; -Ue.clone(Ue.UNIT_X, Or[0]), Ue.clone(Ue.UNIT_Y, Or[1]), Ue.clone(Ue.UNIT_Z, Or[2]); -const Vr = new Ue(), - Fr = new Ue(); -new We(), new Ar(new Ue(1, 0, 0), 0); -class $r extends $t { + /** + * Constructs a culling volume from a bounding sphere. Creates six planes that create a box containing the sphere. + * The planes are aligned to the x, y, and z axes in world coordinates. + * + * @param {BoundingSphere} boundingSphere The bounding sphere used to create the culling volume. + * @param {CullingVolume} [result] The object onto which to store the result. + * @returns {CullingVolume} The culling volume created from the bounding sphere. + */ + static fromBoundingSphere(boundingSphere, result) { + if (!defined(boundingSphere)) { + throw new Error("boundingSphere is required."); + } + if (!defined(result)) { + result = new CullingVolume(); + } + const length = faces.length; + const planes = result.planes; + planes.length = 2 * length; + const center = boundingSphere.center; + const radius = boundingSphere.radius; + let planeIndex = 0; + for (let i = 0; i < length; ++i) { + const faceNormal = faces[i]; + let plane0 = planes[planeIndex]; + let plane1 = planes[planeIndex + 1]; + if (!defined(plane0)) { + plane0 = planes[planeIndex] = new Vector4(); + } + if (!defined(plane1)) { + plane1 = planes[planeIndex + 1] = new Vector4(); + } + Vector3.multiplyByScalar(faceNormal, -radius, scratchPlaneCenter); + Vector3.add(center, scratchPlaneCenter, scratchPlaneCenter); + plane0.x = faceNormal.x; + plane0.y = faceNormal.y; + plane0.z = faceNormal.z; + plane0.w = -Vector3.dot(faceNormal, scratchPlaneCenter); + Vector3.multiplyByScalar(faceNormal, radius, scratchPlaneCenter); + Vector3.add(center, scratchPlaneCenter, scratchPlaneCenter); + plane1.x = -faceNormal.x; + plane1.y = -faceNormal.y; + plane1.z = -faceNormal.z; + plane1.w = -Vector3.dot(Vector3.negate(faceNormal, scratchPlaneNormal), scratchPlaneCenter); + planeIndex += 2; + } + return result; + } + /** + * Determines whether a bounding volume intersects the culling volume. + * + * @param {Object} boundingVolume The bounding volume whose intersection with the culling volume is to be tested. + * @returns {Intersect} Intersect.OUTSIDE, Intersect.INTERSECTING, or Intersect.INSIDE. + */ + computeVisibility(boundingVolume) { + if (!defined(boundingVolume)) { + throw new Error("boundingVolume is required."); + } + const planes = this.planes; + let intersecting = false; + for (let k = 0, len = planes.length; k < len; ++k) { + const result = boundingVolume.intersectPlane(planes[k]); + if (result === Intersect.OUTSIDE) { + return Intersect.OUTSIDE; + } else if (result === Intersect.INTERSECTING) { + intersecting = true; + } + } + return intersecting ? Intersect.INTERSECTING : Intersect.INSIDE; + } +} +CullingVolume.MASK_OUTSIDE = 0xffffffff; +CullingVolume.MASK_INSIDE = 0x00000000; +CullingVolume.MASK_INDETERMINATE = 0x7fffffff; +const faces = [new Vector3(), new Vector3(), new Vector3()]; +Vector3.clone(Vector3.UNIT_X, faces[0]); +Vector3.clone(Vector3.UNIT_Y, faces[1]); +Vector3.clone(Vector3.UNIT_Z, faces[2]); +const scratchPlaneCenter = new Vector3(); +const scratchPlaneNormal = new Vector3(); +new Vector4(); +new Plane(new Vector3(1.0, 0.0, 0.0), 0.0); + +class Camera extends RenderObject { constructor() { - super(), - (this._viewMatrix = void 0), - (this.type = Z.Camera), - (this.cullingVolume = new Br()), - (this._viewMatrix = new et()), - (this._vpMatrix = new et()), - (this.projectMatrixDirty = !0), - this.createShaderData(); + super(); + this._viewMatrix = undefined; + this.type = RenderObjectType.Camera; + this.cullingVolume = new CullingVolume(); + this._viewMatrix = new Matrix4(); + this._vpMatrix = new Matrix4(); + this.projectMatrixDirty = true; + this.createShaderData(); } get viewMatrix() { - return this.updateMatrix(), et.inverse(this.modelMatrix, this._viewMatrix), this._viewMatrix; + this.updateMatrix(); + Matrix4.inverse(this.modelMatrix, this._viewMatrix); + return this._viewMatrix; } get projectionMatrix() { - return this.updateProjectionMatrix(), this._projectionMatrix; + this.updateProjectionMatrix(); + return this._projectionMatrix; } get vpMatrix() { - return et.multiply(this.projectionMatrix, this.viewMatrix, this._vpMatrix), this._vpMatrix; + Matrix4.multiply(this.projectionMatrix, this.viewMatrix, this._vpMatrix); + return this._vpMatrix; } get inverseViewMatrix() { - return this.updateMatrix(), this.modelMatrix; + this.updateMatrix(); + return this.modelMatrix; } updateProjectionMatrix() {} + /** + * get a culling volume for this frustum. + */ getCullingVolume() { - const e = this.viewMatrix.clone(new et()), - t = et.multiply(this.projectionMatrix, e, new et()), - i = this.cullingVolume.planes, - r = t, - n = r[0], - s = r[1], - a = r[2], - o = r[3], - c = r[4], - l = r[5], - h = r[6], - u = r[7], - f = r[8], - d = r[9], - m = r[10], - p = r[11], - g = r[12], - x = r[13], - v = r[14], - y = r[15]; - return ( - (i[0] = new Ar(new Ue(o - n, u - c, p - f), y - g)), - i[0].normalize(), - (i[1] = new Ar(new Ue(o + n, u + c, p + f), y + g)), - i[1].normalize(), - (i[2] = new Ar(new Ue(o + s, u + l, p + d), y + x)), - i[2].normalize(), - (i[3] = new Ar(new Ue(o - s, u - l, p - d), y - x)), - i[3].normalize(), - (i[4] = new Ar(new Ue(o - a, u - h, p - m), y - v)), - i[4].normalize(), - (i[5] = new Ar(new Ue(o + a, u + h, p + m), y + v)), - i[5].normalize(), - this.cullingVolume - ); + const cloneViewMatrix = this.viewMatrix.clone(new Matrix4()); + const vpMatrix = Matrix4.multiply(this.projectionMatrix, cloneViewMatrix, new Matrix4()); + const planes = this.cullingVolume.planes; + const me = vpMatrix; + const me0 = me[0], + me1 = me[1], + me2 = me[2], + me3 = me[3]; + const me4 = me[4], + me5 = me[5], + me6 = me[6], + me7 = me[7]; + const me8 = me[8], + me9 = me[9], + me10 = me[10], + me11 = me[11]; + const me12 = me[12], + me13 = me[13], + me14 = me[14], + me15 = me[15]; + planes[0] = new Plane(new Vector3(me3 - me0, me7 - me4, me11 - me8), me15 - me12); + planes[0].normalize(); + planes[1] = new Plane(new Vector3(me3 + me0, me7 + me4, me11 + me8), me15 + me12); + planes[1].normalize(); + planes[2] = new Plane(new Vector3(me3 + me1, me7 + me5, me11 + me9), me15 + me13); + planes[2].normalize(); + planes[3] = new Plane(new Vector3(me3 - me1, me7 - me5, me11 - me9), me15 - me13); + planes[3].normalize(); + planes[4] = new Plane(new Vector3(me3 - me2, me7 - me6, me11 - me10), me15 - me14); + planes[4].normalize(); + planes[5] = new Plane(new Vector3(me3 + me2, me7 + me6, me11 + me10), me15 + me14); + planes[5].normalize(); + return this.cullingVolume; } createShaderData() { - this.shaderData = new Yi("camera", 0, 1, 1); - const e = new Ri({ label: "camera" }); - e.setUniform("projectionMatrix", () => this.projectionMatrix, Q.Mat4), - e.setUniform("viewMatrix", () => this.viewMatrix, Q.Mat4), - e.setUniform("inverseViewMatrix", () => this.inverseViewMatrix, Q.Mat4), - e.setUniform("position", () => this.position, Q.FloatVec3), - this.shaderData.setUniformBuffer("camera", e); - } -} -class Gr extends $r { - constructor(e = 50, t = 1, i = 0.1, r = 2e3) { - super(), - (this._aspect = t), - (this.fov = e), - (this.near = i), - (this.far = r), - (this.xOffset = 0), - (this.yOffset = 0), - (this.projectMatrixDirty = !0), - this.updateCameraParms(), - (this.cullingVolume = new Br()), - (this.isPerspectiveCamera = !0); + this.shaderData = new ShaderData("camera", 0, 1, 1); + const uniformBuffer = new UniformBuffer({ label: "camera" }); + uniformBuffer.setUniform( + "projectionMatrix", + () => { + return this.projectionMatrix; + }, + UniformEnum.Mat4 + ); + uniformBuffer.setUniform( + "viewMatrix", + () => { + return this.viewMatrix; + }, + UniformEnum.Mat4 + ); + uniformBuffer.setUniform( + "inverseViewMatrix", + () => { + return this.inverseViewMatrix; + }, + UniformEnum.Mat4 + ); + uniformBuffer.setUniform( + "position", + () => { + return this.position; + }, + UniformEnum.FloatVec3 + ); + this.shaderData.setUniformBuffer("camera", uniformBuffer); + } +} + +class PerspectiveCamera extends Camera { + constructor(fov = 50, aspect = 1, near = 0.1, far = 2000) { + super(); + this._aspect = aspect; + this.fov = fov; + this.near = near; + this.far = far; + this.xOffset = 0; + this.yOffset = 0; + this.projectMatrixDirty = true; + this.updateCameraParms(); + this.cullingVolume = new CullingVolume(); + this.isPerspectiveCamera = true; } get aspect() { return this._aspect; } - set aspect(e) { - (this.projectMatrixDirty = !0), (this._aspect = e); + set aspect(v) { + this.projectMatrixDirty = true; + this._aspect = v; } get fov() { return this._fov; } - set fov(e) { - (this.projectMatrixDirty = !0), (this._fov = e); + set fov(v) { + this.projectMatrixDirty = true; + this._fov = v; } updateCameraParms() { - (this.top = this.near * Math.tan(0.5 * ve.RADIANS_PER_DEGREE * this.fov)), - (this.height = 2 * this.top), - (this.width = this.aspect * this.height), - (this.left = -0.5 * this.width); + this.top = this.near * Math.tan(0.5 * GMath.RADIANS_PER_DEGREE * this.fov); + this.height = 2 * this.top; + this.width = this.aspect * this.height; + this.left = -0.5 * this.width; } updateProjectionMatrix() { - this.projectMatrixDirty && - (this.updateCameraParms(), - (this._projectionMatrix = et.makePerspective( + if (this.projectMatrixDirty) { + this.updateCameraParms(); + this._projectionMatrix = Matrix4.makePerspective( this.left, this.left + this.width, this.top, this.top - this.height, this.near, this.far - )), - (this.projectMatrixDirty = !1)); + ); + this.projectMatrixDirty = false; + } } } -class kr extends Gr { - constructor(e = 50, t = 1, i = 0.1, r = 2e3) { - super(e, t, i, r), (this.vpMatrixArray = [new et(), new et(), new et(), new et(), new et(), new et()]); - } + +class PointLightShadowCamera extends PerspectiveCamera { + constructor(fov = 50, aspect = 1, near = 0.1, far = 2000) { + super(fov, aspect, near, far); + this.vpMatrixArray = [new Matrix4(), new Matrix4(), new Matrix4(), new Matrix4(), new Matrix4(), new Matrix4()]; + } + // createShaderData() { + // this.shaderData = new ShaderData("camera", 0, 1, 1); + // const uniformBuffer = new UniformBuffer({ + // label: "pointLightShadowCamera", + // type: "read-only-storage", + // usage: BufferUsage.Storage | BufferUsage.CopyDst, + // hasDynamicOffset: true, + // minBindingSize: 64, + // maxOffset: 6, + // size: 256 * 6 + // }); + // uniformBuffer.setMatrix4Array( + // "vpMatrixArray", + // () => { + // if (this.vpMatrixArray.length != 6) throw new Error("pointLightShadowCamera uniformBuffer has Error"); + // return this.vpMatrixArray; + // }, + // 6, + // 256 + // ); + // this.shaderData.setUniformBuffer("pointLightShadowCamera", uniformBuffer); + // this.shaderData.setDefine("isPointLightShadowMap", true); + // } createShaderData() { - this.shaderData = new Yi("camera", 0, 1, 1); - const e = new Ri({ label: "pointLightShadowCamera", type: "read-only-storage", usage: r.Storage | r.CopyDst }); - e.setUniform("vpMatrix", () => this.vpMatrix, Q.Mat4), - this.shaderData.setUniformBuffer("pointLightShadowCamera", e), - this.shaderData.setDefine("isPointLightShadowMap", !0); + this.shaderData = new ShaderData("camera", 0, 1, 1); + const uniformBuffer = new UniformBuffer({ + label: "pointLightShadowCamera", + type: "read-only-storage", + usage: BufferUsage.Storage | BufferUsage.CopyDst + }); + uniformBuffer.setUniform( + "vpMatrix", + () => { + return this.vpMatrix; + }, + UniformEnum.Mat4 + ); + this.shaderData.setUniformBuffer("pointLightShadowCamera", uniformBuffer); + this.shaderData.setDefine("isPointLightShadowMap", true); } - updateVpMatrixArrayAndIndex(e) { - et.clone(this.vpMatrix, this.vpMatrixArray[e]); + updateVpMatrixArrayAndIndex(index) { + Matrix4.clone(this.vpMatrix, this.vpMatrixArray[index]); } } -class qr { - constructor(e, t) { - (this._shadowMapSize = e), - (this._camera = t), - (this.viewPortDirty = !0), - (this.vpMatrixDirty = !0), - this._init(); + +class BaseShadow { + constructor(shadowMapSize, camera) { + this._shadowMapSize = shadowMapSize; + this._camera = camera; + this.viewPortDirty = true; + this.vpMatrixDirty = true; + this._init(); } get camera() { return this._camera; @@ -10636,648 +14191,982 @@ class qr { this._createShadowMapTexture(); } _createShadowMapTexture() { - this._shadowMap = new fe({ - size: { width: this._shadowMapSize.x, height: this._shadowMapSize.y, depth: 1 }, - fixedSize: !0, - sampleType: g.Depth, - format: l.Depth24Plus, - usage: a.RenderAttachment | a.TextureBinding | a.CopySrc + this._shadowMap = new Texture({ + size: { + width: this._shadowMapSize.x, + height: this._shadowMapSize.y, + depth: 1 + }, + fixedSize: true, + sampleType: TextureSampleType.Depth, + format: TextureFormat.Depth24Plus, + usage: TextureUsage.RenderAttachment | TextureUsage.TextureBinding | TextureUsage.CopySrc }); } - update(e) {} + update(light) {} } -class jr extends qr { + +class PointLightShadow extends BaseShadow { get camera() { return this._camera; } constructor() { - const e = new kr(90, 1, 0.1, 500); - super(new Se(1536, 1024), e), - (this.viewportSize = new Se(512, 512)), - (this.currentViewportIndex = 0), - (this.type = "pointLightShadow"), - (this.vpMatrixArrayDirty = !0), - (this._viewports = [ - new We(0, 0, 1 / 3, 0.5), - new We(1, 0, 1 / 3, 0.5), - new We(2, 0, 1 / 3, 0.5), - new We(0, 1, 1 / 3, 0.5), - new We(1, 1, 1 / 3, 0.5), - new We(2, 1, 1 / 3, 0.5) - ]), - (this._pointLightShadowLookDirections = [ - new Ue(1, 0, 0), - new Ue(-1, 0, 0), - new Ue(0, 0, 1), - new Ue(0, 0, -1), - new Ue(0, 1, 0), - new Ue(0, -1, 0) - ]), - (this._pointLightShadowUps = [ - new Ue(0, 1, 0), - new Ue(0, 1, 0), - new Ue(0, 1, 0), - new Ue(0, 1, 0), - new Ue(0, 0, 1), - new Ue(0, 0, -1) - ]); - } - update(e) { - this.updateMatrices(e); - } - updateMatrices(e) { - if (this.camera instanceof kr) { - this.camera.position.copy(e.position); - const t = Ue.clone(e.position); - t.add(this._pointLightShadowLookDirections[this.currentViewportIndex]), - this.camera.up.copy(this._pointLightShadowUps[this.currentViewportIndex]); - const { x: i, y: r, z: n } = t; - this.camera.lookAt(i, r, n), - this.camera.updateMatrix(), - this.camera.updateVpMatrixArrayAndIndex(this.currentViewportIndex), - 5 == this.currentViewportIndex && (this.vpMatrixArrayDirty = !0); - } - } -} -class Hr extends Ht { + const camera = new PointLightShadowCamera(90, 1, 0.1, 500); + super(new Vector2(1536, 1024), camera); + this.viewportSize = new Vector2(512, 512); + this.currentViewportIndex = 0; + this.type = "pointLightShadow"; + this.vpMatrixArrayDirty = true; + this._viewports = [ + // positive X 0 + new Vector4(0, 0, 1 / 3, 1 / 2), + // negative X 1 + new Vector4(1, 0, 1 / 3, 1 / 2), + // positive Z 2 + new Vector4(2, 0, 1 / 3, 1 / 2), + // negative Z 3 + new Vector4(0, 1, 1 / 3, 1 / 2), + // positive Y 4 + new Vector4(1, 1, 1 / 3, 1 / 2), + // negative Y 5 + new Vector4(2, 1, 1 / 3, 1 / 2) + ]; + this._pointLightShadowLookDirections = [ + new Vector3(1, 0, 0), + new Vector3(-1, 0, 0), + new Vector3(0, 0, 1), + new Vector3(0, 0, -1), + new Vector3(0, 1, 0), + new Vector3(0, -1, 0) + ]; + this._pointLightShadowUps = [ + new Vector3(0, 1, 0), + new Vector3(0, 1, 0), + new Vector3(0, 1, 0), + new Vector3(0, 1, 0), + new Vector3(0, 0, 1), + new Vector3(0, 0, -1) + ]; + } + update(light) { + this.updateMatrices(light); + } + updateMatrices(light) { + if (this.camera instanceof PointLightShadowCamera) { + this.camera.position.copy(light.position); + const target = Vector3.clone(light.position); + target.add(this._pointLightShadowLookDirections[this.currentViewportIndex]); + this.camera.up.copy(this._pointLightShadowUps[this.currentViewportIndex]); + const { x, y, z } = target; + this.camera.lookAt(x, y, z); + this.camera.updateMatrix(); + this.camera.updateVpMatrixArrayAndIndex(this.currentViewportIndex); + if (this.currentViewportIndex == 5) this.vpMatrixArrayDirty = true; + } + } +} + +class PointLight extends Light { get shadow() { return this._shadow; } - set shadow(e) { - (this.shadowDirty = !0), (this._shadow = e); + set shadow(value) { + this.shadowDirty = true; + this._shadow = value; } - constructor(e, t, i = 0, r = 4, n = !0) { - super(e, t), - (this._distance = i), - (this._decay = r), - (this.distanceDirty = !0), - (this.decayDirty = !0), - (this.lightType = K.PointLight), - n && (this.shadow = new jr()); + constructor(color, intensity, distance = 0, decay = 4, openShadow = true) { + super(color, intensity); + this._distance = distance; + this._decay = decay; + this.distanceDirty = true; + this.decayDirty = true; + this.lightType = LightType.PointLight; + if (openShadow) this.shadow = new PointLightShadow(); } - set distance(e) { - (this.distanceDirty = !0), (this._distance = e); + set distance(value) { + this.distanceDirty = true; + this._distance = value; } get distance() { return this._distance; } - set decay(e) { - (this.decayDirty = !0), (this._decay = e); + set decay(value) { + this.decayDirty = true; + this._decay = value; } get decay() { return this._decay; } } -class Xr extends Cr { - constructor(e) { - super(e), this.init(e); - } - render(e, t) { - const { renderQueue: i, context: r, lightManger: n } = e, - s = n.getAllLights(); - if (0 !== s.length) { - for (let e = 0; e < s.length; e++) { - const t = s[e], - a = t.shadow; - if (a) - if (a instanceof jr && t instanceof Hr) - for (let e = 0; e < a.viewports.length; e++) { - if (0 === e) this.renderTarget.depthAttachment.op = "clear"; - else this.renderTarget.depthAttachment.op = "load"; - this.beforeRender({ shadow: a }); - const s = a.viewports[e], - o = a.viewportSize; - (a.currentViewportIndex = e), - a.update(t), - r.setViewPort(s.x * o.x, s.y * o.y, o.x, o.y), - r.setScissorTest(s.x * o.x, s.y * o.y, o.x, o.y), - this.subRender(i, a, n), - super.afterRender(); - } - else - (this.renderTarget.depthAttachment.op = "clear"), - this.beforeRender({ shadow: a }), - a.update(t), - r.setViewPort(0, 0, a.shadowMapSize.x, a.shadowMapSize.y), - r.setScissorTest(0, 0, a.shadowMapSize.x, a.shadowMapSize.y), - this.subRender(i, a, n), - super.afterRender(); +// uniform +// color: {}, +// position: {}, +// decay: {}, +// distance: {} + +class ShadowPass extends Pass { + constructor(context) { + super(context); + this.init(context); + } + render(frameState, camera) { + const { renderQueue, context, lightManger } = frameState; + const lights = lightManger.getAllLights(); + if (lights.length === 0) return; + for (let i = 0; i < lights.length; i++) { + const light = lights[i]; + const shadow = light.shadow; + if (!shadow) continue; + // this._testTexture = context.lightManger._testTexture + // this.beforeRender({ shadow }); + if (shadow instanceof PointLightShadow && light instanceof PointLight) { + for (let i = 0; i < shadow.viewports.length; i++) { + // 动态buffer暂未调通,先以此种方式解决 + switch (i) { + case 0: + this.renderTarget.depthAttachment.op = "clear"; + break; + default: + this.renderTarget.depthAttachment.op = "load"; + break; + } + this.beforeRender({ shadow }); + const viewport = shadow.viewports[i]; + const viewportSize = shadow.viewportSize; + shadow.currentViewportIndex = i; + shadow.update(light); + // light.forceUpdate = true; + context.setViewPort( + viewport.x * viewportSize.x, + viewport.y * viewportSize.y, + viewportSize.x, + viewportSize.y + ); + context.setScissorTest( + viewport.x * viewportSize.x, + viewport.y * viewportSize.y, + viewportSize.x, + viewportSize.y + ); + this.subRender(renderQueue, shadow, lightManger); + super.afterRender(); + } + } else { + this.renderTarget.depthAttachment.op = "clear"; + this.beforeRender({ shadow }); + shadow.update(light); + context.setViewPort(0, 0, shadow.shadowMapSize.x, shadow.shadowMapSize.y); + context.setScissorTest(0, 0, shadow.shadowMapSize.x, shadow.shadowMapSize.y); + this.subRender(renderQueue, shadow, lightManger); + super.afterRender(); } - n.updateLightShadow(), r.resetViewPortToFullCanvas(); } + // super.afterRender(); + lightManger.updateLightShadow(); + context.resetViewPortToFullCanvas(); + } + subRender(renderQueue, shadow, lightManger) { + renderQueue.sort(); + // renderQueue.preRender(shadow.camera, this.context, this.passRenderEncoder); + renderQueue.transparentRender( + shadow.camera, + this.context, + this.passRenderEncoder, + this.shadowMaterial, + CommandSubType.Shadow, + lightManger + ); + renderQueue.opaqueRender( + shadow.camera, + this.context, + this.passRenderEncoder, + this.shadowMaterial, + CommandSubType.Shadow, + lightManger + ); } - subRender(e, t, i) { - e.sort(), - e.transparentRender(t.camera, this.context, this.passRenderEncoder, this.shadowMaterial, V.Shadow, i), - e.opaqueRender(t.camera, this.context, this.passRenderEncoder, this.shadowMaterial, V.Shadow, i); - } - beforeRender(e) { - const { shadow: t } = e; - this.setRenderTarget(t), super.beforeRender(); + // getDepthTexture(): Texture { + // return this._testTexture; + // } + beforeRender(options) { + const { shadow } = options; + this.setRenderTarget(shadow); + super.beforeRender(); } - setSize(e, t) { - this.renderTarget.setSize(e, t, 1); + setSize(width, height) { + this.renderTarget.setSize(width, height, 1); } - setRenderTarget(e) { - this.renderTarget.depthAttachment.texture = e.getShadowMapTexture(); + setRenderTarget(shadow) { + this.renderTarget.depthAttachment.texture = shadow.getShadowMapTexture(); } - init(e) { - this.createRenderTarget(e), this.createShadowMaterial(); + init(context) { + this.createRenderTarget(context); + this.createShadowMaterial(); } - createRenderTarget(e) { - const t = new me(1, { texture: void 0 }); - this.renderTarget = new $e("render", [], t); + createRenderTarget(context) { + const depthAttachment = new Attachment(1.0, { texture: undefined }); + this.renderTarget = new RenderTarget("render", [], depthAttachment); } createShadowMaterial() { - this.shadowMaterial = new Zi({ + const shadowMapShaderFunction = (defines = {}) => { + const finalDefines = Object.assign( + { + selfBinding: 0, + cameraBinding: 0, + positionLocation: 0 + }, + defines + ); + return getVertFrag("shadowMap", finalDefines).vert; + }; + this.shadowMaterial = new ShaderMaterial({ type: "shadowMaterial", - uniforms: { modelMatrix: { type: "mat4x4", value: null } }, - vert: (e = {}) => - $i("shadowMap", Object.assign({ selfBinding: 0, cameraBinding: 0, positionLocation: 0 }, e)).vert, - frag: void 0, - light: !1 + uniforms: { + modelMatrix: { type: "mat4x4", value: null } + }, + vert: shadowMapShaderFunction, + frag: undefined, + light: false // TODO:先true,false有显示bug }); } } -class Yr { - constructor(e) { - (this.context = e), (this.basicPass = new Rr(e)), (this.shadowPass = new Xr(e)); + +class ForwardRenderLine { + constructor(context) { + this.context = context; + this.basicPass = new BasicPass(context); + this.shadowPass = new ShadowPass(context); } getOutputTexture() { return this.basicPass.getColorTexture(0); + // return this.shadowPass.getDepthTexture() } - render(e, t) { - this.shadowPass.render(e, t), - this.basicPass.beforeRender(e), - this.basicPass.render(e, t), - this.basicPass.afterRender(); + render(frameState, camera) { + this.shadowPass.render(frameState, camera); + this.basicPass.beforeRender(frameState); + this.basicPass.render(frameState, camera); + this.basicPass.afterRender(); } - setSize(e, t) { - this.basicPass.setSize(e, t), this.shadowPass.setSize(e, t); + setSize(width, height) { + this.basicPass.setSize(width, height); + this.shadowPass.setSize(width, height); } destroy() { - this.basicPass = void 0; - } -} -class Wr extends br { - constructor(e) { - super(), - (this.container = - e.container instanceof HTMLDivElement ? e.container : document.getElementById(e.container)), - (this.meshManger = new Ur()), - (this.postEffectCollection = new Lr()), - (this.context = new ue({ canvas: null, container: this.container, pixelRatio: 1 })), - (this.requestAdapter = e.requestAdapter || {}), - (this.deviceDescriptor = e.deviceDescriptor || {}), - (this.presentationContextDescriptor = e.presentationContextDescriptor), - (this.ready = !1), - (this.inited = !1), - (this.lightManger = new Mr({ openShadow: !0 })), - (this.background = e.background); + this.basicPass = undefined; + } +} + +class Scene extends EventDispatcher { + constructor(options) { + super(); + this.container = + options.container instanceof HTMLDivElement + ? options.container + : document.getElementById(options.container); + this.meshManger = new MeshManger(); + this.postEffectCollection = new PostEffectCollection(); + this.context = new Context({ + canvas: null, + container: this.container, + pixelRatio: 1 + }); + this.requestAdapter = options.requestAdapter || {}; + this.deviceDescriptor = options.deviceDescriptor || {}; + this.presentationContextDescriptor = options.presentationContextDescriptor; + this.ready = false; + this.inited = false; + this.lightManger = new LightManger({ openShadow: true }); + this.background = options.background; } async init() { - await this.context.init(this.requestAdapter, this.deviceDescriptor, this.presentationContextDescriptor), - (this.currentRenderPipeline = new Yr(this.context)), - (this.frameState = new Tr(this.context, this.lightManger, Tr.getFrameStateOptionsByScene(this))), - (this.viewport = new se(0, 0, this.context.presentationSize.width, this.context.presentationSize.height)), - (this.ready = !0); - } - add(e) { - [Z.Node, Z.Skybox, Z.Mesh, Z.Debug].includes(e.type) - ? this.meshManger.add(e) - : e.type == Z.Light - ? this.lightManger.add(e) - : e.type == Z.PostEffect && this.postEffectCollection.add(e); - } - remove(e) { - [Z.Node, Z.Skybox, Z.Mesh].includes(e.type) - ? this.meshManger.remove(e) - : e.type == Z.Light - ? this.lightManger.remove(e) - : e.type == Z.PostEffect && this.postEffectCollection.remove(e); - } - setCamera(e) { - this.camera = e; - } - resize(e, t) { - this.context.resize(e, t), - this?.currentRenderPipeline?.setSize(e, t), - this?.postEffectCollection?.setSize(e, t); - } - async render(e, t) { - this.inited - ? (this.update(e, t), this.afterRender()) - : ((this.inited = !0), await this.init(), this.update(e, t), this.afterRender()); - } - afterRender() {} - setViewPort(e, t, i, r) { - return !!this.ready && (this.context.setViewPort(e, t, i, r), !0); - } - setScissorTest(e, t, i, r) { - return !!this.ready && (this.context.setScissorTest(e, t, i, r), !0); - } - update(e, t) { - this.ready && - (nr.releasedTextures(), - this.frameState.update(t ?? this.camera, Tr.getFrameStateOptionsByScene(this)), - (e ?? this.meshManger).update(this.frameState, t ?? this.camera), - this.currentRenderPipeline.render(this.frameState, t ?? this.camera), - this.postEffectCollection.render(this.context, this.currentRenderPipeline.getOutputTexture())); - } -} -class Zr { - constructor(e, t, i) { - (this.width = e), - (this.height = t), - this.initDefaultParms(), - (this.id = i), - (this.priority = 0), - (this.isPostEffect = !0), - (this.type = Z.PostEffect); - } - render(e, t) { + await this.context.init(this.requestAdapter, this.deviceDescriptor, this.presentationContextDescriptor); + this.currentRenderPipeline = new ForwardRenderLine(this.context); + this.frameState = new FrameState(this.context, this.lightManger, FrameState.getFrameStateOptionsByScene(this)); + this.viewport = new ViewPort(0, 0, this.context.presentationSize.width, this.context.presentationSize.height); + this.ready = true; + } + add(instance) { + if ( + [RenderObjectType.Node, RenderObjectType.Skybox, RenderObjectType.Mesh, RenderObjectType.Debug].includes( + instance.type + ) + ) { + this.meshManger.add(instance); + } else if (instance.type == RenderObjectType.Light) { + this.lightManger.add(instance); + } else if (instance.type == RenderObjectType.PostEffect) { + this.postEffectCollection.add(instance); + } + } + remove(instance) { + if ([RenderObjectType.Node, RenderObjectType.Skybox, RenderObjectType.Mesh].includes(instance.type)) { + this.meshManger.remove(instance); + } else if (instance.type == RenderObjectType.Light) { + this.lightManger.remove(instance); + } else if (instance.type == RenderObjectType.PostEffect) { + this.postEffectCollection.remove(instance); + } + } + setCamera(camera) { + this.camera = camera; + } + resize(width, height) { + this.context.resize(width, height); + this?.currentRenderPipeline?.setSize(width, height); + this?.postEffectCollection?.setSize(width, height); + } + async render(node, camera) { + if (!this.inited) { + this.inited = true; + await this.init(); + this.update(node, camera); + this.afterRender(); + } else { + this.update(node, camera); + this.afterRender(); + } + } + afterRender() { + // TODO + } + setViewPort(x, y, width, height) { + if (!this.ready) return false; + this.context.setViewPort(x, y, width, height); + return true; + } + setScissorTest(x, y, width, height) { + if (!this.ready) return false; + this.context.setScissorTest(x, y, width, height); + return true; + } + update(node, camera) { + if (!this.ready) return; + // 释放纹理 + textureCache.releasedTextures(); + // 更新FrameState + this.frameState.update(camera ?? this.camera, FrameState.getFrameStateOptionsByScene(this)); + // update primitive and select + (node ?? this.meshManger).update(this.frameState, camera ?? this.camera); + // selct renderPipeline + this.currentRenderPipeline.render(this.frameState, camera ?? this.camera); + // 后处理 + this.postEffectCollection.render(this.context, this.currentRenderPipeline.getOutputTexture()); + } +} + +class PostEffect { + constructor(width, height, id) { + this.width = width; + this.height = height; + this.initDefaultParms(); + this.id = id; + this.priority = 0; + this.isPostEffect = true; + this.type = RenderObjectType.PostEffect; + } + render(context, colorTexture) { return null; } - setSize(e, t) {} + setSize(width, height) { + // todo ; + } destroy() { this?.currentRenderTarget?.destroy(); } - renderMesh(e) { - (this.fullScreenQuad.material.dirty = !0), this.fullScreenQuad.material.update(); - const t = this.fullScreenQuad.getDrawCommand(), - i = this.currentRenderTarget.beginRenderPass(e.device); - t.render({ device: e.device, passEncoder: i }), this.currentRenderTarget.endRenderPass(); + renderMesh(context) { + this.fullScreenQuad.material.dirty = true; + this.fullScreenQuad.material.update(); + const drawComand = this.fullScreenQuad.getDrawCommand(); + const currentRenderPassEncoder = this.currentRenderTarget.beginRenderPass(context.device); + drawComand.render({ device: context.device, passEncoder: currentRenderPassEncoder }); + this.currentRenderTarget.endRenderPass(); } initDefaultParms() { - const e = new At({}); - e.setAttribute(new Ie("position", [-1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1], 2)), (e.count = 6); - const t = new ae(), - i = new ce(), - r = new te(); - (r.primitive = t), - (r.targets = [i]), - (this.renderState = r), - (this.fullScreenQuad = new Qi(e)), - (this.defaultSampler = new de()); - } -} -class Kr extends Zr { - constructor(e) { - super(e.width, e.height, "bloom"), - (this.strength = e.strength), - (this.radius = e.radius), - (this.threshold = e.threshold), - this.init(); + const geometry = new Geometry({}); + geometry.setAttribute( + new Float32Attribute("position", [-1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0], 2) + ); + geometry.count = 6; + // rs + const primitive = new Primitive(); + const target = new Target(); + // target.format=TextureFormat.RGBA8Unorm + const renderState = new RenderState(); + renderState.primitive = primitive; + renderState.targets = [target]; + this.renderState = renderState; + this.fullScreenQuad = new Mesh(geometry); + this.defaultSampler = new Sampler(); + } +} + +class BloomPostEffect extends PostEffect { + constructor(options) { + super(options.width, options.height, "bloom"); + this.strength = options.strength; + this.radius = options.radius; + this.threshold = options.threshold; + this.init(); } destroy() { this.renderTargetBright.destroy(); } - render(e, t) { - (this.currentRenderTarget = this.renderTargetBright), - (this.highPassUniforms.tDiffuse.value = t), - (this.fullScreenQuad.material = this.materialHighPassFilter), - this.renderMesh(e); - let i = this.renderTargetBright; - for (let t = 0; t < this.nMips; t++) - (this.fullScreenQuad.material = this.separableBlurMaterials[t]), - (this.separableBlurMaterials[t].uniforms.tDiffuse.value = i.getColorTexture()), - (this.separableBlurMaterials[t].uniforms.direction.value = Kr.BlurDirectionX), - (this.currentRenderTarget = this.renderTargetsHorizontal[t]), - this.renderMesh(e), - (this.fullScreenQuad.material = this.separableBlurYMaterials[t]), - (this.separableBlurYMaterials[t].uniforms.tDiffuse.value = - this.renderTargetsHorizontal[t].getColorTexture()), - (this.separableBlurYMaterials[t].uniforms.direction.value = Kr.BlurDirectionY), - (this.currentRenderTarget = this.renderTargetsVertical[t]), - this.renderMesh(e), - (i = this.renderTargetsVertical[t]); - return ( - (this.fullScreenQuad.material = this.compositeMaterial), - (this.currentRenderTarget = this.renderTargetsHorizontal[0]), - this.renderMesh(e), - (this.blendUniforms.baseColorTexture.value = t), - (this.fullScreenQuad.material = this.blendMaterial), - (this.currentRenderTarget = this.blendTarget), - this.renderMesh(e), - this.currentRenderTarget.getColorTexture() - ); - } - setSize(e, t) { - this?.renderTargetsHorizontal?.forEach((i) => i.setSize(e, t, 1)), - this?.renderTargetsVertical?.forEach((i) => i.setSize(e, t, 1)), - this?.renderTargetBright?.setSize?.(e, t, 1), - this?.blendTarget?.setSize?.(e, t, 1); + render(context, colorTexture) { + // 1. Extract Bright Areas + this.currentRenderTarget = this.renderTargetBright; + this.highPassUniforms.tDiffuse.value = colorTexture; + this.fullScreenQuad.material = this.materialHighPassFilter; + this.renderMesh(context); + // 2. Blur All the mips progressively + let inputRenderTarget = this.renderTargetBright; + for (let i = 0; i < this.nMips; i++) { + this.fullScreenQuad.material = this.separableBlurMaterials[i]; + this.separableBlurMaterials[i].uniforms.tDiffuse.value = inputRenderTarget.getColorTexture(); + this.separableBlurMaterials[i].uniforms.direction.value = BloomPostEffect.BlurDirectionX; + this.currentRenderTarget = this.renderTargetsHorizontal[i]; + this.renderMesh(context); + this.fullScreenQuad.material = this.separableBlurYMaterials[i]; + this.separableBlurYMaterials[i].uniforms.tDiffuse.value = this.renderTargetsHorizontal[i].getColorTexture(); + this.separableBlurYMaterials[i].uniforms.direction.value = BloomPostEffect.BlurDirectionY; + this.currentRenderTarget = this.renderTargetsVertical[i]; + this.renderMesh(context); + inputRenderTarget = this.renderTargetsVertical[i]; + } + // Composite All the mips + this.fullScreenQuad.material = this.compositeMaterial; + this.currentRenderTarget = this.renderTargetsHorizontal[0]; + this.renderMesh(context); + // blend + this.blendUniforms.baseColorTexture.value = colorTexture; + this.fullScreenQuad.material = this.blendMaterial; + this.currentRenderTarget = this.blendTarget; + this.renderMesh(context); + return this.currentRenderTarget.getColorTexture(); + } + setSize(width, height) { + this?.renderTargetsHorizontal?.forEach((renderTarget) => renderTarget.setSize(width, height, 1)); + this?.renderTargetsVertical?.forEach((renderTarget) => renderTarget.setSize(width, height, 1)); + this?.renderTargetBright?.setSize?.(width, height, 1); + this?.blendTarget?.setSize?.(width, height, 1); } init() { - (this.renderTargetsHorizontal = []), (this.renderTargetsVertical = []), (this.nMips = 5); - let e = Math.round(this.width / 2), - t = Math.round(this.height / 2); - this.renderTargetBright = new $e("render", [this.createColorAttachment(e, t)]); + this.renderTargetsHorizontal = []; + this.renderTargetsVertical = []; + this.nMips = 5; + let resx = Math.round(this.width / 2); + let resy = Math.round(this.height / 2); + this.renderTargetBright = new RenderTarget("render", [this.createColorAttachment(resx, resy)]); for (let i = 0; i < this.nMips; i++) { - const i = new $e("render", [this.createColorAttachment(e, t)]); - this.renderTargetsHorizontal.push(i); - const r = new $e("render", [this.createColorAttachment(e, t)]); - this.renderTargetsVertical.push(r), (e = Math.round(e / 2)), (t = Math.round(t / 2)); + const renderTargetHorizonal = new RenderTarget("render", [this.createColorAttachment(resx, resy)]); + this.renderTargetsHorizontal.push(renderTargetHorizonal); + const renderTargetVertical = new RenderTarget("render", [this.createColorAttachment(resx, resy)]); + this.renderTargetsVertical.push(renderTargetVertical); + resx = Math.round(resx / 2); + resy = Math.round(resy / 2); } + // luminosity high pass material this.highPassUniforms = { tDiffuse: { type: "texture", value: null }, - tSampler: { type: "sampler", value: this.defaultSampler }, + tSampler: { + type: "sampler", + value: this.defaultSampler + }, luminosityThreshol: { type: "float", value: this.threshold }, smoothWidth: { type: "float", value: 0.01 }, - defaultColor: { type: "color", value: new Qt(0, 0, 0) }, - defaultOpacity: { type: "float", value: 1 } + defaultColor: { type: "color", value: new Color(0.0, 0, 0) }, + defaultOpacity: { type: "float", value: 1.0 } }; - const i = $i("luminosityHigh", { positionLocation: 0 }); - (this.materialHighPassFilter = new Zi({ + const shader = getVertFrag("luminosityHigh", { positionLocation: 0 }); + this.materialHighPassFilter = new ShaderMaterial({ type: "bloom", uniforms: this.highPassUniforms, - vert: i.vert, - frag: i.frag - })), - (this.materialHighPassFilter.renderState = this.renderState), - (this.separableBlurMaterials = []), - (this.separableBlurYMaterials = []); - const r = [3, 5, 7, 9, 11]; - (e = Math.round(this.width / 2)), (t = Math.round(this.height / 2)); - for (let i = 0; i < this.nMips; i++) - this.separableBlurMaterials.push(this.getSeperableBlurMaterial(r[i], "BlurMaterial" + i)), - this.separableBlurYMaterials.push(this.getSeperableBlurMaterial(r[i], "BlurMaterialY" + i)), - (e = Math.round(e / 2)), - (t = Math.round(t / 2)); - (this.compositeMaterial = this.getCompositeMaterial(this.nMips, "compositeMaterial")), - (this.compositeMaterial.renderState = this.renderState), - (this.blendUniforms = { - tDiffuse: { type: "texture", value: this.renderTargetsHorizontal[0].getColorTexture() }, - baseColorTexture: { type: "texture", value: null }, - tSampler: { type: "sampler", value: this.defaultSampler } - }); - const n = $i("blend", { positionLocation: 0 }); - (this.blendMaterial = new Zi({ type: "postBlend", uniforms: this.blendUniforms, vert: n.vert, frag: n.frag })), - (this.blendMaterial.renderState = this.renderState), - (this.blendTarget = new $e("render", [this.createColorAttachment(this.width, this.height)])); - } - createColorAttachment(e, t) { - const i = new fe({ - size: { width: e, height: t, depth: 1 }, - format: l.BGRA8Unorm, - usage: a.RenderAttachment | a.TextureBinding + vert: shader.vert, + frag: shader.frag + }); + // Gaussian Blur Materials + this.materialHighPassFilter.renderState = this.renderState; + this.separableBlurMaterials = []; + this.separableBlurYMaterials = []; + const kernelSizeArray = [3, 5, 7, 9, 11]; + resx = Math.round(this.width / 2); + resy = Math.round(this.height / 2); + for (let i = 0; i < this.nMips; i++) { + this.separableBlurMaterials.push(this.getSeperableBlurMaterial(kernelSizeArray[i], "BlurMaterial" + i)); + this.separableBlurYMaterials.push(this.getSeperableBlurMaterial(kernelSizeArray[i], "BlurMaterialY" + i)); + resx = Math.round(resx / 2); + resy = Math.round(resy / 2); + } + // Composite material + this.compositeMaterial = this.getCompositeMaterial(this.nMips, "compositeMaterial"); + this.compositeMaterial.renderState = this.renderState; + this.blendUniforms = { + tDiffuse: { type: "texture", value: this.renderTargetsHorizontal[0].getColorTexture() }, + baseColorTexture: { type: "texture", value: null }, + tSampler: { + type: "sampler", + value: this.defaultSampler + } + }; + const blendShader = getVertFrag("blend", { positionLocation: 0 }); + this.blendMaterial = new ShaderMaterial({ + type: "postBlend", + uniforms: this.blendUniforms, + vert: blendShader.vert, + frag: blendShader.frag }); - return new me({ r: 0, g: 0, b: 0, a: 0 }, { texture: i }); + this.blendMaterial.renderState = this.renderState; + this.blendTarget = new RenderTarget("render", [this.createColorAttachment(this.width, this.height)]); + } + createColorAttachment(width, height) { + const colorTexture = new Texture({ + size: { width, height, depth: 1 }, + format: TextureFormat.BGRA8Unorm, + usage: TextureUsage.RenderAttachment | TextureUsage.TextureBinding + }); + const colorAttachment = new Attachment({ r: 0.0, g: 0.0, b: 0.0, a: 0.0 }, { texture: colorTexture }); + return colorAttachment; } - getCompositeMaterial(e, t) { - return new Zi({ - type: t, + getCompositeMaterial(nMips, type) { + return new ShaderMaterial({ + type, uniforms: { blurTexture1: { type: "texture", value: this.renderTargetsVertical[0].getColorTexture() }, blurTexture2: { type: "texture", value: this.renderTargetsVertical[1].getColorTexture() }, blurTexture3: { type: "texture", value: this.renderTargetsVertical[2].getColorTexture() }, blurTexture4: { type: "texture", value: this.renderTargetsVertical[3].getColorTexture() }, blurTexture5: { type: "texture", value: this.renderTargetsVertical[4].getColorTexture() }, - tSampler: { type: "sampler", value: this.defaultSampler }, + tSampler: { + type: "sampler", + value: this.defaultSampler + }, bloomStrength: { type: "f32", value: this.strength }, bloomRadius: { type: "f32", value: this.radius }, - bloomFactors: { type: "array", value: [1, 0.8, 0.6, 0.4, 0.2] }, + bloomFactors: { type: "array", value: [1.0, 0.8, 0.6, 0.4, 0.2] }, bloomTintColors: { type: "array", - value: [new Ue(1, 1, 1), new Ue(1, 1, 1), new Ue(1, 1, 1), new Ue(1, 1, 1), new Ue(1, 1, 1)] + value: [ + new Vector3(1, 1, 1), + new Vector3(1, 1, 1), + new Vector3(1, 1, 1), + new Vector3(1, 1, 1), + new Vector3(1, 1, 1) + ] } }, - vert: () => - "\n struct VertexInput {\n @location(0) position: vec2, \n }\n struct VertexOutput {\n @builtin(position) position: vec4,\n @location(0) uv: vec2,\n };\n @vertex\n fn main(input: VertexInput) -> VertexOutput {\n var output:VertexOutput;\n output.uv = input.position * 0.5 + 0.5;\n output.position = vec4(input.position, 0.0, 1.0);;\n return output;\n }\n ", - frag: (e) => - `\n struct FragInput {\n @location(0) uv: vec2,\n };\n struct BloomUniforms{\n bloomStrength:f32,\n bloomRadius:f32,\n bloomFactors : array,\n bloomTintColors : array,5>\n } \n @group(0) @binding(0) var bloomUniforms : BloomUniforms;\n\n @group(0) @binding(${e.blurTexture1Binding}) var blurTexture1: texture_2d;\n @group(0) @binding(${e.blurTexture2Binding}) var blurTexture2: texture_2d;\n @group(0) @binding(${e.blurTexture3Binding}) var blurTexture3: texture_2d;\n @group(0) @binding(${e.blurTexture4Binding}) var blurTexture4: texture_2d;\n @group(0) @binding(${e.blurTexture5Binding}) var blurTexture5: texture_2d;\n @group(0) @binding(${e.tSamplerBinding}}) var tSampler: sampler;\n\n\t\t\t\tfn lerpBloomFactor(factor:f32)->f32 {\n\t\t\t\t\tlet mirrorFactor:f32 = 1.2 - factor;\n\t\t\t\t\treturn mix(factor, mirrorFactor, bloomUniforms.bloomRadius);\n\t\t\t\t}\n @fragment\n\t\t\t\tfn main(input:FragInput)-> @location(0) vec4 {\n\t\t\t\t\treturn bloomUniforms.bloomStrength * ( lerpBloomFactor(bloomUniforms.bloomFactors[0]) * vec4(bloomUniforms.bloomTintColors[0], 1.0) * textureSample(blurTexture1, tSampler, input.uv) +\n\t\t\t\t\t\tlerpBloomFactor(bloomUniforms.bloomFactors[1]) * vec4(bloomUniforms.bloomTintColors[1], 1.0) * textureSample(blurTexture2, tSampler, input.uv) +\n\t\t\t\t\t\tlerpBloomFactor(bloomUniforms.bloomFactors[2]) * vec4(bloomUniforms.bloomTintColors[2], 1.0) * textureSample(blurTexture3, tSampler, input.uv) +\n\t\t\t\t\t\tlerpBloomFactor(bloomUniforms.bloomFactors[3]) * vec4(bloomUniforms.bloomTintColors[3], 1.0) * textureSample(blurTexture4, tSampler, input.uv) +\n\t\t\t\t\t\tlerpBloomFactor(bloomUniforms.bloomFactors[4]) * vec4(bloomUniforms.bloomTintColors[4], 1.0) * textureSample(blurTexture5, tSampler, input.uv) );\n\t\t\t\t}` + vert: () => { + return ` + struct VertexInput { + @location(0) position: vec2, + } + struct VertexOutput { + @builtin(position) position: vec4, + @location(0) uv: vec2, + }; + @vertex + fn main(input: VertexInput) -> VertexOutput { + var output:VertexOutput; + output.uv = input.position * 0.5 + 0.5; + output.position = vec4(input.position, 0.0, 1.0);; + return output; + } + `; + }, + frag: (defines) => { + return ` + struct FragInput { + @location(0) uv: vec2, + }; + struct BloomUniforms{ + bloomStrength:f32, + bloomRadius:f32, + bloomFactors : array, + bloomTintColors : array,5> + } + @group(0) @binding(0) var bloomUniforms : BloomUniforms; + + @group(0) @binding(${defines.blurTexture1Binding}) var blurTexture1: texture_2d; + @group(0) @binding(${defines.blurTexture2Binding}) var blurTexture2: texture_2d; + @group(0) @binding(${defines.blurTexture3Binding}) var blurTexture3: texture_2d; + @group(0) @binding(${defines.blurTexture4Binding}) var blurTexture4: texture_2d; + @group(0) @binding(${defines.blurTexture5Binding}) var blurTexture5: texture_2d; + @group(0) @binding(${defines.tSamplerBinding}}) var tSampler: sampler; + + fn lerpBloomFactor(factor:f32)->f32 { + let mirrorFactor:f32 = 1.2 - factor; + return mix(factor, mirrorFactor, bloomUniforms.bloomRadius); + } + @fragment + fn main(input:FragInput)-> @location(0) vec4 { + return bloomUniforms.bloomStrength * ( lerpBloomFactor(bloomUniforms.bloomFactors[0]) * vec4(bloomUniforms.bloomTintColors[0], 1.0) * textureSample(blurTexture1, tSampler, input.uv) + + lerpBloomFactor(bloomUniforms.bloomFactors[1]) * vec4(bloomUniforms.bloomTintColors[1], 1.0) * textureSample(blurTexture2, tSampler, input.uv) + + lerpBloomFactor(bloomUniforms.bloomFactors[2]) * vec4(bloomUniforms.bloomTintColors[2], 1.0) * textureSample(blurTexture3, tSampler, input.uv) + + lerpBloomFactor(bloomUniforms.bloomFactors[3]) * vec4(bloomUniforms.bloomTintColors[3], 1.0) * textureSample(blurTexture4, tSampler, input.uv) + + lerpBloomFactor(bloomUniforms.bloomFactors[4]) * vec4(bloomUniforms.bloomTintColors[4], 1.0) * textureSample(blurTexture5, tSampler, input.uv) ); + }`; + } }); } - getSeperableBlurMaterial(e, t) { - const i = $i("blur", { KERNEL_RADIUS: e, SIGMA: e, positionLocation: 0 }), - r = new Zi({ - type: t, - uniforms: { - tDiffuse: { type: "texture", value: null }, - direction: { type: "vec2", value: new Se(0, 0) }, - tSampler: { type: "sampler", value: this.defaultSampler } - }, - vert: i.vert, - frag: i.frag - }); - return (r.renderState = this.renderState), r; + getSeperableBlurMaterial(kernelRadius, type) { + const shader = getVertFrag("blur", { + KERNEL_RADIUS: kernelRadius, + SIGMA: kernelRadius, + positionLocation: 0 + }); + const mat = new ShaderMaterial({ + type, + uniforms: { + tDiffuse: { type: "texture", value: null }, + direction: { type: "vec2", value: new Vector2(0.0, 0.0) }, + tSampler: { + type: "sampler", + value: this.defaultSampler + } + }, + vert: shader.vert, + frag: shader.frag + }); + mat.renderState = this.renderState; + return mat; } } -(Kr.BlurDirectionX = new Se(1, 0)), (Kr.BlurDirectionY = new Se(0, 1)); -class Qr extends $r { - constructor(e = -1, t = 1, i = 1, r = -1, n = 0.1, s = 2e3) { - super(), - (this.near = n), - (this.far = s), - (this.left = e), - (this.top = i), - (this.bottom = r), - (this.right = t), - (this.isOrthographicCamera = !0); +BloomPostEffect.BlurDirectionX = new Vector2(1.0, 0.0); +BloomPostEffect.BlurDirectionY = new Vector2(0.0, 1.0); + +class OrthographicCamera extends Camera { + constructor(left = -1, right = 1, top = 1, bottom = -1, near = 0.1, far = 2000) { + super(); + this.near = near; + this.far = far; + this.left = left; + this.top = top; + this.bottom = bottom; + this.right = right; + this.isOrthographicCamera = true; } updateCameraParms() { - const e = (this.right - this.left) / 2, - t = (this.top - this.bottom) / 2, - i = (this.right + this.left) / 2, - r = (this.top + this.bottom) / 2; - return { left: i - e, right: i + e, top: r + t, bottom: r - t }; + const dx = (this.right - this.left) / 2; + const dy = (this.top - this.bottom) / 2; + const cx = (this.right + this.left) / 2; + const cy = (this.top + this.bottom) / 2; + return { + left: cx - dx, + right: cx + dx, + top: cy + dy, + bottom: cy - dy + }; } updateProjectionMatrix() { if (this.projectMatrixDirty) { - const { left: e, right: t, top: i, bottom: r } = this.updateCameraParms(); - (this._projectionMatrix = et.makeOrthographic(e, t, i, r, this.near, this.far)), - (this.projectMatrixDirty = !1); + const { left, right, top, bottom } = this.updateCameraParms(); + this._projectionMatrix = Matrix4.makeOrthographic(left, right, top, bottom, this.near, this.far); + this.projectMatrixDirty = false; } } } -class Jr extends qr { + +class SpotLightShadow extends BaseShadow { constructor() { - const e = new Gr(60, 1, 0.1, 500); - super(new Se(1024, 1024), e), (this.type = "spotLightShadow"); - } - update(e) { - this.updateMatrices(e); - } - updateMatrices(e) { - this.camera.position.copy(e.position); - const { x: t, y: i, z: r } = e.target; - this.camera.lookAt(t, i, r), this.camera.updateMatrix(), (this.vpMatrixDirty = !0); - } -} -class en extends Ht { - constructor(e, t, i = 0, r = 60, n = 60, s = 4, a = !0) { - super(e, t), - (this._distance = i), - (this._angle = (r / 180) * Math.PI), - (this._penumbra = (n / 180) * Math.PI), - (this._decay = s), - (this.lightType = K.SpotLight), - (this.angleDirty = !0), - (this.penumbraDirty = !0), - (this.distanceDirty = !0), - (this.decayDirty = !0), - (this.coneCosDirty = !0), - (this.penumbraCosDirty = !0), - a && (this.shadow = new Jr()), - this.updateConeCosOrPenumbraCos(); + const camera = new PerspectiveCamera(60, 1, 0.1, 500); + super(new Vector2(1024, 1024), camera); + this.type = "spotLightShadow"; + } + update(light) { + this.updateMatrices(light); + } + updateMatrices(light) { + this.camera.position.copy(light.position); + const { x, y, z } = light.target; + this.camera.lookAt(x, y, z); + this.camera.updateMatrix(); + this.vpMatrixDirty = true; + } +} + +class SpotLight extends Light { + constructor(color, intensity, distance = 0, angle = 60, penumbra = 60, decay = 4, openShadow = true) { + super(color, intensity); + this._distance = distance; + this._angle = (angle / 180) * Math.PI; + this._penumbra = (penumbra / 180) * Math.PI; + this._decay = decay; + this.lightType = LightType.SpotLight; + this.angleDirty = true; + this.penumbraDirty = true; + this.distanceDirty = true; + this.decayDirty = true; + this.coneCosDirty = true; + this.penumbraCosDirty = true; + if (openShadow) this.shadow = new SpotLightShadow(); + this.updateConeCosOrPenumbraCos(); } get dirtectDirty() { return this.positionDirty || this.targetDirty; } - set dirtectDirty(e) { - (this.positionDirty = e), (this.targetDirty = e); + set dirtectDirty(value) { + this.positionDirty = value; + this.targetDirty = value; } get directional() { - const e = new Ue(); - return Ue.subtract(this.position, this.target, e), Ue.normalize(e, new Ue()); + const result = new Vector3(); + Vector3.subtract(this.position, this.target, result); + return Vector3.normalize(result, new Vector3()); } get angle() { return this._angle; } - set angle(e) { - (this.angleDirty = !0), (this._angle = (e / 180) * Math.PI), this.updateConeCosOrPenumbraCos(); + set angle(value) { + this.angleDirty = true; + this._angle = (value / 180) * Math.PI; + this.updateConeCosOrPenumbraCos(); } get penumbra() { return this._penumbra; } - set penumbra(e) { - (this.penumbraDirty = !0), (this._penumbra = (e / 180) * Math.PI), this.updateConeCosOrPenumbraCos(); + set penumbra(value) { + this.penumbraDirty = true; + this._penumbra = (value / 180) * Math.PI; + this.updateConeCosOrPenumbraCos(); } - set distance(e) { - (this.distanceDirty = !0), (this._distance = e); + set distance(value) { + this.distanceDirty = true; + this._distance = value; } get distance() { return this._distance; } - set decay(e) { - (this.decayDirty = !0), (this._decay = e); + set decay(value) { + this.decayDirty = true; + this._decay = value; } get decay() { return this._decay; } - set coneCos(e) { - (this.coneCosDirty = !0), (this._coneCos = e); + set coneCos(value) { + this.coneCosDirty = true; + this._coneCos = value; } get coneCos() { return this._coneCos; } - set penumbraCos(e) { - (this.penumbraCosDirty = !0), (this._penumbraCos = e); + set penumbraCos(value) { + this.penumbraCosDirty = true; + this._penumbraCos = value; } get penumbraCos() { return this._penumbraCos; } updateConeCosOrPenumbraCos() { - (this._coneCos = Math.cos(this.angle)), (this._penumbraCos = Math.cos(this.angle + this.penumbra)); + this._coneCos = Math.cos(this.angle); + this._penumbraCos = Math.cos(this.angle + this.penumbra); } } -class tn extends qr { +// uniform +// color: {}, +// position: {}, +// direction: {}, +// distance: {}, +// coneCos: {}, +// penumbraCos: {}, +// decay: {} + +class DirectionalLightShadow extends BaseShadow { constructor() { - const e = new Qr(-50, 50, 50, -50, 0, 100); - super(new Se(1024, 1024), e), (this.type = "directionalLightShadow"); + const camera = new OrthographicCamera(-50, 50, 50, -50, 0, 100); + super(new Vector2(1024, 1024), camera); + this.type = "directionalLightShadow"; } - update(e) { - this.updateMatrices(e); + update(light) { + this.updateMatrices(light); } - updateMatrices(e) { - this.camera.position.copy(e.position); - const { x: t, y: i, z: r } = e.target; - this.camera.lookAt(t, i, r), this.camera.updateMatrix(), (this.vpMatrixDirty = !0); + updateMatrices(light) { + this.camera.position.copy(light.position); + const { x, y, z } = light.target; + this.camera.lookAt(x, y, z); + this.camera.updateMatrix(); + this.vpMatrixDirty = true; } } -class rn extends Ht { - constructor(e, t, i = !0) { - super(e, t), (this.lightType = K.DirectionalLight), i && (this.shadow = new tn()); + +class DirectionalLight extends Light { + constructor(color, intensity, openShadow = true) { + super(color, intensity); + this.lightType = LightType.DirectionalLight; + if (openShadow) this.shadow = new DirectionalLightShadow(); } get dirtectDirty() { return this.positionDirty || this.targetDirty; } - set dirtectDirty(e) { - (this.positionDirty = e), (this.targetDirty = e); + set dirtectDirty(value) { + this.positionDirty = value; + this.targetDirty = value; } get directional() { - const e = new Ue(); - return Ue.subtract(this.target, this.position, e), e.normalize(); + const result = new Vector3(); + Vector3.subtract(this.target, this.position, result); + return result.normalize(); } } -class nn extends $t { +// uniform +// direction: {}, +// color: {} + +class Node extends RenderObject { constructor() { - super(), (this.type = Z.Node), (this.children = new Map()), (this.parent = null), (this.uid = Ki()); - } - add(e) { - (e.parent = this), this.children.set(e.uid, e); - } - remove(e) { - this.children.delete(e.uid); - } - update(e, t) { - this.updateMatrix(this?.parent?.modelMatrix?.clone()), - this?.children?.forEach?.((i) => { - i.update(e, t); - }); + super(); + this.type = RenderObjectType.Node; + this.children = new Map(); + this.parent = null; + this.uid = createGuid(); + } + add(node) { + node.parent = this; + this.children.set(node.uid, node); + } + remove(node) { + this.children.delete(node.uid); + } + update(frameState, camera) { + this.updateMatrix(this?.parent?.modelMatrix?.clone()); + this?.children?.forEach?.((node) => { + node.update(frameState, camera); + }); } destroy() { - this.children.forEach((e) => { - e.destroy(); - }), - this?.children?.clear(); - } - traverse(e, t) { - for (let i = 0, r = this.children.size; i < r; i++) - this.children.forEach((i) => { - i.traverse(e, t); + this.children.forEach((node) => { + node.destroy(); + }); + this?.children?.clear(); + } + traverse(traverseFunction, param) { + for (let i = 0, len = this.children.size; i < len; i++) { + this.children.forEach((child) => { + child.traverse(traverseFunction, param); }); + } } } -class sn extends Qi { - constructor(e, t) { - super(e, t), (this.type = Z.SkinMesh), (this.uniformMatrixs = []), (this.hasAddJoints = !1); - } - setSkinData(e) { - (this.inverseBindMatrices = e.inverseBindMatrices), (this.joints = e.joints); - } - update(e, t) { - (this.uniformMatrixs = this.joints.map((e) => e.modelMatrix)), - super.update(e, t), - this.hasAddJoints || this.addUniformsToMaterial(); + +class SKinMesh extends Mesh { + constructor(geometry, material) { + super(geometry, material); + this.type = RenderObjectType.SkinMesh; + this.uniformMatrixs = []; + this.hasAddJoints = false; + } + setSkinData(data) { + this.inverseBindMatrices = data.inverseBindMatrices; + this.joints = data.joints; + } + update(frameState, camera) { + this.uniformMatrixs = this.joints.map((joint) => joint.modelMatrix); + super.update(frameState, camera); + if (!this.hasAddJoints) this.addUniformsToMaterial(); } addUniformsToMaterial() { - if (this.material.shaderData && ((this.hasAddJoints = !0), this.joints)) { - const e = new Ri({ - label: "skinJointsBuffer", - type: m.ReadOnlyStorage, - usage: r.Storage | r.CopyDst, - size: 3e3 - }), - t = new Ri({ label: "invsBuffer", type: m.ReadOnlyStorage, usage: r.Storage | r.CopyDst, size: 3e3 }); - e.setUniform("joints", () => this.uniformMatrixs, Q.Mat4Array, this.uniformMatrixs.length), - t.setUniform("jointsInv", () => this.inverseBindMatrices, Q.Mat4Array, this.inverseBindMatrices.length), - this.material.shaderData.setUniformBuffer("skinJointsBuffer", e), - this.material.shaderData.setUniformBuffer("invsBuffer", t); - } - } -} -function an(e, t, i, r) { - switch (e) { + if (!this.material.shaderData) return; + this.hasAddJoints = true; + if (this.joints) { + const skinJointsBuffer = new UniformBuffer({ + label: "skinJointsBuffer", + type: BufferBindingType.ReadOnlyStorage, + usage: BufferUsage.Storage | BufferUsage.CopyDst, + size: 3000 + }); + const invsBuffer = new UniformBuffer({ + label: "invsBuffer", + type: BufferBindingType.ReadOnlyStorage, + usage: BufferUsage.Storage | BufferUsage.CopyDst, + size: 3000 + }); + skinJointsBuffer.setUniform( + "joints", + () => { + return this.uniformMatrixs; + }, + UniformEnum.Mat4Array, + this.uniformMatrixs.length + ); + invsBuffer.setUniform( + "jointsInv", + () => { + return this.inverseBindMatrices; + }, + UniformEnum.Mat4Array, + this.inverseBindMatrices.length + ); + this.material.shaderData.setUniformBuffer("skinJointsBuffer", skinJointsBuffer); + this.material.shaderData.setUniformBuffer("invsBuffer", invsBuffer); + } + } +} + +function newTypedArray(type, buffer, byteOffset, length) { + switch (type) { case 5120: - return new Int8Array(t, i, r); + return new Int8Array(buffer, byteOffset, length); case 5121: - return new Uint8Array(t, i, r); + return new Uint8Array(buffer, byteOffset, length); case 5122: - return new Int16Array(t, i, r); + return new Int16Array(buffer, byteOffset, length); case 5123: - return new Uint16Array(t, i, r); + return new Uint16Array(buffer, byteOffset, length); case 5124: - return new Int32Array(t, i, r); + return new Int32Array(buffer, byteOffset, length); case 5125: - return new Uint32Array(t, i, r); + return new Uint32Array(buffer, byteOffset, length); case 5126: - return new Float32Array(t, i, r); + return new Float32Array(buffer, byteOffset, length); default: throw new Error("invalid component type"); } } -const on = { +function toIndices(array) { + if (array instanceof Uint16Array || array instanceof Uint32Array) { + return array; + } + let toArray; + if (array instanceof Float32Array) { + toArray = new Uint32Array(array.length); + } else { + toArray = new Uint16Array(array.length); + } + array.forEach((element, index) => { + toArray[index] = element; + }); + return toArray; +} +function generateNormals(indices, positions) { + const normals = new Float32Array(positions.length); + const vertexCount = indices ? indices.length : positions.length; + for (let i = 0; i < vertexCount; i += 3) { + const triIndices = []; + for (let n = 0; n < 3; n += 1) { + if (indices) { + triIndices.push(indices[i + n]); + } else { + triIndices.push(i + n); + } + } + const triangle = triIndices.map((vertexIndex) => { + const index = vertexIndex * 3; + return new Vector3(positions[index], positions[index + 1], positions[index + 2]); + }); + const dv1 = new Vector3(); + Vector3.subtract(triangle[1], triangle[0], dv1); + const dv2 = new Vector3(); + Vector3.subtract(triangle[2], triangle[0], dv2); + const normal = new Vector3(); + Vector3.cross(dv1.normalize(), dv2.normalize(), normal); + for (let n = 0; n < 3; n += 1) { + const index = (i + n) * 3; + normals[index + 0] += normal.x; + normals[index + 1] += normal.y; + normals[index + 2] += normal.z; + } + } + return normals; +} +const gltfEnum = { SCALAR: 1, VEC2: 2, VEC3: 3, @@ -11301,613 +15190,794 @@ const on = { 33648: "mirror-repeat", 10497: "repeat" }; -class cn { - constructor(e) { - (this.values = e.values ?? []), - (this.id = e.id), - (this.count = e.count), - (this.componentType = e.componentType), - (this.type = e.type), - (this.min = e.min), - (this.max = e.max); + +class Accessor { + constructor(options) { + this.values = options.values ?? []; + this.id = options.id; + this.count = options.count; + this.componentType = options.componentType; + this.type = options.type; + this.min = options.min; + this.max = options.max; } getArray() { return Array.from(this.values); } getVec4Array() { - const e = []; - for (let t = 0; t < this.values.length; t += 4) - e.push(new We(this.values[t], this.values[t + 1], this.values[t + 2], this.values[t + 3])); - return e; + const result = []; + for (let i = 0; i < this.values.length; i += 4) { + result.push(new Vector4(this.values[i], this.values[i + 1], this.values[i + 2], this.values[i + 3])); + } + return result; } getMat4Array() { - const e = []; - for (let t = 0; t < this.values.length; t += 16) { - const i = new et(); - et.fromColumnMajorArray(this.values.slice(t, t + 16), i), e.push(i); + const result = []; + for (let i = 0; i < this.values.length; i += 16) { + const mat4 = new Matrix4(); + Matrix4.fromColumnMajorArray(this.values.slice(i, i + 16), mat4); + result.push(mat4); } - return e; + return result; } } -class ln { - constructor(e, t, i) { - (this.name = e), (this.samplers = t), (this.channels = i); - } - play(e) { - let t, i, r; - this?.channels?.map((n) => { - switch (((i = n.sampler), i.getValue(e), (r = n.target), (t = r.node), r.path)) { + +class Animation { + constructor(name, samplers, channels) { + this.name = name; + this.samplers = samplers; + this.channels = channels; + } + play(time) { + let node, animationSampler, target; + this?.channels?.map((channel) => { + animationSampler = channel.sampler; + animationSampler.getValue(time); + target = channel.target; + node = target.node; + switch (target.path) { case "rotation": - zt.clone(i.currentValue, t.quaternion); + Quaternion.clone(animationSampler.currentValue, node.quaternion); break; case "translation": - We.clone(i.currentValue, t.position); + Vector4.clone(animationSampler.currentValue, node.position); break; case "scale": - We.clone(i.currentValue, t.scale); + Vector4.clone(animationSampler.currentValue, node.scale); + break; } }); } } -class hn { + +class AnimationChannel { + constructor() {} +} + +class AnimationChannelTarget { + constructor(node, path) { + this.node = node; + this.path = path; + } +} + +var Type2NumOfComponent; +(function (Type2NumOfComponent) { + Type2NumOfComponent[(Type2NumOfComponent["SCALAR"] = 1)] = "SCALAR"; + Type2NumOfComponent[(Type2NumOfComponent["VEC2"] = 2)] = "VEC2"; + Type2NumOfComponent[(Type2NumOfComponent["VEC3"] = 3)] = "VEC3"; + Type2NumOfComponent[(Type2NumOfComponent["VEC4"] = 4)] = "VEC4"; + Type2NumOfComponent[(Type2NumOfComponent["MAT2"] = 4)] = "MAT2"; + Type2NumOfComponent[(Type2NumOfComponent["MAT3"] = 9)] = "MAT3"; + Type2NumOfComponent[(Type2NumOfComponent["MAT4"] = 16)] = "MAT4"; +})(Type2NumOfComponent || (Type2NumOfComponent = {})); + +class AnimationSampler { constructor() {} + formGltf(gltf, sampler) { + this.input = gltf.accessors[sampler.input].values; //required, accessor object + this.output = gltf.accessors[sampler.output].values; //required, accessor object + this.interpolation = sampler.interpolation !== undefined ? sampler.interpolation : "LINEAR"; + this.currentIndex = 0; + // this.currentValue=new Vector4(); + this.endTime = this.input[this.input.length - 1]; + this.inputMax = this.endTime - this.input[0]; + this.inputType = gltf?.json?.accessors[sampler.input]?.type; + this.outputType = gltf?.json?.accessors[sampler.output]?.type; + } + getValue(time) { + if (time > this.endTime) { + time -= this.inputMax * Math.ceil((time - this.endTime) / this.inputMax); + this.currentIndex = 0; + } + const len = this.input.length; + while (this.currentIndex <= len - 2 && time >= this.input[this.currentIndex + 1]) { + this.currentIndex++; + } + if (this.currentIndex >= len - 1) { + // loop + time -= this.inputMax; + this.currentIndex = 0; + } + // @tmp: assume no stride + const count = Type2NumOfComponent[this.outputType]; + const animationOutputValueVec4a = count === 4 ? new Quaternion() : new Vector4(); + const animationOutputValueVec4b = count === 4 ? new Quaternion() : new Vector4(); + if (!this.currentValue) this.currentValue = count === 4 ? new Quaternion() : new Vector4(); + const i = this.currentIndex; + const o = i * count; + const on = o + count; + const u = Math.max(0, time - this.input[i]) / (this.input[i + 1] - this.input[i]); + animationOutputValueVec4a.set(this.output[o + 0], this.output[o + 1], this.output[o + 2], this.output[o + 3]); + animationOutputValueVec4b.set( + this.output[on + 0], + this.output[on + 1], + this.output[on + 2], + this.output[on + 3] + ); + switch (this.interpolation) { + case "LINEAR": + count === 4 + ? Quaternion.slerp(animationOutputValueVec4a, animationOutputValueVec4b, u, this.currentValue) + : Vector4.lerp(animationOutputValueVec4a, animationOutputValueVec4b, u, this.currentValue); + break; + } + } } -class un { - constructor(e, t) { - (this.node = e), (this.path = t); - } -} -var fn; -!(function (e) { - (e[(e.SCALAR = 1)] = "SCALAR"), - (e[(e.VEC2 = 2)] = "VEC2"), - (e[(e.VEC3 = 3)] = "VEC3"), - (e[(e.VEC4 = 4)] = "VEC4"), - (e[(e.MAT2 = 4)] = "MAT2"), - (e[(e.MAT3 = 9)] = "MAT3"), - (e[(e.MAT4 = 16)] = "MAT4"); -})(fn || (fn = {})); -class dn { - constructor() {} - formGltf(e, t) { - (this.input = e.accessors[t.input].values), - (this.output = e.accessors[t.output].values), - (this.interpolation = void 0 !== t.interpolation ? t.interpolation : "LINEAR"), - (this.currentIndex = 0), - (this.endTime = this.input[this.input.length - 1]), - (this.inputMax = this.endTime - this.input[0]), - (this.inputType = e?.json?.accessors[t.input]?.type), - (this.outputType = e?.json?.accessors[t.output]?.type); - } - getValue(e) { - e > this.endTime && - ((e -= this.inputMax * Math.ceil((e - this.endTime) / this.inputMax)), (this.currentIndex = 0)); - const t = this.input.length; - for (; this.currentIndex <= t - 2 && e >= this.input[this.currentIndex + 1]; ) this.currentIndex++; - this.currentIndex >= t - 1 && ((e -= this.inputMax), (this.currentIndex = 0)); - const i = fn[this.outputType], - r = 4 === i ? new zt() : new We(), - n = 4 === i ? new zt() : new We(); - this.currentValue || (this.currentValue = 4 === i ? new zt() : new We()); - const s = this.currentIndex, - a = s * i, - o = a + i, - c = Math.max(0, e - this.input[s]) / (this.input[s + 1] - this.input[s]); - if ( - (r.set(this.output[a + 0], this.output[a + 1], this.output[a + 2], this.output[a + 3]), - n.set(this.output[o + 0], this.output[o + 1], this.output[o + 2], this.output[o + 3]), - "LINEAR" === this.interpolation) - ) - 4 === i ? zt.slerp(r, n, c, this.currentValue) : We.lerp(r, n, c, this.currentValue); - } -} -class mn { - constructor(e, t, i = 0, r) { - (this.json = e), - (this.bufferViews = e.bufferViews), - (this.glbOffset = i), - (this.rootUrl = t), - (this.scenes = e.scenes), - (this.cameras = e.cameras || []), - (this.glbBin = r), - (this.meshes = []); + +class GLTF { + constructor(json, rootUrl, glbOffset = 0, glbBin) { + this.json = json; + this.bufferViews = json.bufferViews; + this.glbOffset = glbOffset; + this.rootUrl = rootUrl; + this.scenes = json.scenes; + this.cameras = json.cameras || []; + this.glbBin = glbBin; + this.meshes = []; } async parseData() { - (this.buffers = await this.loadBuffes()), - (this.images = await this.loadImages()), - this.parseSamplers(), - this.parseTextures(), - this.parseMaterials(), - this.parseAccessors(), - this.parseMeshs(), - this.parseNodes(), - this.normalizeData(), - this.parseScenes(), - this.parseAnimations(); - } - getAccessor(e) { - return this.accessors[e]; + this.buffers = await this.loadBuffes(); + this.images = await this.loadImages(); + this.parseSamplers(); + this.parseTextures(); + this.parseMaterials(); + this.parseAccessors(); + this.parseMeshs(); + this.parseNodes(); + this.normalizeData(); + this.parseScenes(); + this.parseAnimations(); + } + getAccessor(index) { + return this.accessors[index]; } parseSamplers() { - this.samplers = this.json.samplers ? this.json.samplers.map((e) => this.getSampler(e)) : []; + this.samplers = this.json.samplers ? this.json.samplers.map((sampler) => this.getSampler(sampler)) : []; } parseScenes() { - this.scenes = this.json.scenes.map((e) => { - const t = e?.nodes?.map((e) => this.nodes[e]); - return t; + this.scenes = this.json.scenes.map((scene) => { + const nodes = scene?.nodes?.map((nodeId) => { + return this.nodes[nodeId]; + }); + return nodes; }); } parseTextures() { this.textures = this.json.textures - ? this.json.textures.map((e) => ({ - sampler: void 0 !== e.sampler ? this.samplers[e.sampler] : this.getSampler({}), - texture: this.createTexture(e.source) - })) + ? this.json.textures.map((texture) => { + return { + sampler: texture.sampler !== undefined ? this.samplers[texture.sampler] : this.getSampler({}), + texture: this.createTexture(texture.source) + }; + }) : []; } parseMaterials() { this.materials = this.json.materials - ? this.json.materials.map((e) => { - const t = new Sr(), - { - baseColorFactor: i, - metallicFactor: r, - metallicRoughnessTexture: n, - baseColorTexture: s, - roughnessFactor: a - } = e.pbrMetallicRoughness; - return ( - e.normalTexture && (t.normalTexture = this.textures[e.normalTexture.index].texture), - e.occlusionTexture && (t.aoTexture = this.textures[e.occlusionTexture.index].texture), - e.emissiveTexture && (t.emissiveTexture = this.textures[e.emissiveTexture.index].texture), - s && (t.baseTexture = this.textures[s.index].texture), - n && (t.metalnessRoughnessTexture = this.textures[n.index].texture), - i && (t.color = new Qt(i[0], i[1], i[2])), - (t.metalness = r ?? 1), - (t.roughness = a ?? 0), - (t.baseSampler = new de({ - magFilter: "linear", - minFilter: "linear", - addressModeU: "repeat", - addressModeV: "repeat" - })), - t - ); + ? this.json.materials.map((material) => { + const mat = new PbrMaterial(); + const { + baseColorFactor, + metallicFactor, + metallicRoughnessTexture, + baseColorTexture, + roughnessFactor + } = material.pbrMetallicRoughness; + if (material.normalTexture) mat.normalTexture = this.textures[material.normalTexture.index].texture; + if (material.occlusionTexture) + mat.aoTexture = this.textures[material.occlusionTexture.index].texture; + if (material.emissiveTexture) + mat.emissiveTexture = this.textures[material.emissiveTexture.index].texture; + if (baseColorTexture) mat.baseTexture = this.textures[baseColorTexture.index].texture; + if (metallicRoughnessTexture) + mat.metalnessRoughnessTexture = this.textures[metallicRoughnessTexture.index].texture; + if (baseColorFactor) + mat.color = new Color(baseColorFactor[0], baseColorFactor[1], baseColorFactor[2]); + mat.metalness = metallicFactor ?? 1.0; + mat.roughness = roughnessFactor ?? 0.0; + mat.baseSampler = new Sampler({ + magFilter: "linear", + minFilter: "linear", + addressModeU: "repeat", + addressModeV: "repeat" + }); + return mat; }) : []; } parseAccessors() { - this.accessors = this.json.accessors.map((e, t) => { - const i = on[e.type]; - let r; - if ( - ((r = - void 0 === e.bufferView - ? an(e.componentType, new ArrayBuffer(i * e.count * on[e.componentType]), 0, e.count * i) - : this.getBufferView(e, i)), - e.sparse) - ) { - (e.sparse.indices.count = e.sparse.count), - (e.sparse.values.count = e.sparse.count), - (e.sparse.values.componentType = e.componentType); - const t = this.getBufferView(e.sparse.indices, 1), - n = this.getBufferView(e.sparse.values, i); - for (let s = 0; s < e.sparse.count; s += 1) - for (let e = 0; e < i; e += 1) r[t[s] * i + e] = n[s * i + e]; + this.accessors = this.json.accessors.map((accessor, index) => { + const n = gltfEnum[accessor.type]; + let array; + if (accessor.bufferView === undefined) { + array = newTypedArray( + accessor.componentType, + new ArrayBuffer(n * accessor.count * gltfEnum[accessor.componentType]), + 0, + accessor.count * n + ); + } else { + array = this.getBufferView(accessor, n); } - return new cn({ - componentType: on[e.componentType], - count: e.count, - type: i, - values: r, - id: t, - min: e?.min, - max: e?.max + if (accessor.sparse) { + accessor.sparse.indices.count = accessor.sparse.count; + accessor.sparse.values.count = accessor.sparse.count; + accessor.sparse.values.componentType = accessor.componentType; + const indices = this.getBufferView(accessor.sparse.indices, 1); + const values = this.getBufferView(accessor.sparse.values, n); + for (let i = 0; i < accessor.sparse.count; i += 1) { + for (let j = 0; j < n; j += 1) { + array[indices[i] * n + j] = values[i * n + j]; + } + } + } + return new Accessor({ + componentType: gltfEnum[accessor.componentType], + count: accessor.count, + type: n, + values: array, + id: index, + min: accessor?.min, + max: accessor?.max }); }); } parseAnimations() { - this.animations = this?.json?.animations?.map((e, t) => { - const i = e?.samplers?.map((e) => { - const t = new dn(); - return t.formGltf(this, e), t; - }), - r = e?.channels?.map((e) => { - const t = new hn(); - return (t.sampler = i[e.sampler]), (t.target = new un(this.nodes[e.target.node], e.target.path)), t; - }); - return new ln(t.toString(), i, r); + this.animations = this?.json?.animations?.map((gltfAnimation, index) => { + const samplers = gltfAnimation?.samplers?.map((gltfSampler) => { + const sampler = new AnimationSampler(); + sampler.formGltf(this, gltfSampler); + return sampler; + }); + const channels = gltfAnimation?.channels?.map((gltfChannel) => { + const animationChannel = new AnimationChannel(); + animationChannel.sampler = samplers[gltfChannel.sampler]; + animationChannel.target = new AnimationChannelTarget( + this.nodes[gltfChannel.target.node], + gltfChannel.target.path + ); + return animationChannel; + }); + const animation = new Animation(index.toString(), samplers, channels); + return animation; }); } parseMeshs() { - this.meshes = this?.json?.meshes?.map?.((e) => ({ - name: e.name, - primitives: e?.primitives?.map?.((t) => { - const i = void 0 !== t.material ? this.materials[t.material] : { pbrMetallicRoughness: {} }, - r = this.createGeometry(t, i), - n = new Qi(r, i); - return (n.name = e.name), n; - }) - })); - } - getSampler(e) { - return new de({ - magFilter: on[e.magFilter || 9729], - minFilter: on[e.minFilter || 9729], - addressModeU: on[e.wrapS || 10497], - addressModeV: on[e.wrapT || 10497] + this.meshes = this?.json?.meshes?.map?.((gltfmesh) => { + return { + name: gltfmesh.name, + primitives: gltfmesh?.primitives?.map?.((primitive) => { + const material = + primitive.material !== undefined + ? this.materials[primitive.material] + : { pbrMetallicRoughness: {} }; + const geo = this.createGeometry(primitive, material); + const mesh = new Mesh(geo, material); + mesh.name = gltfmesh.name; + return mesh; + }) + }; }); } - getBufferView(e, t) { - const i = this.bufferViews[e.bufferView], - r = (i.byteOffset || 0) + (e.byteOffset || 0), - n = Math.max(i.byteStride / 4 || 0, t); - let s = an( - e.componentType, - this.buffers[i.buffer], - 0 === i.buffer ? r + this.glbOffset : r, - (e.count - 1) * n + t - ); - if (n > t) { - const i = new (0, s.constructor)(e.count * t); - for (let e = 0, r = 0; e < i.length; e += t, r += n) for (let n = 0; n < t; n += 1) i[e + n] = s[r + n]; - s = i; - } - return s; - } - createGeometry(e, t) { - let i = null, - r = null; - const n = { HAS_NORMAL: !0 }; - let s; - r = this.getAccessor(e.attributes.POSITION); - const a = r.getArray(); - let o; - (s = r.count), - void 0 !== e.indices && - ((r = this.getAccessor(e.indices)), - (i = (function (e) { - if (e instanceof Uint16Array || e instanceof Uint32Array) return e; - let t; - return ( - (t = e instanceof Float32Array ? new Uint32Array(e.length) : new Uint16Array(e.length)), - e.forEach((e, i) => { - t[i] = e; - }), - t - ); - })(r.getArray())), - (s = r.count)), - void 0 !== e.attributes.NORMAL - ? ((r = this.getAccessor(e.attributes.NORMAL)), (o = r.getArray())) - : (o = (function (e, t) { - const i = new Float32Array(t.length), - r = e ? e.length : t.length; - for (let n = 0; n < r; n += 3) { - const r = []; - for (let t = 0; t < 3; t += 1) e ? r.push(e[n + t]) : r.push(n + t); - const s = r.map((e) => { - const i = 3 * e; - return new Ue(t[i], t[i + 1], t[i + 2]); - }), - a = new Ue(); - Ue.subtract(s[1], s[0], a); - const o = new Ue(); - Ue.subtract(s[2], s[0], o); - const c = new Ue(); - Ue.cross(a.normalize(), o.normalize(), c); - for (let e = 0; e < 3; e += 1) { - const t = 3 * (n + e); - (i[t + 0] += c.x), (i[t + 1] += c.y), (i[t + 2] += c.z); - } - } - return i; - })(i, a)); - let c = null; - void 0 !== e.attributes.TEXCOORD_0 && - ((r = this.getAccessor(e.attributes.TEXCOORD_0)), (c = r.getArray()), (n.HAS_UV = !0)), - void 0 !== e.attributes.TEXCOORD_1 && - ((r = this.getAccessor(e.attributes.TEXCOORD_1)), r.getArray(), (n.HAS_UV1 = !0)), - void 0 !== e.attributes.TANGENT && void 0 !== e.attributes.NORMAL - ? ((r = this.getAccessor(e.attributes.TANGENT)), r.getArray()) - : t.normalTexture; - let l = null, - h = 3; - void 0 !== e.attributes.COLOR_0 && - ((r = this.accessors[e.attributes.COLOR_0]), (l = r.getArray()), (h = r.type), (n.HAS_COLOR = !0)); - let u = null; - void 0 !== e.attributes.JOINTS_0 && - ((r = this.getAccessor(e.attributes.JOINTS_0)), (u = r.getArray()), (n.HAS_SKIN = !0)); - let f = null; - void 0 !== e.attributes.WEIGHTS_0 && ((r = this.getAccessor(e.attributes.WEIGHTS_0)), (f = r.getArray())); - const d = new At({ type: "pbrGeomtry" }); - return ( - i && d.setIndice(Array.from(i)), - a && d.setAttribute(new Ie("position", Array.from(a), 3)), - o && d.setAttribute(new Ie("normal", Array.from(o), 3)), - l && d.setAttribute(new Ie("color", Array.from(l), h)), - c && d.setAttribute(new Ie("uv", Array.from(c), 2)), - u && d.setAttribute(new Ie("joint0", Array.from(u), 4)), - f && d.setAttribute(new Ie("weight0", Array.from(f), 4)), - (d.defines = n), - d.computeBoundingSphere(Array.from(a)), - (d.count = s), - d - ); + getSampler(samplerJson) { + return new Sampler({ + magFilter: gltfEnum[samplerJson.magFilter || 9729], + minFilter: gltfEnum[samplerJson.minFilter || 9729], + addressModeU: gltfEnum[samplerJson.wrapS || 10497], + addressModeV: gltfEnum[samplerJson.wrapT || 10497] + }); } - createTexture(e) { - return new fe({ - size: { width: this.images[e].width, height: this.images[e].height, depth: 1 }, - data: { source: this.images[e] }, + getBufferView(accessor, n) { + const bufferView = this.bufferViews[accessor.bufferView]; + const offset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0); + const stride = Math.max(bufferView.byteStride / 4 || 0, n); + let array = newTypedArray( + accessor.componentType, + this.buffers[bufferView.buffer], + bufferView.buffer === 0 ? offset + this.glbOffset : offset, + (accessor.count - 1) * stride + n + ); + if (stride > n) { + const TypedArrayConstructor = array.constructor; + const strided = new TypedArrayConstructor(accessor.count * n); + for (let i = 0, j = 0; i < strided.length; i += n, j += stride) { + for (let k = 0; k < n; k += 1) { + strided[i + k] = array[j + k]; + } + } + array = strided; + } + return array; + } + createGeometry(primitive, material) { + let indices = null; + let accessor = null; + const defines = { HAS_NORMAL: true }; + let vertexCount; + accessor = this.getAccessor(primitive.attributes.POSITION); + const positions = accessor.getArray(); + vertexCount = accessor.count; + // const { max, min } = accessor; + // const boundingBox = { max, min }; + if (primitive.indices !== undefined) { + accessor = this.getAccessor(primitive.indices); + indices = toIndices(accessor.getArray()); + vertexCount = accessor.count; + } + let normals; + if (primitive.attributes.NORMAL !== undefined) { + accessor = this.getAccessor(primitive.attributes.NORMAL); + normals = accessor.getArray(); + } else { + normals = generateNormals(indices, positions); + } + let uvs = null; + if (primitive.attributes.TEXCOORD_0 !== undefined) { + accessor = this.getAccessor(primitive.attributes.TEXCOORD_0); + uvs = accessor.getArray(); + defines.HAS_UV = true; + } + if (primitive.attributes.TEXCOORD_1 !== undefined) { + accessor = this.getAccessor(primitive.attributes.TEXCOORD_1); + accessor.getArray(); + defines.HAS_UV1 = true; + } + if (primitive.attributes.TANGENT !== undefined && primitive.attributes.NORMAL !== undefined) { + accessor = this.getAccessor(primitive.attributes.TANGENT); + accessor.getArray(); + // defines.HAS_TANGENT = true; + } else if (material.normalTexture); + let colors = null, + colorSize = 3; + if (primitive.attributes.COLOR_0 !== undefined) { + accessor = this.accessors[primitive.attributes.COLOR_0]; + colors = accessor.getArray(); + colorSize = accessor.type; + defines.HAS_COLOR = true; + } + let joints = null; + if (primitive.attributes.JOINTS_0 !== undefined) { + accessor = this.getAccessor(primitive.attributes.JOINTS_0); + joints = accessor.getArray(); + defines.HAS_SKIN = true; + } + let weights = null; + if (primitive.attributes.WEIGHTS_0 !== undefined) { + accessor = this.getAccessor(primitive.attributes.WEIGHTS_0); + weights = accessor.getArray(); + } + const geo = new Geometry({ type: "pbrGeomtry" }); + if (indices) geo.setIndice(Array.from(indices)); + if (positions) geo.setAttribute(new Float32Attribute("position", Array.from(positions), 3)); + if (normals) geo.setAttribute(new Float32Attribute("normal", Array.from(normals), 3)); + if (colors) geo.setAttribute(new Float32Attribute("color", Array.from(colors), colorSize)); + if (uvs) geo.setAttribute(new Float32Attribute("uv", Array.from(uvs), 2)); + if (joints) geo.setAttribute(new Float32Attribute("joint0", Array.from(joints), 4)); + if (weights) geo.setAttribute(new Float32Attribute("weight0", Array.from(weights), 4)); + geo.defines = defines; + geo.computeBoundingSphere(Array.from(positions)); + geo.count = vertexCount; + return geo; + } + createTexture(source) { + return new Texture({ + size: { + width: this.images[source].width, + height: this.images[source].height, + depth: 1 + }, + data: { + source: this.images[source] + }, format: "rgba8unorm", usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT }); } async loadImages() { - const e = []; - let t = Promise.resolve(); - this.json.images && - (t = Promise.all( - this.json.images.map(async (t, i) => { - if (t.uri) { - const r = "data:" === t.uri.slice(0, 5) ? t.uri : `${this.rootUrl}/${t.uri}`; - e[i] = await fetch(r) - .then((e) => e.blob()) - .then((e) => createImageBitmap(e, { colorSpaceConversion: "none" })); + const images = []; + let loadExternalImages = Promise.resolve(); + if (this.json.images) { + loadExternalImages = Promise.all( + this.json.images.map(async (image, index) => { + if (image.uri) { + const imageUrl = image.uri.slice(0, 5) === "data:" ? image.uri : `${this.rootUrl}/${image.uri}`; + images[index] = await fetch(imageUrl) + .then((response) => response.blob()) + .then((blob) => + createImageBitmap(blob, { + colorSpaceConversion: "none" + }) + ); } }) - )); - let i = Promise.resolve(); - return ( - this.json.images && - (i = Promise.all( - this.json.images.map(async (t, i) => { - if (void 0 !== t.bufferView) { - const { buffer: r, byteOffset: n, byteLength: s } = this.json.bufferViews[t.bufferView], - a = new Uint8Array(this.buffers[r], 0 === r ? n + this.glbOffset : n, s); - let o; - o = t.mimeType ? t.mimeType : 255 === a[0] ? "image/jpeg" : "image/png"; - const c = new Blob([a], { type: o }); - e[i] = await createImageBitmap(c, { colorSpaceConversion: "none" }); + ); + } + let loadInternalImages = Promise.resolve(); + if (this.json.images) { + loadInternalImages = Promise.all( + this.json.images.map(async (image, index) => { + if (image.bufferView !== undefined) { + const { buffer, byteOffset, byteLength } = this.json.bufferViews[image.bufferView]; + const array = new Uint8Array( + this.buffers[buffer], + buffer === 0 ? byteOffset + this.glbOffset : byteOffset, + byteLength + ); + let type; + if (image.mimeType) { + type = image.mimeType; + } else { + type = array[0] === 0xff ? "image/jpeg" : "image/png"; } - }) - )), - await Promise.all([t, i]), - e - ); + const blob = new Blob([array], { type }); + images[index] = await createImageBitmap(blob, { + colorSpaceConversion: "none" + }); + } + }) + ); + } + await Promise.all([loadExternalImages, loadInternalImages]); + return images; } async loadBuffes() { - const e = []; - return ( - await Promise.all( - this.json.buffers.map((t, i) => { - if (!t.uri) { - if (0 !== i) throw new Error("buffer uri undefined"); - return (e[i] = this.glbBin), Promise.resolve(); + const buffers = []; + await Promise.all( + this.json.buffers.map((buffer, index) => { + if (!buffer.uri) { + if (index !== 0) { + throw new Error("buffer uri undefined"); } - const r = "data:" === t.uri.slice(0, 5) ? t.uri : `${this.rootUrl}/${t.uri}`; - return fetch(r) - .then((e) => e.arrayBuffer()) - .then((t) => { - e[i] = t; - }); - }) - ), - e + buffers[index] = this.glbBin; + return Promise.resolve(); + } + const bufferUrl = buffer.uri.slice(0, 5) === "data:" ? buffer.uri : `${this.rootUrl}/${buffer.uri}`; + return fetch(bufferUrl) + .then((response) => response.arrayBuffer()) + .then((arrayBuffer) => { + buffers[index] = arrayBuffer; + }); + }) ); + return buffers; } parseNodes() { - this.nodes = this?.json?.nodes?.map((e) => { - const t = new nn(); - if ((this.parseNodeTRS(t, e), e.name && (t.name = e.name), null != e.mesh)) { - let i, - r = !1; - null != e.skin && ((i = this.json.skins[e.skin]), (r = !0)), - this.meshes[e.mesh].primitives.forEach((e, n, s) => { - const a = r && e.type == Z.Mesh ? new sn(e.geometry, e.material) : e; - r && - e.type == Z.Mesh && - ((s[n] = a), - a.setSkinData({ - inverseBindMatrices: this.getAccessor(i.inverseBindMatrices).getMat4Array(), - joints: i.joints - })), - t.add(a); - }); + this.nodes = this?.json?.nodes?.map((gltfNode) => { + const node = new Node(); + this.parseNodeTRS(node, gltfNode); + if (gltfNode.name) node.name = gltfNode.name; + if (gltfNode.mesh != undefined) { + let gltfSkin = undefined, + isSkinMesh = false; + if (gltfNode.skin != undefined) { + gltfSkin = this.json.skins[gltfNode.skin]; + isSkinMesh = true; + } + this.meshes[gltfNode.mesh].primitives.forEach((primitive, index, source) => { + const tempPrimitive = + isSkinMesh && primitive.type == RenderObjectType.Mesh + ? new SKinMesh(primitive.geometry, primitive.material) + : primitive; + if (isSkinMesh && primitive.type == RenderObjectType.Mesh) { + source[index] = tempPrimitive; + tempPrimitive.setSkinData({ + inverseBindMatrices: this.getAccessor(gltfSkin.inverseBindMatrices).getMat4Array(), + joints: gltfSkin.joints + // name: gltfSkin.name, + // skeleton: gltfSkin.skeleton + }); + } + node.add(tempPrimitive); + }); } - return t; + return node; }); } - parseNodeTRS(e, t) { - let { matrix: i, rotation: r, translation: n, scale: s } = t; - if (i) { - const e = new et(), - t = new Ue(), - a = new Ue(), - o = new zt(); - et.fromColumnMajorArray(i, e), - et.getScale(e, t), - et.getTranslation(e, a), - et.getRotation(e, o), - (r = o.toArray()), - (n = a.toArray()), - (s = t.toArray()); + parseNodeTRS(node, gltfNode) { + let { matrix, rotation, translation, scale } = gltfNode; + if (matrix) { + const tempMatrix4 = new Matrix4(), + tempScale = new Vector3(), + tempTranslation = new Vector3(), + tempRotation = new Quaternion(); + Matrix4.fromColumnMajorArray(matrix, tempMatrix4); + Matrix4.getScale(tempMatrix4, tempScale); + Matrix4.getTranslation(tempMatrix4, tempTranslation); + Matrix4.getRotation(tempMatrix4, tempRotation); + rotation = tempRotation.toArray(); + translation = tempTranslation.toArray(); + scale = tempScale.toArray(); } - return ( - r && e.quaternion.set(r[0], r[1], r[2], r[3]), - n && e.position.set(n[0], n[1], n[2]), - s && e.scale.set(s[0], s[1], s[2]), - e - ); + if (rotation) node.quaternion.set(rotation[0], rotation[1], rotation[2], rotation[3]); + if (translation) node.position.set(translation[0], translation[1], translation[2]); + if (scale) node.scale.set(scale[0], scale[1], scale[2]); + return node; } normalizeData() { - this?.nodes?.map?.((e, t) => { - this.json?.nodes[t]?.children?.map((t) => { - const i = this.nodes[t]; - e.add(i); + this?.nodes?.map?.((node, index) => { + this.json?.nodes[index]?.children?.map((nodeId) => { + const childNode = this.nodes[nodeId]; + node.add(childNode); }); - }), - this.meshes.map((e) => { - e.primitives.map((e) => { - e.type == Z.SkinMesh && (e.joints = e.joints.map((e) => this.nodes[e])); - }); + }); + this.meshes.map((mesh) => { + mesh.primitives.map((primitive) => { + if (primitive.type == RenderObjectType.SkinMesh) + primitive.joints = primitive.joints.map((joint) => { + return this.nodes[joint]; + }); }); + }); } } -async function pn(e) { - let t; - const i = e.split(".").pop(), - r = e.substring(0, e.lastIndexOf("/")); - if ("gltf" === i) { - const i = await fetch(e).then((e) => e.json()); - t = new mn(i, r, 0); +async function loadGLTF(url) { + let gltf; + const ext = url.split(".").pop(); + const rootUrl = url.substring(0, url.lastIndexOf("/")); + if (ext === "gltf") { + const json = await fetch(url).then((response) => response.json()); + gltf = new GLTF(json, rootUrl, 0); } else { - const i = await fetch(e).then((e) => e.arrayBuffer()), - n = new Uint32Array(i, 12, 1)[0], - s = new Uint8Array(i, 20, n), - a = JSON.parse(new TextDecoder("utf-8").decode(s)); - t = new mn(a, r, 28 + n, i); - } - return await t.parseData(), t; + const glb = await fetch(url).then((response) => response.arrayBuffer()); + const jsonLength = new Uint32Array(glb, 12, 1)[0]; + const jsonChunk = new Uint8Array(glb, 20, jsonLength); + const json = JSON.parse(new TextDecoder("utf-8").decode(jsonChunk)); + gltf = new GLTF(json, rootUrl, 28 + jsonLength, glb); + } + await gltf.parseData(); + return gltf; } -async function gn(e) { - const t = document.createElement("img"); - (t.src = e), await t.decode(); - const i = await createImageBitmap(t); - return new fe({ size: { width: i.width, height: i.height, depth: 1 }, data: { source: i }, format: "rgba8unorm" }); + +async function loadTexture(url) { + const img = document.createElement("img"); + img.src = url; + await img.decode(); + const imageBitmap = await createImageBitmap(img); + const baseTexture = new Texture({ + size: { width: imageBitmap.width, height: imageBitmap.height, depth: 1 }, + data: { + source: imageBitmap + }, + format: "rgba8unorm" + }); + return baseTexture; } -class xn { - constructor(e = 1, t = 0, i = 0) { - return (this.radius = e), (this.phi = t), (this.theta = i), this; + +// from three.js +class Spherical { + constructor(radius = 1, phi = 0, theta = 0) { + this.radius = radius; + this.phi = phi; // polar angle + this.theta = theta; // azimuthal angle + return this; } - set(e, t, i) { - return (this.radius = e), (this.phi = t), (this.theta = i), this; + set(radius, phi, theta) { + this.radius = radius; + this.phi = phi; + this.theta = theta; + return this; } - copy(e) { - return (this.radius = e.radius), (this.phi = e.phi), (this.theta = e.theta), this; + copy(other) { + this.radius = other.radius; + this.phi = other.phi; + this.theta = other.theta; + return this; } + // restrict phi to be between EPS and PI-EPS makeSafe() { - const e = 1e-6; - return (this.phi = Math.max(e, Math.min(Math.PI - e, this.phi))), this; + const EPS = 0.000001; + this.phi = Math.max(EPS, Math.min(Math.PI - EPS, this.phi)); + return this; } - setFromVector3(e) { - return this.setFromCartesianCoords(e.x, e.y, e.z); + setFromVector3(v) { + return this.setFromCartesianCoords(v.x, v.y, v.z); } - setFromCartesianCoords(e, t, i) { - return ( - (this.radius = Math.sqrt(e * e + t * t + i * i)), - 0 === this.radius - ? ((this.theta = 0), (this.phi = 0)) - : ((this.theta = Math.atan2(e, i)), (this.phi = Math.acos(ve.clamp(t / this.radius, -1, 1)))), - this - ); + setFromCartesianCoords(x, y, z) { + this.radius = Math.sqrt(x * x + y * y + z * z); + if (this.radius === 0) { + this.theta = 0; + this.phi = 0; + } else { + this.theta = Math.atan2(x, z); + this.phi = Math.acos(GMath.clamp(y / this.radius, -1, 1)); + } + return this; } clone() { - return new xn(this.radius, this.phi, this.theta); - } -} -const vn = { type: "change" }, - yn = { type: "start" }, - Sn = { type: "end" }; -class bn extends br { - constructor(e, t) { - super(), - void 0 === t && console.warn('OrbitControls: The second parameter "domElement" is now mandatory.'), - t === document && - console.error( - 'OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.' - ), - (this.object = e), - (this.domElement = t), - (this.domElement.style.touchAction = "none"), - (this.enabled = !0), - (this.target = new Ue()), - (this.minDistance = 0), - (this.maxDistance = 1 / 0), - (this.minZoom = 0), - (this.maxZoom = 1 / 0), - (this.minPolarAngle = 0), - (this.maxPolarAngle = Math.PI), - (this.minAzimuthAngle = -1 / 0), - (this.maxAzimuthAngle = 1 / 0), - (this.enableDamping = !1), - (this.dampingFactor = 0.05), - (this.enableZoom = !0), - (this.zoomSpeed = 1), - (this.enableRotate = !0), - (this.rotateSpeed = 1), - (this.enablePan = !0), - (this.panSpeed = 1), - (this.screenSpacePanning = !1), - (this.keyPanSpeed = 7), - (this.autoRotate = !1), - (this.autoRotateSpeed = 2), - (this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" }), - (this.mouseButtons = { LEFT: $n.ROTATE, MIDDLE: $n.DOLLY, RIGHT: $n.PAN }), - (this.touches = { ONE: Gn.ROTATE, TWO: Gn.DOLLY_PAN }), - (this.target0 = this.target.clone()), - (this.position0 = this.object.position.clone()), - (this.zoom0 = this.object.zoom), - (this._domElementKeyEvents = null); - const i = this; - (this.update = (function () { - const e = new Ue(), - t = new zt().setFromUnitVectors(i.object.up, new Ue(0, 1, 0)), - r = t.clone().invert(), - n = new Ue(), - s = new zt(), - a = 2 * Math.PI; - return function () { - const o = i.object.position; - e.copy(o).subtract(i.target), - e.applyQuaternion(t), - Mn.setFromVector3(e), - i.autoRotate && Tn === wn.NONE && kn(i.getAutoRotationAngle()), - i.enableDamping - ? ((Mn.theta += Un.theta * i.dampingFactor), (Mn.phi += Un.phi * i.dampingFactor)) - : ((Mn.theta += Un.theta), (Mn.phi += Un.phi)); - let c = i.minAzimuthAngle, - l = i.maxAzimuthAngle; - return ( - isFinite(c) && - isFinite(l) && - (c < -Math.PI ? (c += a) : c > Math.PI && (c -= a), - l < -Math.PI ? (l += a) : l > Math.PI && (l -= a), - (Mn.theta = - c <= l - ? Math.max(c, Math.min(l, Mn.theta)) - : Mn.theta > (c + l) / 2 - ? Math.max(c, Mn.theta) - : Math.min(l, Mn.theta))), - (Mn.phi = Math.max(i.minPolarAngle, Math.min(i.maxPolarAngle, Mn.phi))), - Mn.makeSafe(), - (Mn.radius *= _n), - (Mn.radius = Math.max(i.minDistance, Math.min(i.maxDistance, Mn.radius))), - !0 === i.enableDamping ? i.target.addScaledVector(Ln, i.dampingFactor) : i.target.add(Ln), - Ue.fromSpherical(Mn, e), - e.applyQuaternion(r), - o.copy(i.target).add(e), - i.object.lookAt(i.target.x, i.target.y, i.target.z), - !0 === i.enableDamping - ? ((Un.theta *= 1 - i.dampingFactor), - (Un.phi *= 1 - i.dampingFactor), - Ue.multiplyByScalar(Ln, 1 - i.dampingFactor, Ln)) - : (Un.set(0, 0, 0), Ln.set(0, 0, 0)), - (_n = 1), - !!( - Cn || - Ue.distanceSquared(n, i.object.position) > En || - 8 * (1 - s.dot(i.object.quaternion)) > En - ) && - (i.dispatchEvent(vn), - Ue.clone(i.object.position, n), - zt.clone(i.object.quaternion, s), - (Cn = !1), - !0) - ); + return new Spherical(this.radius, this.phi, this.theta); + } +} + +//from three.js +const _changeEvent = { type: "change" }; +const _startEvent = { type: "start" }; +const _endEvent = { type: "end" }; +class OrbitControl extends EventDispatcher { + constructor(object, domElement) { + super(); + if (domElement === undefined) + console.warn('OrbitControls: The second parameter "domElement" is now mandatory.'); + if (domElement === document) + console.error( + 'OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.' + ); + this.object = object; + this.domElement = domElement; + this.domElement.style.touchAction = "none"; // disable touch scroll + // Set to false to disable this control + this.enabled = true; + // "target" sets the location of focus, where the object orbits around + this.target = new Vector3(); + // How far you can dolly in and out ( PerspectiveCamera only ) + this.minDistance = 0; + this.maxDistance = Infinity; + // How far you can zoom in and out ( OrthographicCamera only ) + this.minZoom = 0; + this.maxZoom = Infinity; + // How far you can orbit vertically, upper and lower limits. + // Range is 0 to Math.PI radians. + this.minPolarAngle = 0; // radians + this.maxPolarAngle = Math.PI; // radians + // How far you can orbit horizontally, upper and lower limits. + // If set, the interval [ min, max ] must be a sub-interval of [ - 2 PI, 2 PI ], with ( max - min < 2 PI ) + this.minAzimuthAngle = -Infinity; // radians + this.maxAzimuthAngle = Infinity; // radians + // Set to true to enable damping (inertia) + // If damping is enabled, you must call controls.update() in your animation loop + this.enableDamping = false; + this.dampingFactor = 0.05; + // This option actually enables dollying in and out; left as "zoom" for backwards compatibility. + // Set to false to disable zooming + this.enableZoom = true; + this.zoomSpeed = 1.0; + // Set to false to disable rotating + this.enableRotate = true; + this.rotateSpeed = 1.0; + // Set to false to disable panning + this.enablePan = true; + this.panSpeed = 1.0; + this.screenSpacePanning = false; // if false, pan orthogonal to world-space direction camera.up + this.keyPanSpeed = 7.0; // pixels moved per arrow key push + // Set to true to automatically rotate around the target + // If auto-rotate is enabled, you must call controls.update() in your animation loop + this.autoRotate = false; + this.autoRotateSpeed = 2.0; // 30 seconds per orbit when fps is 60 + // The four arrow keys + this.keys = { + LEFT: "ArrowLeft", + UP: "ArrowUp", + RIGHT: "ArrowRight", + BOTTOM: "ArrowDown" + }; + // Mouse buttons + this.mouseButtons = { + LEFT: MOUSE.ROTATE, + MIDDLE: MOUSE.DOLLY, + RIGHT: MOUSE.PAN + }; + // Touch fingers + this.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN }; + // for reset + this.target0 = this.target.clone(); + this.position0 = this.object.position.clone(); + this.zoom0 = this.object.zoom; + // the target DOM element for key events + this._domElementKeyEvents = null; + // + // public methods + // + // this method is exposed, but perhaps it would be better if we can make it private... + const that = this; + this.update = (function () { + const offset = new Vector3(); + // so camera.up is the orbit axis + const quat = new Quaternion().setFromUnitVectors(that.object.up, new Vector3(0, 1, 0)); + const quatInverse = quat.clone().invert(); + const lastPosition = new Vector3(); + const lastQuaternion = new Quaternion(); + const twoPI = 2 * Math.PI; + return function update() { + const position = that.object.position; + offset.copy(position).subtract(that.target); + // rotate offset to "y-axis-is-up" space + offset.applyQuaternion(quat); + // angle from z-axis around y-axis + spherical.setFromVector3(offset); + if (that.autoRotate && state === STATE.NONE) { + rotateLeft(that.getAutoRotationAngle()); + } + if (that.enableDamping) { + spherical.theta += sphericalDelta.theta * that.dampingFactor; + spherical.phi += sphericalDelta.phi * that.dampingFactor; + } else { + spherical.theta += sphericalDelta.theta; + spherical.phi += sphericalDelta.phi; + } + // restrict theta to be between desired limits + let min = that.minAzimuthAngle; + let max = that.maxAzimuthAngle; + if (isFinite(min) && isFinite(max)) { + if (min < -Math.PI) min += twoPI; + else if (min > Math.PI) min -= twoPI; + if (max < -Math.PI) max += twoPI; + else if (max > Math.PI) max -= twoPI; + if (min <= max) { + spherical.theta = Math.max(min, Math.min(max, spherical.theta)); + } else { + spherical.theta = + spherical.theta > (min + max) / 2 + ? Math.max(min, spherical.theta) + : Math.min(max, spherical.theta); + } + } + // restrict phi to be between desired limits + spherical.phi = Math.max(that.minPolarAngle, Math.min(that.maxPolarAngle, spherical.phi)); + spherical.makeSafe(); + spherical.radius *= scale; + // restrict radius to be between desired limits + spherical.radius = Math.max(that.minDistance, Math.min(that.maxDistance, spherical.radius)); + // move target to panned location + if (that.enableDamping === true) { + that.target.addScaledVector(panOffset, that.dampingFactor); + } else { + that.target.add(panOffset); + } + Vector3.fromSpherical(spherical, offset); + // rotate offset back to "camera-up-vector-is-up" space + offset.applyQuaternion(quatInverse); + position.copy(that.target).add(offset); + that.object.lookAt(that.target.x, that.target.y, that.target.z); + if (that.enableDamping === true) { + sphericalDelta.theta *= 1 - that.dampingFactor; + sphericalDelta.phi *= 1 - that.dampingFactor; + Vector3.multiplyByScalar(panOffset, 1 - that.dampingFactor, panOffset); + // panOffset.multiplyScalar( 1 - this.dampingFactor ); + } else { + sphericalDelta.set(0, 0, 0); + panOffset.set(0, 0, 0); + } + scale = 1; + // update condition is: + // min(camera displacement, camera rotation in radians)^2 > EPS + // using small-angle approximation cos(x/2) = 1 - x^2 / 8 + if ( + zoomChanged || + Vector3.distanceSquared(lastPosition, that.object.position) > EPS || + 8 * (1 - lastQuaternion.dot(that.object.quaternion)) > EPS + ) { + that.dispatchEvent(_changeEvent); + //lastPosition.copy( this.object.position ); + Vector3.clone(that.object.position, lastPosition); + Quaternion.clone(that.object.quaternion, lastQuaternion); + //lastQuaternion.copy( this.object.quaternion ); + zoomChanged = false; + return true; + } + return false; }; - })()), - this.init(); + })(); + this.init(); } getPolarAngle() { return this.spherical.phi; @@ -11916,350 +15986,453 @@ class bn extends br { return this.spherical.theta; } getDistance() { - return Ue.distance(this.object.position, this.target); + return Vector3.distance(this.object.position, this.target); } - listenToKeyEvents(e) { - e.addEventListener("keydown", this.onKeyDown), (this._domElementKeyEvents = e); + listenToKeyEvents(domElement) { + domElement.addEventListener("keydown", this.onKeyDown); + this._domElementKeyEvents = domElement; } saveState() { - Ue.clone(this.target, this.target0), - Ue.clone(this.object.position, this.position0), - (this.zoom0 = this.object.zoom); + Vector3.clone(this.target, this.target0); + //this.target0.copy( this.target ); + Vector3.clone(this.object.position, this.position0); + //this.position0.copy( this.object.position ); + this.zoom0 = this.object.zoom; } reset() { - Ue.clone(this.target0, this.target), - Ue.clone(this.position0, this.object.position), - (this.object.zoom = this.zoom0), - this.object.updateProjectionMatrix(), - this.dispatchEvent(vn), - this.update(), - (Tn = wn.NONE); + Vector3.clone(this.target0, this.target); + //this.target.copy( this.target0 ); + Vector3.clone(this.position0, this.object.position); + //this.object.position.copy( this.position0 ); + this.object.zoom = this.zoom0; + this.object.updateProjectionMatrix(); + this.dispatchEvent(_changeEvent); + this.update(); + state = STATE.NONE; } init() { - const e = this, - t = (function () { - const e = new Ue(); - return function (t, i) { - e.setFromMatrixColumn(i, 0), e.multiplyByScalar(-t), Ln.add(e); - }; - })(), - i = (function () { - const t = new Ue(); - return function (i, r) { - !0 === e.screenSpacePanning - ? t.setFromMatrixColumn(r, 1) - : (t.setFromMatrixColumn(r, 0), Ue.cross(e.object.up, t, t)), - t.multiplyByScalar(i), - Ln.add(t); - }; - })(), - r = (function () { - const r = new Ue(); - return function (n, s) { - const a = e.domElement; - if (e.object.isPerspectiveCamera) { - const o = e.object.position; - r.copy(o).subtract(e.target); - let c = r.length(); - (c *= Math.tan(((e.object.fov / 2) * Math.PI) / 180)), - t((2 * n * c) / a.clientHeight, e.object.modelMatrix), - i((2 * s * c) / a.clientHeight, e.object.modelMatrix); - } else - e.object.isOrthographicCamera - ? (t( - (n * (e.object.right - e.object.left)) / e.object.zoom / a.clientWidth, - e.object.modelMatrix - ), - i( - (s * (e.object.top - e.object.bottom)) / e.object.zoom / a.clientHeight, - e.object.modelMatrix - )) - : (console.warn( - "WARNING: OrbitControls.js encountered an unknown camera type - pan disabled." - ), - (e.enablePan = !1)); - }; - })(), - n = (e) => { - this.object.isPerspectiveCamera - ? (_n /= e) - : this.object.isOrthographicCamera - ? ((this.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom * e))), - this.object.updateProjectionMatrix(), - (Cn = !0)) - : (console.warn( - "WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled." - ), - (this.enableZoom = !1)); - }, - s = (e) => { - this.object.isPerspectiveCamera - ? (_n *= e) - : this.object.isOrthographicCamera - ? ((this.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom / e))), - this.object.updateProjectionMatrix(), - (Cn = !0)) - : (console.warn( - "WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled." - ), - (this.enableZoom = !1)); - }, - a = (e) => { - An.set(e.clientX, e.clientY), Se.subtract(An, Rn, Dn), Se.multiplyByScalar(Dn, this.rotateSpeed, Dn); - const t = this.domElement; - kn((2 * Math.PI * Dn.x) / t.clientHeight), - qn((2 * Math.PI * Dn.y) / t.clientHeight), - Se.clone(An, Rn), - this.update(); - }, - o = (e) => { - Bn.set(e.clientX, e.clientY), - Se.subtract(Bn, Nn, On), - On.y > 0 ? n(w()) : On.y < 0 && s(w()), - Se.clone(Bn, Nn), - this.update(); - }, - c = (e) => { - In.set(e.clientX, e.clientY), - Se.subtract(In, zn, Pn), - Se.multiplyByScalar(Pn, this.panSpeed, Pn), - r(Pn.x, Pn.y), - Se.clone(In, zn), - this.update(); - }, - l = (e) => { - e.deltaY < 0 ? s(w()) : e.deltaY > 0 && n(w()), this.update(); - }, - h = (e) => { - let t = !1; - switch (e.code) { - case this.keys.UP: - r(0, this.keyPanSpeed), (t = !0); - break; - case this.keys.BOTTOM: - r(0, -this.keyPanSpeed), (t = !0); - break; - case this.keys.LEFT: - r(this.keyPanSpeed, 0), (t = !0); - break; - case this.keys.RIGHT: - r(-this.keyPanSpeed, 0), (t = !0); - } - t && (e.preventDefault(), this.update()); - }, - u = () => { - this.enableZoom && Jn(), this.enablePan && Qn(); - }, - f = () => { - this.enableZoom && Jn(), this.enableRotate && Kn(); - }, - d = (e) => { - if (1 == Vn.length) An.set(e.pageX, e.pageY); - else { - const t = Xn(e), - i = 0.5 * (e.pageX + t.x), - r = 0.5 * (e.pageY + t.y); - An.set(i, r); - } - Se.subtract(An, Rn, Dn), Se.multiplyByScalar(Dn, this.rotateSpeed, Dn); - const t = this.domElement; - kn((2 * Math.PI * Dn.x) / t.clientHeight), qn((2 * Math.PI * Dn.y) / t.clientHeight), Se.clone(An, Rn); - }, - m = (e) => { - if (1 === Vn.length) In.set(e.pageX, e.pageY); - else { - const t = Xn(e), - i = 0.5 * (e.pageX + t.x), - r = 0.5 * (e.pageY + t.y); - In.set(i, r); - } - Se.subtract(In, zn, Pn), Se.multiplyByScalar(Pn, this.panSpeed, Pn), r(Pn.x, Pn.y), Se.clone(In, zn); - }, - p = (e) => { - const t = Xn(e), - i = e.pageX - t.x, - r = e.pageY - t.y, - s = Math.sqrt(i * i + r * r); - Bn.set(0, s), On.set(0, Math.pow(Bn.y / Nn.y, this.zoomSpeed)), n(On.y), Se.clone(Bn, Nn); - }, - g = (e) => { - this.enableZoom && p(e), this.enablePan && m(e); - }, - x = (e) => { - this.enableZoom && p(e), this.enableRotate && d(e); + const that = this; + const panLeft = (function () { + const v = new Vector3(); + return function panLeft(distance, objectMatrix) { + v.setFromMatrixColumn(objectMatrix, 0); // get X column of objectMatrix + v.multiplyByScalar(-distance); + panOffset.add(v); }; - (this.onPointerDown = (e) => { - !1 !== this.enabled && - (0 === Vn.length && - (this.domElement.setPointerCapture(e.pointerId), - this.domElement.addEventListener("pointermove", this.onPointerMove), - this.domElement.addEventListener("pointerup", this.onPointerUp)), - (function (e) { - Vn.push(e); - })(e), - "touch" === e.pointerType ? S(e) : v(e)); - }), - (this.onPointerMove = (e) => { - !1 !== this.enabled && ("touch" === e.pointerType ? b(e) : y(e)); - }), - (this.onPointerUp = (e) => { - jn(e), - 0 === Vn.length && - (this.domElement.releasePointerCapture(e.pointerId), - this.domElement.removeEventListener("pointermove", this.onPointerMove), - this.domElement.removeEventListener("pointerup", this.onPointerUp)), - this.dispatchEvent(Sn), - (Tn = wn.NONE); - }); - const v = (e) => { - let t; - switch (e.button) { - case 0: - t = this.mouseButtons.LEFT; - break; - case 1: - t = this.mouseButtons.MIDDLE; - break; - case 2: - t = this.mouseButtons.RIGHT; - break; - default: - t = -1; - } - switch (t) { - case $n.DOLLY: - if (!1 === this.enableZoom) return; - !(function (e) { - Nn.set(e.clientX, e.clientY); - })(e), - (Tn = wn.DOLLY); - break; - case $n.ROTATE: - if (e.ctrlKey || e.metaKey || e.shiftKey) { - if (!1 === this.enablePan) return; - Wn(e), (Tn = wn.PAN); - } else { - if (!1 === this.enableRotate) return; - Yn(e), (Tn = wn.ROTATE); - } - break; - case $n.PAN: - if (e.ctrlKey || e.metaKey || e.shiftKey) { - if (!1 === this.enableRotate) return; - Yn(e), (Tn = wn.ROTATE); - } else { - if (!1 === this.enablePan) return; - Wn(e), (Tn = wn.PAN); - } - break; - default: - Tn = wn.NONE; - } - Tn !== wn.NONE && this.dispatchEvent(yn); - }, - y = (e) => { - switch (Tn) { - case wn.ROTATE: - if (!1 === this.enableRotate) return; - a(e); - break; - case wn.DOLLY: - if (!1 === this.enableZoom) return; - o(e); - break; - case wn.PAN: - if (!1 === this.enablePan) return; - c(e); + })(); + const panUp = (function () { + const panUpV = new Vector3(); + return function panUp(distance, objectMatrix) { + if (that.screenSpacePanning === true) { + panUpV.setFromMatrixColumn(objectMatrix, 1); + } else { + panUpV.setFromMatrixColumn(objectMatrix, 0); + //panUpV.crossVectors( this.object.up, panUpV ); + Vector3.cross(that.object.up, panUpV, panUpV); } + panUpV.multiplyByScalar(distance); + panOffset.add(panUpV); }; - (this.onMouseWheel = (e) => { - !1 !== this.enabled && - !1 !== this.enableZoom && - Tn === wn.NONE && - (e.preventDefault(), this.dispatchEvent(yn), l(e), this.dispatchEvent(Sn)); - }), - (this.onKeyDown = (e) => { - !1 !== this.enabled && !1 !== this.enablePan && h(e); - }); - const S = (e) => { - switch ((Hn(e), Vn.length)) { - case 1: - switch (this.touches.ONE) { - case Gn.ROTATE: - if (!1 === this.enableRotate) return; - Kn(), (Tn = wn.TOUCH_ROTATE); - break; - case Gn.PAN: - if (!1 === this.enablePan) return; - Qn(), (Tn = wn.TOUCH_PAN); - break; - default: - Tn = wn.NONE; - } - break; - case 2: - switch (this.touches.TWO) { - case Gn.DOLLY_PAN: - if (!1 === this.enableZoom && !1 === this.enablePan) return; - u(), (Tn = wn.TOUCH_DOLLY_PAN); - break; - case Gn.DOLLY_ROTATE: - if (!1 === this.enableZoom && !1 === this.enableRotate) return; - f(), (Tn = wn.TOUCH_DOLLY_ROTATE); - break; - default: - Tn = wn.NONE; - } - break; - default: - Tn = wn.NONE; - } - Tn !== wn.NONE && this.dispatchEvent(yn); - }, - b = (e) => { - switch ((Hn(e), Tn)) { - case wn.TOUCH_ROTATE: - if (!1 === this.enableRotate) return; - d(e), this.update(); - break; - case wn.TOUCH_PAN: - if (!1 === this.enablePan) return; - m(e), this.update(); - break; - case wn.TOUCH_DOLLY_PAN: - if (!1 === this.enableZoom && !1 === this.enablePan) return; - g(e), this.update(); - break; - case wn.TOUCH_DOLLY_ROTATE: - if (!1 === this.enableZoom && !1 === this.enableRotate) return; - x(e), this.update(); - break; - default: - Tn = wn.NONE; + })(); + // deltaX and deltaY are in pixels; right and down are positive + const pan = (function () { + const offset = new Vector3(); + return function pan(deltaX, deltaY) { + const element = that.domElement; + if (that.object.isPerspectiveCamera) { + // perspective + const position = that.object.position; + offset.copy(position).subtract(that.target); + let targetDistance = offset.length(); + // half of the fov is center to top of screen + targetDistance *= Math.tan(((that.object.fov / 2) * Math.PI) / 180.0); + // we use only clientHeight here so aspect ratio does not distort speed + panLeft((2 * deltaX * targetDistance) / element.clientHeight, that.object.modelMatrix); + panUp((2 * deltaY * targetDistance) / element.clientHeight, that.object.modelMatrix); + } else if (that.object.isOrthographicCamera) { + // orthographic + panLeft( + (deltaX * (that.object.right - that.object.left)) / that.object.zoom / element.clientWidth, + that.object.modelMatrix + ); + panUp( + (deltaY * (that.object.top - that.object.bottom)) / that.object.zoom / element.clientHeight, + that.object.modelMatrix + ); + } else { + // camera neither orthographic nor perspective + console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."); + that.enablePan = false; } }; - (this.onContextMenu = (e) => { - !1 !== this.enabled && e.preventDefault(); - }), - (this.getAutoRotationAngle = () => ((2 * Math.PI) / 60 / 60) * this.autoRotateSpeed); - const w = () => Math.pow(0.95, this.zoomSpeed); - this.domElement.addEventListener("contextmenu", this.onContextMenu), - this.domElement.addEventListener("pointerdown", this.onPointerDown), - this.domElement.addEventListener("pointercancel", Zn), - this.domElement.addEventListener("wheel", this.onMouseWheel, { passive: !1 }); + })(); + const dollyOut = (dollyScale) => { + if (this.object.isPerspectiveCamera) { + scale /= dollyScale; + } else if (this.object.isOrthographicCamera) { + this.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom * dollyScale)); + this.object.updateProjectionMatrix(); + zoomChanged = true; + } else { + console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."); + this.enableZoom = false; + } + }; + const dollyIn = (dollyScale) => { + if (this.object.isPerspectiveCamera) { + scale *= dollyScale; + } else if (this.object.isOrthographicCamera) { + this.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom / dollyScale)); + this.object.updateProjectionMatrix(); + zoomChanged = true; + } else { + console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."); + this.enableZoom = false; + } + }; + const handleMouseMoveRotate = (event) => { + rotateEnd.set(event.clientX, event.clientY); + Vector2.subtract(rotateEnd, rotateStart, rotateDelta); + Vector2.multiplyByScalar(rotateDelta, this.rotateSpeed, rotateDelta); + //rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( this.rotateSpeed ); + const element = this.domElement; + rotateLeft((2 * Math.PI * rotateDelta.x) / element.clientHeight); // yes, height + rotateUp((2 * Math.PI * rotateDelta.y) / element.clientHeight); + Vector2.clone(rotateEnd, rotateStart); + //rotateStart.copy( rotateEnd ); + this.update(); + }; + const handleMouseMoveDolly = (event) => { + dollyEnd.set(event.clientX, event.clientY); + Vector2.subtract(dollyEnd, dollyStart, dollyDelta); + // dollyDelta.subVectors( dollyEnd, dollyStart ); + if (dollyDelta.y > 0) { + dollyOut(getZoomScale()); + } else if (dollyDelta.y < 0) { + dollyIn(getZoomScale()); + } + Vector2.clone(dollyEnd, dollyStart); + // dollyStart.copy( dollyEnd ); + this.update(); + }; + const handleMouseMovePan = (event) => { + panEnd.set(event.clientX, event.clientY); + Vector2.subtract(panEnd, panStart, panDelta); + Vector2.multiplyByScalar(panDelta, this.panSpeed, panDelta); + //panDelta.subVectors( panEnd, panStart ).multiplyScalar( this.panSpeed ); + pan(panDelta.x, panDelta.y); + Vector2.clone(panEnd, panStart); + //panStart.copy( panEnd ); + this.update(); + }; + const handleMouseWheel = (event) => { + if (event.deltaY < 0) { + dollyIn(getZoomScale()); + } else if (event.deltaY > 0) { + dollyOut(getZoomScale()); + } + this.update(); + }; + const handleKeyDown = (event) => { + let needsUpdate = false; + switch (event.code) { + case this.keys.UP: + pan(0, this.keyPanSpeed); + needsUpdate = true; + break; + case this.keys.BOTTOM: + pan(0, -this.keyPanSpeed); + needsUpdate = true; + break; + case this.keys.LEFT: + pan(this.keyPanSpeed, 0); + needsUpdate = true; + break; + case this.keys.RIGHT: + pan(-this.keyPanSpeed, 0); + needsUpdate = true; + break; + } + if (needsUpdate) { + // prevent the browser from scrolling on cursor keys + event.preventDefault(); + this.update(); + } + }; + const handleTouchStartDollyPan = () => { + if (this.enableZoom) handleTouchStartDolly(); + if (this.enablePan) handleTouchStartPan(); + }; + const handleTouchStartDollyRotate = () => { + if (this.enableZoom) handleTouchStartDolly(); + if (this.enableRotate) handleTouchStartRotate(); + }; + const handleTouchMoveRotate = (event) => { + if (pointers.length == 1) { + rotateEnd.set(event.pageX, event.pageY); + } else { + const position = getSecondPointerPosition(event); + const x = 0.5 * (event.pageX + position.x); + const y = 0.5 * (event.pageY + position.y); + rotateEnd.set(x, y); + } + Vector2.subtract(rotateEnd, rotateStart, rotateDelta); + Vector2.multiplyByScalar(rotateDelta, this.rotateSpeed, rotateDelta); + //rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( this.rotateSpeed ); + const element = this.domElement; + rotateLeft((2 * Math.PI * rotateDelta.x) / element.clientHeight); // yes, height + rotateUp((2 * Math.PI * rotateDelta.y) / element.clientHeight); + Vector2.clone(rotateEnd, rotateStart); + //rotateStart.copy( rotateEnd ); + }; + const handleTouchMovePan = (event) => { + if (pointers.length === 1) { + panEnd.set(event.pageX, event.pageY); + } else { + const position = getSecondPointerPosition(event); + const x = 0.5 * (event.pageX + position.x); + const y = 0.5 * (event.pageY + position.y); + panEnd.set(x, y); + } + Vector2.subtract(panEnd, panStart, panDelta); + Vector2.multiplyByScalar(panDelta, this.panSpeed, panDelta); + //panDelta.subVectors( panEnd, panStart ).multiplyScalar( this.panSpeed ); + pan(panDelta.x, panDelta.y); + Vector2.clone(panEnd, panStart); + // panStart.copy( panEnd ); + }; + const handleTouchMoveDolly = (event) => { + const position = getSecondPointerPosition(event); + const dx = event.pageX - position.x; + const dy = event.pageY - position.y; + const distance = Math.sqrt(dx * dx + dy * dy); + dollyEnd.set(0, distance); + dollyDelta.set(0, Math.pow(dollyEnd.y / dollyStart.y, this.zoomSpeed)); + dollyOut(dollyDelta.y); + Vector2.clone(dollyEnd, dollyStart); + //dollyStart.copy( dollyEnd ); + }; + const handleTouchMoveDollyPan = (event) => { + if (this.enableZoom) handleTouchMoveDolly(event); + if (this.enablePan) handleTouchMovePan(event); + }; + const handleTouchMoveDollyRotate = (event) => { + if (this.enableZoom) handleTouchMoveDolly(event); + if (this.enableRotate) handleTouchMoveRotate(event); + }; + // + // event handlers - FSM: listen for events and reset state + // + this.onPointerDown = (event) => { + if (this.enabled === false) return; + if (pointers.length === 0) { + this.domElement.setPointerCapture(event.pointerId); + this.domElement.addEventListener("pointermove", this.onPointerMove); + this.domElement.addEventListener("pointerup", this.onPointerUp); + } + // + addPointer(event); + if (event.pointerType === "touch") { + onTouchStart(event); + } else { + onMouseDown(event); + } + }; + this.onPointerMove = (event) => { + if (this.enabled === false) return; + if (event.pointerType === "touch") { + onTouchMove(event); + } else { + onMouseMove(event); + } + }; + this.onPointerUp = (event) => { + removePointer(event); + if (pointers.length === 0) { + this.domElement.releasePointerCapture(event.pointerId); + this.domElement.removeEventListener("pointermove", this.onPointerMove); + this.domElement.removeEventListener("pointerup", this.onPointerUp); + } + this.dispatchEvent(_endEvent); + state = STATE.NONE; + }; + const onMouseDown = (event) => { + let mouseAction; + switch (event.button) { + case 0: + mouseAction = this.mouseButtons.LEFT; + break; + case 1: + mouseAction = this.mouseButtons.MIDDLE; + break; + case 2: + mouseAction = this.mouseButtons.RIGHT; + break; + default: + mouseAction = -1; + } + switch (mouseAction) { + case MOUSE.DOLLY: + if (this.enableZoom === false) return; + handleMouseDownDolly(event); + state = STATE.DOLLY; + break; + case MOUSE.ROTATE: + if (event.ctrlKey || event.metaKey || event.shiftKey) { + if (this.enablePan === false) return; + handleMouseDownPan(event); + state = STATE.PAN; + } else { + if (this.enableRotate === false) return; + handleMouseDownRotate(event); + state = STATE.ROTATE; + } + break; + case MOUSE.PAN: + if (event.ctrlKey || event.metaKey || event.shiftKey) { + if (this.enableRotate === false) return; + handleMouseDownRotate(event); + state = STATE.ROTATE; + } else { + if (this.enablePan === false) return; + handleMouseDownPan(event); + state = STATE.PAN; + } + break; + default: + state = STATE.NONE; + } + if (state !== STATE.NONE) { + this.dispatchEvent(_startEvent); + } + }; + const onMouseMove = (event) => { + switch (state) { + case STATE.ROTATE: + if (this.enableRotate === false) return; + handleMouseMoveRotate(event); + break; + case STATE.DOLLY: + if (this.enableZoom === false) return; + handleMouseMoveDolly(event); + break; + case STATE.PAN: + if (this.enablePan === false) return; + handleMouseMovePan(event); + break; + } + }; + this.onMouseWheel = (event) => { + if (this.enabled === false || this.enableZoom === false || state !== STATE.NONE) return; + event.preventDefault(); + this.dispatchEvent(_startEvent); + handleMouseWheel(event); + this.dispatchEvent(_endEvent); + }; + this.onKeyDown = (event) => { + if (this.enabled === false || this.enablePan === false) return; + handleKeyDown(event); + }; + const onTouchStart = (event) => { + trackPointer(event); + switch (pointers.length) { + case 1: + switch (this.touches.ONE) { + case TOUCH.ROTATE: + if (this.enableRotate === false) return; + handleTouchStartRotate(); + state = STATE.TOUCH_ROTATE; + break; + case TOUCH.PAN: + if (this.enablePan === false) return; + handleTouchStartPan(); + state = STATE.TOUCH_PAN; + break; + default: + state = STATE.NONE; + } + break; + case 2: + switch (this.touches.TWO) { + case TOUCH.DOLLY_PAN: + if (this.enableZoom === false && this.enablePan === false) return; + handleTouchStartDollyPan(); + state = STATE.TOUCH_DOLLY_PAN; + break; + case TOUCH.DOLLY_ROTATE: + if (this.enableZoom === false && this.enableRotate === false) return; + handleTouchStartDollyRotate(); + state = STATE.TOUCH_DOLLY_ROTATE; + break; + default: + state = STATE.NONE; + } + break; + default: + state = STATE.NONE; + } + if (state !== STATE.NONE) { + this.dispatchEvent(_startEvent); + } + }; + const onTouchMove = (event) => { + trackPointer(event); + switch (state) { + case STATE.TOUCH_ROTATE: + if (this.enableRotate === false) return; + handleTouchMoveRotate(event); + this.update(); + break; + case STATE.TOUCH_PAN: + if (this.enablePan === false) return; + handleTouchMovePan(event); + this.update(); + break; + case STATE.TOUCH_DOLLY_PAN: + if (this.enableZoom === false && this.enablePan === false) return; + handleTouchMoveDollyPan(event); + this.update(); + break; + case STATE.TOUCH_DOLLY_ROTATE: + if (this.enableZoom === false && this.enableRotate === false) return; + handleTouchMoveDollyRotate(event); + this.update(); + break; + default: + state = STATE.NONE; + } + }; + this.onContextMenu = (event) => { + if (this.enabled === false) return; + event.preventDefault(); + }; + this.getAutoRotationAngle = () => { + return ((2 * Math.PI) / 60 / 60) * this.autoRotateSpeed; + }; + const getZoomScale = () => { + return Math.pow(0.95, this.zoomSpeed); + }; + this.domElement.addEventListener("contextmenu", this.onContextMenu); + this.domElement.addEventListener("pointerdown", this.onPointerDown); + this.domElement.addEventListener("pointercancel", onPointerCancel); + this.domElement.addEventListener("wheel", this.onMouseWheel, { + passive: false + }); } dispose() { - this.domElement.removeEventListener("contextmenu", this.onContextMenu), - this.domElement.removeEventListener("pointerdown", this.onPointerDown), - this.domElement.removeEventListener("pointercancel", Zn), - this.domElement.removeEventListener("wheel", this.onMouseWheel), - this.domElement.removeEventListener("pointermove", this.onPointerMove), - this.domElement.removeEventListener("pointerup", this.onPointerUp), - null !== this._domElementKeyEvents && - this._domElementKeyEvents.removeEventListener("keydown", this.onKeyDown); + this.domElement.removeEventListener("contextmenu", this.onContextMenu); + this.domElement.removeEventListener("pointerdown", this.onPointerDown); + this.domElement.removeEventListener("pointercancel", onPointerCancel); + this.domElement.removeEventListener("wheel", this.onMouseWheel); + this.domElement.removeEventListener("pointermove", this.onPointerMove); + this.domElement.removeEventListener("pointerup", this.onPointerUp); + if (this._domElementKeyEvents !== null) { + this._domElementKeyEvents.removeEventListener("keydown", this.onKeyDown); + } + //this.dispatchEvent( { type: 'dispose' } ); // should this be added here? } } -const wn = { +const STATE = { NONE: -1, ROTATE: 0, DOLLY: 1, @@ -12269,149 +16442,170 @@ const wn = { TOUCH_DOLLY_PAN: 5, TOUCH_DOLLY_ROTATE: 6 }; -let Tn = wn.NONE; -const En = 1e-6, - Mn = new xn(), - Un = new xn(); -let _n = 1; -const Ln = new Ue(); -let Cn = !1; -const Rn = new Se(), - An = new Se(), - Dn = new Se(), - zn = new Se(), - In = new Se(), - Pn = new Se(), - Nn = new Se(), - Bn = new Se(), - On = new Se(), - Vn = [], - Fn = {}; -var $n, Gn; -function kn(e) { - Un.theta -= e; -} -function qn(e) { - Un.phi -= e; -} -function jn(e) { - delete Fn[e.pointerId]; - for (let t = 0; t < Vn.length; t++) if (Vn[t].pointerId == e.pointerId) return void Vn.splice(t, 1); -} -function Hn(e) { - let t = Fn[e.pointerId]; - void 0 === t && ((t = new Se()), (Fn[e.pointerId] = t)), t.set(e.pageX, e.pageY); -} -function Xn(e) { - const t = e.pointerId === Vn[0].pointerId ? Vn[1] : Vn[0]; - return Fn[t.pointerId]; -} -function Yn(e) { - Rn.set(e.clientX, e.clientY); -} -function Wn(e) { - zn.set(e.clientX, e.clientY); -} -function Zn(e) { - jn(e); -} -function Kn() { - if (1 === Vn.length) Rn.set(Vn[0].pageX, Vn[0].pageY); - else { - const e = 0.5 * (Vn[0].pageX + Vn[1].pageX), - t = 0.5 * (Vn[0].pageY + Vn[1].pageY); - Rn.set(e, t); - } -} -function Qn() { - if (1 === Vn.length) zn.set(Vn[0].pageX, Vn[0].pageY); - else { - const e = 0.5 * (Vn[0].pageX + Vn[1].pageX), - t = 0.5 * (Vn[0].pageY + Vn[1].pageY); - zn.set(e, t); - } -} -function Jn() { - const e = Vn[0].pageX - Vn[1].pageX, - t = Vn[0].pageY - Vn[1].pageY, - i = Math.sqrt(e * e + t * t); - Nn.set(0, i); -} -!(function (e) { - (e[(e.LEFT = 0)] = "LEFT"), - (e[(e.MIDDLE = 1)] = "MIDDLE"), - (e[(e.RIGHT = 2)] = "RIGHT"), - (e[(e.ROTATE = 0)] = "ROTATE"), - (e[(e.DOLLY = 1)] = "DOLLY"), - (e[(e.PAN = 2)] = "PAN"); -})($n || ($n = {})), - (function (e) { - (e[(e.ROTATE = 0)] = "ROTATE"), - (e[(e.PAN = 1)] = "PAN"), - (e[(e.DOLLY_PAN = 2)] = "DOLLY_PAN"), - (e[(e.DOLLY_ROTATE = 3)] = "DOLLY_ROTATE"); - })(Gn || (Gn = {})); +let state = STATE.NONE; +const EPS = 0.000001; +// current position in spherical coordinates +const spherical = new Spherical(); +const sphericalDelta = new Spherical(); +let scale = 1; +const panOffset = new Vector3(); +let zoomChanged = false; +const rotateStart = new Vector2(); +const rotateEnd = new Vector2(); +const rotateDelta = new Vector2(); +const panStart = new Vector2(); +const panEnd = new Vector2(); +const panDelta = new Vector2(); +const dollyStart = new Vector2(); +const dollyEnd = new Vector2(); +const dollyDelta = new Vector2(); +const pointers = []; +const pointerPositions = {}; +var MOUSE; +(function (MOUSE) { + MOUSE[(MOUSE["LEFT"] = 0)] = "LEFT"; + MOUSE[(MOUSE["MIDDLE"] = 1)] = "MIDDLE"; + MOUSE[(MOUSE["RIGHT"] = 2)] = "RIGHT"; + MOUSE[(MOUSE["ROTATE"] = 0)] = "ROTATE"; + MOUSE[(MOUSE["DOLLY"] = 1)] = "DOLLY"; + MOUSE[(MOUSE["PAN"] = 2)] = "PAN"; +})(MOUSE || (MOUSE = {})); +var TOUCH; +(function (TOUCH) { + TOUCH[(TOUCH["ROTATE"] = 0)] = "ROTATE"; + TOUCH[(TOUCH["PAN"] = 1)] = "PAN"; + TOUCH[(TOUCH["DOLLY_PAN"] = 2)] = "DOLLY_PAN"; + TOUCH[(TOUCH["DOLLY_ROTATE"] = 3)] = "DOLLY_ROTATE"; +})(TOUCH || (TOUCH = {})); +function rotateLeft(angle) { + sphericalDelta.theta -= angle; +} +function rotateUp(angle) { + sphericalDelta.phi -= angle; +} +function addPointer(event) { + pointers.push(event); +} +function removePointer(event) { + delete pointerPositions[event.pointerId]; + for (let i = 0; i < pointers.length; i++) { + if (pointers[i].pointerId == event.pointerId) { + pointers.splice(i, 1); + return; + } + } +} +function trackPointer(event) { + let position = pointerPositions[event.pointerId]; + if (position === undefined) { + position = new Vector2(); + pointerPositions[event.pointerId] = position; + } + position.set(event.pageX, event.pageY); +} +function getSecondPointerPosition(event) { + const pointer = event.pointerId === pointers[0].pointerId ? pointers[1] : pointers[0]; + return pointerPositions[pointer.pointerId]; +} +function handleMouseDownRotate(event) { + rotateStart.set(event.clientX, event.clientY); +} +function handleMouseDownDolly(event) { + dollyStart.set(event.clientX, event.clientY); +} +function handleMouseDownPan(event) { + panStart.set(event.clientX, event.clientY); +} +function onPointerCancel(event) { + removePointer(event); +} +function handleTouchStartRotate() { + if (pointers.length === 1) { + rotateStart.set(pointers[0].pageX, pointers[0].pageY); + } else { + const x = 0.5 * (pointers[0].pageX + pointers[1].pageX); + const y = 0.5 * (pointers[0].pageY + pointers[1].pageY); + rotateStart.set(x, y); + } +} +function handleTouchStartPan() { + if (pointers.length === 1) { + panStart.set(pointers[0].pageX, pointers[0].pageY); + } else { + const x = 0.5 * (pointers[0].pageX + pointers[1].pageX); + const y = 0.5 * (pointers[0].pageY + pointers[1].pageY); + panStart.set(x, y); + } +} +function handleTouchStartDolly() { + const dx = pointers[0].pageX - pointers[1].pageX; + const dy = pointers[0].pageY - pointers[1].pageY; + const distance = Math.sqrt(dx * dx + dy * dy); + dollyStart.set(0, distance); +} + export { - h as AddressMode, - Er as AmbientLight, - me as Attachment, - De as Attribute, - tr as Axes, - Ve as BindGroup, - Fe as BindGroupEntity, - E as BlendFactor, - M as BlendOperation, - yr as BlinnPhongMaterial, - Kr as BloomPostEffect, - gr as BoxGeometry, - $ as Buffer, - r as BufferUsage, - Qt as Color, - T as ColorWriteFlags, - f as CompareFunction, - ue as Context, - sr as CubeTextureLoader, - w as CullMode, - rn as DirectionalLight, - Y as DrawCommand, - u as FilterMode, - b as FrontFace, - _ as IndexFormat, - C as InputStepMode, - cr as Instance, - lr as InstanceMesh, - Qi as Mesh, - ur as Model, - bn as OrbitControl, - Qr as OrthographicCamera, - Sr as PbrMaterial, - Gr as PerspectiveCamera, - Dt as PlaneGeometry, - Hr as PointLight, - S as PrimitiveTopology, - te as RenderState, - $e as RenderTarget, - de as Sampler, - Wr as Scene, - Zi as ShaderMaterial, - d as ShaderStage, - Ji as ShadowMapDebugger, - or as SkyBox, - pr as SphereGeometry, - en as SpotLight, - mr as Sprite, - U as StencilOperation, - x as StorageTextureAccess, - fe as Texture, - c as TextureAspect, - s as TextureDimension, - l as TextureFormat, - g as TextureSampleType, - a as TextureUsage, - o as TextureViewDimension, - xr as TorusKnotGeometry, - Ue as Vector3, - L as VertexFormat, - pn as loadGLTF, - gn as loadTexture + AddressMode, + AmbientLight, + Attachment, + Attribute, + Axes, + BindGroup, + BindGroupEntity, + BlendFactor, + BlendOperation, + BlinnPhongMaterial, + BloomPostEffect, + BoxGeometry, + Buffer, + BufferUsage, + Color, + ColorWriteFlags, + CompareFunction, + Context, + CubeTextureLoader, + CullMode, + DirectionalLight, + DrawCommand, + FilterMode, + FrontFace, + IndexFormat, + InputStepMode, + Instance, + InstanceMesh, + Mesh, + Model, + OrbitControl, + OrthographicCamera, + PbrMaterial, + PerspectiveCamera, + PlaneGeometry, + PointLight, + PrimitiveTopology, + RenderState, + RenderTarget, + Sampler, + Scene, + ShaderMaterial, + ShaderStage, + ShadowMapDebugger, + SkyBox, + SphereGeometry, + SpotLight, + Sprite, + StencilOperation, + StorageTextureAccess, + Texture, + TextureAspect, + TextureDimension, + TextureFormat, + TextureSampleType, + TextureUsage, + TextureViewDimension, + TorusKnotGeometry, + Vector3, + VertexFormat, + loadGLTF, + loadTexture }; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb3JlL1dlYkdQVUNvbnN0YW50LnRzIiwiLi4vc3JjL3JlbmRlci9CdWZmZXIudHMiLCIuLi9zcmMvcmVuZGVyL1BpcGVsaW5lTGF5b3V0LnRzIiwiLi4vc3JjL3JlbmRlci9QaXBlbGluZS50cyIsIi4uL3NyYy9yZW5kZXIvRHJhd0NvbW1hbmQudHMiLCIuLi9zcmMvY29yZS9XZWJHUFVUeXBlcy50cyIsIi4uL3NyYy91dGlscy9NaXBtYXBHZW5lcmF0b3IudHMiLCIuLi9zcmMvdXRpbHMvZGVmYXVsdFZhbHVlLnRzIiwiLi4vc3JjL3JlbmRlci9SZW5kZXJTdGF0ZS50cyIsIi4uL3NyYy9yZW5kZXIvQ29udGV4dC50cyIsIi4uL3NyYy9yZW5kZXIvVGV4dHVyZS50cyIsIi4uL3NyYy9yZW5kZXIvU2FtcGxlci50cyIsIi4uL3NyYy9yZW5kZXIvQXR0YWNobWVudC50cyIsIi4uL3NyYy91dGlscy9kZWZpbmVkLnRzIiwiLi4vbm9kZV9tb2R1bGVzL21lcnNlbm5lLXR3aXN0ZXIvc3JjL21lcnNlbm5lLXR3aXN0ZXIuanMiLCIuLi9zcmMvbWF0aC9NYXRoLnRzIiwiLi4vc3JjL21hdGgvVmVjdG9yMi50cyIsIi4uL3NyYy9tYXRoL1ZlY3RvcjMudHMiLCIuLi9zcmMvcmVuZGVyL0F0dHJpYnV0ZS50cyIsIi4uL3NyYy9yZW5kZXIvQmluZEdyb3VwLnRzIiwiLi4vc3JjL3JlbmRlci9CaW5kR3JvdXBFbnRpdHkudHMiLCIuLi9zcmMvcmVuZGVyL1JlbmRlclRhcmdldC50cyIsIi4uL3NyYy9tYXRoL01hdHJpeDMudHMiLCIuLi9zcmMvbWF0aC9WZWN0b3I0LnRzIiwiLi4vc3JjL21hdGgvTWF0cml4NC50cyIsIi4uL3NyYy9jb3JlL0JvdW5kaW5nU3BoZXJlLnRzIiwiLi4vc3JjL3JlbmRlci9JbmRleEJ1ZmZlci50cyIsIi4uL3NyYy9yZW5kZXIvQXR0cmlidXRlcy50cyIsIi4uL3NyYy9yZW5kZXIvVmVydGV4QnVmZmVyLnRzIiwiLi4vc3JjL3V0aWxzL2NvbWJpbmUudHMiLCIuLi9zcmMvZ2VvbWV0cnkvR2VvbWV0cnkudHMiLCIuLi9zcmMvZ2VvbWV0cnkvUGxhbmVHZW9tZXRyeS50cyIsIi4uL3NyYy9tYXRoL1F1YXRlcm5pb24udHMiLCIuLi9zcmMvY29yZS9SZW5kZXJPYmplY3QudHMiLCIuLi9zcmMvbGlnaHQvTGlnaHQudHMiLCIuLi9zcmMvbWF0aC9Db2xvci50cyIsIi4uL3NyYy9tYXRoL01hdHJpeDIudHMiLCIuLi9zcmMvcmVuZGVyL1VuaWZvcm1zLnRzIiwiLi4vc3JjL3JlbmRlci9Vbmlmb3JtQnVmZmVyLnRzIiwiLi4vc3JjL3NoYWRlci9tYXRlcmlhbC9jb2xvckZyYWcudHMiLCIuLi9zcmMvc2hhZGVyL21hdGVyaWFsL2NvbG9yVmVydC50cyIsIi4uL3NyYy9zaGFkZXIvV2dzbFByZXByb2Nlc3Nvci50cyIsIi4uL3NyYy9zaGFkZXIvbWF0ZXJpYWwvcGJyX2ZzLnRzIiwiLi4vc3JjL3NoYWRlci9tYXRlcmlhbC9wYnJfdnMudHMiLCIuLi9zcmMvc2hhZGVyL21hdGVyaWFsL3BickZyYWcudHMiLCIuLi9zcmMvc2hhZGVyL21hdGVyaWFsL3BiclZlcnQudHMiLCIuLi9zcmMvc2hhZGVyL21hdGVyaWFsL3Bob25nRnJhZy50cyIsIi4uL3NyYy9zaGFkZXIvbWF0ZXJpYWwvcGhvbmdWZXJ0LnRzIiwiLi4vc3JjL3NoYWRlci9tYXRlcmlhbC9wb2ludF9mcy50cyIsIi4uL3NyYy9zaGFkZXIvbWF0ZXJpYWwvcG9pbnRfdnMudHMiLCIuLi9zcmMvc2hhZGVyL21hdGVyaWFsL3F1YWRGcmFnLnRzIiwiLi4vc3JjL3NoYWRlci9tYXRlcmlhbC9xdWFkVmVydC50cyIsIi4uL3NyYy9zaGFkZXIvbWF0ZXJpYWwvc2t5Qm94RnJhZy50cyIsIi4uL3NyYy9zaGFkZXIvbWF0ZXJpYWwvc2t5Qm94VmVydC50cyIsIi4uL3NyYy9zaGFkZXIvbWF0ZXJpYWwvc3ByaXRlX2ZzLnRzIiwiLi4vc3JjL3NoYWRlci9tYXRlcmlhbC9zcHJpdGVfdnMudHMiLCIuLi9zcmMvc2hhZGVyL3Bvc3RQcm9jZXNzL2JsZW5kL2JsZW5kRnJhZy50cyIsIi4uL3NyYy9zaGFkZXIvcG9zdFByb2Nlc3MvYmxvb20vQmx1ci50cyIsIi4uL3NyYy9zaGFkZXIvcG9zdFByb2Nlc3MvYmxvb20vTHVtaW5vc2l0eUhpZ2gudHMiLCIuLi9zcmMvc2hhZGVyL3NoYWRlckNodW5rL2F0dHJpYnV0ZS9GcmFnSW5wdXQudHMiLCIuLi9zcmMvc2hhZGVyL3NoYWRlckNodW5rL2F0dHJpYnV0ZS9Qb2ludEZyYWdJbnB1dC50cyIsIi4uL3NyYy9zaGFkZXIvc2hhZGVyQ2h1bmsvYXR0cmlidXRlL1BvaW50VmVydElucHV0LnRzIiwiLi4vc3JjL3NoYWRlci9zaGFkZXJDaHVuay9hdHRyaWJ1dGUvUG9pbnRWZXJ0T3V0cHV0LnRzIiwiLi4vc3JjL3NoYWRlci9zaGFkZXJDaHVuay9hdHRyaWJ1dGUvVmVydGV4SW5wdXQudHMiLCIuLi9zcmMvc2hhZGVyL3NoYWRlckNodW5rL2F0dHJpYnV0ZS9WZXJ0ZXhPdXRwdXQudHMiLCIuLi9zcmMvc2hhZGVyL3NoYWRlckNodW5rL2NvbW1vbi9TeXN0ZW1Vbmlmb3JtLnRzIiwiLi4vc3JjL3NoYWRlci9zaGFkZXJDaHVuay9jb21tb24vVGV4dHVyZUFuZFNhbXBsZXJEZWZpbmUudHMiLCIuLi9zcmMvc2hhZGVyL3NoYWRlckNodW5rL2Vudmlyb25tZW50L2Vudmlyb25tZW50LnRzIiwiLi4vc3JjL3NoYWRlci9zaGFkZXJDaHVuay9pbnN0YW5jZS9JbnN0YW5jZS50cyIsIi4uL3NyYy9zaGFkZXIvc2hhZGVyQ2h1bmsvbGlnaHQvbGlnaHQudHMiLCIuLi9zcmMvc2hhZGVyL3NoYWRlckNodW5rL2xpZ2h0L2xpZ2h0Q29tbW9uLnRzIiwiLi4vc3JjL3NoYWRlci9zaGFkZXJDaHVuay9ub3JtYWwvZ2V0Tm9ybWFsQmFja1VwLnRzIiwiLi4vc3JjL3NoYWRlci9zaGFkZXJDaHVuay9wYnIvYnJkZi50cyIsIi4uL3NyYy9zaGFkZXIvc2hhZGVyQ2h1bmsvcGJyL2libC50cyIsIi4uL3NyYy9zaGFkZXIvc2hhZGVyQ2h1bmsvcGJyL3BickZ1bmN0aW9uLnRzIiwiLi4vc3JjL3NoYWRlci9zaGFkZXJDaHVuay9wYnIvcGJyU3RydWN0LnRzIiwiLi4vc3JjL3NoYWRlci9zaGFkZXJDaHVuay9wYnIvcGJyVGV4dHVyZS50cyIsIi4uL3NyYy9zaGFkZXIvc2hhZGVyQ2h1bmsvcGJyL3BiclV0aWxzLnRzIiwiLi4vc3JjL3NoYWRlci9zaGFkZXJDaHVuay9waG9uZy9ibGlubl9waG9uZy50cyIsIi4uL3NyYy9zaGFkZXIvc2hhZGVyQ2h1bmsvcGhvbmcvcGhvbmdGdW5jdGlvbi50cyIsIi4uL3NyYy9zaGFkZXIvc2hhZGVyQ2h1bmsvcGhvbmcvcGhvbmdVdGlscy50cyIsIi4uL3NyYy9zaGFkZXIvc2hhZGVyQ2h1bmsvc2tpbi9Ta2luVmVydC50cyIsIi4uL3NyYy9zaGFkZXIvc2hhZGVyQ2h1bmsvc3RydWN0L1Bick1hdGVyaWFsU3RydWN0LnRzIiwiLi4vc3JjL3NoYWRlci9zaGFkZXJDaHVuay9TaGFkZXJDaHVuay50cyIsIi4uL3NyYy9zaGFkZXIvc2hhZGVyQ2h1bmsvc2hhZG93L3NoYWRvd01hcERlYnVnZ2VyRnJhZy50cyIsIi4uL3NyYy9zaGFkZXIvc2hhZGVyQ2h1bmsvc2hhZG93L3NoYWRvd01hcERlYnVnZ2VyVmVydC50cyIsIi4uL3NyYy9zaGFkZXIvc2hhZGVyQ2h1bmsvc2hhZG93L3NoYWRvd01hcEZyYWcudHMiLCIuLi9zcmMvc2hhZGVyL3NoYWRlckNodW5rL3NoYWRvdy9zaGFkb3dNYXBWZXJ0LnRzIiwiLi4vc3JjL3NoYWRlci9TaGFkZXJzLnRzIiwiLi4vc3JjL3NoYWRlci9TaGFkZXJTb3VyY2UudHMiLCIuLi9zcmMvdXRpbHMvdW5pZm9ybVV0aWxzLnRzIiwiLi4vc3JjL3JlbmRlci9CaW5kR3JvdXBMYXlvdXQudHMiLCIuLi9zcmMvcmVuZGVyL0JpbmRHcm91cExheW91dEVudHJ5LnRzIiwiLi4vc3JjL3JlbmRlci9TaGFkZXJEYXRhLnRzIiwiLi4vc3JjL21hdGVyaWFsL01hdGVyaWFsLnRzIiwiLi4vc3JjL21hdGVyaWFsL1NoYWRlck1hdGVyaWFsLnRzIiwiLi4vc3JjL3V0aWxzL2NyZWF0ZUd1aWQudHMiLCIuLi9zcmMvbWVzaC9NZXNoLnRzIiwiLi4vc3JjL2hlbHBlci9TaGFkb3dNYXBEZWJ1Z2dlci50cyIsIi4uL3NyYy9tYXRlcmlhbC9Db2xvck1hdGVyaWFsLnRzIiwiLi4vc3JjL21lc2gvQXhlcy50cyIsIi4uL3NyYy9nZW9tZXRyeS9Ta3lCb3hHZW9tZXRyeS50cyIsIi4uL3NyYy91dGlscy9kZXN0cm95T2JqZWN0LnRzIiwiLi4vc3JjL2NvcmUvVGV4dHVyZUNhY2hlLnRzIiwiLi4vc3JjL2xvYWRlci9DdWJlVGV4dHVyZUxvYWRlci50cyIsIi4uL3NyYy9tYXRlcmlhbC9Ta3lCb3hNYXRlcmlhbC50cyIsIi4uL3NyYy9tZXNoL1NreUJveC50cyIsIi4uL3NyYy9tZXNoL0luc3RhbmNlLnRzIiwiLi4vc3JjL21lc2gvSW5zdGFuY2VNZXNoLnRzIiwiLi4vc3JjL3JlbmRlci9Db21wdXRlQ29tbWFuZC50cyIsIi4uL3NyYy9tZXNoL01vZGVsLnRzIiwiLi4vc3JjL2dlb21ldHJ5L1Nwcml0ZUdlb21ldHJ5LnRzIiwiLi4vc3JjL21hdGVyaWFsL1Nwcml0ZU1hdGVyaWFsLnRzIiwiLi4vc3JjL21lc2gvU3ByaXRlLnRzIiwiLi4vc3JjL3V0aWxzL0dlb21ldHJ5VXRpbHMudHMiLCIuLi9zcmMvZ2VvbWV0cnkvU3BoZXJlR2VvbWV0cnkudHMiLCIuLi9zcmMvZ2VvbWV0cnkvQm94R2VvbWV0cnkudHMiLCIuLi9zcmMvZ2VvbWV0cnkvVG9ydXNLbm90R2VvbWV0cnkudHMiLCIuLi9zcmMvbWF0ZXJpYWwvQmxpbm5QaG9uZ01hdGVyaWFsLnRzIiwiLi4vc3JjL21hdGVyaWFsL1Bick1hdGVyaWFsLnRzIiwiLi4vc3JjL2NvcmUvRXZlbnREaXNwYXRjaGVyLnRzIiwiLi4vc3JjL2NvcmUvUmVuZGVyUXVldWUudHMiLCIuLi9zcmMvY29yZS9GcmFtZVN0YXRlLnRzIiwiLi4vc3JjL2xpZ2h0L0FtYmllbnRMaWdodC50cyIsIi4uL3NyYy9jb3JlL0xpZ2h0TWFuZ2VyLnRzIiwiLi4vc3JjL2NvcmUvTWVzaE1hbmdlci50cyIsIi4uL3NyYy9wb3N0LXByb2Nlc3MvUmVzb2x2ZUZyYW1lLnRzIiwiLi4vc3JjL3Bvc3QtcHJvY2Vzcy9Qb3N0RWZmZWN0Q29sbGVjdGlvbi50cyIsIi4uL3NyYy9wYXNzL1Bhc3MudHMiLCIuLi9zcmMvcGFzcy9CYXNpY1Bhc3MudHMiLCIuLi9zcmMvbWF0aC9QbGFuZS50cyIsIi4uL3NyYy9jb3JlL0N1bGxpbmdWb2x1bWUudHMiLCIuLi9zcmMvY2FtZXJhL0NhbWVyYS50cyIsIi4uL3NyYy9jYW1lcmEvUGVyc3BlY3RpdmVDYW1lcmEudHMiLCIuLi9zcmMvY2FtZXJhL1BvaW50TGlnaHRTaGFkb3dDYW1lcmEudHMiLCIuLi9zcmMvbGlnaHQvc2hhZG93cy9CYXNlU2hhZG93LnRzIiwiLi4vc3JjL2xpZ2h0L3NoYWRvd3MvUG9pbnRMaWdodFNoYWRvdy50cyIsIi4uL3NyYy9saWdodC9Qb2ludExpZ2h0LnRzIiwiLi4vc3JjL3Bhc3MvU2hhZG93UGFzcy50cyIsIi4uL3NyYy9yZW5kZXJwaXBlbGluZS9Gb3J3YXJkUmVuZGVyTGluZS50cyIsIi4uL3NyYy9TY2VuZS50cyIsIi4uL3NyYy9wb3N0LXByb2Nlc3MvUG9zdEVmZmVjdC50cyIsIi4uL3NyYy9wb3N0LXByb2Nlc3MvQmxvb21Qb3N0RWZmZWN0LnRzIiwiLi4vc3JjL2NhbWVyYS9PcnRob2dyYXBoaWNDYW1lcmEudHMiLCIuLi9zcmMvbGlnaHQvc2hhZG93cy9TcG90TGlnaHRTaGFkb3cudHMiLCIuLi9zcmMvbGlnaHQvU3BvdExpZ2h0LnRzIiwiLi4vc3JjL2xpZ2h0L3NoYWRvd3MvRGlyZWN0aW9uYWxMaWdodFNoYWRvdy50cyIsIi4uL3NyYy9saWdodC9EaXJlY3Rpb25hbExpZ2h0LnRzIiwiLi4vc3JjL21lc2gvTm9kZS50cyIsIi4uL3NyYy9tZXNoL1NLaW5NZXNoLnRzIiwiLi4vc3JjL3V0aWxzL2dsdGZVdGlscy50cyIsIi4uL3NyYy9sb2FkZXIvZ2x0Zi9saWJzL0FjY2Vzc29yLnRzIiwiLi4vc3JjL2xvYWRlci9nbHRmL2xpYnMvQW5pbWF0aW9uLnRzIiwiLi4vc3JjL2xvYWRlci9nbHRmL2xpYnMvQW5pbWF0aW9uQ2hhbm5lbC50cyIsIi4uL3NyYy9sb2FkZXIvZ2x0Zi9saWJzL0FuaW1hdGlvbkNoYW5uZWxUYXJnZXQudHMiLCIuLi9zcmMvbG9hZGVyL2dsdGYvdHlwZXMvZ2x0ZlR5cGUudHMiLCIuLi9zcmMvbG9hZGVyL2dsdGYvbGlicy9BbmltYXRpb25TYW1wbGVyLnRzIiwiLi4vc3JjL2xvYWRlci9HTFRGTG9hZGVyLnRzIiwiLi4vc3JjL3V0aWxzL3V0aWxzLnRzIiwiLi4vc3JjL21hdGgvU3BoZXJpY2FsLnRzIiwiLi4vc3JjL2NvbnRyb2wvT3JiaXRDb250cm9sLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBlbnVtIFByZWRlZmluZWRDb2xvclNwYWNlIHtcblx0U1JHQiA9IFwic3JnYlwiXG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBlbnVtIFBvd2VyUHJlZmVyZW5jZSB7XG5cdExvd1Bvd2VyID0gXCJsb3ctcG93ZXJcIixcblx0SGlnaFBlcmZvcm1hbmNlID0gXCJoaWdoLXBlcmZvcm1hbmNlXCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gRmVhdHVyZU5hbWUge1xuXHREZXB0aENsaXBDb250cm9sID0gXCJkZXB0aC1jbGlwLWNvbnRyb2xcIixcblx0RGVwdGgyNFVub3JtU3RlbmNpbDggPSBcImRlcHRoMjR1bm9ybS1zdGVuY2lsOFwiLFxuXHREZXB0aDMyRmxvYXRTdGVuY2lsOCA9IFwiZGVwdGgzMmZsb2F0LXN0ZW5jaWw4XCIsXG5cdFRleHR1cmVDb21wcmVzc2lvbkJDID0gXCJ0ZXh0dXJlLWNvbXByZXNzaW9uLWJjXCIsXG5cdFRleHR1cmVDb21wcmVzc2lvbkVUQzIgPSBcInRleHR1cmUtY29tcHJlc3Npb24tZXRjMlwiLFxuXHRUZXh0dXJlQ29tcHJlc3Npb25BU1RDID0gXCJ0ZXh0dXJlLWNvbXByZXNzaW9uLWFzdGNcIixcblx0VGltZXN0YW1wUXVlcnkgPSBcInRpbWVzdGFtcC1xdWVyeVwiLFxuXHRJbmRpcmVjdEZpcnN0SW5zdGFuY2UgPSBcImluZGlyZWN0LWZpcnN0LWluc3RhbmNlXCIsXG5cdFNoYWRlckYxNiA9IFwic2hhZGVyLWYxNlwiLFxuXHRCR1JBOFVub3JtU3RvcmFnZSA9IFwiYmdyYTh1bm9ybS1zdG9yYWdlXCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gQnVmZmVyVXNhZ2Uge1xuXHRNYXBSZWFkID0gMSxcblx0TWFwV3JpdGUgPSAyLFxuXHRDb3B5U3JjID0gNCxcblx0Q29weURzdCA9IDgsXG5cdEluZGV4ID0gMTYsXG5cdFZlcnRleCA9IDMyLFxuXHRVbmlmb3JtID0gNjQsXG5cdFN0b3JhZ2UgPSAxMjgsXG5cdEluZGlyZWN0ID0gMjU2LFxuXHRRdWVyeVJlc29sdmUgPSA1MTJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gTWFwTW9kZSB7XG5cdFJlYWQgPSAxLFxuXHRXcml0ZSA9IDJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gVGV4dHVyZURpbWVuc2lvbiB7XG5cdEUxZCA9IFwiMWRcIixcblx0RTJkID0gXCIyZFwiLFxuXHRFM2QgPSBcIjNkXCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gVGV4dHVyZVVzYWdlIHtcblx0Q29weVNyYyA9IDEsXG5cdENvcHlEc3QgPSAyLFxuXHRUZXh0dXJlQmluZGluZyA9IDQsXG5cdFN0b3JhZ2VCaW5kaW5nID0gOCxcblx0UmVuZGVyQXR0YWNobWVudCA9IDE2XG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBlbnVtIFRleHR1cmVWaWV3RGltZW5zaW9uIHtcblx0RTFkID0gXCIxZFwiLFxuXHRFMmQgPSBcIjJkXCIsXG5cdEUyZEFycmF5ID0gXCIyZC1hcnJheVwiLFxuXHRDdWJlID0gXCJjdWJlXCIsXG5cdEN1YmVBcnJheSA9IFwiY3ViZS1hcnJheVwiLFxuXHRFM2QgPSBcIjNkXCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gVGV4dHVyZUFzcGVjdCB7XG5cdEFsbCA9IFwiYWxsXCIsXG5cdFN0ZW5jaWxPbmx5ID0gXCJzdGVuY2lsLW9ubHlcIixcblx0RGVwdGhPbmx5ID0gXCJkZXB0aC1vbmx5XCJcbn1cblxuLyoqXG4gKiBDb21tZW50cyB0YWtlbiBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9nZngtcnMvd2dwdS9ibG9iL21hc3Rlci93Z3B1LXR5cGVzL3NyYy9saWIucnNcbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZW51bSBUZXh0dXJlRm9ybWF0IHtcblx0Ly8gOC1iaXQgZm9ybWF0c1xuXHRSOFVub3JtID0gXCJyOHVub3JtXCIsIC8vIFJlZCBjaGFubmVsIG9ubHkuIDggYml0IGludGVnZXIgcGVyIGNoYW5uZWwuIFswLCAyNTVdIGNvbnZlcnRlZCB0by9mcm9tIGZsb2F0IFswLCAxXSBpbiBzaGFkZXIuXG5cdFI4U25vcm0gPSBcInI4c25vcm1cIiwgLy8gUmVkIGNoYW5uZWwgb25seS4gOCBiaXQgaW50ZWdlciBwZXIgY2hhbm5lbC4gWy0xMjcsIDEyN10gY29udmVydGVkIHRvL2Zyb20gZmxvYXQgWy0xLCAxXSBpbiBzaGFkZXIuXG5cdFI4VWludCA9IFwicjh1aW50XCIsIC8vIFJlZCBjaGFubmVsIG9ubHkuIDggYml0IGludGVnZXIgcGVyIGNoYW5uZWwuIFVuc2lnbmVkIGluIHNoYWRlci5cblx0UjhTaW50ID0gXCJyOHNpbnRcIiwgLy8gUmVkIGNoYW5uZWwgb25seS4gOCBiaXQgaW50ZWdlciBwZXIgY2hhbm5lbC4gU2lnbmVkIGluIHNoYWRlci5cblxuXHQvLyAxNi1iaXQgZm9ybWF0c1xuXHRSMTZVaW50ID0gXCJyMTZ1aW50XCIsIC8vIFJlZCBjaGFubmVsIG9ubHkuIDE2IGJpdCBpbnRlZ2VyIHBlciBjaGFubmVsLiBVbnNpZ25lZCBpbiBzaGFkZXIuXG5cdFIxNlNpbnQgPSBcInIxNnNpbnRcIiwgLy8gUmVkIGNoYW5uZWwgb25seS4gMTYgYml0IGludGVnZXIgcGVyIGNoYW5uZWwuIFNpZ25lZCBpbiBzaGFkZXIuXG5cdFIxNkZsb2F0ID0gXCJyMTZmbG9hdFwiLCAvLyBSZWQgY2hhbm5lbCBvbmx5LiAxNiBiaXQgZmxvYXQgcGVyIGNoYW5uZWwuIEZsb2F0IGluIHNoYWRlci5cblx0Ukc4VW5vcm0gPSBcInJnOHVub3JtXCIsIC8vIFJlZCBhbmQgZ3JlZW4gY2hhbm5lbHMuIDggYml0IGludGVnZXIgcGVyIGNoYW5uZWwuIFswLCAyNTVdIGNvbnZlcnRlZCB0by9mcm9tIGZsb2F0IFswLCAxXSBpbiBzaGFkZXIuXG5cdFJHOFNub3JtID0gXCJyZzhzbm9ybVwiLCAvLyBSZWQgYW5kIGdyZWVuIGNoYW5uZWxzLiA4IGJpdCBpbnRlZ2VyIHBlciBjaGFubmVsLiBbLTEyNywgMTI3XSBjb252ZXJ0ZWQgdG8vZnJvbSBmbG9hdCBbLTEsIDFdIGluIHNoYWRlci5cblx0Ukc4VWludCA9IFwicmc4dWludFwiLCAvLyBSZWQgYW5kIGdyZWVuIGNoYW5uZWxzLiA4IGJpdCBpbnRlZ2VyIHBlciBjaGFubmVsLiBVbnNpZ25lZCBpbiBzaGFkZXIuXG5cdFJHOFNpbnQgPSBcInJnOHNpbnRcIiwgLy8gUmVkIGFuZCBncmVlbiBjaGFubmVscy4gOCBiaXQgaW50ZWdlciBwZXIgY2hhbm5lbC4gU2lnbmVkIGluIHNoYWRlci5cblxuXHQvLyAzMi1iaXQgZm9ybWF0c1xuXHRSMzJVaW50ID0gXCJyMzJ1aW50XCIsIC8vIFJlZCBjaGFubmVsIG9ubHkuIDMyIGJpdCBpbnRlZ2VyIHBlciBjaGFubmVsLiBVbnNpZ25lZCBpbiBzaGFkZXIuXG5cdFIzMlNpbnQgPSBcInIzMnNpbnRcIiwgLy8gUmVkIGNoYW5uZWwgb25seS4gMzIgYml0IGludGVnZXIgcGVyIGNoYW5uZWwuIFNpZ25lZCBpbiBzaGFkZXIuXG5cdFIzMkZsb2F0ID0gXCJyMzJmbG9hdFwiLCAvLyBSZWQgY2hhbm5lbCBvbmx5LiAzMiBiaXQgZmxvYXQgcGVyIGNoYW5uZWwuIEZsb2F0IGluIHNoYWRlci5cblx0UkcxNlVpbnQgPSBcInJnMTZ1aW50XCIsIC8vIFJlZCBhbmQgZ3JlZW4gY2hhbm5lbHMuIDE2IGJpdCBpbnRlZ2VyIHBlciBjaGFubmVsLiBVbnNpZ25lZCBpbiBzaGFkZXIuXG5cdFJHMTZTaW50ID0gXCJyZzE2c2ludFwiLCAvLyBSZWQgYW5kIGdyZWVuIGNoYW5uZWxzLiAxNiBiaXQgaW50ZWdlciBwZXIgY2hhbm5lbC4gU2lnbmVkIGluIHNoYWRlci5cblx0UkcxNkZsb2F0ID0gXCJyZzE2ZmxvYXRcIiwgLy8gUmVkIGFuZCBncmVlbiBjaGFubmVscy4gMTYgYml0IGZsb2F0IHBlciBjaGFubmVsLiBGbG9hdCBpbiBzaGFkZXIuXG5cdFJHQkE4VW5vcm0gPSBcInJnYmE4dW5vcm1cIiwgLy8gUmVkLCBncmVlbiwgYmx1ZSwgYW5kIGFscGhhIGNoYW5uZWxzLiA4IGJpdCBpbnRlZ2VyIHBlciBjaGFubmVsLiBbMCwgMjU1XSBjb252ZXJ0ZWQgdG8vZnJvbSBmbG9hdCBbMCwgMV0gaW4gc2hhZGVyLlxuXHRSR0JBOFVub3JtU1JHQiA9IFwicmdiYTh1bm9ybS1zcmdiXCIsIC8vIFJlZCwgZ3JlZW4sIGJsdWUsIGFuZCBhbHBoYSBjaGFubmVscy4gOCBiaXQgaW50ZWdlciBwZXIgY2hhbm5lbC4gU3JnYi1jb2xvciBbMCwgMjU1XSBjb252ZXJ0ZWQgdG8vZnJvbSBsaW5lYXItY29sb3IgZmxvYXQgWzAsIDFdIGluIHNoYWRlci5cblx0UkdCQThTbm9ybSA9IFwicmdiYThzbm9ybVwiLCAvLyBSZWQsIGdyZWVuLCBibHVlLCBhbmQgYWxwaGEgY2hhbm5lbHMuIDggYml0IGludGVnZXIgcGVyIGNoYW5uZWwuIFstMTI3LCAxMjddIGNvbnZlcnRlZCB0by9mcm9tIGZsb2F0IFstMSwgMV0gaW4gc2hhZGVyLlxuXHRSR0JBOFVpbnQgPSBcInJnYmE4dWludFwiLCAvLyBSZWQsIGdyZWVuLCBibHVlLCBhbmQgYWxwaGEgY2hhbm5lbHMuIDggYml0IGludGVnZXIgcGVyIGNoYW5uZWwuIFVuc2lnbmVkIGluIHNoYWRlci5cblx0UkdCQThTaW50ID0gXCJyZ2JhOHNpbnRcIiwgLy8gUmVkLCBncmVlbiwgYmx1ZSwgYW5kIGFscGhhIGNoYW5uZWxzLiA4IGJpdCBpbnRlZ2VyIHBlciBjaGFubmVsLiBTaWduZWQgaW4gc2hhZGVyLlxuXHRCR1JBOFVub3JtID0gXCJiZ3JhOHVub3JtXCIsIC8vIEJsdWUsIGdyZWVuLCByZWQsIGFuZCBhbHBoYSBjaGFubmVscy4gOCBiaXQgaW50ZWdlciBwZXIgY2hhbm5lbC4gWzAsIDI1NV0gY29udmVydGVkIHRvL2Zyb20gZmxvYXQgWzAsIDFdIGluIHNoYWRlci5cblx0QkdSQThVbm9ybVNSR0IgPSBcImJncmE4dW5vcm0tc3JnYlwiLCAvLyBCbHVlLCBncmVlbiwgcmVkLCBhbmQgYWxwaGEgY2hhbm5lbHMuIDggYml0IGludGVnZXIgcGVyIGNoYW5uZWwuIFNyZ2ItY29sb3IgWzAsIDI1NV0gY29udmVydGVkIHRvL2Zyb20gbGluZWFyLWNvbG9yIGZsb2F0IFswLCAxXSBpbiBzaGFkZXIuXG5cdC8vIFBhY2tlZCAzMi1iaXQgZm9ybWF0c1xuXHRSR0I5RTVVRmxvYXQgPSBcInJnYjllNXVmbG9hdFwiLCAvLyBQYWNrZWQgdW5zaWduZWQgZmxvYXQgd2l0aCA5IGJpdHMgbWFudGlzYSBmb3IgZWFjaCBSR0IgY29tcG9uZW50LCB0aGVuIGEgY29tbW9uIDUgYml0cyBleHBvbmVudFxuXHRSR0IxMEEyVW5vcm0gPSBcInJnYjEwYTJ1bm9ybVwiLCAvLyBSZWQsIGdyZWVuLCBibHVlLCBhbmQgYWxwaGEgY2hhbm5lbHMuIDEwIGJpdCBpbnRlZ2VyIGZvciBSR0IgY2hhbm5lbHMsIDIgYml0IGludGVnZXIgZm9yIGFscGhhIGNoYW5uZWwuIFswLCAxMDIzXSAoWzAsIDNdIGZvciBhbHBoYSkgY29udmVydGVkIHRvL2Zyb20gZmxvYXQgWzAsIDFdIGluIHNoYWRlci5cblx0UkcxMUIxMFVGbG9hdCA9IFwicmcxMWIxMHVmbG9hdFwiLCAvLyBSZWQsIGdyZWVuLCBhbmQgYmx1ZSBjaGFubmVscy4gMTEgYml0IGZsb2F0IHdpdGggbm8gc2lnbiBiaXQgZm9yIFJHIGNoYW5uZWxzLiAxMCBiaXQgZmxvYXQgd2l0aCBubyBzaWduIGJpdCBmb3IgYmx1ZSBjaGFubmVsLiBGbG9hdCBpbiBzaGFkZXIuXG5cblx0Ly8gNjQtYml0IGZvcm1hdHNcblx0UkczMlVpbnQgPSBcInJnMzJ1aW50XCIsIC8vIFJlZCBhbmQgZ3JlZW4gY2hhbm5lbHMuIDMyIGJpdCBpbnRlZ2VyIHBlciBjaGFubmVsLiBVbnNpZ25lZCBpbiBzaGFkZXIuXG5cdFJHMzJTaW50ID0gXCJyZzMyc2ludFwiLCAvLyBSZWQgYW5kIGdyZWVuIGNoYW5uZWxzLiAzMiBiaXQgaW50ZWdlciBwZXIgY2hhbm5lbC4gU2lnbmVkIGluIHNoYWRlci5cblx0UkczMkZsb2F0ID0gXCJyZzMyZmxvYXRcIiwgLy8gUmVkIGFuZCBncmVlbiBjaGFubmVscy4gMzIgYml0IGZsb2F0IHBlciBjaGFubmVsLiBGbG9hdCBpbiBzaGFkZXIuXG5cdFJHQkExNlVpbnQgPSBcInJnYmExNnVpbnRcIiwgLy8gUmVkLCBncmVlbiwgYmx1ZSwgYW5kIGFscGhhIGNoYW5uZWxzLiAxNiBiaXQgaW50ZWdlciBwZXIgY2hhbm5lbC4gVW5zaWduZWQgaW4gc2hhZGVyLlxuXHRSR0JBMTZTaW50ID0gXCJyZ2JhMTZzaW50XCIsIC8vIFJlZCwgZ3JlZW4sIGJsdWUsIGFuZCBhbHBoYSBjaGFubmVscy4gMTYgYml0IGludGVnZXIgcGVyIGNoYW5uZWwuIFNpZ25lZCBpbiBzaGFkZXIuXG5cdFJHQkExNkZsb2F0ID0gXCJyZ2JhMTZmbG9hdFwiLCAvLyBSZWQsIGdyZWVuLCBibHVlLCBhbmQgYWxwaGEgY2hhbm5lbHMuIDE2IGJpdCBmbG9hdCBwZXIgY2hhbm5lbC4gRmxvYXQgaW4gc2hhZGVyLlxuXG5cdC8vIDEyOC1iaXQgZm9ybWF0c1xuXHRSR0JBMzJVaW50ID0gXCJyZ2JhMzJ1aW50XCIsIC8vIFJlZCwgZ3JlZW4sIGJsdWUsIGFuZCBhbHBoYSBjaGFubmVscy4gMzIgYml0IGludGVnZXIgcGVyIGNoYW5uZWwuIFVuc2lnbmVkIGluIHNoYWRlci5cblx0UkdCQTMyU2ludCA9IFwicmdiYTMyc2ludFwiLCAvLyBSZWQsIGdyZWVuLCBibHVlLCBhbmQgYWxwaGEgY2hhbm5lbHMuIDMyIGJpdCBpbnRlZ2VyIHBlciBjaGFubmVsLiBTaWduZWQgaW4gc2hhZGVyLlxuXHRSR0JBMzJGbG9hdCA9IFwicmdiYTMyZmxvYXRcIiwgLy8gUmVkLCBncmVlbiwgYmx1ZSwgYW5kIGFscGhhIGNoYW5uZWxzLiAzMiBiaXQgZmxvYXQgcGVyIGNoYW5uZWwuIEZsb2F0IGluIHNoYWRlci5cblxuXHQvLyBEZXB0aCBhbmQgc3RlbmNpbCBmb3JtYXRzXG5cdFN0ZW5jaWw4ID0gXCJzdGVuY2lsOFwiLFxuXHREZXB0aDE2VW5vcm0gPSBcImRlcHRoMTZ1bm9ybVwiLFxuXHREZXB0aDI0UGx1cyA9IFwiZGVwdGgyNHBsdXNcIiwgLy8gU3BlY2lhbCBkZXB0aCBmb3JtYXQgd2l0aCBhdCBsZWFzdCAyNCBiaXQgaW50ZWdlciBkZXB0aC5cblx0RGVwdGgyNFBsdXNTdGVuY2lsOCA9IFwiZGVwdGgyNHBsdXMtc3RlbmNpbDhcIiwgLy8gU3BlY2lhbCBkZXB0aC9zdGVuY2lsIGZvcm1hdCB3aXRoIGF0IGxlYXN0IDI0IGJpdCBpbnRlZ2VyIGRlcHRoIGFuZCA4IGJpdHMgaW50ZWdlciBzdGVuY2lsLlxuXHREZXB0aDMyRmxvYXQgPSBcImRlcHRoMzJmbG9hdFwiLCAvLyBTcGVjaWFsIGRlcHRoIGZvcm1hdCB3aXRoIDMyIGJpdCBmbG9hdGluZyBwb2ludCBkZXB0aC5cblxuXHQvLyBCQyBjb21wcmVzc2VkIGZvcm1hdHMgdXNhYmxlIGlmIFwidGV4dHVyZS1jb21wcmVzc2lvbi1iY1wiIGlzIGJvdGhcblx0Ly8gc3VwcG9ydGVkIGJ5IHRoZSBkZXZpY2UvdXNlciBhZ2VudCBhbmQgZW5hYmxlZCBpbiByZXF1ZXN0RGV2aWNlLlxuXHRCQzFSR0JBVW5vcm0gPSBcImJjMS1yZ2JhLXVub3JtXCIsIC8vIDR4NCBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDggYnl0ZXMgcGVyIGJsb2NrICg0IGJpdC9weCkuIDQgY29sb3IgKyBhbHBoYSBwYWxsZXQuIDUgYml0IFIgKyA2IGJpdCBHICsgNSBiaXQgQiArIDEgYml0IGFscGhhLiBBbHNvIGtub3duIGFzIERYVDEuXG5cdEJDMVJHQkFVbm9ybVNSR0IgPSBcImJjMS1yZ2JhLXVub3JtLXNyZ2JcIiwgLy8gNHg0IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gOCBieXRlcyBwZXIgYmxvY2sgKDQgYml0L3B4KS4gNCBjb2xvciArIGFscGhhIHBhbGxldC4gNSBiaXQgUiArIDYgYml0IEcgKyA1IGJpdCBCICsgMSBiaXQgYWxwaGEuIEFsc28ga25vd24gYXMgRFhUMS5cblx0QkMyUkdCQVVub3JtID0gXCJiYzItcmdiYS11bm9ybVwiLCAvLyA0eDQgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiAxNiBieXRlcyBwZXIgYmxvY2sgKDggYml0L3B4KS4gNCBjb2xvciBwYWxsZXQuIDUgYml0IFIgKyA2IGJpdCBHICsgNSBiaXQgQiArIDQgYml0IGFscGhhLiBBbHNvIGtub3duIGFzIERYVDMuXG5cdEJDMlJHQkFVbm9ybVNSR0IgPSBcImJjMi1yZ2JhLXVub3JtLXNyZ2JcIiwgLy8gNHg0IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gMTYgYnl0ZXMgcGVyIGJsb2NrICg4IGJpdC9weCkuIDQgY29sb3IgcGFsbGV0LiA1IGJpdCBSICsgNiBiaXQgRyArIDUgYml0IEIgKyA0IGJpdCBhbHBoYS4gQWxzbyBrbm93biBhcyBEWFQzLlxuXHRCQzNSR0JBVW5vcm0gPSBcImJjMy1yZ2JhLXVub3JtXCIsIC8vIDR4NCBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoOCBiaXQvcHgpLiA0IGNvbG9yIHBhbGxldCArIDggYWxwaGEgcGFsbGV0LiA1IGJpdCBSICsgNiBiaXQgRyArIDUgYml0IEIgKyA4IGJpdCBhbHBoYS4gQWxzbyBrbm93biBhcyBEWFQ1LlxuXHRCQzNSR0JBVW5vcm1TUkdCID0gXCJiYzMtcmdiYS11bm9ybS1zcmdiXCIsIC8vIDR4NCBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoOCBiaXQvcHgpLiA0IGNvbG9yIHBhbGxldCArIDggYWxwaGEgcGFsbGV0LiA1IGJpdCBSICsgNiBiaXQgRyArIDUgYml0IEIgKyA4IGJpdCBhbHBoYS4gQWxzbyBrbm93biBhcyBEWFQ1LlxuXHRCQzRSVW5vcm0gPSBcImJjNC1yLXVub3JtXCIsIC8vIDR4NCBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDggYnl0ZXMgcGVyIGJsb2NrICg0IGJpdC9weCkuIDggY29sb3IgcGFsbGV0LiA4IGJpdCBSLiBBbHNvIGtub3duIGFzIFJHVEMxLlxuXHRCQzRSU25vcm0gPSBcImJjNC1yLXNub3JtXCIsIC8vIDR4NCBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDggYnl0ZXMgcGVyIGJsb2NrICg0IGJpdC9weCkuIDggY29sb3IgcGFsbGV0LiA4IGJpdCBSLiBBbHNvIGtub3duIGFzIFJHVEMxLlxuXHRCQzVSR1Vub3JtID0gXCJiYzUtcmctdW5vcm1cIiwgLy8gNHg0IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gMTYgYnl0ZXMgcGVyIGJsb2NrICg4IGJpdC9weCkuIDggY29sb3IgcmVkIHBhbGxldCArIDggY29sb3IgZ3JlZW4gcGFsbGV0LiA4IGJpdCBSRy4gQWxzbyBrbm93biBhcyBSR1RDMi5cblx0QkM1UkdTbm9ybSA9IFwiYmM1LXJnLXNub3JtXCIsIC8vIDR4NCBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoOCBiaXQvcHgpLiA4IGNvbG9yIHJlZCBwYWxsZXQgKyA4IGNvbG9yIGdyZWVuIHBhbGxldC4gOCBiaXQgUkcuIEFsc28ga25vd24gYXMgUkdUQzIuXG5cdEJDNkhSR0JVRmxvYXQgPSBcImJjNmgtcmdiLXVmbG9hdFwiLCAvLyA0eDQgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiAxNiBieXRlcyBwZXIgYmxvY2sgKDggYml0L3B4KS4gVmFyaWFibGUgc2l6ZWQgcGFsbGV0LiAxNiBiaXQgdW5zaWduZWQgZmxvYXQgUkdCLiBGbG9hdCBpbiBzaGFkZXIuIEFsc28ga25vd24gYXMgQlBUQyAoZmxvYXQpLlxuXHRCQzZIUkdCRmxvYXQgPSBcImJjNmgtcmdiLWZsb2F0XCIsIC8vIDR4NCBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoOCBiaXQvcHgpLiBWYXJpYWJsZSBzaXplZCBwYWxsZXQuIDE2IGJpdCBzaWduZWQgZmxvYXQgUkdCLiBGbG9hdCBpbiBzaGFkZXIuIEFsc28ga25vd24gYXMgQlBUQyAoZmxvYXQpLlxuXHRCQzdSR0JBVW5vcm0gPSBcImJjNy1yZ2JhLXVub3JtXCIsIC8vIDR4NCBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoOCBiaXQvcHgpLiBWYXJpYWJsZSBzaXplZCBwYWxsZXQuIDggYml0IGludGVnZXIgUkdCQS4gQWxzbyBrbm93biBhcyBCUFRDICh1bm9ybSkuXG5cdEJDN1JHQkFVbm9ybVNSR0IgPSBcImJjNy1yZ2JhLXVub3JtLXNyZ2JcIiwgLy8gNHg0IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gMTYgYnl0ZXMgcGVyIGJsb2NrICg4IGJpdC9weCkuIFZhcmlhYmxlIHNpemVkIHBhbGxldC4gOCBiaXQgaW50ZWdlciBSR0JBLiBBbHNvIGtub3duIGFzIEJQVEMgKHVub3JtKS5cblxuXHQvLyBFVEMyIGNvbXByZXNzZWQgZm9ybWF0cyB1c2FibGUgaWYgXCJ0ZXh0dXJlLWNvbXByZXNzaW9uLWV0YzJcIiBpcyBib3RoXG5cdC8vIHN1cHBvcnRlZCBieSB0aGUgZGV2aWNlL3VzZXIgYWdlbnQgYW5kIGVuYWJsZWQgaW4gcmVxdWVzdERldmljZS5cblx0RVRDMlJHQjhVbm9ybSA9IFwiZXRjMi1yZ2I4dW5vcm1cIiwgLy8gNHg0IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gOCBieXRlcyBwZXIgYmxvY2sgKDQgYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDggYml0IGludGVnZXIgUkdCLlxuXHRFVEMyUkdCOFVub3JtU1JHQiA9IFwiZXRjMi1yZ2I4dW5vcm0tc3JnYlwiLCAvLyA0eDQgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiA4IGJ5dGVzIHBlciBibG9jayAoNCBiaXQvcHgpLiBDb21wbGV4IHBhbGxldC4gOCBiaXQgaW50ZWdlciBSR0IuXG5cdEVUQzJSR0I4QTFVbm9ybSA9IFwiZXRjMi1yZ2I4YTF1bm9ybVwiLCAvLyA0eDQgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiA4IGJ5dGVzIHBlciBibG9jayAoNCBiaXQvcHgpLiBDb21wbGV4IHBhbGxldC4gOCBiaXQgaW50ZWdlciBSR0IgKyAxIGJpdCBhbHBoYS5cblx0RVRDMlJHQjhBMVVub3JtU1JHQiA9IFwiZXRjMi1yZ2I4YTF1bm9ybS1zcmdiXCIsIC8vIDR4NCBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDggYnl0ZXMgcGVyIGJsb2NrICg0IGJpdC9weCkuIENvbXBsZXggcGFsbGV0LiA4IGJpdCBpbnRlZ2VyIFJHQiArIDEgYml0IGFscGhhLlxuXHRFVEMyUkdCQThVbm9ybSA9IFwiZXRjMi1yZ2JhOHVub3JtXCIsIC8vIDR4NCBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoOCBiaXQvcHgpLiBDb21wbGV4IHBhbGxldC4gOCBiaXQgaW50ZWdlciBSR0IgKyA4IGJpdCBhbHBoYS5cblx0RVRDMlJHQkE4VW5vcm1TUkdCID0gXCJldGMyLXJnYmE4dW5vcm0tc3JnYlwiLCAvLyA0eDQgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiAxNiBieXRlcyBwZXIgYmxvY2sgKDggYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDggYml0IGludGVnZXIgUkdCICsgOCBiaXQgYWxwaGEuXG5cdEVBQ1IxMVVub3JtID0gXCJlYWMtcjExdW5vcm1cIiwgLy8gNHg0IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gOCBieXRlcyBwZXIgYmxvY2sgKDQgYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDExIGJpdCBpbnRlZ2VyIFIuXG5cdEVBQ1IxMVNub3JtID0gXCJlYWMtcjExc25vcm1cIiwgLy8gNHg0IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gOCBieXRlcyBwZXIgYmxvY2sgKDQgYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDExIGJpdCBpbnRlZ2VyIFIuXG5cdEVBQ1JHMTFVbm9ybSA9IFwiZWFjLXJnMTF1bm9ybVwiLCAvLyA0eDQgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiAxNiBieXRlcyBwZXIgYmxvY2sgKDggYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDExIGJpdCBpbnRlZ2VyIFIgKyAxMSBiaXQgaW50ZWdlciBHLlxuXHRFQUNSRzExU25vcm0gPSBcImVhYy1yZzExc25vcm1cIiwgLy8gNHg0IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gMTYgYnl0ZXMgcGVyIGJsb2NrICg4IGJpdC9weCkuIENvbXBsZXggcGFsbGV0LiAxMSBiaXQgaW50ZWdlciBSICsgMTEgYml0IGludGVnZXIgRy5cblxuXHQvLyBBU1RDIGNvbXByZXNzZWQgZm9ybWF0cyB1c2FibGUgaWYgXCJ0ZXh0dXJlLWNvbXByZXNzaW9uLWFzdGNcIiBpcyBib3RoXG5cdC8vIHN1cHBvcnRlZCBieSB0aGUgZGV2aWNlL3VzZXIgYWdlbnQgYW5kIGVuYWJsZWQgaW4gcmVxdWVzdERldmljZS5cblx0QVNUQzR4NFVub3JtID0gXCJhc3RjLTR4NC11bm9ybVwiLCAvLyA0eDQgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiAxNiBieXRlcyBwZXIgYmxvY2sgKDggYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDggYml0IGludGVnZXIgUkdCQS5cblx0QVNUQzR4NFVub3JtU1JHQiA9IFwiYXN0Yy00eDQtdW5vcm0tc3JnYlwiLCAvLyA0eDQgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiAxNiBieXRlcyBwZXIgYmxvY2sgKDggYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDggYml0IGludGVnZXIgUkdCQS5cblx0QVNUQzV4NFVub3JtID0gXCJhc3RjLTV4NC11bm9ybVwiLCAvLyA1eDQgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiAxNiBieXRlcyBwZXIgYmxvY2sgKDYuNCBiaXQvcHgpLiBDb21wbGV4IHBhbGxldC4gOCBiaXQgaW50ZWdlciBSR0JBLlxuXHRBU1RDNXg0VW5vcm1TUkdCID0gXCJhc3RjLTV4NC11bm9ybS1zcmdiXCIsIC8vIDV4NCBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoNi40IGJpdC9weCkuIENvbXBsZXggcGFsbGV0LiA4IGJpdCBpbnRlZ2VyIFJHQkEuXG5cdEFTVEM1eDVVbm9ybSA9IFwiYXN0Yy01eDUtdW5vcm1cIiwgLy8gNXg1IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gMTYgYnl0ZXMgcGVyIGJsb2NrICg1LjEyIGJpdC9weCkuIENvbXBsZXggcGFsbGV0LiA4IGJpdCBpbnRlZ2VyIFJHQkEuXG5cdEFTVEM1eDVVbm9ybVNSR0IgPSBcImFzdGMtNXg1LXVub3JtLXNyZ2JcIiwgLy8gNXg1IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gMTYgYnl0ZXMgcGVyIGJsb2NrICg1LjEyIGJpdC9weCkuIENvbXBsZXggcGFsbGV0LiA4IGJpdCBpbnRlZ2VyIFJHQkEuXG5cdEFTVEM2eDVVbm9ybSA9IFwiYXN0Yy02eDUtdW5vcm1cIiwgLy8gNng1IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gMTYgYnl0ZXMgcGVyIGJsb2NrICg0LjI3IGJpdC9weCkuIENvbXBsZXggcGFsbGV0LiA4IGJpdCBpbnRlZ2VyIFJHQkEuXG5cdEFTVEM2eDVVbm9ybVNSR0IgPSBcImFzdGMtNng1LXVub3JtLXNyZ2JcIiwgLy8gNng1IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gMTYgYnl0ZXMgcGVyIGJsb2NrICg0LjI3IGJpdC9weCkuIENvbXBsZXggcGFsbGV0LiA4IGJpdCBpbnRlZ2VyIFJHQkEuXG5cdEFTVEM2eDZVbm9ybSA9IFwiYXN0Yy02eDYtdW5vcm1cIiwgLy8gNng2IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gMTYgYnl0ZXMgcGVyIGJsb2NrICgzLjU2IGJpdC9weCkuIENvbXBsZXggcGFsbGV0LiA4IGJpdCBpbnRlZ2VyIFJHQkEuXG5cdEFTVEM2eDZVbm9ybVNSR0IgPSBcImFzdGMtNng2LXVub3JtLXNyZ2JcIiwgLy8gNng2IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gMTYgYnl0ZXMgcGVyIGJsb2NrICgzLjU2IGJpdC9weCkuIENvbXBsZXggcGFsbGV0LiA4IGJpdCBpbnRlZ2VyIFJHQkEuXG5cdEFTVEM4eDVVbm9ybSA9IFwiYXN0Yy04eDUtdW5vcm1cIiwgLy8gOHg1IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gMTYgYnl0ZXMgcGVyIGJsb2NrICgzLjIgYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDggYml0IGludGVnZXIgUkdCQS5cblx0QVNUQzh4NVVub3JtU1JHQiA9IFwiYXN0Yy04eDUtdW5vcm0tc3JnYlwiLCAvLyA4eDUgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiAxNiBieXRlcyBwZXIgYmxvY2sgKDMuMiBiaXQvcHgpLiBDb21wbGV4IHBhbGxldC4gOCBiaXQgaW50ZWdlciBSR0JBLlxuXHRBU1RDOHg2VW5vcm0gPSBcImFzdGMtOHg2LXVub3JtXCIsIC8vIDh4NiBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoMi42NyBiaXQvcHgpLiBDb21wbGV4IHBhbGxldC4gOCBiaXQgaW50ZWdlciBSR0JBLlxuXHRBU1RDOHg2VW5vcm1TUkdCID0gXCJhc3RjLTh4Ni11bm9ybS1zcmdiXCIsIC8vIDh4NiBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoMi42NyBiaXQvcHgpLiBDb21wbGV4IHBhbGxldC4gOCBiaXQgaW50ZWdlciBSR0JBLlxuXHRBU1RDOHg4VW5vcm0gPSBcImFzdGMtOHg4LXVub3JtXCIsIC8vIDh4OCBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoMiBiaXQvcHgpLiBDb21wbGV4IHBhbGxldC4gOCBiaXQgaW50ZWdlciBSR0JBLlxuXHRBU1RDOHg4VW5vcm1TUkdCID0gXCJhc3RjLTh4OC11bm9ybS1zcmdiXCIsIC8vIDh4OCBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoMiBiaXQvcHgpLiBDb21wbGV4IHBhbGxldC4gOCBiaXQgaW50ZWdlciBSR0JBLlxuXHRBU1RDMTB4NVVub3JtID0gXCJhc3RjLTEweDUtdW5vcm1cIiwgLy8gMTB4NSBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoMi41NiBiaXQvcHgpLiBDb21wbGV4IHBhbGxldC4gOCBiaXQgaW50ZWdlciBSR0JBLlxuXHRBU1RDMTB4NVVub3JtU1JHQiA9IFwiYXN0Yy0xMHg1LXVub3JtLXNyZ2JcIiwgLy8gMTB4NSBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoMi41NiBiaXQvcHgpLiBDb21wbGV4IHBhbGxldC4gOCBiaXQgaW50ZWdlciBSR0JBLlxuXHRBU1RDMTB4NlVub3JtID0gXCJhc3RjLTEweDYtdW5vcm1cIiwgLy8gMTB4NiBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoMi4xMyBiaXQvcHgpLiBDb21wbGV4IHBhbGxldC4gOCBiaXQgaW50ZWdlciBSR0JBLlxuXHRBU1RDMTB4NlVub3JtU1JHQiA9IFwiYXN0Yy0xMHg2LXVub3JtLXNyZ2JcIiwgLy8gMTB4NiBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoMi4xMyBiaXQvcHgpLiBDb21wbGV4IHBhbGxldC4gOCBiaXQgaW50ZWdlciBSR0JBLlxuXHRBU1RDMTB4OFVub3JtID0gXCJhc3RjLTEweDgtdW5vcm1cIiwgLy8gMTB4OCBibG9jayBjb21wcmVzc2VkIHRleHR1cmUuIDE2IGJ5dGVzIHBlciBibG9jayAoMS42IGJpdC9weCkuIENvbXBsZXggcGFsbGV0LiA4IGJpdCBpbnRlZ2VyIFJHQkEuXG5cdEFTVEMxMHg4VW5vcm1TUkdCID0gXCJhc3RjLTEweDgtdW5vcm0tc3JnYlwiLCAvLyAxMHg4IGJsb2NrIGNvbXByZXNzZWQgdGV4dHVyZS4gMTYgYnl0ZXMgcGVyIGJsb2NrICgxLjYgYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDggYml0IGludGVnZXIgUkdCQS5cblx0QVNUQzEweDEwVW5vcm0gPSBcImFzdGMtMTB4MTAtdW5vcm1cIiwgLy8gMTB4MTAgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiAxNiBieXRlcyBwZXIgYmxvY2sgKDEuMjggYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDggYml0IGludGVnZXIgUkdCQS5cblx0QVNUQzEweDEwVW5vcm1TUkdCID0gXCJhc3RjLTEweDEwLXVub3JtLXNyZ2JcIiwgLy8gMTB4MTAgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiAxNiBieXRlcyBwZXIgYmxvY2sgKDEuMjggYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDggYml0IGludGVnZXIgUkdCQS5cblx0QVNUQzEyeDEwVW5vcm0gPSBcImFzdGMtMTJ4MTAtdW5vcm1cIiwgLy8gMTJ4MTAgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiAxNiBieXRlcyBwZXIgYmxvY2sgKDEuMDcgYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDggYml0IGludGVnZXIgUkdCQS5cblx0QVNUQzEyeDEwVW5vcm1TUkdCID0gXCJhc3RjLTEyeDEwLXVub3JtLXNyZ2JcIiwgLy8gMTJ4MTAgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiAxNiBieXRlcyBwZXIgYmxvY2sgKDEuMDcgYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDggYml0IGludGVnZXIgUkdCQS5cblx0QVNUQzEyeDEyVW5vcm0gPSBcImFzdGMtMTJ4MTItdW5vcm1cIiwgLy8gMTJ4MTIgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiAxNiBieXRlcyBwZXIgYmxvY2sgKDAuODkgYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDggYml0IGludGVnZXIgUkdCQS5cblx0QVNUQzEyeDEyVW5vcm1TUkdCID0gXCJhc3RjLTEyeDEyLXVub3JtLXNyZ2JcIiwgLy8gMTJ4MTIgYmxvY2sgY29tcHJlc3NlZCB0ZXh0dXJlLiAxNiBieXRlcyBwZXIgYmxvY2sgKDAuODkgYml0L3B4KS4gQ29tcGxleCBwYWxsZXQuIDggYml0IGludGVnZXIgUkdCQS5cblxuXHQvLyBcImRlcHRoMjR1bm9ybS1zdGVuY2lsOFwiIGZlYXR1cmVcblx0RGVwdGgyNFVub3JtU3RlbmNpbDggPSBcImRlcHRoMjR1bm9ybS1zdGVuY2lsOFwiLFxuXG5cdC8vIFwiZGVwdGgzMmZsb2F0LXN0ZW5jaWw4XCIgZmVhdHVyZVxuXHREZXB0aDMyRmxvYXRTdGVuY2lsOCA9IFwiZGVwdGgzMmZsb2F0LXN0ZW5jaWw4XCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gQWRkcmVzc01vZGUge1xuXHRDbGFtcFRvRWRnZSA9IFwiY2xhbXAtdG8tZWRnZVwiLFxuXHRSZXBlYXQgPSBcInJlcGVhdFwiLFxuXHRNaXJyb3JSZXBlYXQgPSBcIm1pcnJvci1yZXBlYXRcIlxufVxuXG4vKiogQGludGVybmFsICovXG5leHBvcnQgZW51bSBGaWx0ZXJNb2RlIHtcblx0TmVhcmVzdCA9IFwibmVhcmVzdFwiLFxuXHRMaW5lYXIgPSBcImxpbmVhclwiXG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBlbnVtIENvbXBhcmVGdW5jdGlvbiB7XG5cdE5ldmVyID0gXCJuZXZlclwiLFxuXHRMZXNzID0gXCJsZXNzXCIsXG5cdEVxdWFsID0gXCJlcXVhbFwiLFxuXHRMZXNzRXF1YWwgPSBcImxlc3MtZXF1YWxcIixcblx0R3JlYXRlciA9IFwiZ3JlYXRlclwiLFxuXHROb3RFcXVhbCA9IFwibm90LWVxdWFsXCIsXG5cdEdyZWF0ZXJFcXVhbCA9IFwiZ3JlYXRlci1lcXVhbFwiLFxuXHRBbHdheXMgPSBcImFsd2F5c1wiXG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBlbnVtIFNoYWRlclN0YWdlIHtcblx0VmVydGV4ID0gMSxcblx0RnJhZ21lbnQgPSAyLFxuXHRDb21wdXRlID0gNFxufVxuXG4vKiogQGludGVybmFsICovXG5leHBvcnQgZW51bSBCdWZmZXJCaW5kaW5nVHlwZSB7XG5cdFVuaWZvcm0gPSBcInVuaWZvcm1cIixcblx0U3RvcmFnZSA9IFwic3RvcmFnZVwiLFxuXHRSZWFkT25seVN0b3JhZ2UgPSBcInJlYWQtb25seS1zdG9yYWdlXCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gU2FtcGxlckJpbmRpbmdUeXBlIHtcblx0RmlsdGVyaW5nID0gXCJmaWx0ZXJpbmdcIixcblx0Tm9uRmlsdGVyaW5nID0gXCJub24tZmlsdGVyaW5nXCIsXG5cdENvbXBhcmlzb24gPSBcImNvbXBhcmlzb25cIlxufVxuXG4vKiogQGludGVybmFsICovXG5leHBvcnQgZW51bSBUZXh0dXJlU2FtcGxlVHlwZSB7XG5cdEZsb2F0ID0gXCJmbG9hdFwiLFxuXHRVbmZpbHRlcmFibGVGbG9hdCA9IFwidW5maWx0ZXJhYmxlLWZsb2F0XCIsXG5cdERlcHRoID0gXCJkZXB0aFwiLFxuXHRTaW50ID0gXCJzaW50XCIsXG5cdFVpbnQgPSBcInVpbnRcIlxufVxuXG4vKiogQGludGVybmFsICovXG5leHBvcnQgZW51bSBTdG9yYWdlVGV4dHVyZUFjY2VzcyB7XG5cdFdyaXRlT25seSA9IFwid3JpdGUtb25seVwiXG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBlbnVtIENvbXBpbGF0aW9uTWVzc2FnZVR5cGUge1xuXHRFcnJvciA9IFwiZXJyb3JcIixcblx0V2FybmluZyA9IFwid2FybmluZ1wiLFxuXHRJbmZvID0gXCJpbmZvXCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gQXV0b0xheW91dE1vZGUge1xuXHRBdXRvID0gXCJhdXRvXCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gUHJpbWl0aXZlVG9wb2xvZ3kge1xuXHRQb2ludExpc3QgPSBcInBvaW50LWxpc3RcIixcblx0TGluZUxpc3QgPSBcImxpbmUtbGlzdFwiLFxuXHRMaW5lU3RyaXAgPSBcImxpbmUtc3RyaXBcIixcblx0VHJpYW5nbGVMaXN0ID0gXCJ0cmlhbmdsZS1saXN0XCIsXG5cdFRyaWFuZ2xlU3RyaXAgPSBcInRyaWFuZ2xlLXN0cmlwXCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gRnJvbnRGYWNlIHtcblx0Q0NXID0gXCJjY3dcIixcblx0Q1cgPSBcImN3XCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gQ3VsbE1vZGUge1xuXHROb25lID0gXCJub25lXCIsXG5cdEZyb250ID0gXCJmcm9udFwiLFxuXHRCYWNrID0gXCJiYWNrXCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gQ29sb3JXcml0ZUZsYWdzIHtcblx0UmVkID0gMSxcblx0R3JlZW4gPSAyLFxuXHRCbHVlID0gNCxcblx0QWxwaGEgPSA4LFxuXHRBbGwgPSAxNVxufVxuXG4vKiogQGludGVybmFsICovXG5leHBvcnQgZW51bSBCbGVuZEZhY3RvciB7XG5cdFplcm8gPSBcInplcm9cIixcblx0T25lID0gXCJvbmVcIixcblx0U3JjID0gXCJzcmNcIixcblx0T25lTWludXNTcmMgPSBcIm9uZS1taW51cy1zcmNcIixcblx0U3JjQWxwaGEgPSBcInNyYy1hbHBoYVwiLFxuXHRPbmVNaW51c1NyY0FscGhhID0gXCJvbmUtbWludXMtc3JjLWFscGhhXCIsXG5cdERzdCA9IFwiZHN0XCIsXG5cdE9uZU1pbnVzRHN0ID0gXCJvbmUtbWludXMtZHN0XCIsXG5cdERzdEFscGhhID0gXCJkc3QtYWxwaGFcIixcblx0T25lTWludXNEc3RBbHBoYSA9IFwib25lLW1pbnVzLWRzdC1hbHBoYVwiLFxuXHRTcmNBbHBoYVNhdHVyYXRlZCA9IFwic3JjLWFscGhhLXNhdHVyYXRlZFwiLFxuXHRDb25zdGFudCA9IFwiY29uc3RhbnRcIixcblx0T25lTWludXNDb25zdGFudCA9IFwib25lLW1pbnVzLWNvbnN0YW50XCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gQmxlbmRPcGVyYXRpb24ge1xuXHRBZGQgPSBcImFkZFwiLFxuXHRTdWJ0cmFjdCA9IFwic3VidHJhY3RcIixcblx0UmV2ZXJzZVN1YnRyYWN0ID0gXCJyZXZlcnNlLXN1YnRyYWN0XCIsXG5cdE1pbiA9IFwibWluXCIsXG5cdE1heCA9IFwibWF4XCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gU3RlbmNpbE9wZXJhdGlvbiB7XG5cdEtlZXAgPSBcImtlZXBcIixcblx0WmVybyA9IFwiemVyb1wiLFxuXHRSZXBsYWNlID0gXCJyZXBsYWNlXCIsXG5cdEludmVydCA9IFwiaW52ZXJ0XCIsXG5cdEluY3JlbWVudENsYW1wID0gXCJpbmNyZW1lbnQtY2xhbXBcIixcblx0RGVjcmVtZW50Q2xhbXAgPSBcImRlY3JlbWVudC1jbGFtcFwiLFxuXHRJbmNyZW1lbnRXcmFwID0gXCJpbmNyZW1lbnQtd3JhcFwiLFxuXHREZWNyZW1lbnRXcmFwID0gXCJkZWNyZW1lbnQtd3JhcFwiXG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBlbnVtIEluZGV4Rm9ybWF0IHtcblx0VWludDE2ID0gXCJ1aW50MTZcIixcblx0VWludDMyID0gXCJ1aW50MzJcIlxufVxuXG4vKiogQGludGVybmFsICovXG5leHBvcnQgZW51bSBWZXJ0ZXhGb3JtYXQge1xuXHRVaW50OHgyID0gXCJ1aW50OHgyXCIsXG5cdFVpbnQ4eDQgPSBcInVpbnQ4eDRcIixcblx0U2ludDh4MiA9IFwic2ludDh4MlwiLFxuXHRTaW50OHg0ID0gXCJzaW50OHg0XCIsXG5cdFVub3JtOHgyID0gXCJ1bm9ybTh4MlwiLFxuXHRVbm9ybTh4NCA9IFwidW5vcm04eDRcIixcblx0U25vcm04eDIgPSBcInNub3JtOHgyXCIsXG5cdFNub3JtOHg0ID0gXCJzbm9ybTh4NFwiLFxuXHRVaW50MTZ4MiA9IFwidWludDE2eDJcIixcblx0VWludDE2eDQgPSBcInVpbnQxNng0XCIsXG5cdFNpbnQxNngyID0gXCJzaW50MTZ4MlwiLFxuXHRTaW50MTZ4NCA9IFwic2ludDE2eDRcIixcblx0VW5vcm0xNngyID0gXCJ1bm9ybTE2eDJcIixcblx0VW5vcm0xNng0ID0gXCJ1bm9ybTE2eDRcIixcblx0U25vcm0xNngyID0gXCJzbm9ybTE2eDJcIixcblx0U25vcm0xNng0ID0gXCJzbm9ybTE2eDRcIixcblx0RmxvYXQxNngyID0gXCJmbG9hdDE2eDJcIixcblx0RmxvYXQxNng0ID0gXCJmbG9hdDE2eDRcIixcblx0RmxvYXQzMiA9IFwiZmxvYXQzMlwiLFxuXHRGbG9hdDMyeDIgPSBcImZsb2F0MzJ4MlwiLFxuXHRGbG9hdDMyeDMgPSBcImZsb2F0MzJ4M1wiLFxuXHRGbG9hdDMyeDQgPSBcImZsb2F0MzJ4NFwiLFxuXHRVaW50MzIgPSBcInVpbnQzMlwiLFxuXHRVaW50MzJ4MiA9IFwidWludDMyeDJcIixcblx0VWludDMyeDMgPSBcInVpbnQzMngzXCIsXG5cdFVpbnQzMng0ID0gXCJ1aW50MzJ4NFwiLFxuXHRTaW50MzIgPSBcInNpbnQzMlwiLFxuXHRTaW50MzJ4MiA9IFwic2ludDMyeDJcIixcblx0U2ludDMyeDMgPSBcInNpbnQzMngzXCIsXG5cdFNpbnQzMng0ID0gXCJzaW50MzJ4NFwiXG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBlbnVtIElucHV0U3RlcE1vZGUge1xuXHRWZXJ0ZXggPSBcInZlcnRleFwiLFxuXHRJbnN0YW5jZSA9IFwiaW5zdGFuY2VcIlxufVxuXG4vKiogQGludGVybmFsICovXG5leHBvcnQgZW51bSBDb21wdXRlUGFzc1RpbWVzdGFtcExvY2F0aW9uIHtcblx0QmVnaW5uaW5nID0gXCJiZWdpbm5pbmdcIixcblx0RW5kID0gXCJlbmRcIlxufVxuXG4vKiogQGludGVybmFsICovXG5leHBvcnQgZW51bSBSZW5kZXJQYXNzVGltZXN0YW1wTG9jYXRpb24ge1xuXHRCZWdpbm5pbmcgPSBcImJlZ2lubmluZ1wiLFxuXHRFbmQgPSBcImVuZFwiXG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBlbnVtIExvYWRPcCB7XG5cdExvYWQgPSBcImxvYWRcIixcblx0Q2xlYXIgPSBcImNsZWFyXCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gU3RvcmVPcCB7XG5cdFN0b3JlID0gXCJzdG9yZVwiLFxuXHREaXNjYXJkID0gXCJkaXNjYXJkXCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gUXVlcnlUeXBlIHtcblx0T2NjbHVzaW9uID0gXCJvY2NsdXNpb25cIixcblx0VGltZXN0YW1wID0gXCJ0aW1lc3RhbXBcIlxufVxuXG4vKiogQGludGVybmFsICovXG5leHBvcnQgZW51bSBDYW52YXNBbHBoYU1vZGUge1xuXHRPcGFxdWUgPSBcIm9wYXF1ZVwiLFxuXHRQcmVtdWx0aXBsaWVkID0gXCJwcmVtdWx0aXBsaWVkXCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gRGV2aWNlTG9zdFJlYXNvbiB7XG5cdERlc3Ryb3llZCA9IFwiZGVzdHJveWVkXCJcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGVudW0gRXJyb3JGaWx0ZXIge1xuXHRPdXRPZk1lbW9yeSA9IFwib3V0LW9mLW1lbW9yeVwiLFxuXHRWYWxpZGF0aW9uID0gXCJ2YWxpZGF0aW9uXCJcbn1cblxuZXhwb3J0IGVudW0gR1BVQ29sb3JXcml0ZSB7XG5cdFJlZCA9IDB4MSxcblx0R3JlZW4gPSAweDIsXG5cdEJsdWUgPSAweDQsXG5cdEFscGhhID0gMHg4LFxuXHRBbGwgPSAweGZcbn1cbmV4cG9ydCBlbnVtIENvbW1hbmRTdWJUeXBlIHtcblx0U2hhZG93ID0gXCJzaGFkb3dcIixcblx0UGljayA9IFwicGlja1wiXG59XG5leHBvcnQgZW51bSBJbnRlcnNlY3Qge1xuXHRPVVRTSURFID0gLTEsXG5cdElOVEVSU0VDVElORyA9IDAsXG5cdElOU0lERSA9IDFcbn1cbiIsImltcG9ydCB7IEJ1ZmZlclVzYWdlIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVQ29uc3RhbnRcIjtcbmNsYXNzIEJ1ZmZlciB7XG5cdHB1YmxpYyBncHVCdWZmZXI6IEdQVUJ1ZmZlcjtcblx0ZGV2aWNlOiBHUFVEZXZpY2U7XG5cdHVzYWdlOiBudW1iZXI7XG5cdGRhdGE6IEFycmF5QnVmZmVyVmlldztcblx0c2l6ZTogbnVtYmVyO1xuXHRjb25zdHJ1Y3Rvcihcblx0XHRsYWJlbDogc3RyaW5nLFxuXHRcdGRldmljZTogR1BVRGV2aWNlLFxuXHRcdHVzYWdlOiBHUFVCdWZmZXJVc2FnZUZsYWdzLFxuXHRcdGRhdGE6IEFycmF5QnVmZmVyVmlldyB8IG51bGwsXG5cdFx0c2l6ZT86IG51bWJlclxuXHQpIHtcblx0XHR0aGlzLmRldmljZSA9IGRldmljZTtcblx0XHR0aGlzLnVzYWdlID0gdXNhZ2U7XG5cdFx0dGhpcy5kYXRhID0gZGF0YTtcblx0XHR0aGlzLnNpemUgPSBzaXplICE9IHVuZGVmaW5lZCA/IChzaXplICsgMykgJiB+MyA6IChkYXRhLmJ5dGVMZW5ndGggKyAzKSAmIH4zOyAvLyA0IGJ5dGVzIGFsaWdubWVudHMgKGJlY2F1c2Ugb2YgdGhlIHVwbG9hZCB3aGljaCByZXF1aXJlcyB0aGlzKVxuXHRcdHRoaXMuZ3B1QnVmZmVyID0gZGV2aWNlLmNyZWF0ZUJ1ZmZlcih7XG5cdFx0XHRsYWJlbDogbGFiZWwgfHwgXCJcIixcblx0XHRcdHNpemU6IHRoaXMuc2l6ZSxcblx0XHRcdHVzYWdlXG5cdFx0fSk7XG5cdFx0aWYgKGRhdGEpIHRoaXMuc2V0U3ViRGF0YSgwLCBkYXRhLCB0aGlzLnNpemUpO1xuXHR9XG5cdHN0YXRpYyBjcmVhdGUoXG5cdFx0bGFiZWw6IHN0cmluZyxcblx0XHRkZXZpY2U6IEdQVURldmljZSxcblx0XHR1c2FnZTogR1BVQnVmZmVyVXNhZ2VGbGFncyxcblx0XHRkYXRhOiBBcnJheUJ1ZmZlclZpZXcgfCBudWxsLFxuXHRcdHNpemU/OiBudW1iZXJcblx0KSB7XG5cdFx0cmV0dXJuIG5ldyBCdWZmZXIobGFiZWwsIGRldmljZSwgdXNhZ2UsIGRhdGEsIHNpemUpO1xuXHR9XG5cdHN0YXRpYyBjcmVhdGVWZXJ0ZXhCdWZmZXIobGFiZWw6IHN0cmluZywgZGV2aWNlOiBHUFVEZXZpY2UsIGRhdGE6IEFycmF5QnVmZmVyVmlldyk6IEJ1ZmZlciB7XG5cdFx0cmV0dXJuIG5ldyBCdWZmZXIobGFiZWwsIGRldmljZSwgQnVmZmVyVXNhZ2UuVmVydGV4IHwgQnVmZmVyVXNhZ2UuQ29weURzdCwgZGF0YSwgZGF0YS5ieXRlTGVuZ3RoKTtcblx0fVxuXG5cdHN0YXRpYyBjcmVhdGVJbmRleEJ1ZmZlcihsYWJlbDogc3RyaW5nLCBkZXZpY2U6IEdQVURldmljZSwgZGF0YTogQXJyYXlCdWZmZXJWaWV3KTogQnVmZmVyIHtcblx0XHRyZXR1cm4gbmV3IEJ1ZmZlcihsYWJlbCwgZGV2aWNlLCBCdWZmZXJVc2FnZS5JbmRleCB8IEJ1ZmZlclVzYWdlLkNvcHlEc3QsIGRhdGEpO1xuXHR9XG5cblx0c3RhdGljIGNyZWF0ZVVuaWZvcm1CdWZmZXIobGFiZWw6IHN0cmluZywgZGV2aWNlOiBHUFVEZXZpY2UsIHNpemU6IG51bWJlciwgdXNhZ2U/OiBCdWZmZXJVc2FnZSk6IEJ1ZmZlciB7XG5cdFx0cmV0dXJuIG5ldyBCdWZmZXIobGFiZWwsIGRldmljZSwgdXNhZ2UsIG51bGwsIHNpemUpO1xuXHR9XG5cblx0c3RhdGljIGNyZWF0ZVN0b3JhZ2VCdWZmZXIobGFiZWw6IHN0cmluZywgZGV2aWNlOiBHUFVEZXZpY2UsIHNpemU6IG51bWJlciwgdXNhZ2UgPSBCdWZmZXJVc2FnZS5TdG9yYWdlKTogQnVmZmVyIHtcblx0XHRyZXR1cm4gbmV3IEJ1ZmZlcihsYWJlbCwgZGV2aWNlLCB1c2FnZSwgbnVsbCwgc2l6ZSk7XG5cdH1cblx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2dwdXdlYi9ncHV3ZWIvYmxvYi9tYWluL2Rlc2lnbi9CdWZmZXJPcGVyYXRpb25zLm1kXG5cdHB1YmxpYyBzZXRTdWJEYXRhKG9mZnNldDogbnVtYmVyLCBkYXRhOiBBcnJheUJ1ZmZlclZpZXcsIHNpemU/OiBudW1iZXIpOiB2b2lkIHtcblx0XHRjb25zdCBzcmNBcnJheUJ1ZmZlciA9IGRhdGEuYnVmZmVyO1xuXHRcdGNvbnN0IGJ5dGVDb3VudCA9IHNpemUgPz8gc3JjQXJyYXlCdWZmZXIuYnl0ZUxlbmd0aDtcblx0XHRjb25zdCBzcmNCdWZmZXIgPSB0aGlzLmRldmljZS5jcmVhdGVCdWZmZXIoe1xuXHRcdFx0bWFwcGVkQXRDcmVhdGlvbjogdHJ1ZSxcblx0XHRcdHNpemU6IGJ5dGVDb3VudCxcblx0XHRcdHVzYWdlOiBHUFVCdWZmZXJVc2FnZS5DT1BZX1NSQ1xuXHRcdH0pO1xuXHRcdGNvbnN0IGFycmF5QnVmZmVyID0gc3JjQnVmZmVyLmdldE1hcHBlZFJhbmdlKCk7XG5cblx0XHRuZXcgVWludDE2QXJyYXkoYXJyYXlCdWZmZXIpLnNldChuZXcgVWludDE2QXJyYXkoc3JjQXJyYXlCdWZmZXIpKTsgLy8gbWVtY3B5XG5cdFx0c3JjQnVmZmVyLnVubWFwKCk7XG5cblx0XHR0aGlzLmNvcHlUb0J1ZmZlcihzcmNCdWZmZXIsIG9mZnNldCwgYnl0ZUNvdW50KTtcblxuXHRcdHNyY0J1ZmZlci5kZXN0cm95KCk7XG5cdH1cblxuXHRwdWJsaWMgY29weVRvQnVmZmVyKHNyY0J1ZmZlcjogR1BVQnVmZmVyLCBvZmZzZXQ6IG51bWJlciwgYnl0ZUNvdW50OiBudW1iZXIpOiB2b2lkIHtcblx0XHRjb25zdCBjb21tYW5kRW5jb2RlciA9IHRoaXMuZGV2aWNlLmNyZWF0ZUNvbW1hbmRFbmNvZGVyKCk7XG5cdFx0Y29tbWFuZEVuY29kZXIuY29weUJ1ZmZlclRvQnVmZmVyKHNyY0J1ZmZlciwgMCwgdGhpcy5ncHVCdWZmZXIsIG9mZnNldCwgYnl0ZUNvdW50KTtcblx0XHR0aGlzLmRldmljZS5xdWV1ZS5zdWJtaXQoW2NvbW1hbmRFbmNvZGVyLmZpbmlzaCgpXSk7XG5cdH1cblxuXHRwdWJsaWMgY29weVRvVGV4dHVyZShcblx0XHRieXRlc1BlclJvdzogbnVtYmVyLFxuXHRcdHJvd3NQZXJJbWFnZTogbnVtYmVyLFxuXHRcdGRlc3RpbmF0aW9uOiBHUFVJbWFnZUNvcHlUZXh0dXJlLFxuXHRcdGV4dGVudDogR1BVRXh0ZW50M0Rcblx0KTogdm9pZCB7XG5cdFx0Y29uc3QgY29tbWFuZEVuY29kZXIgPSB0aGlzLmRldmljZS5jcmVhdGVDb21tYW5kRW5jb2RlcigpO1xuXHRcdGNvbW1hbmRFbmNvZGVyLmNvcHlCdWZmZXJUb1RleHR1cmUoXG5cdFx0XHR7XG5cdFx0XHRcdGJ1ZmZlcjogdGhpcy5ncHVCdWZmZXIsXG5cdFx0XHRcdGJ5dGVzUGVyUm93LFxuXHRcdFx0XHRyb3dzUGVySW1hZ2Vcblx0XHRcdH0sXG5cdFx0XHRkZXN0aW5hdGlvbixcblx0XHRcdGV4dGVudFxuXHRcdCk7XG5cdFx0dGhpcy5kZXZpY2UucXVldWUuc3VibWl0KFtjb21tYW5kRW5jb2Rlci5maW5pc2goKV0pO1xuXHR9XG5cblx0cHVibGljIGRlc3Ryb3koKTogdm9pZCB7XG5cdFx0dGhpcy5ncHVCdWZmZXIuZGVzdHJveSgpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEJ1ZmZlcjtcbiIsImltcG9ydCBCaW5kR3JvdXBMYXlvdXQgZnJvbSBcIi4vQmluZEdyb3VwTGF5b3V0XCI7XHJcblxyXG5jb25zdCBwaXBlbGluZUxheW91dENhY2hlID0gbmV3IE1hcCgpO1xyXG5leHBvcnQgY2xhc3MgUGlwZWxpbmVMYXlvdXQge1xyXG4gIHB1YmxpYyBncHVQaXBlbGluZUxheW91dDogR1BVUGlwZWxpbmVMYXlvdXQ7XHJcbiAgaW5kZXg6IG51bWJlcjtcclxuICBwcml2YXRlIGNvbnN0cnVjdG9yKFxyXG4gICAgZGV2aWNlOiBHUFVEZXZpY2UsXHJcbiAgICBsYWJlbDogc3RyaW5nLFxyXG4gICAgcHVibGljIGdyb3VwTGF5b3V0czogQmluZEdyb3VwTGF5b3V0W10gPSBbXSxcclxuICAgIGluZGV4PzogbnVtYmVyXHJcbiAgKSB7XHJcbiAgICB0aGlzLmluZGV4ID0gaW5kZXggfHwgMDtcclxuICAgIHRoaXMuZ3B1UGlwZWxpbmVMYXlvdXQgPSBkZXZpY2UuY3JlYXRlUGlwZWxpbmVMYXlvdXQoe1xyXG4gICAgICBsYWJlbDogbGFiZWwsXHJcbiAgICAgIGJpbmRHcm91cExheW91dHM6IGdyb3VwTGF5b3V0cy5tYXAoKGxheW91dCkgPT4ge1xyXG4gICAgICAgIHJldHVybiBsYXlvdXQuZ3B1QmluZEdyb3VwTGF5b3V0O1xyXG4gICAgICB9KSxcclxuICAgIH0pO1xyXG4gIH1cclxuICBzdGF0aWMgZ2V0UGlwZWxpbmVMYXlvdXRGcm9tQ2FjaGUoXHJcbiAgICBkZXZpY2U6IEdQVURldmljZSxcclxuICAgIGxhYmVsOiBzdHJpbmcsXHJcbiAgICBncm91cExheW91dHM6IEJpbmRHcm91cExheW91dFtdXHJcbiAgKTogUGlwZWxpbmVMYXlvdXQge1xyXG4gICAgaWYgKHBpcGVsaW5lTGF5b3V0Q2FjaGUuaGFzKGxhYmVsKSkge1xyXG4gICAgICByZXR1cm4gcGlwZWxpbmVMYXlvdXRDYWNoZS5nZXQobGFiZWwpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgYmluZEdyb3VwTGF5b3V0ID0gbmV3IFBpcGVsaW5lTGF5b3V0KGRldmljZSwgbGFiZWwsIGdyb3VwTGF5b3V0cyk7XHJcbiAgICAgIHBpcGVsaW5lTGF5b3V0Q2FjaGUuc2V0KGxhYmVsLCBiaW5kR3JvdXBMYXlvdXQpO1xyXG4gICAgICByZXR1cm4gYmluZEdyb3VwTGF5b3V0O1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCJpbXBvcnQgQmluZEdyb3VwTGF5b3V0IGZyb20gXCIuL0JpbmRHcm91cExheW91dFwiO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbW1hbmQgfSBmcm9tIFwiLi9Db21wdXRlQ29tbWFuZFwiO1xuaW1wb3J0IERyYXdDb21tYW5kIGZyb20gXCIuL0RyYXdDb21tYW5kXCI7XG5pbXBvcnQgeyBQaXBlbGluZUxheW91dCB9IGZyb20gXCIuL1BpcGVsaW5lTGF5b3V0XCI7XG5pbXBvcnQgeyBSZW5kZXJTdGF0ZSB9IGZyb20gXCIuL1JlbmRlclN0YXRlXCI7XG5cbmNvbnN0IHJlbmRlclBpcGVsaW5lcyA9IG5ldyBNYXAoKTtcbmNvbnN0IGNvbXB1dGVQaXBlbGluZXMgPSBuZXcgTWFwKCk7XG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQaXBlbGluZSB7XG5cdGdwdVBpcGVsaW5lOiBHUFVSZW5kZXJQaXBlbGluZSB8IEdQVUNvbXB1dGVQaXBlbGluZTtcblx0dHlwZTogc3RyaW5nO1xuXHRkZXZpY2U6IEdQVURldmljZTtcblx0ZGVzY3JpcHRvcjogR1BVUmVuZGVyUGlwZWxpbmVEZXNjcmlwdG9yIHwgR1BVQ29tcHV0ZVBpcGVsaW5lRGVzY3JpcHRvcjtcblx0Y29uc3RydWN0b3IoXG5cdFx0dHlwZTogc3RyaW5nLFxuXHRcdGRldmljZTogR1BVRGV2aWNlLFxuXHRcdGRlc2NyaXB0b3I6IEdQVVJlbmRlclBpcGVsaW5lRGVzY3JpcHRvciB8IEdQVUNvbXB1dGVQaXBlbGluZURlc2NyaXB0b3Jcblx0KSB7XG5cdFx0dGhpcy50eXBlID0gdHlwZTtcblx0XHR0aGlzLmRlc2NyaXB0b3IgPSBkZXNjcmlwdG9yO1xuXHRcdHRoaXMuZGV2aWNlID0gZGV2aWNlO1xuXHRcdHRoaXMuY3JlYXRlUGlwZWxpbmUoKTtcblx0fVxuXHRwcml2YXRlIGNyZWF0ZVBpcGVsaW5lKCkge1xuXHRcdGlmICh0aGlzLnR5cGUgPT0gXCJyZW5kZXJcIikge1xuXHRcdFx0dGhpcy5ncHVQaXBlbGluZSA9IHRoaXMuZGV2aWNlLmNyZWF0ZVJlbmRlclBpcGVsaW5lKHRoaXMuZGVzY3JpcHRvciBhcyBHUFVSZW5kZXJQaXBlbGluZURlc2NyaXB0b3IpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLmdwdVBpcGVsaW5lID0gdGhpcy5kZXZpY2UuY3JlYXRlQ29tcHV0ZVBpcGVsaW5lKHRoaXMuZGVzY3JpcHRvciBhcyBHUFVDb21wdXRlUGlwZWxpbmVEZXNjcmlwdG9yKTtcblx0XHR9XG5cdH1cblx0cHVibGljIGJpbmQocGFzc0VuY29kZXI6IEdQVVJlbmRlclBhc3NFbmNvZGVyIHwgR1BVQ29tcHV0ZVBhc3NFbmNvZGVyKSB7XG5cdFx0aWYgKHRoaXMudHlwZSA9PSBcInJlbmRlclwiKSB7XG5cdFx0XHQocGFzc0VuY29kZXIgYXMgR1BVUmVuZGVyUGFzc0VuY29kZXIpLnNldFBpcGVsaW5lKHRoaXMuZ3B1UGlwZWxpbmUgYXMgR1BVUmVuZGVyUGlwZWxpbmUpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQocGFzc0VuY29kZXIgYXMgR1BVQ29tcHV0ZVBhc3NFbmNvZGVyKS5zZXRQaXBlbGluZSh0aGlzLmdwdVBpcGVsaW5lIGFzIEdQVUNvbXB1dGVQaXBlbGluZSk7XG5cdFx0fVxuXHR9XG5cdHN0YXRpYyBnZXRSZW5kZXJQaXBlbGluZUZyb21DYWNoZShcblx0XHRkZXZpY2U6IEdQVURldmljZSxcblx0XHRkcmF3Q29tYW5kOiBEcmF3Q29tbWFuZCxcblx0XHRncm91cExheW91dHM6IEJpbmRHcm91cExheW91dFtdXG5cdCk6IFBpcGVsaW5lIHtcblx0XHRjb25zdCB7IHJlbmRlclN0YXRlLCBzaGFkZXJTb3VyY2UgfSA9IGRyYXdDb21hbmQ7XG5cdFx0Y29uc3QgcnNTdHIgPSBKU09OLnN0cmluZ2lmeShyZW5kZXJTdGF0ZSk7XG5cdFx0Y29uc3QgY29tYmluZVN0ciA9IHNoYWRlclNvdXJjZS51aWQuY29uY2F0KHJzU3RyKTtcblx0XHRjb25zdCBoYXNoSWQgPSBzdHJpbmdUb0hhc2goY29tYmluZVN0cik7XG5cdFx0Y29uc3QgY29tYmluZUxheW91dHMgPSBncm91cExheW91dHNcblx0XHRcdD8uZmlsdGVyKChsYXlvdXQpID0+IGxheW91dCAhPSB1bmRlZmluZWQpXG5cdFx0XHQ/LnNvcnQoKGxheW91dDEsIGxheW91dDIpID0+IGxheW91dDEuaW5kZXggLSBsYXlvdXQyLmluZGV4KTtcblx0XHRsZXQgcGlwZWxpbmUgPSByZW5kZXJQaXBlbGluZXMuZ2V0KGhhc2hJZCk7XG5cdFx0aWYgKCFwaXBlbGluZSkge1xuXHRcdFx0Y29uc3QgZGVzY3JpcHRvciA9IFBpcGVsaW5lLmdldFBpcGVsaW5lRGVzY3JpcHRvcihcblx0XHRcdFx0ZGV2aWNlLFxuXHRcdFx0XHRkcmF3Q29tYW5kLFxuXHRcdFx0XHRyZW5kZXJTdGF0ZSxcblx0XHRcdFx0Y29tYmluZUxheW91dHMsXG5cdFx0XHRcdGhhc2hJZC50b1N0cmluZygpXG5cdFx0XHQpO1xuXHRcdFx0cGlwZWxpbmUgPSBuZXcgUGlwZWxpbmUoXCJyZW5kZXJcIiwgZGV2aWNlLCBkZXNjcmlwdG9yKTtcblx0XHRcdHJlbmRlclBpcGVsaW5lcy5zZXQoaGFzaElkLCBwaXBlbGluZSk7XG5cdFx0fVxuXHRcdHJldHVybiBwaXBlbGluZTtcblx0fVxuXHRzdGF0aWMgZ2V0Q29tcHV0ZVBpcGVsaW5lRnJvbUNhY2hlKFxuXHRcdGRldmljZTogR1BVRGV2aWNlLFxuXHRcdGNvbXB1dGVDb21tYWQ6IENvbXB1dGVDb21tYW5kLFxuXHRcdGdyb3VwTGF5b3V0czogQmluZEdyb3VwTGF5b3V0W11cblx0KTogUGlwZWxpbmUge1xuXHRcdGNvbnN0IHsgc2hhZGVyU291cmNlIH0gPSBjb21wdXRlQ29tbWFkO1xuXHRcdGNvbnN0IGhhc2hJZCA9IHN0cmluZ1RvSGFzaChzaGFkZXJTb3VyY2UudWlkKTtcblx0XHRsZXQgcGlwZWxpbmUgPSBjb21wdXRlUGlwZWxpbmVzLmdldChoYXNoSWQpO1xuXHRcdGlmICghcGlwZWxpbmUpIHtcblx0XHRcdHBpcGVsaW5lID0gbmV3IFBpcGVsaW5lKFwiY29tcHV0ZVwiLCBkZXZpY2UsIHtcblx0XHRcdFx0bGF5b3V0OiBQaXBlbGluZUxheW91dC5nZXRQaXBlbGluZUxheW91dEZyb21DYWNoZShkZXZpY2UsIGhhc2hJZC50b1N0cmluZygpLCBncm91cExheW91dHMpXG5cdFx0XHRcdFx0LmdwdVBpcGVsaW5lTGF5b3V0LFxuXHRcdFx0XHRjb21wdXRlOiB7XG5cdFx0XHRcdFx0bW9kdWxlOiBzaGFkZXJTb3VyY2UuZ2V0U2hhZGVyTW9kdWxlKGRldmljZSkuY29tcHV0ZSxcblx0XHRcdFx0XHRlbnRyeVBvaW50OiBzaGFkZXJTb3VyY2U/LmNvbXB1dGU/LmNvbXB1dGVNYWluIHx8IFwibWFpblwiXG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0Y29tcHV0ZVBpcGVsaW5lcy5zZXQoaGFzaElkLCBwaXBlbGluZSk7XG5cdFx0fVxuXHRcdHJldHVybiBwaXBlbGluZTtcblx0fVxuXHRwcml2YXRlIHN0YXRpYyBnZXRQaXBlbGluZURlc2NyaXB0b3IoXG5cdFx0ZGV2aWNlOiBHUFVEZXZpY2UsXG5cdFx0ZHJhd0NvbWFuZDogRHJhd0NvbW1hbmQsXG5cdFx0cmVuZGVyU3RhdGU6IFJlbmRlclN0YXRlLFxuXHRcdGdyb3VwTGF5b3V0czogQmluZEdyb3VwTGF5b3V0W10sXG5cdFx0aGFzaElkOiBzdHJpbmdcblx0KTogR1BVUmVuZGVyUGlwZWxpbmVEZXNjcmlwdG9yIHtcblx0XHRjb25zdCB7IHZlcnRleEJ1ZmZlcnMsIHNoYWRlclNvdXJjZSB9ID0gZHJhd0NvbWFuZDtcblx0XHRjb25zdCB7IHZlcnQsIGZyYWcgfSA9IHNoYWRlclNvdXJjZS5nZXRTaGFkZXJNb2R1bGUoZGV2aWNlKTtcblx0XHRjb25zdCBwaXBlbGluZURlYyA9IHtcblx0XHRcdGxheW91dDogUGlwZWxpbmVMYXlvdXQuZ2V0UGlwZWxpbmVMYXlvdXRGcm9tQ2FjaGUoZGV2aWNlLCBoYXNoSWQsIGdyb3VwTGF5b3V0cykuZ3B1UGlwZWxpbmVMYXlvdXRcblx0XHR9IGFzIGFueTtcblx0XHRpZiAodmVydClcblx0XHRcdHBpcGVsaW5lRGVjLnZlcnRleCA9IHtcblx0XHRcdFx0bW9kdWxlOiB2ZXJ0LFxuXHRcdFx0XHRlbnRyeVBvaW50OiBzaGFkZXJTb3VyY2U/LnJlbmRlcj8udmVydE1haW4gfHwgXCJtYWluXCIsXG5cdFx0XHRcdGJ1ZmZlcnM6IHZlcnRleEJ1ZmZlcnMubWFwKCh2ZXJ0ZXhCdWZmZXIpID0+IHZlcnRleEJ1ZmZlci5nZXRCdWZmZXJEZXMoKSlcblx0XHRcdH07XG5cdFx0aWYgKHJlbmRlclN0YXRlLnByaW1pdGl2ZSkgcGlwZWxpbmVEZWMucHJpbWl0aXZlID0gcmVuZGVyU3RhdGUucHJpbWl0aXZlLmdldEdQVVByaW1pdGl2ZURlYygpO1xuXHRcdGlmIChyZW5kZXJTdGF0ZS5kZXB0aFN0ZW5jaWwpIHBpcGVsaW5lRGVjLmRlcHRoU3RlbmNpbCA9IHJlbmRlclN0YXRlLmRlcHRoU3RlbmNpbC5nZXRHUFVEZXB0aFN0ZW5jaWxEZWMoKTtcblx0XHRpZiAocmVuZGVyU3RhdGUubXVsdGlzYW1wbGUpIHBpcGVsaW5lRGVjLm11bHRpc2FtcGxlID0gcmVuZGVyU3RhdGUubXVsdGlzYW1wbGUuZ2V0TXVsdGlTYW1wbGVEZWMoKTtcblx0XHRpZiAoZnJhZylcblx0XHRcdHBpcGVsaW5lRGVjLmZyYWdtZW50ID0ge1xuXHRcdFx0XHRtb2R1bGU6IGZyYWcsXG5cdFx0XHRcdGVudHJ5UG9pbnQ6IHNoYWRlclNvdXJjZT8ucmVuZGVyPy5mcmFnTWFpbiB8fCBcIm1haW5cIixcblx0XHRcdFx0dGFyZ2V0czogcmVuZGVyU3RhdGUudGFyZ2V0cy5tYXAoKHRhcmdldCkgPT4ge1xuXHRcdFx0XHRcdHJldHVybiB0YXJnZXQuZ2V0R1BVVGFyZ2V0RGVjKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHR9O1xuXHRcdHJldHVybiBwaXBlbGluZURlYztcblx0fVxufVxuLy8gQm9ycm93ZWQgZnJvbSBodHRwczovL3dlcnhsdGQuY29tL3dwLzIwMTAvMDUvMTMvamF2YXNjcmlwdC1pbXBsZW1lbnRhdGlvbi1vZi1qYXZhcy1zdHJpbmctaGFzaGNvZGUtbWV0aG9kL1xuZnVuY3Rpb24gc3RyaW5nVG9IYXNoKHN0cikge1xuXHRsZXQgaGFzaCA9IDA7XG5cdGlmIChzdHIubGVuZ3RoID09IDApIHJldHVybiBoYXNoO1xuXHRmb3IgKGxldCBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuXHRcdGNvbnN0IGNoYXIgPSBzdHIuY2hhckNvZGVBdChpKTtcblx0XHRoYXNoID0gKGhhc2ggPDwgNSkgLSBoYXNoICsgY2hhcjtcblx0XHRoYXNoID0gaGFzaCAmIGhhc2g7IC8vIENvbnZlcnQgdG8gMzJiaXQgaW50ZWdlclxuXHR9XG5cdHJldHVybiBoYXNoO1xufVxuIiwiaW1wb3J0IENhbWVyYSBmcm9tIFwiLi4vY2FtZXJhL0NhbWVyYVwiO1xuaW1wb3J0IHsgRHJhd0NvbW1hbmRQYXJhbXMgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVUeXBlc1wiO1xuaW1wb3J0IHsgTWF0ZXJpYWwgfSBmcm9tIFwiLi4vbWF0ZXJpYWwvTWF0ZXJpYWxcIjtcbmltcG9ydCB7IFNoYWRlclNvdXJjZSB9IGZyb20gXCIuLi9zaGFkZXIvU2hhZGVyU291cmNlXCI7XG5pbXBvcnQgQnVmZmVyIGZyb20gXCIuL0J1ZmZlclwiO1xuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gXCIuL0NvbW1hbmRcIjtcbmltcG9ydCBDb250ZXh0IGZyb20gXCIuL0NvbnRleHRcIjtcbmltcG9ydCBJbmRleEJ1ZmZlciBmcm9tIFwiLi9JbmRleEJ1ZmZlclwiO1xuaW1wb3J0IFBpcGVsaW5lIGZyb20gXCIuL1BpcGVsaW5lXCI7XG5pbXBvcnQgUXVlcnlTZXQgZnJvbSBcIi4vUXVlcnlTZXRcIjtcbmltcG9ydCB7IFJlbmRlclN0YXRlLCBTY2lzc29yVGVzdCwgVmlld1BvcnQgfSBmcm9tIFwiLi9SZW5kZXJTdGF0ZVwiO1xuaW1wb3J0IFJlbmRlclRhcmdldCBmcm9tIFwiLi9SZW5kZXJUYXJnZXRcIjtcbmltcG9ydCBTaGFkZXJEYXRhIGZyb20gXCIuL1NoYWRlckRhdGFcIjtcbmltcG9ydCBWZXJ0ZXhCdWZmZXIgZnJvbSBcIi4vVmVydGV4QnVmZmVyXCI7XG5cbmNsYXNzIERyYXdDb21tYW5kIGltcGxlbWVudHMgQ29tbWFuZCB7XG5cdHB1YmxpYyBzaGFkZXJEYXRhPzogU2hhZGVyRGF0YTtcblxuXHRwdWJsaWMgcmVuZGVyVGFyZ2V0PzogUmVuZGVyVGFyZ2V0O1xuXG5cdHB1YmxpYyB2ZXJ0ZXhCdWZmZXJzPzogQXJyYXk8VmVydGV4QnVmZmVyPjtcblxuXHRwdWJsaWMgaW5kZXhCdWZmZXI/OiBJbmRleEJ1ZmZlcjtcblxuXHRwdWJsaWMgcmVuZGVyU3RhdGU/OiBSZW5kZXJTdGF0ZTtcblxuXHRwdWJsaWMgcXVlcnlJbmRleD86IG51bWJlcjtcblxuXHRwdWJsaWMgY291bnQ/OiBudW1iZXI7XG5cblx0cHVibGljIGluc3RhbmNlcz86IG51bWJlcjtcblxuXHRwdWJsaWMgc2hhZGVyU291cmNlPzogU2hhZGVyU291cmNlO1xuXG5cdHB1YmxpYyBkaXJ0eT86IGJvb2xlYW47XG5cblx0cHVibGljIGluZGlyZWN0QnVmZmVyPzogQnVmZmVyO1xuXG5cdHB1YmxpYyBpbmRpcmVjdE9mZnNldD86IG51bWJlcjtcblxuXHRwdWJsaWMgbGlnaHRTaGFkZXJEYXRhPzogU2hhZGVyRGF0YTtcblxuXHRwdWJsaWMgdXNlTGlnaHQ/OiBib29sZWFuO1xuXG5cdGNvbnN0cnVjdG9yKG9wdGlvbnM6IERyYXdDb21tYW5kUGFyYW1zKSB7XG5cdFx0dGhpcy5zaGFkZXJEYXRhID0gb3B0aW9ucy5zaGFkZXJEYXRhO1xuXG5cdFx0dGhpcy5yZW5kZXJUYXJnZXQgPSBvcHRpb25zLnJlbmRlclRhcmdldDtcblxuXHRcdHRoaXMudXNlTGlnaHQgPSBvcHRpb25zLnVzZUxpZ2h0O1xuXG5cdFx0dGhpcy52ZXJ0ZXhCdWZmZXJzID0gb3B0aW9ucy52ZXJ0ZXhCdWZmZXJzO1xuXG5cdFx0dGhpcy5pbmRleEJ1ZmZlciA9IG9wdGlvbnMuaW5kZXhCdWZmZXI7XG5cblx0XHR0aGlzLnJlbmRlclN0YXRlID0gb3B0aW9ucy5yZW5kZXJTdGF0ZTtcblxuXHRcdHRoaXMucXVlcnlJbmRleCA9IG9wdGlvbnMucXVlcnlJbmRleDtcblxuXHRcdHRoaXMuY291bnQgPSBvcHRpb25zLmNvdW50O1xuXG5cdFx0dGhpcy5pbnN0YW5jZXMgPSBvcHRpb25zLmluc3RhbmNlcztcblxuXHRcdHRoaXMuc2hhZGVyU291cmNlID0gb3B0aW9ucy5zaGFkZXJTb3VyY2U7XG5cblx0XHR0aGlzLmRpcnR5ID0gb3B0aW9ucy5kaXJ0eTtcblxuXHRcdHRoaXMubGlnaHRTaGFkZXJEYXRhID0gb3B0aW9ucy5saWdodFNoYWRlckRhdGE7XG5cdH1cblx0cHVibGljIHNoYWxsb3dDbG9uZShtYXRlcmlhbD86IE1hdGVyaWFsKSB7XG5cdFx0aWYgKCFtYXRlcmlhbCkgcmV0dXJuO1xuXHRcdHJldHVybiBuZXcgRHJhd0NvbW1hbmQoe1xuXHRcdFx0dmVydGV4QnVmZmVyczogdGhpcy52ZXJ0ZXhCdWZmZXJzLFxuXHRcdFx0aW5kZXhCdWZmZXI6IHRoaXMuaW5kZXhCdWZmZXIsXG5cdFx0XHRzaGFkZXJEYXRhOiBtYXRlcmlhbC5zaGFkZXJEYXRhLFxuXHRcdFx0aW5zdGFuY2VzOiB0aGlzLmluc3RhbmNlcyxcblx0XHRcdGNvdW50OiB0aGlzLmNvdW50LFxuXHRcdFx0cmVuZGVyU3RhdGU6IG1hdGVyaWFsLnJlbmRlclN0YXRlLFxuXHRcdFx0c2hhZGVyU291cmNlOiBtYXRlcmlhbC5zaGFkZXJTb3VyY2UsXG5cdFx0XHRsaWdodFNoYWRlckRhdGE6IG1hdGVyaWFsLmxpZ2h0ID8gdGhpcy5saWdodFNoYWRlckRhdGEgOiB1bmRlZmluZWQsXG5cdFx0XHR1c2VMaWdodDogbWF0ZXJpYWwubGlnaHRcblx0XHR9KTtcblx0fVxuXHRwdWJsaWMgcmVuZGVyKHBhcmFtcz86IFJlbmRlclBhcmFtcyk6IHZvaWQge1xuXHRcdGNvbnN0IHsgZGV2aWNlLCBwYXNzRW5jb2RlciwgY2FtZXJhLCBxdWVyeVNldCwgdmlld1BvcnQsIHNjaXNzb3JUZXN0IH0gPSBwYXJhbXMgfHwge307XG5cdFx0Y29uc3Qge1xuXHRcdFx0c2hhZGVyRGF0YSxcblx0XHRcdHJlbmRlclN0YXRlLFxuXHRcdFx0dmVydGV4QnVmZmVycyxcblx0XHRcdGluZGV4QnVmZmVyLFxuXHRcdFx0bGlnaHRTaGFkZXJEYXRhLFxuXHRcdFx0c2hhZGVyU291cmNlLFxuXHRcdFx0Y291bnQsXG5cdFx0XHRpbnN0YW5jZXMsXG5cdFx0XHRyZW5kZXJUYXJnZXQsXG5cdFx0XHR1c2VMaWdodCxcblx0XHRcdGluZGlyZWN0T2Zmc2V0LFxuXHRcdFx0aW5kaXJlY3RCdWZmZXIsXG5cdFx0XHRxdWVyeUluZGV4XG5cdFx0fSA9IHRoaXM7XG5cdFx0Y29uc3QgY3VycmVudFBhc3NFbmNvZGVyID0gcmVuZGVyVGFyZ2V0Py5iZWdpblJlbmRlclBhc3M/LihkZXZpY2UpID8/IHBhc3NFbmNvZGVyO1xuXHRcdGNvbnN0IGRlZmluZXMgPSBPYmplY3QuYXNzaWduKHt9LCBsaWdodFNoYWRlckRhdGE/LmRlZmluZXMgPz8ge30sIGNhbWVyYT8uc2hhZGVyRGF0YT8uZGVmaW5lcyA/PyB7fSk7XG5cblx0XHRzaGFkZXJEYXRhPy5iaW5kPy4oZGV2aWNlLCBjdXJyZW50UGFzc0VuY29kZXIpO1xuXG5cdFx0Y2FtZXJhPy5zaGFkZXJEYXRhPy5iaW5kKGRldmljZSwgY3VycmVudFBhc3NFbmNvZGVyKTtcblxuXHRcdHVzZUxpZ2h0ICYmIGxpZ2h0U2hhZGVyRGF0YT8uYmluZD8uKGRldmljZSwgY3VycmVudFBhc3NFbmNvZGVyKTtcblxuXHRcdHJlbmRlclN0YXRlPy5iaW5kPy4oe1xuXHRcdFx0cGFzc0VuY29kZXI6IGN1cnJlbnRQYXNzRW5jb2Rlcixcblx0XHRcdHZpZXdQb3J0OiB2aWV3UG9ydCBhcyBWaWV3UG9ydCxcblx0XHRcdHNjaXNzb3JUZXN0OiA8U2Npc3NvclRlc3Q+c2Npc3NvclRlc3Rcblx0XHR9KTtcblxuXHRcdHZlcnRleEJ1ZmZlcnM/LmZvckVhY2g/LigodmVydGV4QnVmZmVyOiBWZXJ0ZXhCdWZmZXIpID0+IHZlcnRleEJ1ZmZlcj8uYmluZD8uKGRldmljZSwgY3VycmVudFBhc3NFbmNvZGVyKSk7XG5cblx0XHRpbmRleEJ1ZmZlcj8uYmluZD8uKGRldmljZSwgY3VycmVudFBhc3NFbmNvZGVyKTtcblxuXHRcdHNoYWRlclNvdXJjZT8uc2V0RGVmaW5lcz8uKGRlZmluZXMpO1xuXG5cdFx0Y29uc3QgcGlwZWxpbmUgPSBQaXBlbGluZS5nZXRSZW5kZXJQaXBlbGluZUZyb21DYWNoZShkZXZpY2UsIHRoaXMsIFtcblx0XHRcdHNoYWRlckRhdGE/Lmdyb3VwTGF5b3V0LFxuXHRcdFx0bGlnaHRTaGFkZXJEYXRhPy5ncm91cExheW91dCxcblx0XHRcdGNhbWVyYT8uc2hhZGVyRGF0YT8uZ3JvdXBMYXlvdXRcblx0XHRdKTtcblx0XHRpZiAocXVlcnlJbmRleCAhPSB1bmRlZmluZWQpIHF1ZXJ5U2V0Py5iZWdpblF1ZXJ5KGN1cnJlbnRQYXNzRW5jb2RlciwgcXVlcnlJbmRleCk7XG5cdFx0cGlwZWxpbmUuYmluZChjdXJyZW50UGFzc0VuY29kZXIpO1xuXHRcdGlmIChpbmRleEJ1ZmZlcikge1xuXHRcdFx0aWYgKGluZGlyZWN0QnVmZmVyKSB7XG5cdFx0XHRcdGN1cnJlbnRQYXNzRW5jb2Rlci5kcmF3SW5kZXhlZEluZGlyZWN0KGluZGlyZWN0QnVmZmVyLmdwdUJ1ZmZlciwgaW5kaXJlY3RPZmZzZXQgfHwgMCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjdXJyZW50UGFzc0VuY29kZXIuZHJhd0luZGV4ZWQoY291bnQgfHwgMCwgaW5zdGFuY2VzIHx8IDEsIDAsIDAsIDApO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZiAoY291bnQpIHtcblx0XHRcdGlmIChpbmRpcmVjdEJ1ZmZlcikge1xuXHRcdFx0XHRjdXJyZW50UGFzc0VuY29kZXIuZHJhd0luZGlyZWN0KGluZGlyZWN0QnVmZmVyLmdwdUJ1ZmZlciwgaW5kaXJlY3RPZmZzZXQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y3VycmVudFBhc3NFbmNvZGVyLmRyYXcoY291bnQsIGluc3RhbmNlcyB8fCAxLCAwLCAwKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKHF1ZXJ5SW5kZXggIT0gdW5kZWZpbmVkKSBxdWVyeVNldD8uZW5kUXVlcnkoY3VycmVudFBhc3NFbmNvZGVyKTtcblx0XHRyZW5kZXJUYXJnZXQ/LmVuZFJlbmRlclBhc3M/LigpO1xuXHR9XG59XG5leHBvcnQgZGVmYXVsdCBEcmF3Q29tbWFuZDtcbnR5cGUgUmVuZGVyUGFyYW1zID0ge1xuXHRjb250ZXh0PzogQ29udGV4dDtcblx0ZGV2aWNlPzogR1BVRGV2aWNlO1xuXHRwYXNzRW5jb2Rlcj86IEdQVVJlbmRlclBhc3NFbmNvZGVyO1xuXHRjYW1lcmE/OiBDYW1lcmE7XG5cdHF1ZXJ5U2V0PzogUXVlcnlTZXQ7XG5cdHZpZXdQb3J0PzogVmlld1BvcnQ7XG5cdHNjaXNzb3JUZXN0PzogU2Npc3NvclRlc3Q7XG59O1xuIiwiaW1wb3J0IHsgTGlnaHQgfSBmcm9tIFwiLi4vbGlnaHQvTGlnaHRcIjtcbmltcG9ydCB7IE1lc2ggfSBmcm9tIFwiLi4vbWVzaC9NZXNoXCI7XG5pbXBvcnQgUG9zdEVmZmVjdCBmcm9tIFwiLi4vcG9zdC1wcm9jZXNzL1Bvc3RFZmZlY3RcIjtcbmltcG9ydCBCaW5kR3JvdXBFbnRpdHkgZnJvbSBcIi4uL3JlbmRlci9CaW5kR3JvdXBFbnRpdHlcIjtcbmltcG9ydCBCaW5kR3JvdXBMYXlvdXQgZnJvbSBcIi4uL3JlbmRlci9CaW5kR3JvdXBMYXlvdXRcIjtcbmltcG9ydCBCdWZmZXIgZnJvbSBcIi4uL3JlbmRlci9CdWZmZXJcIjtcbmltcG9ydCBJbmRleEJ1ZmZlciBmcm9tIFwiLi4vcmVuZGVyL0luZGV4QnVmZmVyXCI7XG5pbXBvcnQgeyBSZW5kZXJTdGF0ZSB9IGZyb20gXCIuLi9yZW5kZXIvUmVuZGVyU3RhdGVcIjtcbmltcG9ydCBSZW5kZXJUYXJnZXQgZnJvbSBcIi4uL3JlbmRlci9SZW5kZXJUYXJnZXRcIjtcbmltcG9ydCBTYW1wbGVyIGZyb20gXCIuLi9yZW5kZXIvU2FtcGxlclwiO1xuaW1wb3J0IFNoYWRlckRhdGEgZnJvbSBcIi4uL3JlbmRlci9TaGFkZXJEYXRhXCI7XG5pbXBvcnQgVGV4dHVyZSBmcm9tIFwiLi4vcmVuZGVyL1RleHR1cmVcIjtcbmltcG9ydCBWZXJ0ZXhCdWZmZXIgZnJvbSBcIi4uL3JlbmRlci9WZXJ0ZXhCdWZmZXJcIjtcbmltcG9ydCB7IFNoYWRlclNvdXJjZSB9IGZyb20gXCIuLi9zaGFkZXIvU2hhZGVyU291cmNlXCI7XG5pbXBvcnQge1xuXHRCbGVuZEZhY3Rvcixcblx0QmxlbmRPcGVyYXRpb24sXG5cdENvbG9yV3JpdGVGbGFncyxcblx0Q29tcGFyZUZ1bmN0aW9uLFxuXHRDdWxsTW9kZSxcblx0RnJvbnRGYWNlLFxuXHRJbmRleEZvcm1hdCxcblx0SW5wdXRTdGVwTW9kZSxcblx0UHJpbWl0aXZlVG9wb2xvZ3ksXG5cdFNoYWRlclN0YWdlLFxuXHRTdGVuY2lsT3BlcmF0aW9uLFxuXHRTdG9yYWdlVGV4dHVyZUFjY2Vzcyxcblx0VGV4dHVyZUZvcm1hdFxufSBmcm9tIFwiLi9XZWJHUFVDb25zdGFudFwiO1xuZXhwb3J0IGNvbnN0IEdQVUNhbnZhc0NvbXBvc2l0aW5nQWxwaGFNb2RlOiB7XG5cdFtrZXk6IHN0cmluZ106IEdQVUNhbnZhc0NvbXBvc2l0aW5nQWxwaGFNb2RlO1xufSA9IHtcblx0T3BhcXVlOiBcIm9wYXF1ZVwiLFxuXHRQcmVtdWx0aXBsaWVkOiBcInByZW11bHRpcGxpZWRcIlxufTtcbmV4cG9ydCBpbnRlcmZhY2UgQ29udGV4dFN0YXRlIHtcblx0ZGV2aWNlOiBHUFVEZXZpY2U7XG5cdGdsc2xhbmc6IHtcblx0XHRjb21waWxlR0xTTDogKHNvdXJjZTogc3RyaW5nLCB0eXBlOiBzdHJpbmcpID0+IHN0cmluZztcblx0fTtcblx0ZGVidWc6IGJvb2xlYW47XG5cdGVycm9yOiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbnRleHRPcHRpb25zIHtcblx0Y2FudmFzPzogSFRNTENhbnZhc0VsZW1lbnQ7XG5cdGNvbnRhaW5lcj86IEhUTUxEaXZFbGVtZW50O1xuXHRjb250ZXh0PzogR1BVQ2FudmFzQ29udGV4dDtcblx0cGl4ZWxSYXRpbz86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMaWdodE1hbmdlck9wdGlvbnMge1xuXHRvcGVuU2hhZG93OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJpbmRHcm91cExheW91dEVudHJ5IGV4dGVuZHMgR1BVQmluZEdyb3VwTGF5b3V0RW50cnkge1xuXHRuYW1lOiBzdHJpbmc7XG5cdHVuaWZvcm1zPzogYW55W107XG5cdGRpbWVuc2lvbj86IEdQVVRleHR1cmVEaW1lbnNpb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmluZEdyb3VwT3B0aW9ucyBleHRlbmRzIEdQVUJpbmRHcm91cERlc2NyaXB0b3Ige1xuXHRyZXNvdXJjZXM6IEdQVUJpbmRpbmdSZXNvdXJjZVtdO1xufVxuXG5leHBvcnQgdHlwZSBTaGFkZXJTdGFnZU5hbWUgPSBcInZlcnRleFwiIHwgXCJmcmFnbWVudFwiIHwgXCJjb21wdXRlXCI7XG5cbmV4cG9ydCB0eXBlIFNoYWRlclN0YWdlTmFtZU9iamVjdEtleXMgPSB7XG5cdFtrZXkgaW4gU2hhZGVyU3RhZ2VOYW1lXT86IHN0cmluZztcbn07XG5leHBvcnQgdHlwZSBTaGFkZXJTdGFnZUJvZHlOYW1lID0gXCJ2ZXJ0ZXhCb2R5XCIgfCBcImZyYWdtZW50Qm9keVwiIHwgXCJjb21wdXRlQm9keVwiO1xuZXhwb3J0IHR5cGUgU2hhZGVyU3RhZ2VCb2R5TmFtZU9iamVjdEtleXMgPSB7XG5cdFtrZXkgaW4gU2hhZGVyU3RhZ2VCb2R5TmFtZV0/OiBzdHJpbmc7XG59O1xuZXhwb3J0IGludGVyZmFjZSBBdHRhY2htZW50T3B0aW9ucyB7XG5cdG9wPzogR1BVU3RvcmVPcDtcblx0dGV4dHVyZT86IFRleHR1cmU7XG5cdHJlc29sdmVUYXJnZXQ/OiBUZXh0dXJlO1xuXHRzdG9yZU9wPzogR1BVU3RvcmVPcDtcblx0dGV4dHVyZVZpZXc/OiAoKSA9PiBHUFVUZXh0dXJlVmlldztcbn1cblxuZXhwb3J0IHR5cGUgUGFzc1R5cGUgPSBcInJlbmRlclwiIHwgXCJjb21wdXRlXCI7XG5cbmV4cG9ydCB0eXBlIEdQVUJpbmRpbmdUeXBlID1cblx0fCBHUFVCdWZmZXJCaW5kaW5nVHlwZVxuXHR8IEdQVVNhbXBsZXJCaW5kaW5nVHlwZVxuXHR8IEdQVVRleHR1cmVTYW1wbGVUeXBlXG5cdHwgR1BVU3RvcmFnZVRleHR1cmVBY2Nlc3M7XG5cbmV4cG9ydCB0eXBlIEJpbmRHcm91cExheW91dEVudHJ5VHlwZSA9IHtcblx0YmluZGluZzogbnVtYmVyO1xuXHR2aXNpYmlsaXR5OiBHUFVTaGFkZXJTdGFnZUZsYWdzO1xuXHR1bmlmb3Jtcz86IGFueVtdO1xuXHRidWZmZXI/OiBHUFVCdWZmZXJCaW5kaW5nTGF5b3V0O1xuXHRzYW1wbGVyPzogR1BVU2FtcGxlckJpbmRpbmdMYXlvdXQ7XG5cdHRleHR1cmU/OiBHUFVUZXh0dXJlQmluZGluZ0xheW91dDtcblx0c3RvcmFnZVRleHR1cmU/OiBHUFVTdG9yYWdlVGV4dHVyZUJpbmRpbmdMYXlvdXQ7XG5cdGV4dGVybmFsVGV4dHVyZT86IEdQVUV4dGVybmFsVGV4dHVyZUJpbmRpbmdMYXlvdXQ7XG59O1xuZXhwb3J0IHR5cGUgQnVmZmVyUmVzb3VyY2VUeXBlID0ge1xuXHRidWZmZXI6IEdQVUJ1ZmZlckJpbmRpbmdUeXBlO1xuXHRvZmZzZXQ6IG51bWJlcjtcblx0c2l6ZTogbnVtYmVyO1xufTtcbmV4cG9ydCB0eXBlIHNhbXBsZXJCaW5kRW50aXR5UmVzb3VyY2VUeXBlID0ge1xuXHRyZXNvdXJjZTogR1BVU2FtcGxlcjtcbn07XG5leHBvcnQgdHlwZSB0ZXh0dXJlQmluZEVudGl0eVJlc291cmNlVHlwZSA9IHtcblx0cmVzb3VyY2U6IEdQVVRleHR1cmVWaWV3O1xufTtcbmV4cG9ydCB0eXBlIEJpbmRHcm91cEVudGl0eVJlc291cmNlVHlwZSA9XG5cdHwgQnVmZmVyUmVzb3VyY2VUeXBlXG5cdHwgc2FtcGxlckJpbmRFbnRpdHlSZXNvdXJjZVR5cGVcblx0fCB0ZXh0dXJlQmluZEVudGl0eVJlc291cmNlVHlwZTtcbmV4cG9ydCB0eXBlIEJpbmRHcm91cEVudGl0eU9wdGlvbnMgPSB7XG5cdGJpbmRpbmc6IG51bWJlcjtcblx0cmVzb3VyY2U6IEdQVUJpbmRpbmdSZXNvdXJjZTtcbn07XG5leHBvcnQgdHlwZSBCaW5kR3JvdXBDYWNoZU9wdGlvbnMgPSB7XG5cdGRldmljZTogR1BVRGV2aWNlO1xuXHRsYWJlbDogc3RyaW5nO1xuXHRsYXlvdXQ6IEJpbmRHcm91cExheW91dDtcblx0ZW50aXJlczogQmluZEdyb3VwRW50aXR5W107XG5cdGluZGV4PzogbnVtYmVyO1xuXHRvZmZzZXQ/OiBudW1iZXI7XG5cdGFsaWduZWRTaXplPzogbnVtYmVyO1xuXHRtYXhPZmZzZXQ/OiBudW1iZXI7XG5cdGR5bmFtaWM/OiBib29sZWFuO1xufTtcbmV4cG9ydCB0eXBlIEltYWdlRGF0YSA9IHtcblx0c291cmNlOiBJbWFnZUJpdG1hcCB8IEhUTUxDYW52YXNFbGVtZW50IHwgVGV4dHVyZTtcblx0d2lkdGg/OiBudW1iZXI7XG5cdGhlaWdodD86IG51bWJlcjtcblx0ZGVwdGg/OiBudW1iZXI7XG5cdHNvdXJjZVg/OiBudW1iZXI7XG5cdHNvdXJjZVk/OiBudW1iZXI7XG5cdG1pcExldmVsPzogbnVtYmVyO1xuXHR4PzogbnVtYmVyO1xuXHR5PzogbnVtYmVyO1xuXHR6PzogbnVtYmVyO1xuXHRhc3BlY3Q/OiBcImFsbFwiIHwgXCJzdGVuY2lsLW9ubHlcIiB8IFwiZGVwdGgtb25seVwiO1xuXHRjb2xvclNwYWNlPzogXCJzcmdiXCI7XG5cdHByZW11bHRpcGxpZWRBbHBoYT86IGJvb2xlYW47XG59O1xuZXhwb3J0IHR5cGUgV2ViR1BVVGV4dHVyZVByb3BzID0ge1xuXHRzaXplOiB0ZXh0dXJlU2l6ZTtcblxuXHRmaXhlZFNpemU/OiBib29sZWFuO1xuXG5cdGZvcm1hdDogc3RyaW5nO1xuXG5cdGxhYmVsPzogc3RyaW5nO1xuXG5cdHVzYWdlPzogbnVtYmVyO1xuXG5cdHNhbXBsZXI/OiBTYW1wbGVyO1xuXG5cdGRhdGE/OiBJbWFnZURhdGEgfCBBcnJheTxJbWFnZURhdGE+O1xuXG5cdG1pcExldmVsQ291bnQ/OiBudW1iZXI7XG5cblx0c2FtcGxlQ291bnQ/OiBudW1iZXI7XG5cblx0ZGltZW5zaW9uPzogZGltZW5zaW9uO1xuXG5cdHZpZXdGb3JtYXRzPzogc3RyaW5nO1xuXG5cdHNhbXBsZVR5cGU/OiBzdHJpbmc7XG5cblx0bmVlZE1pcE1hcD86IGJvb2xlYW47XG5cblx0ZGF0YUlzVGV4dHVyZT86IGJvb2xlYW47XG5cblx0YWNjZXNzPzogU3RvcmFnZVRleHR1cmVBY2Nlc3M7XG59O1xuZXhwb3J0IHR5cGUgdGV4dHVyZVNpemUgPSB7XG5cdHdpZHRoOiBudW1iZXI7XG5cdGhlaWdodDogbnVtYmVyO1xuXHRkZXB0aDogbnVtYmVyO1xufTtcbmV4cG9ydCB0eXBlIGRpbWVuc2lvbiA9IFwiMWRcIiB8IFwiMmRcIiB8IFwiM2RcIjtcbmV4cG9ydCB0eXBlIGJ1ZmZlckxheW91dFR5cGUgPSB7XG5cdHR5cGU6IHN0cmluZzsgLy8gXCJ1bmlmb3JtXCJcblx0aGFzRHluYW1pY09mZnNldD86IGJvb2xlYW47XG5cdG1pbkJpbmRpbmdTaXplPzogbnVtYmVyO1xufTtcbi8vIHJlbmRlcnN0YXRlXG5leHBvcnQgdHlwZSBEZXB0aFN0ZW5jaWwgPSB7XG5cdGZvcm1hdDogVGV4dHVyZUZvcm1hdDtcblx0ZGVwdGhXcml0ZUVuYWJsZWQ6IGJvb2xlYW47XG5cdGRlcHRoQ29tcGFyZTogQ29tcGFyZUZ1bmN0aW9uO1xuXHRzdGVuY2lsUmVhZE1hc2s/OiBudW1iZXI7XG5cdHN0ZW5jaWxXcml0ZU1hc2s/OiBudW1iZXI7XG5cdHN0ZW5jaWxGcm9udD86IHtcblx0XHRjb21wYXJlOiBDb21wYXJlRnVuY3Rpb247XG5cdFx0ZmFpbE9wOiBTdGVuY2lsT3BlcmF0aW9uO1xuXHRcdGRlcHRoRmFpbE9wOiBTdGVuY2lsT3BlcmF0aW9uO1xuXHRcdHBhc3NPcDogU3RlbmNpbE9wZXJhdGlvbjtcblx0fTtcblx0c3RlbmNpbEJhY2s/OiB7XG5cdFx0Y29tcGFyZTogQ29tcGFyZUZ1bmN0aW9uO1xuXHRcdGZhaWxPcDogU3RlbmNpbE9wZXJhdGlvbjtcblx0XHRkZXB0aEZhaWxPcDogU3RlbmNpbE9wZXJhdGlvbjtcblx0XHRwYXNzT3A6IFN0ZW5jaWxPcGVyYXRpb247XG5cdH07XG5cdGRlcHRoQmlhcz86IG51bWJlcjtcblx0ZGVwdGhCaWFzU2xvcGVTY2FsZT86IG51bWJlcjtcblx0ZGVwdGhCaWFzQ2xhbXA/OiBudW1iZXI7XG59O1xuZXhwb3J0IHR5cGUgUHJpbWl0aXZlU3RhdGUgPSB7XG5cdGZyb250RmFjZT86IEZyb250RmFjZTtcblx0Y3VsbE1vZGU/OiBDdWxsTW9kZTtcblx0dW5jbGlwcGVkRGVwdGg/OiBib29sZWFuO1xuXHR0b3BvbG9neT86IFByaW1pdGl2ZVRvcG9sb2d5O1xuXHRzdHJpcEluZGV4Rm9ybWF0PzogSW5kZXhGb3JtYXQ7XG59O1xuZXhwb3J0IHR5cGUgTXVsdGlTYW1wbGUgPSB7XG5cdGNvdW50PzogbnVtYmVyO1xuXHRtYXNrPzogbnVtYmVyO1xuXHRhbHBoYVRvQ292ZXJhZ2VFbmFibGVkPzogYm9vbGVhbjtcbn07XG5leHBvcnQgdHlwZSBUYXJnZXQgPSB7XG5cdGZvcm1hdDogVGV4dHVyZUZvcm1hdDtcblx0YmxlbmQ/OiB7XG5cdFx0Y29sb3I6IHtcblx0XHRcdG9wZXJhdGlvbjogQmxlbmRPcGVyYXRpb247XG5cdFx0XHRzcmNGYWN0b3I6IEJsZW5kRmFjdG9yO1xuXHRcdFx0ZHN0RmFjdG9yOiBCbGVuZEZhY3Rvcjtcblx0XHR9O1xuXHRcdGFscGhhOiB7XG5cdFx0XHRvcGVyYXRpb246IEJsZW5kT3BlcmF0aW9uO1xuXHRcdFx0c3JjRmFjdG9yOiBCbGVuZEZhY3Rvcjtcblx0XHRcdGRzdEZhY3RvcjogQmxlbmRGYWN0b3I7XG5cdFx0fTtcblx0fTtcblx0d3JpdGVNYXNrOiBDb2xvcldyaXRlRmxhZ3M7XG59O1xuZXhwb3J0IHR5cGUgQmxlbmRDb25zdGFudCA9IHtcblx0cjogbnVtYmVyO1xuXHRnOiBudW1iZXI7XG5cdGI6IG51bWJlcjtcblx0YTogbnVtYmVyO1xufTtcbmV4cG9ydCB0eXBlIFJlbmRlclN0YXRlUHJvcHMgPSB7XG5cdGRlcHRoU3RlbmNpbD86IERlcHRoU3RlbmNpbDtcblx0cHJpbWl0aXZlPzogUHJpbWl0aXZlU3RhdGU7XG5cdG11bHRpc2FtcGxlPzogTXVsdGlTYW1wbGU7XG5cdHN0ZW5jaWxSZWZlcmVuY2U/OiBudW1iZXI7XG5cdHRhcmdldHM/OiBBcnJheTxUYXJnZXQ+O1xuXHR2aWV3cG9ydD86IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH07XG5cdGJsZW5kQ29uc3RhbnQ/OiBCbGVuZENvbnN0YW50O1xuXHRzY2lzc29yVGVzdEVuYWJsZWQ/OiBib29sZWFuO1xuXHRzdGVuY2lsRW5hYmxlZD86IGJvb2xlYW47XG59O1xuZXhwb3J0IHR5cGUgVmlld1BvcnQgPSB7XG5cdHg/OiBudW1iZXI7XG5cdHk/OiBudW1iZXI7XG5cdHdpZHRoPzogbnVtYmVyO1xuXHRoZWlnaHQ/OiBudW1iZXI7XG5cdG1pbkRlcHRoPzogbnVtYmVyO1xuXHRtYXhEZXB0aD86IG51bWJlcjtcbn07XG5leHBvcnQgdHlwZSBTY2lzc29yVGVzdCA9IHtcblx0eDogbnVtYmVyO1xuXHR5OiBudW1iZXI7XG5cdHdpZHRoOiBudW1iZXI7XG5cdGhlaWdodDogbnVtYmVyO1xufTtcbmV4cG9ydCB0eXBlIFNoYWRlck1hdGVyaWFsUGFybXMgPSB7XG5cdHR5cGU6IHN0cmluZztcblx0ZnJhZzogc3RyaW5nIHwgU2hhZGVyRnVuYztcblx0dmVydDogc3RyaW5nIHwgU2hhZGVyRnVuYztcblx0dW5pZm9ybXM6IHsgW3VuaWZvcm06IHN0cmluZ106IElVbmlmb3JtIH07XG5cdGRlZmluZXM/OiBTaGFkZXJEZWZpbmU7XG5cdGxpZ2h0PzogYm9vbGVhbjtcbn07XG5leHBvcnQgaW50ZXJmYWNlIElVbmlmb3JtPFRWYWx1ZSA9IGFueT4ge1xuXHR0eXBlOiBzdHJpbmc7XG5cdHZhbHVlOiBUVmFsdWU7XG5cdGJpbmRpbmc/OiBudW1iZXI7XG5cdHZpc2liaWxpdHk/OiBudW1iZXI7XG5cdHRleHR1cmVWaWV3PzogR1BVVGV4dHVyZVZpZXc7XG59XG5leHBvcnQgdHlwZSBVbmlmb3JtcyA9IHsgW3VuaWZvcm06IHN0cmluZ106IElVbmlmb3JtIH07XG5leHBvcnQgdHlwZSBJbnN0YW5jZSA9IE1lc2ggfCBQb3N0RWZmZWN0IHwgTGlnaHQ7XG5cbmV4cG9ydCBlbnVtIFJlbmRlck9iamVjdFR5cGUge1xuXHRDYW1lcmEgPSBcImNhbWVyYVwiLFxuXHRMaWdodCA9IFwibGlnaHRcIixcblx0TWVzaCA9IFwibWVzaFwiLFxuXHRTa2luTWVzaCA9IFwic2tpbk1lc2hcIixcblx0Tm9kZSA9IFwibm9kZVwiLFxuXHRBeGVzID0gXCJheGVzXCIsXG5cdFNreWJveCA9IFwic2t5Qm94XCIsXG5cdFBvc3RFZmZlY3QgPSBcInBvc3RFZmZlY3RcIixcblx0RGVidWcgPSBcImRlYnVnXCJcbn1cbmV4cG9ydCBlbnVtIExpZ2h0VHlwZSB7XG5cdFNwb3RMaWdodCA9IFwic3BvdExpZ2h0XCIsXG5cdFBvaW50TGlnaHQgPSBcInBvaW50TGlnaHRcIixcblx0QW1iaWVudExpZ2h0ID0gXCJhbWJpZW50TGlnaHRcIixcblx0RGlyZWN0aW9uYWxMaWdodCA9IFwiZGlyZWN0aW9uYWxMaWdodFwiXG59XG5leHBvcnQgdHlwZSBTaGFkZXJEZWZpbmUgPSB7IFtwcm9wOiBzdHJpbmddOiBib29sZWFuIHwgbnVtYmVyIH07XG5cbmV4cG9ydCB0eXBlIFNoYWRlclNvdXJjZVBhcmFtcyA9IHtcblx0c2hhZGVySWQ/OiBzdHJpbmc7XG5cdGRlZmluZXM/OiBTaGFkZXJEZWZpbmU7XG5cdGNvbXB1dGU/OiBjb21wdXRlUGFyYW1zO1xuXHRyZW5kZXI/OiByZW5kZXJQYXJhbXM7XG59O1xuZXhwb3J0IHR5cGUgcmVuZGVyUGFyYW1zID0ge1xuXHR2ZXJ0TWFpbj86IHN0cmluZztcblx0ZnJhZ01haW4/OiBzdHJpbmc7XG5cdGZyYWdTaGFkZXI/OiBzdHJpbmcgfCBTaGFkZXJGdW5jO1xuXHR2ZXJ0U2hhZGVyPzogc3RyaW5nIHwgU2hhZGVyRnVuYztcbn07XG5leHBvcnQgdHlwZSBjb21wdXRlUGFyYW1zID0ge1xuXHRjb21wdXRlTWFpbj86IHN0cmluZztcblx0Y29tcHV0ZVNoYWRlcj86IHN0cmluZyB8IFNoYWRlckZ1bmM7XG59O1xuZXhwb3J0IGludGVyZmFjZSBHUFVTaGFkZXJNb2R1bGVPYmplY3Qge1xuXHR2ZXJ0OiBHUFVTaGFkZXJNb2R1bGU7XG5cdGZyYWc6IEdQVVNoYWRlck1vZHVsZTtcbn1cbmV4cG9ydCB0eXBlIFNoYWRlckZ1bmMgPSAoZGVmaW5lcz86IFNoYWRlckRlZmluZSkgPT4gc3RyaW5nO1xuZXhwb3J0IHR5cGUgU2hhZGVyU3RyaW5nID0ge1xuXHR2ZXJ0Pzogc3RyaW5nO1xuXHRmcmFnPzogc3RyaW5nO1xuXHRjb21wdXRlPzogc3RyaW5nO1xufTtcbmV4cG9ydCB0eXBlIFNoYWRlck1vZHVsZSA9IHtcblx0dmVydD86IEdQVVNoYWRlck1vZHVsZTtcblx0ZnJhZz86IEdQVVNoYWRlck1vZHVsZTtcblx0Y29tcHV0ZT86IEdQVVNoYWRlck1vZHVsZTtcbn07XG5leHBvcnQgdHlwZSBVbmlmb3JtRnVuYyA9ICgpID0+IGFueTtcblxuZXhwb3J0IHR5cGUgRHJhd0NvbW1hbmRQYXJhbXMgPSB7XG5cdHNoYWRlckRhdGE/OiBTaGFkZXJEYXRhO1xuXG5cdHJlbmRlclRhcmdldD86IFJlbmRlclRhcmdldDtcblxuXHR2ZXJ0ZXhCdWZmZXJzPzogQXJyYXk8VmVydGV4QnVmZmVyPjtcblxuXHRpbmRleEJ1ZmZlcj86IEluZGV4QnVmZmVyO1xuXG5cdHJlbmRlclN0YXRlPzogUmVuZGVyU3RhdGU7XG5cblx0cXVlcnlJbmRleD86IG51bWJlcjtcblxuXHRjb3VudD86IG51bWJlcjtcblxuXHRpbnN0YW5jZXM/OiBudW1iZXI7XG5cblx0c2hhZGVyU291cmNlPzogU2hhZGVyU291cmNlO1xuXG5cdGRpcnR5PzogYm9vbGVhbjtcblxuXHRsaWdodFNoYWRlckRhdGE/OiBTaGFkZXJEYXRhO1xuXG5cdHVzZUxpZ2h0PzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCB0eXBlIE1vZGVsUGFyYW1zID0ge1xuXHRzaGFkZXJJZD86IHN0cmluZztcblx0ZnJhZz86IHN0cmluZztcblx0dmVydD86IHN0cmluZztcblx0Y29tcHV0ZT86IHN0cmluZztcblx0dmVydGV4QnVmZmVycz86IEFycmF5PFZlcnRleEJ1ZmZlclByb3A+O1xuXHR1bmlmb3JtVGV4dHVyZUFuZFNhbXBsZXI/OiB7XG5cdFx0W3VuaWZvcm06IHN0cmluZ106IElVbmlmb3JtPGFueT47XG5cdH07XG5cdHVuaWZvcm1CdWZmZXJzPzogQXJyYXk8VW5pZm9ybUJ1ZmZlclByb3A+O1xuXHRyZW5kZXJTdGF0ZT86IFJlbmRlclN0YXRlUHJvcDtcblx0Y291bnQ/OiBudW1iZXI7XG5cdGluc3RhbmNlcz86IG51bWJlcjtcblx0aW5kaWNlcz86IEFycmF5PG51bWJlcj47XG5cdGRyYXc/OiBEcmF3UGFybWFzO1xuXHRkaXNwYXRjaD86IHsgeD86IG51bWJlcjsgeT86IG51bWJlcjsgej86IG51bWJlciB9O1xuXHRyZW5kZXJUYXJnZXQ/OiBSZW5kZXJUYXJnZXQ7XG59O1xuZXhwb3J0IHR5cGUgVmVydGV4QnVmZmVyUHJvcCA9IHtcblx0dWlkPzogc3RyaW5nO1xuXHRzdGVwTW9kZT86IHN0cmluZztcblx0YXJyYXlTdHJpZGU/OiBudW1iZXI7XG5cdGF0dHJpYnV0ZXM/OiB7IFtwcm9wOiBzdHJpbmddOiBBdHRyaWJ1dGVQcm9wIH07XG59O1xuZXhwb3J0IHR5cGUgVW5pZm9ybUJ1ZmZlclByb3AgPSB7XG5cdHVpZD86IHN0cmluZztcblx0dHlwZT86IHN0cmluZztcblx0dXNhZ2U/OiBudW1iZXI7XG5cdGJpbmRpbmc/OiBudW1iZXI7XG5cdGJ1ZmZlcj86IEJ1ZmZlcjtcblx0YnVmZmVyU2l6ZT86IG51bWJlcjtcblx0dmlzaWJsaXR5PzogU2hhZGVyU3RhZ2U7XG5cdHVuaWZvcm1zPzogeyBbdW5pZm9ybTogc3RyaW5nXTogSVVuaWZvcm08YW55PiB9O1xufTtcbmV4cG9ydCB0eXBlIEF0dHJpYnV0ZVByb3AgPSB7XG5cdHNpemU/OiBudW1iZXI7XG5cdHZhbHVlPzogW107XG5cdG5hbWVzPzogQXJyYXk8c3RyaW5nPjtcblx0aXRlbVNpemVzPzogW107XG5cdGJ1ZmZlcj86IEJ1ZmZlcjtcbn07XG5leHBvcnQgdHlwZSBSZW5kZXJTdGF0ZVByb3AgPSB7XG5cdHN0ZW5jaWxSZWZlcmVuY2U6IG51bWJlcjtcblx0YmxlbmRDb25zdGFudD86IHtcblx0XHRyOiBudW1iZXI7XG5cdFx0ZzogbnVtYmVyO1xuXHRcdGI6IG51bWJlcjtcblx0XHRhOiBudW1iZXI7XG5cdH07XG5cdG11bHRpU2FtcGxlPzoge1xuXHRcdGNvdW50OiBudW1iZXI7XG5cdFx0bWFzazogbnVtYmVyO1xuXHRcdGFscGhhVG9Db3ZlcmFnZUVuYWJsZWQ6IGJvb2xlYW47XG5cdH07XG5cdHNjaXNzb3JUZXN0Pzoge1xuXHRcdHg6IG51bWJlcjtcblx0XHR5OiBudW1iZXI7XG5cdFx0d2lkdGg6IG51bWJlcjtcblx0XHRoZWlnaHQ6IG51bWJlcjtcblx0fTtcblx0dmlld1BvcnQ/OiB7XG5cdFx0eDogbnVtYmVyO1xuXHRcdHk6IG51bWJlcjtcblx0XHR3aWR0aDogbnVtYmVyO1xuXHRcdGhlaWdodDogbnVtYmVyO1xuXHRcdG1pbkRlcHRoOiBudW1iZXI7XG5cdFx0bWF4RGVwdGg6IG51bWJlcjtcblx0fTtcblx0cHJpbWl0aXZlPzoge1xuXHRcdGZyb250RmFjZTogc3RyaW5nO1xuXHRcdGN1bGxNb2RlOiBzdHJpbmc7XG5cdFx0dW5jbGlwcGVkRGVwdGg6IGJvb2xlYW47XG5cdFx0dG9wb2xvZ3k6IHN0cmluZztcblx0fTtcblx0ZGVwdGhTdGVuY2lsPzoge1xuXHRcdGZvcm1hdDogc3RyaW5nO1xuXHRcdGRlcHRoV3JpdGVFbmFibGVkOiBib29sZWFuO1xuXHRcdGRlcHRoQ29tcGFyZTogc3RyaW5nO1xuXHRcdHN0ZW5jaWxSZWFkTWFzazogbnVtYmVyO1xuXHRcdHN0ZW5jaWxXcml0ZU1hc2s6IG51bWJlcjtcblx0XHRzdGVuY2lsRnJvbnRDb21wYXJlOiBzdHJpbmc7XG5cdFx0c3RlbmNpbEZyb250RmFpbE9wOiBzdHJpbmc7XG5cdFx0c3RlbmNpbEZyb250RGVwdGhGYWlsT3A6IHN0cmluZztcblx0XHRzdGVuY2lsRnJvbnRQYXNzT3A6IHN0cmluZztcblxuXHRcdHN0ZW5jaWxCYWNrQ29tcGFyZTogc3RyaW5nO1xuXHRcdHN0ZW5jaWxCYWNrRmFpbE9wOiBzdHJpbmc7XG5cdFx0c3RlbmNpbEJhY2tEZXB0aEZhaWxPcDogc3RyaW5nO1xuXHRcdHN0ZW5jaWxCYWNrUGFzc09wOiBzdHJpbmc7XG5cdFx0ZGVwdGhCaWFzOiBudW1iZXI7XG5cdFx0ZGVwdGhCaWFzU2xvcGVTY2FsZTogbnVtYmVyO1xuXHRcdGRlcHRoQmlhc0NsYW1wOiBudW1iZXI7XG5cdH07XG5cdHRhcmdldHM/OiBBcnJheTx7XG5cdFx0Zm9ybWF0Pzogc3RyaW5nO1xuXHRcdGJsZW5kQ29sb3JPcGVyYXRpb24/OiBzdHJpbmc7XG5cdFx0YmxlbmRDb2xvclNyY0ZhY3Rvcj86IHN0cmluZztcblx0XHRibGVuZENvbG9yRHN0RmFjdG9yPzogc3RyaW5nO1xuXHRcdGJsZW5kQWxwaGFPcGVyYXRpb24/OiBzdHJpbmc7XG5cdFx0YmxlbmRBbHBoYVNyY0ZhY3Rvcj86IHN0cmluZztcblx0XHRibGVuZEFscGhhRHN0RmFjdG9yPzogc3RyaW5nO1xuXHRcdHdyaXRlTWFzazogR1BVQ29sb3JXcml0ZTtcblx0fT47XG59O1xuZXhwb3J0IHR5cGUgRHJhd1Bhcm1hcyA9IHtcblx0Y291bnQ/OiBudW1iZXI7IC8vIFRoZSBudW1iZXIgb2YgaW5kaWNlcyB0byBkcmF3Li9UaGUgbnVtYmVyIG9mIHZlcnRpY2VzIHRvIGRyYXcuXG5cdGluc3RhbmNlQ291bnQ/OiBudW1iZXI7IC8vIFRoZSBudW1iZXIgb2YgaW5zdGFuY2VzIHRvIGRyYXcuXG5cdGZpcnN0SW5kZXg/OiBudW1iZXI7IC8vIE9mZnNldCBpbnRvIHRoZSBpbmRleCBidWZmZXIsIGluIGluZGljZXMsIGJlZ2luIGRyYXdpbmdcblx0Zmlyc3RWZXJ0ZXg/OiBudW1iZXI7IC8vIE9mZnNldCBpbnRvIHRoZSB2ZXJ0ZXggYnVmZmVycywgaW4gdmVydGljZXMsIHRvIGJlZ2luIGRyYXdpbmcgZnJvbS5cblx0YmFzZVZlcnRleD86IG51bWJlcjsgLy8gIEFkZGVkIHRvIGVhY2ggaW5kZXggdmFsdWUgYmVmb3JlIGluZGV4aW5nIGludG8gdGhlIHZlcnRleCBidWZmZXJzLlxuXHRmaXJzdEluc3RhbmNlPzogbnVtYmVyOyAvLyBGaXJzdCBpbnN0YW5jZSB0byBkcmF3LlxufTtcbmV4cG9ydCB0eXBlIFVuaWZvcm1TdHJ1Y3QgPSB7XG5cdFt1bmlmb3JtOiBzdHJpbmddOiB7IHR5cGU/OiBzdHJpbmc7IHZhbHVlPzogb2JqZWN0IHwgQXJyYXk8bnVtYmVyPjsgb2Zmc2V0PzogbnVtYmVyIH07XG59O1xuZXhwb3J0IGVudW0gVW5pZm9ybUVudW0ge1xuXHRGbG9hdCA9IFwiZjMyXCIsXG5cdEZsb2F0VmVjMiA9IFwidmVjMjxmMzI+XCIsXG5cdEZsb2F0VmVjMyA9IFwidmVjMzxmMzI+XCIsXG5cdEZsb2F0VmVjNCA9IFwidmVjNDxmMzI+XCIsXG5cdEZsb2F0QXJyYXkgPSBcImFycmF5PGYzMj5cIixcblx0TWF0MiA9IFwibWF0MngyPGYzMj5cIixcblx0TWF0MyA9IFwibWF0M3gzPGYzMj5cIixcblx0TWF0NCA9IFwibWF0NHg0PGYzMj5cIixcblx0Q29sb3IgPSBcImNvbG9yXCIsXG5cdE1hdDRBcnJheSA9IFwiYXJyYXk8bWF0NHg0PGYzMj4+XCIsXG5cdFZlYzJBcnJheSA9IFwiYXJyYXk8dmVjMjxmMzI+PlwiLFxuXHRWZWMzQXJyYXkgPSBcImFycmF5PHZlYzM8ZjMyPj5cIixcblx0VmVjNEFycmF5ID0gXCJhcnJheTx2ZWM0PGYzMj4+XCIsXG5cdFVuaWZvcm1VaW50ID0gXCJ1MzJcIixcblx0UG9pbnRMaWdodHMgPSBcInBvaW50TGlnaHRzXCIsXG5cdFBvaW50TGlnaHRTaGFkb3dzID0gXCJwb2ludExpZ2h0U2hhZG93c1wiLFxuXHRTcG90TGlnaHRzID0gXCJzcG90TGlnaHRzXCIsXG5cdFNwb3RMaWdodFNoYWRvd3MgPSBcInNwb3RMaWdodFNoYWRvd3NcIixcblx0RGlydGVjdExpZ2h0cyA9IFwiZGlydGVjdExpZ2h0c1wiLFxuXHREaXJ0ZWN0TGlnaHRTaGFkb3dzID0gXCJkaXJ0ZWN0TGlnaHRTaGFkb3dzXCIsXG5cdFVuaWZvcm1TdHJ1Y3RBcnJheSA9IFwiU3RydWN0QXJyYXlcIlxufVxuZXhwb3J0IHR5cGUgVmVydGV4QnVmZmVyUGFyYW1zID0ge1xuXHRsYWJlbDogc3RyaW5nO1xuXHRpbmRleD86IG51bWJlcjtcblx0bG9jYXRpb25JbmRleD86IG51bWJlcjtcblx0c3RlcE1vZGU/OiBJbnB1dFN0ZXBNb2RlO1xuXHRhcnJheVN0cmlkZT86IG51bWJlcjtcbn07XG4iLCJpbXBvcnQgVGV4dHVyZSBmcm9tIFwiLi4vcmVuZGVyL1RleHR1cmVcIjtcblxuZXhwb3J0IGNsYXNzIE1pcG1hcEdlbmVyYXRvciB7XG5cdGRldmljZTogR1BVRGV2aWNlO1xuXHRzYW1wbGVyOiBHUFVTYW1wbGVyO1xuXHRwaXBlbGluZXM6IG9iamVjdDtcblx0bWlwbWFwU2hhZGVyTW9kdWxlOiBHUFVTaGFkZXJNb2R1bGU7XG5cdGNvbnN0cnVjdG9yKGRldmljZSkge1xuXHRcdHRoaXMuZGV2aWNlID0gZGV2aWNlO1xuXHRcdHRoaXMuc2FtcGxlciA9IGRldmljZS5jcmVhdGVTYW1wbGVyKHsgbWluRmlsdGVyOiBcImxpbmVhclwiIH0pO1xuXHRcdC8vIFdlJ2xsIG5lZWQgYSBuZXcgcGlwZWxpbmUgZm9yIGV2ZXJ5IHRleHR1cmUgZm9ybWF0IHVzZWQuXG5cdFx0dGhpcy5waXBlbGluZXMgPSB7fTtcblx0fVxuXHRwcml2YXRlIGdldE1pcG1hcFBpcGVsaW5lKGZvcm1hdCkge1xuXHRcdGxldCBwaXBlbGluZSA9IHRoaXMucGlwZWxpbmVzW2Zvcm1hdF07XG5cdFx0aWYgKCFwaXBlbGluZSkge1xuXHRcdFx0Ly8gU2hhZGVyIG1vZHVsZXMgaXMgc2hhcmVkIGJldHdlZW4gYWxsIHBpcGVsaW5lcywgc28gb25seSBjcmVhdGUgb25jZS5cblx0XHRcdGlmICghdGhpcy5taXBtYXBTaGFkZXJNb2R1bGUpIHtcblx0XHRcdFx0dGhpcy5taXBtYXBTaGFkZXJNb2R1bGUgPSB0aGlzLmRldmljZS5jcmVhdGVTaGFkZXJNb2R1bGUoe1xuXHRcdFx0XHRcdGNvZGU6IGBcbiAgICAgICAgICAgICAgdmFyPHByaXZhdGU+IHBvcyA6IGFycmF5PHZlYzI8ZjMyPiwgMz4gPSBhcnJheTx2ZWMyPGYzMj4sIDM+KFxuICAgICAgICAgICAgICAgIHZlYzI8ZjMyPigtMS4wLCAtMS4wKSwgdmVjMjxmMzI+KC0xLjAsIDMuMCksIHZlYzI8ZjMyPigzLjAsIC0xLjApKTtcbiAgICAgICAgICAgICAgc3RydWN0IFZlcnRleE91dHB1dCB7XG4gICAgICAgICAgICAgICAgQGJ1aWx0aW4ocG9zaXRpb24pIHBvc2l0aW9uIDogdmVjNDxmMzI+LFxuICAgICAgICAgICAgICAgIEBsb2NhdGlvbigwKSB0ZXhDb29yZCA6IHZlYzI8ZjMyPixcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgQHZlcnRleFxuICAgICAgICAgICAgICBmbiB2ZXJ0ZXhNYWluKEBidWlsdGluKHZlcnRleF9pbmRleCkgdmVydGV4SW5kZXggOiB1MzIpIC0+IFZlcnRleE91dHB1dCB7XG4gICAgICAgICAgICAgICAgdmFyIG91dHB1dCA6IFZlcnRleE91dHB1dDtcbiAgICAgICAgICAgICAgICBvdXRwdXQudGV4Q29vcmQgPSBwb3NbdmVydGV4SW5kZXhdICogdmVjMjxmMzI+KDAuNSwgLTAuNSkgKyB2ZWMyPGYzMj4oMC41KTtcbiAgICAgICAgICAgICAgICBvdXRwdXQucG9zaXRpb24gPSB2ZWM0PGYzMj4ocG9zW3ZlcnRleEluZGV4XSwgMC4wLCAxLjApO1xuICAgICAgICAgICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhciBpbWdTYW1wbGVyIDogc2FtcGxlcjtcbiAgICAgICAgICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciBpbWcgOiB0ZXh0dXJlXzJkPGYzMj47XG4gICAgICAgICAgICAgIEBmcmFnbWVudFxuICAgICAgICAgICAgICBmbiBmcmFnbWVudE1haW4oQGxvY2F0aW9uKDApIHRleENvb3JkIDogdmVjMjxmMzI+KSAtPiBAbG9jYXRpb24oMCkgdmVjNDxmMzI+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGV4dHVyZVNhbXBsZShpbWcsIGltZ1NhbXBsZXIsIHRleENvb3JkKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgYFxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHRcdHBpcGVsaW5lID0gdGhpcy5kZXZpY2UuY3JlYXRlUmVuZGVyUGlwZWxpbmUoe1xuXHRcdFx0XHRsYXlvdXQ6IFwiYXV0b1wiLFxuXHRcdFx0XHR2ZXJ0ZXg6IHtcblx0XHRcdFx0XHRtb2R1bGU6IHRoaXMubWlwbWFwU2hhZGVyTW9kdWxlLFxuXHRcdFx0XHRcdGVudHJ5UG9pbnQ6IFwidmVydGV4TWFpblwiXG5cdFx0XHRcdH0sXG5cdFx0XHRcdGZyYWdtZW50OiB7XG5cdFx0XHRcdFx0bW9kdWxlOiB0aGlzLm1pcG1hcFNoYWRlck1vZHVsZSxcblx0XHRcdFx0XHRlbnRyeVBvaW50OiBcImZyYWdtZW50TWFpblwiLFxuXHRcdFx0XHRcdHRhcmdldHM6IFt7IGZvcm1hdCB9XVxuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHRcdHRoaXMucGlwZWxpbmVzW2Zvcm1hdF0gPSBwaXBlbGluZTtcblx0XHR9XG5cdFx0cmV0dXJuIHBpcGVsaW5lO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdlbmVyYXRlcyBtaXBtYXBzIGZvciB0aGUgZ2l2ZW4gR1BVVGV4dHVyZSBmcm9tIHRoZSBkYXRhIGluIGxldmVsIDAuXG5cdCAqXG5cdCAqIEBwYXJhbSB7bW9kdWxlOkV4dGVybmFsLkdQVVRleHR1cmV9IHRleHR1cmUgLSBUZXh0dXJlIHRvIGdlbmVyYXRlIG1pcG1hcHMgZm9yLlxuXHQgKiBAcGFyYW0ge29iamVjdH0gdGV4dHVyZURlc2NyaXB0b3IgLSBHUFVUZXh0dXJlRGVzY3JpcHRvciB0aGUgdGV4dHVyZSB3YXMgY3JlYXRlZCB3aXRoLlxuXHQgKiBAcmV0dXJucyB7bW9kdWxlOkV4dGVybmFsLkdQVVRleHR1cmV9IC0gVGhlIG9yaWdpbmFsbHkgcGFzc2VkIHRleHR1cmVcblx0ICovXG5cdGdlbmVyYXRlTWlwbWFwKHNvdXJjZVRleHR1cmU6IFRleHR1cmUpIHtcblx0XHRjb25zdCB0ZXh0dXJlID0gc291cmNlVGV4dHVyZS5ncHVUZXh0dXJlO1xuXHRcdGNvbnN0IHRleHR1cmVEZXNjcmlwdG9yID0gc291cmNlVGV4dHVyZS50ZXh0dXJlUHJvcDtcblx0XHQvLyBUT0RPOiBEb2VzIHRoaXMgbmVlZCB0byBoYW5kbGUgc1JHQiBmb3JtYXRzIGRpZmZlcmVudGx5P1xuXHRcdGNvbnN0IHBpcGVsaW5lID0gdGhpcy5nZXRNaXBtYXBQaXBlbGluZSh0ZXh0dXJlRGVzY3JpcHRvci5mb3JtYXQpO1xuXG5cdFx0aWYgKHRleHR1cmVEZXNjcmlwdG9yLmRpbWVuc2lvbiA9PSBcIjNkXCIgfHwgdGV4dHVyZURlc2NyaXB0b3IuZGltZW5zaW9uID09IFwiMWRcIikge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiR2VuZXJhdGluZyBtaXBtYXBzIGZvciBub24tMmQgdGV4dHVyZXMgaXMgY3VycmVudGx5IHVuc3VwcG9ydGVkIVwiKTtcblx0XHR9XG5cblx0XHRsZXQgbWlwVGV4dHVyZSA9IHRleHR1cmU7XG5cdFx0Y29uc3QgYXJyYXlMYXllckNvdW50ID0gdGV4dHVyZURlc2NyaXB0b3Iuc2l6ZS5kZXB0aCB8fCAxOyAvLyBPbmx5IHZhbGlkIGZvciAyRCB0ZXh0dXJlcy5cblxuXHRcdC8vIElmIHRoZSB0ZXh0dXJlIHdhcyBjcmVhdGVkIHdpdGggUkVOREVSX0FUVEFDSE1FTlQgdXNhZ2Ugd2UgY2FuIHJlbmRlciBkaXJlY3RseSBiZXR3ZWVuIG1pcCBsZXZlbHMuXG5cdFx0Y29uc3QgcmVuZGVyVG9Tb3VyY2UgPSB0ZXh0dXJlRGVzY3JpcHRvci51c2FnZSAmIEdQVVRleHR1cmVVc2FnZS5SRU5ERVJfQVRUQUNITUVOVDtcblx0XHRpZiAoIXJlbmRlclRvU291cmNlKSB7XG5cdFx0XHQvLyBPdGhlcndpc2Ugd2UgaGF2ZSB0byB1c2UgYSBzZXBhcmF0ZSB0ZXh0dXJlIHRvIHJlbmRlciBpbnRvLiBJdCBjYW4gYmUgb25lIG1pcCBsZXZlbCBzbWFsbGVyIHRoYW4gdGhlIHNvdXJjZVxuXHRcdFx0Ly8gdGV4dHVyZSwgc2luY2Ugd2UgYWxyZWFkeSBoYXZlIHRoZSB0b3AgbGV2ZWwuXG5cdFx0XHRjb25zdCBtaXBUZXh0dXJlRGVzY3JpcHRvciA9IHtcblx0XHRcdFx0c2l6ZToge1xuXHRcdFx0XHRcdHdpZHRoOiBNYXRoLmNlaWwodGV4dHVyZURlc2NyaXB0b3Iuc2l6ZS53aWR0aCAvIDIpLFxuXHRcdFx0XHRcdGhlaWdodDogTWF0aC5jZWlsKHRleHR1cmVEZXNjcmlwdG9yLnNpemUuaGVpZ2h0IC8gMiksXG5cdFx0XHRcdFx0ZGVwdGhPckFycmF5TGF5ZXJzOiBhcnJheUxheWVyQ291bnRcblx0XHRcdFx0fSxcblx0XHRcdFx0Zm9ybWF0OiA8R1BVVGV4dHVyZUZvcm1hdD50ZXh0dXJlRGVzY3JpcHRvci5mb3JtYXQsXG5cdFx0XHRcdHVzYWdlOiBHUFVUZXh0dXJlVXNhZ2UuVEVYVFVSRV9CSU5ESU5HIHwgR1BVVGV4dHVyZVVzYWdlLkNPUFlfU1JDIHwgR1BVVGV4dHVyZVVzYWdlLlJFTkRFUl9BVFRBQ0hNRU5ULFxuXHRcdFx0XHRtaXBMZXZlbENvdW50OiB0ZXh0dXJlRGVzY3JpcHRvci5taXBMZXZlbENvdW50IC0gMVxuXHRcdFx0fTtcblx0XHRcdG1pcFRleHR1cmUgPSB0aGlzLmRldmljZS5jcmVhdGVUZXh0dXJlKG1pcFRleHR1cmVEZXNjcmlwdG9yKTtcblx0XHR9XG5cblx0XHRjb25zdCBjb21tYW5kRW5jb2RlciA9IHRoaXMuZGV2aWNlLmNyZWF0ZUNvbW1hbmRFbmNvZGVyKHt9KTtcblx0XHQvLyBUT0RPOiBDb25zaWRlciBtYWtpbmcgdGhpcyBzdGF0aWMuXG5cdFx0Y29uc3QgYmluZEdyb3VwTGF5b3V0ID0gcGlwZWxpbmUuZ2V0QmluZEdyb3VwTGF5b3V0KDApO1xuXG5cdFx0Zm9yIChsZXQgYXJyYXlMYXllciA9IDA7IGFycmF5TGF5ZXIgPCBhcnJheUxheWVyQ291bnQ7ICsrYXJyYXlMYXllcikge1xuXHRcdFx0bGV0IHNyY1ZpZXcgPSB0ZXh0dXJlLmNyZWF0ZVZpZXcoe1xuXHRcdFx0XHRiYXNlTWlwTGV2ZWw6IDAsXG5cdFx0XHRcdG1pcExldmVsQ291bnQ6IDEsXG5cdFx0XHRcdGRpbWVuc2lvbjogXCIyZFwiLFxuXHRcdFx0XHRiYXNlQXJyYXlMYXllcjogYXJyYXlMYXllcixcblx0XHRcdFx0YXJyYXlMYXllckNvdW50OiAxXG5cdFx0XHR9KTtcblxuXHRcdFx0bGV0IGRzdE1pcExldmVsID0gcmVuZGVyVG9Tb3VyY2UgPyAxIDogMDtcblx0XHRcdGZvciAobGV0IGkgPSAxOyBpIDwgdGV4dHVyZURlc2NyaXB0b3IubWlwTGV2ZWxDb3VudDsgKytpKSB7XG5cdFx0XHRcdGNvbnN0IGRzdFZpZXcgPSBtaXBUZXh0dXJlLmNyZWF0ZVZpZXcoe1xuXHRcdFx0XHRcdGJhc2VNaXBMZXZlbDogZHN0TWlwTGV2ZWwrKyxcblx0XHRcdFx0XHRtaXBMZXZlbENvdW50OiAxLFxuXHRcdFx0XHRcdGRpbWVuc2lvbjogXCIyZFwiLFxuXHRcdFx0XHRcdGJhc2VBcnJheUxheWVyOiBhcnJheUxheWVyLFxuXHRcdFx0XHRcdGFycmF5TGF5ZXJDb3VudDogMVxuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHRjb25zdCBwYXNzRW5jb2RlciA9IGNvbW1hbmRFbmNvZGVyLmJlZ2luUmVuZGVyUGFzcyh7XG5cdFx0XHRcdFx0Y29sb3JBdHRhY2htZW50czogW1xuXHRcdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0XHR2aWV3OiBkc3RWaWV3LFxuXHRcdFx0XHRcdFx0XHRsb2FkT3A6IFwiY2xlYXJcIixcblx0XHRcdFx0XHRcdFx0c3RvcmVPcDogXCJzdG9yZVwiXG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XVxuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHRjb25zdCBiaW5kR3JvdXAgPSB0aGlzLmRldmljZS5jcmVhdGVCaW5kR3JvdXAoe1xuXHRcdFx0XHRcdGxheW91dDogYmluZEdyb3VwTGF5b3V0LFxuXHRcdFx0XHRcdGVudHJpZXM6IFtcblx0XHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdFx0YmluZGluZzogMCxcblx0XHRcdFx0XHRcdFx0cmVzb3VyY2U6IHRoaXMuc2FtcGxlclxuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdFx0YmluZGluZzogMSxcblx0XHRcdFx0XHRcdFx0cmVzb3VyY2U6IHNyY1ZpZXdcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRdXG5cdFx0XHRcdH0pO1xuXG5cdFx0XHRcdHBhc3NFbmNvZGVyLnNldFBpcGVsaW5lKHBpcGVsaW5lKTtcblx0XHRcdFx0cGFzc0VuY29kZXIuc2V0QmluZEdyb3VwKDAsIGJpbmRHcm91cCk7XG5cdFx0XHRcdHBhc3NFbmNvZGVyLmRyYXcoMywgMSwgMCwgMCk7XG5cdFx0XHRcdHBhc3NFbmNvZGVyLmVuZCgpO1xuXG5cdFx0XHRcdHNyY1ZpZXcgPSBkc3RWaWV3O1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIElmIHdlIGRpZG4ndCByZW5kZXIgdG8gdGhlIHNvdXJjZSB0ZXh0dXJlLCBmaW5pc2ggYnkgY29weWluZyB0aGUgbWlwIHJlc3VsdHMgZnJvbSB0aGUgdGVtcG9yYXJ5IG1pcG1hcCB0ZXh0dXJlXG5cdFx0Ly8gdG8gdGhlIHNvdXJjZS5cblx0XHRpZiAoIXJlbmRlclRvU291cmNlKSB7XG5cdFx0XHRjb25zdCBtaXBMZXZlbFNpemUgPSB7XG5cdFx0XHRcdHdpZHRoOiBNYXRoLmNlaWwodGV4dHVyZURlc2NyaXB0b3Iuc2l6ZS53aWR0aCAvIDIpLFxuXHRcdFx0XHRoZWlnaHQ6IE1hdGguY2VpbCh0ZXh0dXJlRGVzY3JpcHRvci5zaXplLmhlaWdodCAvIDIpLFxuXHRcdFx0XHRkZXB0aE9yQXJyYXlMYXllcnM6IGFycmF5TGF5ZXJDb3VudFxuXHRcdFx0fTtcblxuXHRcdFx0Zm9yIChsZXQgaSA9IDE7IGkgPCB0ZXh0dXJlRGVzY3JpcHRvci5taXBMZXZlbENvdW50OyArK2kpIHtcblx0XHRcdFx0Y29tbWFuZEVuY29kZXIuY29weVRleHR1cmVUb1RleHR1cmUoXG5cdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0dGV4dHVyZTogbWlwVGV4dHVyZSxcblx0XHRcdFx0XHRcdG1pcExldmVsOiBpIC0gMVxuXHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0dGV4dHVyZTogdGV4dHVyZSxcblx0XHRcdFx0XHRcdG1pcExldmVsOiBpXG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRtaXBMZXZlbFNpemVcblx0XHRcdFx0KTtcblxuXHRcdFx0XHRtaXBMZXZlbFNpemUud2lkdGggPSBNYXRoLmNlaWwobWlwTGV2ZWxTaXplLndpZHRoIC8gMik7XG5cdFx0XHRcdG1pcExldmVsU2l6ZS5oZWlnaHQgPSBNYXRoLmNlaWwobWlwTGV2ZWxTaXplLmhlaWdodCAvIDIpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMuZGV2aWNlLnF1ZXVlLnN1Ym1pdChbY29tbWFuZEVuY29kZXIuZmluaXNoKCldKTtcblxuXHRcdGlmICghcmVuZGVyVG9Tb3VyY2UpIHtcblx0XHRcdG1pcFRleHR1cmUuZGVzdHJveSgpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0ZXh0dXJlO1xuXHR9XG59XG4iLCJmdW5jdGlvbiBkZWZhdWx0VmFsdWUoYSwgYikge1xuXHRpZiAoYSAhPT0gdW5kZWZpbmVkICYmIGEgIT09IG51bGwpIHtcblx0XHRyZXR1cm4gYTtcblx0fVxuXHRyZXR1cm4gYjtcbn1cblxuLyoqXG4gKiBBIGZyb3plbiBlbXB0eSBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCBhcyB0aGUgZGVmYXVsdCB2YWx1ZSBmb3Igb3B0aW9ucyBwYXNzZWQgYXNcbiAqIGFuIG9iamVjdCBsaXRlcmFsLlxuICogQHR5cGUge09iamVjdH1cbiAqIEBtZW1iZXJvZiBkZWZhdWx0VmFsdWVcbiAqL1xuZGVmYXVsdFZhbHVlLkVNUFRZX09CSkVDVCA9IE9iamVjdC5mcmVlemUoe30pO1xuXG5leHBvcnQgZGVmYXVsdCBkZWZhdWx0VmFsdWU7XG4iLCJpbXBvcnQge1xuXHRCbGVuZEZhY3Rvcixcblx0QmxlbmRPcGVyYXRpb24sXG5cdFRleHR1cmVGb3JtYXQsXG5cdEdQVUNvbG9yV3JpdGUsXG5cdENvbXBhcmVGdW5jdGlvbixcblx0U3RlbmNpbE9wZXJhdGlvbixcblx0RnJvbnRGYWNlLFxuXHRDdWxsTW9kZSxcblx0UHJpbWl0aXZlVG9wb2xvZ3lcbn0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVQ29uc3RhbnRcIjtcbi8vIGltcG9ydCB7IEJpbmRSZW5kZXJTdGF0ZSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XG5pbXBvcnQgZGVmYXVsdFZhbHVlIGZyb20gXCIuLi91dGlscy9kZWZhdWx0VmFsdWVcIjtcblxuZXhwb3J0IGNsYXNzIFJlbmRlclN0YXRlIHtcblx0c2Npc3NvclRlc3Q6IFNjaXNzb3JUZXN0O1xuXHR2aWV3cG9ydDogVmlld1BvcnQ7XG5cdHRhcmdldHM6IEFycmF5PFRhcmdldD47XG5cdGRlcHRoU3RlbmNpbDogRGVwdGhTdGVuY2lsO1xuXHRibGVuZENvbnN0YW50OiBCbGVuZENvbnN0YW50O1xuXHRzdGVuY2lsUmVmZXJlbmNlOiBudW1iZXI7XG5cdG11bHRpc2FtcGxlOiBNdWx0aVNhbXBsZTtcblx0cHJpbWl0aXZlOiBQcmltaXRpdmU7XG5cdHN0ZW5jaWxFbmFibGVkOiBib29sZWFuO1xuXHRzY2lzc29yVGVzdEVuYWJsZWQ6IGJvb2xlYW47XG5cdGNvbnN0cnVjdG9yKHBhcmFtcz86IFJlbmRlclN0YXRlUGFyYW1zKSB7XG5cdFx0dGhpcy5zY2lzc29yVGVzdCA9IHBhcmFtcz8uc2Npc3NvclRlc3Q7XG5cdFx0dGhpcy52aWV3cG9ydCA9IHBhcmFtcz8udmlld3BvcnQ7XG5cdFx0dGhpcy5kZXB0aFN0ZW5jaWwgPSBwYXJhbXM/LmRlcHRoU3RlbmNpbDtcblx0XHR0aGlzLmJsZW5kQ29uc3RhbnQgPSBwYXJhbXM/LmJsZW5kQ29uc3RhbnQ7XG5cdFx0dGhpcy5zdGVuY2lsUmVmZXJlbmNlID0gcGFyYW1zPy5zdGVuY2lsUmVmZXJlbmNlO1xuXHRcdHRoaXMubXVsdGlzYW1wbGUgPSBwYXJhbXM/Lm11bHRpc2FtcGxlO1xuXHRcdHRoaXMucHJpbWl0aXZlID0gcGFyYW1zPy5wcmltaXRpdmU7XG5cdFx0dGhpcy5zdGVuY2lsRW5hYmxlZCA9IGZhbHNlO1xuXHRcdHRoaXMuc2Npc3NvclRlc3RFbmFibGVkID0gZmFsc2U7XG5cdFx0dGhpcy50YXJnZXRzID0gcGFyYW1zPy50YXJnZXRzO1xuXHR9XG5cdGJpbmQocGFyYW1zOiBCaW5kUmVuZGVyU3RhdGUpIHtcblx0XHRjb25zdCB7IHBhc3NFbmNvZGVyLCB2aWV3UG9ydCwgc2Npc3NvclRlc3QgfSA9IHBhcmFtcztcblx0XHRjb25zdCBmaW5hbFZpZXdwb3J0ID0gdGhpcy52aWV3cG9ydCA/PyB2aWV3UG9ydDtcblx0XHRjb25zdCBmaW5hbFNjaXNzb3JUZXN0ID0gdGhpcy5zY2lzc29yVGVzdCA/PyBzY2lzc29yVGVzdDtcblx0XHRpZiAodGhpcy5zdGVuY2lsUmVmZXJlbmNlKSBwYXNzRW5jb2Rlci5zZXRTdGVuY2lsUmVmZXJlbmNlKHRoaXMuc3RlbmNpbFJlZmVyZW5jZSk7XG5cdFx0aWYgKChmaW5hbFZpZXdwb3J0IGFzIFZpZXdQb3J0KT8uZXF1YWxzQW5kVXBkYXRlQ2FjaGUoY2FjaGVWaWV3UG9ydCkpIHtcblx0XHRcdGNvbnN0IHsgeCwgeSwgd2lkdGgsIGhlaWdodCwgbWluRGVwdGgsIG1heERlcHRoIH0gPSBmaW5hbFZpZXdwb3J0O1xuXHRcdFx0cGFzc0VuY29kZXIuc2V0Vmlld3BvcnQoeCwgeSwgd2lkdGgsIGhlaWdodCwgbWluRGVwdGgsIG1heERlcHRoKTtcblx0XHR9XG5cdFx0aWYgKHRoaXMuYmxlbmRDb25zdGFudCkgcGFzc0VuY29kZXIuc2V0QmxlbmRDb25zdGFudCh0aGlzLmJsZW5kQ29uc3RhbnQpO1xuXHRcdGlmICgoZmluYWxTY2lzc29yVGVzdCBhcyBTY2lzc29yVGVzdCk/LmVxdWFsc0FuZFVwZGF0ZUNhY2hlKGNhY2hlU2Npc3NvclRlc3QpKSB7XG5cdFx0XHRjb25zdCB7IHgsIHksIHdpZHRoLCBoZWlnaHQgfSA9IGZpbmFsU2Npc3NvclRlc3Q7XG5cdFx0XHRwYXNzRW5jb2Rlci5zZXRTY2lzc29yUmVjdCh4LCB5LCB3aWR0aCwgaGVpZ2h0KTtcblx0XHR9XG5cdH1cblx0ZGVzdHJveSgpIHtcblx0XHR0aGlzLnNjaXNzb3JUZXN0ID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMudmlld3BvcnQgPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy5kZXB0aFN0ZW5jaWwgPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy5ibGVuZENvbnN0YW50ID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMuc3RlbmNpbFJlZmVyZW5jZSA9IC0xO1xuXHRcdHRoaXMubXVsdGlzYW1wbGUgPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy5wcmltaXRpdmUgPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy5zdGVuY2lsRW5hYmxlZCA9IGZhbHNlO1xuXHRcdHRoaXMuc2Npc3NvclRlc3RFbmFibGVkID0gZmFsc2U7XG5cdH1cbn1cbmV4cG9ydCBjbGFzcyBCbGVuZENvbnN0YW50IHtcblx0cjogbnVtYmVyO1xuXHRnOiBudW1iZXI7XG5cdGI6IG51bWJlcjtcblx0YTogbnVtYmVyO1xuXHRjb25zdHJ1Y3RvcihyOiBudW1iZXIsIGc6IG51bWJlciwgYjogbnVtYmVyLCBhOiBudW1iZXIpIHtcblx0XHR0aGlzLnIgPSByO1xuXHRcdHRoaXMuZyA9IGc7XG5cdFx0dGhpcy5iID0gYjtcblx0XHR0aGlzLmEgPSBhO1xuXHR9XG59XG5leHBvcnQgY2xhc3MgTXVsdGlTYW1wbGUge1xuXHRjb3VudDogbnVtYmVyO1xuXHRtYXNrOiBudW1iZXI7XG5cdGFscGhhVG9Db3ZlcmFnZUVuYWJsZWQ6IGJvb2xlYW47XG5cdGNvbnN0cnVjdG9yKGNvdW50ID0gMSwgbWFzayA9IDB4ZmZmZmZmZmYsIGFscGhhVG9Db3ZlcmFnZUVuYWJsZWQgPSBmYWxzZSkge1xuXHRcdHRoaXMuY291bnQgPSBjb3VudDtcblx0XHR0aGlzLm1hc2sgPSBtYXNrO1xuXHRcdHRoaXMuYWxwaGFUb0NvdmVyYWdlRW5hYmxlZCA9IGFscGhhVG9Db3ZlcmFnZUVuYWJsZWQ7XG5cdH1cblx0Z2V0TXVsdGlTYW1wbGVEZWMoKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdGNvdW50OiB0aGlzLmNvdW50LFxuXHRcdFx0bWFzazogdGhpcy5tYXNrLFxuXHRcdFx0YWxwaGFUb0NvdmVyYWdlRW5hYmxlZDogdGhpcy5hbHBoYVRvQ292ZXJhZ2VFbmFibGVkXG5cdFx0fTtcblx0fVxufVxuZXhwb3J0IGNsYXNzIFNjaXNzb3JUZXN0IHtcblx0eDogbnVtYmVyO1xuXHR5OiBudW1iZXI7XG5cdHdpZHRoOiBudW1iZXI7XG5cdGhlaWdodDogbnVtYmVyO1xuXHR2YXJpYWJsZTogYm9vbGVhbjtcblx0Y29uc3RydWN0b3IoeCA9IDAsIHkgPSAwLCB3aWR0aCA9IDAsIGhlaWdodCA9IDAsIHZhcmlhYmxlID0gdHJ1ZSkge1xuXHRcdHRoaXMueCA9IHg7XG5cdFx0dGhpcy55ID0geTtcblx0XHR0aGlzLndpZHRoID0gd2lkdGg7XG5cdFx0dGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG5cdFx0dGhpcy52YXJpYWJsZSA9IHZhcmlhYmxlO1xuXHR9XG5cdHNldCh4OiBudW1iZXIsIHk6IG51bWJlciwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcblx0XHR0aGlzLnggPSB4O1xuXHRcdHRoaXMueSA9IHk7XG5cdFx0dGhpcy53aWR0aCA9IHdpZHRoO1xuXHRcdHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xuXHR9XG5cdGVxdWFsc0FuZFVwZGF0ZUNhY2hlKHNjaXNzb3JUZXN0OiBTY2lzc29yVGVzdCk6IGJvb2xlYW4ge1xuXHRcdGNvbnN0IHsgeCwgeSwgd2lkdGgsIGhlaWdodCB9ID0gc2Npc3NvclRlc3Q7XG5cdFx0aWYgKHRoaXMueCAhPSB4IHx8IHRoaXMueSAhPSB5IHx8IHRoaXMud2lkdGggIT0gd2lkdGggfHwgdGhpcy5oZWlnaHQgIT0gaGVpZ2h0KSB7XG5cdFx0XHRzY2lzc29yVGVzdC5zZXQodGhpcy54LCB0aGlzLnksIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn1cbmV4cG9ydCBjbGFzcyBWaWV3UG9ydCB7XG5cdHg6IG51bWJlcjtcblx0eTogbnVtYmVyO1xuXHR3aWR0aDogbnVtYmVyO1xuXHRoZWlnaHQ6IG51bWJlcjtcblx0bWluRGVwdGg6IG51bWJlcjtcblx0bWF4RGVwdGg6IG51bWJlcjtcblx0dmFyaWFibGU6IGJvb2xlYW47XG5cdGNvbnN0cnVjdG9yKHggPSAwLCB5ID0gMCwgd2lkdGggPSAwLCBoZWlnaHQgPSAwLCBtaW5EZXB0aCA9IDAsIG1heERlcHRoID0gMSwgdmFyaWFibGUgPSB0cnVlKSB7XG5cdFx0dGhpcy54ID0geDtcblx0XHR0aGlzLnkgPSB5O1xuXHRcdHRoaXMud2lkdGggPSB3aWR0aDtcblx0XHR0aGlzLmhlaWdodCA9IGhlaWdodDtcblx0XHR0aGlzLm1pbkRlcHRoID0gbWluRGVwdGg7XG5cdFx0dGhpcy5tYXhEZXB0aCA9IG1heERlcHRoO1xuXHRcdHRoaXMudmFyaWFibGUgPSB2YXJpYWJsZTtcblx0fVxuXHRzZXQoeDogbnVtYmVyLCB5OiBudW1iZXIsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBtaW5EZXB0aCA9IDAsIG1heERlcHRoID0gMSkge1xuXHRcdGlmICghdGhpcy52YXJpYWJsZSkgcmV0dXJuO1xuXHRcdHRoaXMueCA9IHg7XG5cdFx0dGhpcy55ID0geTtcblx0XHR0aGlzLndpZHRoID0gd2lkdGg7XG5cdFx0dGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG5cdFx0dGhpcy5taW5EZXB0aCA9IG1pbkRlcHRoO1xuXHRcdHRoaXMubWF4RGVwdGggPSBtYXhEZXB0aDtcblx0fVxuXHRlcXVhbHNBbmRVcGRhdGVDYWNoZSh2aWV3UG9ydDogVmlld1BvcnQpOiBib29sZWFuIHtcblx0XHRjb25zdCB7IHgsIHksIHdpZHRoLCBoZWlnaHQsIG1pbkRlcHRoLCBtYXhEZXB0aCB9ID0gdmlld1BvcnQ7XG5cdFx0aWYgKFxuXHRcdFx0dGhpcy54ICE9IHggfHxcblx0XHRcdHRoaXMueSAhPSB5IHx8XG5cdFx0XHR0aGlzLndpZHRoICE9IHdpZHRoIHx8XG5cdFx0XHR0aGlzLmhlaWdodCAhPSBoZWlnaHQgfHxcblx0XHRcdHRoaXMubWluRGVwdGggIT0gbWluRGVwdGggfHxcblx0XHRcdHRoaXMubWF4RGVwdGggIT0gbWF4RGVwdGhcblx0XHQpIHtcblx0XHRcdHZpZXdQb3J0LnNldCh0aGlzLngsIHRoaXMueSwgdGhpcy53aWR0aCwgdGhpcy5oZWlnaHQsIHRoaXMubWluRGVwdGgsIHRoaXMubWF4RGVwdGgpO1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufVxuZXhwb3J0IGNsYXNzIFByaW1pdGl2ZSB7XG5cdGZyb250RmFjZTogRnJvbnRGYWNlO1xuXHRjdWxsTW9kZTogQ3VsbE1vZGU7XG5cdHVuY2xpcHBlZERlcHRoOiBib29sZWFuO1xuXHR0b3BvbG9neTogUHJpbWl0aXZlVG9wb2xvZ3k7XG5cdGNvbnN0cnVjdG9yKHRvcG9sb2d5PzogUHJpbWl0aXZlVG9wb2xvZ3ksIGN1bGxNb2RlPzogQ3VsbE1vZGUsIGZyb250RmFjZT86IEZyb250RmFjZSwgdW5jbGlwcGVkRGVwdGg/OiBib29sZWFuKSB7XG5cdFx0dGhpcy5mcm9udEZhY2UgPSBkZWZhdWx0VmFsdWUoZnJvbnRGYWNlLCBGcm9udEZhY2UuQ0NXKTtcblx0XHR0aGlzLmN1bGxNb2RlID0gZGVmYXVsdFZhbHVlKGN1bGxNb2RlLCBDdWxsTW9kZS5Ob25lKTtcblx0XHR0aGlzLnVuY2xpcHBlZERlcHRoID0gZGVmYXVsdFZhbHVlKHVuY2xpcHBlZERlcHRoLCBmYWxzZSk7XG5cdFx0dGhpcy50b3BvbG9neSA9IGRlZmF1bHRWYWx1ZSh0b3BvbG9neSwgUHJpbWl0aXZlVG9wb2xvZ3kuVHJpYW5nbGVMaXN0KTtcblx0fVxuXHRnZXRHUFVQcmltaXRpdmVEZWMoKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdGZyb250RmFjZTogdGhpcy5mcm9udEZhY2UsXG5cdFx0XHRjdWxsTW9kZTogdGhpcy5jdWxsTW9kZSxcblx0XHRcdHVuY2xpcHBlZERlcHRoOiB0aGlzLnVuY2xpcHBlZERlcHRoLFxuXHRcdFx0dG9wb2xvZ3k6IHRoaXMudG9wb2xvZ3lcblx0XHR9O1xuXHR9XG59XG5leHBvcnQgY2xhc3MgRGVwdGhTdGVuY2lsIHtcblx0Zm9ybWF0OiBUZXh0dXJlRm9ybWF0O1xuXHRkZXB0aFdyaXRlRW5hYmxlZDogYm9vbGVhbjtcblx0ZGVwdGhDb21wYXJlOiBDb21wYXJlRnVuY3Rpb247XG5cdHN0ZW5jaWxSZWFkTWFzazogbnVtYmVyO1xuXHRzdGVuY2lsV3JpdGVNYXNrOiBudW1iZXI7XG5cdHN0ZW5jaWxGcm9udENvbXBhcmU6IENvbXBhcmVGdW5jdGlvbjtcblx0c3RlbmNpbEZyb250RmFpbE9wOiBTdGVuY2lsT3BlcmF0aW9uO1xuXHRzdGVuY2lsRnJvbnREZXB0aEZhaWxPcDogU3RlbmNpbE9wZXJhdGlvbjtcblx0c3RlbmNpbEZyb250UGFzc09wOiBTdGVuY2lsT3BlcmF0aW9uO1xuXG5cdHN0ZW5jaWxCYWNrQ29tcGFyZTogQ29tcGFyZUZ1bmN0aW9uO1xuXHRzdGVuY2lsQmFja0ZhaWxPcDogU3RlbmNpbE9wZXJhdGlvbjtcblx0c3RlbmNpbEJhY2tEZXB0aEZhaWxPcDogU3RlbmNpbE9wZXJhdGlvbjtcblx0c3RlbmNpbEJhY2tQYXNzT3A6IFN0ZW5jaWxPcGVyYXRpb247XG5cdGRlcHRoQmlhczogbnVtYmVyO1xuXHRkZXB0aEJpYXNTbG9wZVNjYWxlOiBudW1iZXI7XG5cdGRlcHRoQmlhc0NsYW1wOiBudW1iZXI7XG5cdGNvbnN0cnVjdG9yKG9wdGlvbnM/OiBEZXB0aFN0ZW5jaWxQcm9wcykge1xuXHRcdHRoaXMuZm9ybWF0ID0gZGVmYXVsdFZhbHVlKG9wdGlvbnM/LmZvcm1hdCwgVGV4dHVyZUZvcm1hdC5EZXB0aDI0UGx1cyk7XG5cdFx0dGhpcy5kZXB0aFdyaXRlRW5hYmxlZCA9IGRlZmF1bHRWYWx1ZShvcHRpb25zPy5kZXB0aFdyaXRlRW5hYmxlZCwgdHJ1ZSk7XG5cdFx0dGhpcy5kZXB0aENvbXBhcmUgPSBkZWZhdWx0VmFsdWUob3B0aW9ucz8uZGVwdGhDb21wYXJlLCBDb21wYXJlRnVuY3Rpb24uTGVzcyk7XG5cdFx0dGhpcy5zdGVuY2lsUmVhZE1hc2sgPSBkZWZhdWx0VmFsdWUob3B0aW9ucz8uc3RlbmNpbFJlYWRNYXNrLCAweGZmZmZmZmZmKTtcblx0XHR0aGlzLnN0ZW5jaWxXcml0ZU1hc2sgPSBkZWZhdWx0VmFsdWUob3B0aW9ucz8uc3RlbmNpbFdyaXRlTWFzaywgMHhmZmZmZmZmZik7XG5cdFx0dGhpcy5zdGVuY2lsRnJvbnRDb21wYXJlID0gZGVmYXVsdFZhbHVlKG9wdGlvbnM/LnN0ZW5jaWxGcm9udENvbXBhcmUsIENvbXBhcmVGdW5jdGlvbi5BbHdheXMpO1xuXHRcdHRoaXMuc3RlbmNpbEZyb250RmFpbE9wID0gZGVmYXVsdFZhbHVlKG9wdGlvbnM/LnN0ZW5jaWxGcm9udEZhaWxPcCwgU3RlbmNpbE9wZXJhdGlvbi5LZWVwKTtcblx0XHR0aGlzLnN0ZW5jaWxGcm9udERlcHRoRmFpbE9wID0gZGVmYXVsdFZhbHVlKG9wdGlvbnM/LnN0ZW5jaWxGcm9udERlcHRoRmFpbE9wLCBTdGVuY2lsT3BlcmF0aW9uLktlZXApO1xuXHRcdHRoaXMuc3RlbmNpbEZyb250UGFzc09wID0gZGVmYXVsdFZhbHVlKG9wdGlvbnM/LnN0ZW5jaWxGcm9udFBhc3NPcCwgU3RlbmNpbE9wZXJhdGlvbi5LZWVwKTtcblx0XHR0aGlzLnN0ZW5jaWxCYWNrQ29tcGFyZSA9IGRlZmF1bHRWYWx1ZShvcHRpb25zPy5zdGVuY2lsQmFja0NvbXBhcmUsIENvbXBhcmVGdW5jdGlvbi5BbHdheXMpO1xuXHRcdHRoaXMuc3RlbmNpbEJhY2tGYWlsT3AgPSBkZWZhdWx0VmFsdWUob3B0aW9ucz8uc3RlbmNpbEJhY2tGYWlsT3AsIFN0ZW5jaWxPcGVyYXRpb24uS2VlcCk7XG5cdFx0dGhpcy5zdGVuY2lsQmFja0RlcHRoRmFpbE9wID0gZGVmYXVsdFZhbHVlKG9wdGlvbnM/LnN0ZW5jaWxCYWNrRGVwdGhGYWlsT3AsIFN0ZW5jaWxPcGVyYXRpb24uS2VlcCk7XG5cdFx0dGhpcy5zdGVuY2lsQmFja1Bhc3NPcCA9IGRlZmF1bHRWYWx1ZShvcHRpb25zPy5zdGVuY2lsQmFja1Bhc3NPcCwgU3RlbmNpbE9wZXJhdGlvbi5LZWVwKTtcblx0XHR0aGlzLmRlcHRoQmlhcyA9IGRlZmF1bHRWYWx1ZShvcHRpb25zPy5kZXB0aEJpYXMsIDApO1xuXHRcdHRoaXMuZGVwdGhCaWFzU2xvcGVTY2FsZSA9IGRlZmF1bHRWYWx1ZShvcHRpb25zPy5kZXB0aEJpYXNTbG9wZVNjYWxlLCAwKTtcblx0XHR0aGlzLmRlcHRoQmlhc0NsYW1wID0gZGVmYXVsdFZhbHVlKG9wdGlvbnM/LmRlcHRoQmlhc0NsYW1wLCAwKTtcblx0fVxuXHRnZXRHUFVEZXB0aFN0ZW5jaWxEZWMoKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdGZvcm1hdDogdGhpcy5mb3JtYXQsXG5cdFx0XHRkZXB0aFdyaXRlRW5hYmxlZDogdGhpcy5kZXB0aFdyaXRlRW5hYmxlZCxcblx0XHRcdGRlcHRoQ29tcGFyZTogdGhpcy5kZXB0aENvbXBhcmUsXG5cdFx0XHRzdGVuY2lsUmVhZE1hc2s6IHRoaXMuc3RlbmNpbFJlYWRNYXNrLFxuXHRcdFx0c3RlbmNpbFdyaXRlTWFzazogdGhpcy5zdGVuY2lsV3JpdGVNYXNrLFxuXHRcdFx0c3RlbmNpbEZyb250OiB7XG5cdFx0XHRcdGNvbXBhcmU6IHRoaXMuc3RlbmNpbEZyb250Q29tcGFyZSxcblx0XHRcdFx0ZmFpbE9wOiB0aGlzLnN0ZW5jaWxGcm9udEZhaWxPcCxcblx0XHRcdFx0ZGVwdGhGYWlsT3A6IHRoaXMuc3RlbmNpbEZyb250RGVwdGhGYWlsT3AsXG5cdFx0XHRcdHBhc3NPcDogdGhpcy5zdGVuY2lsRnJvbnRQYXNzT3Bcblx0XHRcdH0sXG5cdFx0XHRzdGVuY2lsQmFjazoge1xuXHRcdFx0XHRjb21wYXJlOiB0aGlzLnN0ZW5jaWxCYWNrQ29tcGFyZSxcblx0XHRcdFx0ZmFpbE9wOiB0aGlzLnN0ZW5jaWxCYWNrRmFpbE9wLFxuXHRcdFx0XHRkZXB0aEZhaWxPcDogdGhpcy5zdGVuY2lsQmFja0RlcHRoRmFpbE9wLFxuXHRcdFx0XHRwYXNzT3A6IHRoaXMuc3RlbmNpbEJhY2tQYXNzT3Bcblx0XHRcdH0sXG5cdFx0XHRkZXB0aEJpYXM6IHRoaXMuZGVwdGhCaWFzLFxuXHRcdFx0ZGVwdGhCaWFzU2xvcGVTY2FsZTogdGhpcy5kZXB0aEJpYXNTbG9wZVNjYWxlLFxuXHRcdFx0ZGVwdGhCaWFzQ2xhbXA6IHRoaXMuZGVwdGhCaWFzQ2xhbXBcblx0XHR9O1xuXHR9XG59XG5leHBvcnQgY2xhc3MgVGFyZ2V0IHtcblx0Zm9ybWF0OiBUZXh0dXJlRm9ybWF0O1xuXHRibGVuZENvbG9yT3BlcmF0aW9uPzogQmxlbmRPcGVyYXRpb247XG5cdGJsZW5kQ29sb3JTcmNGYWN0b3I/OiBCbGVuZEZhY3Rvcjtcblx0YmxlbmRDb2xvckRzdEZhY3Rvcj86IEJsZW5kRmFjdG9yO1xuXHRibGVuZEFscGhhT3BlcmF0aW9uPzogQmxlbmRPcGVyYXRpb247XG5cdGJsZW5kQWxwaGFTcmNGYWN0b3I/OiBCbGVuZEZhY3Rvcjtcblx0YmxlbmRBbHBoYURzdEZhY3Rvcj86IEJsZW5kRmFjdG9yO1xuXHR3cml0ZU1hc2s6IEdQVUNvbG9yV3JpdGU7XG5cdGNvbnN0cnVjdG9yKG9wdGlvbnM/OiBUYXJnZXRQcm9wcykge1xuXHRcdHRoaXMuZm9ybWF0ID0gZGVmYXVsdFZhbHVlKG9wdGlvbnM/LmZvcm1hdCwgVGV4dHVyZUZvcm1hdC5CR1JBOFVub3JtKTtcblx0XHR0aGlzLmJsZW5kQ29sb3JPcGVyYXRpb24gPSBkZWZhdWx0VmFsdWUob3B0aW9ucz8uYmxlbmRDb2xvck9wZXJhdGlvbiwgQmxlbmRPcGVyYXRpb24uQWRkKTtcblx0XHR0aGlzLmJsZW5kQ29sb3JTcmNGYWN0b3IgPSBkZWZhdWx0VmFsdWUob3B0aW9ucz8uYmxlbmRDb2xvclNyY0ZhY3RvciwgQmxlbmRGYWN0b3I/LlNyY0FscGhhKTtcblx0XHR0aGlzLmJsZW5kQ29sb3JEc3RGYWN0b3IgPSBkZWZhdWx0VmFsdWUob3B0aW9ucz8uYmxlbmRDb2xvckRzdEZhY3RvciwgQmxlbmRGYWN0b3IuT25lTWludXNTcmNBbHBoYSk7XG5cdFx0dGhpcy5ibGVuZEFscGhhT3BlcmF0aW9uID0gZGVmYXVsdFZhbHVlKG9wdGlvbnM/LmJsZW5kQWxwaGFPcGVyYXRpb24sIEJsZW5kT3BlcmF0aW9uLkFkZCk7XG5cdFx0dGhpcy5ibGVuZEFscGhhU3JjRmFjdG9yID0gZGVmYXVsdFZhbHVlKG9wdGlvbnM/LmJsZW5kQWxwaGFTcmNGYWN0b3IsIEJsZW5kRmFjdG9yLk9uZSk7XG5cdFx0dGhpcy5ibGVuZEFscGhhRHN0RmFjdG9yID0gZGVmYXVsdFZhbHVlKG9wdGlvbnM/LmJsZW5kQWxwaGFEc3RGYWN0b3IsIEJsZW5kRmFjdG9yLk9uZSk7XG5cdFx0dGhpcy53cml0ZU1hc2sgPSBkZWZhdWx0VmFsdWUob3B0aW9ucz8ud3JpdGVNYXNrLCBHUFVDb2xvcldyaXRlLkFsbCk7XG5cdH1cblx0Z2V0R1BVVGFyZ2V0RGVjKCkge1xuXHRcdHJldHVybiB7XG5cdFx0XHRmb3JtYXQ6IHRoaXMuZm9ybWF0LFxuXHRcdFx0YmxlbmQ6IHtcblx0XHRcdFx0Y29sb3I6IHtcblx0XHRcdFx0XHRvcGVyYXRpb246IHRoaXMuYmxlbmRDb2xvck9wZXJhdGlvbixcblx0XHRcdFx0XHRzcmNGYWN0b3I6IHRoaXMuYmxlbmRDb2xvclNyY0ZhY3Rvcixcblx0XHRcdFx0XHRkc3RGYWN0b3I6IHRoaXMuYmxlbmRDb2xvckRzdEZhY3RvclxuXHRcdFx0XHR9LFxuXHRcdFx0XHRhbHBoYToge1xuXHRcdFx0XHRcdG9wZXJhdGlvbjogdGhpcy5ibGVuZEFscGhhT3BlcmF0aW9uLFxuXHRcdFx0XHRcdHNyY0ZhY3RvcjogdGhpcy5ibGVuZEFscGhhU3JjRmFjdG9yLFxuXHRcdFx0XHRcdGRzdEZhY3RvcjogdGhpcy5ibGVuZEFscGhhRHN0RmFjdG9yXG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHR3cml0ZU1hc2s6IHRoaXMud3JpdGVNYXNrXG5cdFx0fTtcblx0fVxufVxuY29uc3QgY2FjaGVWaWV3UG9ydCA9IG5ldyBWaWV3UG9ydCgpO1xuY29uc3QgY2FjaGVTY2lzc29yVGVzdCA9IG5ldyBTY2lzc29yVGVzdCgpO1xuZXhwb3J0IHR5cGUgRGVwdGhTdGVuY2lsUHJvcHMgPSB7XG5cdGZvcm1hdD86IFRleHR1cmVGb3JtYXQ7XG5cdGRlcHRoV3JpdGVFbmFibGVkPzogYm9vbGVhbjtcblx0ZGVwdGhDb21wYXJlPzogQ29tcGFyZUZ1bmN0aW9uO1xuXHRzdGVuY2lsUmVhZE1hc2s/OiBudW1iZXI7XG5cdHN0ZW5jaWxXcml0ZU1hc2s/OiBudW1iZXI7XG5cdHN0ZW5jaWxGcm9udENvbXBhcmU/OiBDb21wYXJlRnVuY3Rpb247XG5cdHN0ZW5jaWxGcm9udEZhaWxPcD86IFN0ZW5jaWxPcGVyYXRpb247XG5cdHN0ZW5jaWxGcm9udERlcHRoRmFpbE9wPzogU3RlbmNpbE9wZXJhdGlvbjtcblx0c3RlbmNpbEZyb250UGFzc09wPzogU3RlbmNpbE9wZXJhdGlvbjtcblxuXHRzdGVuY2lsQmFja0NvbXBhcmU/OiBDb21wYXJlRnVuY3Rpb247XG5cdHN0ZW5jaWxCYWNrRmFpbE9wPzogU3RlbmNpbE9wZXJhdGlvbjtcblx0c3RlbmNpbEJhY2tEZXB0aEZhaWxPcD86IFN0ZW5jaWxPcGVyYXRpb247XG5cdHN0ZW5jaWxCYWNrUGFzc09wPzogU3RlbmNpbE9wZXJhdGlvbjtcblx0ZGVwdGhCaWFzPzogbnVtYmVyO1xuXHRkZXB0aEJpYXNTbG9wZVNjYWxlPzogbnVtYmVyO1xuXHRkZXB0aEJpYXNDbGFtcD86IG51bWJlcjtcbn07XG5leHBvcnQgdHlwZSBUYXJnZXRQcm9wcyA9IHtcblx0Zm9ybWF0PzogVGV4dHVyZUZvcm1hdDtcblx0YmxlbmRDb2xvck9wZXJhdGlvbj86IEJsZW5kT3BlcmF0aW9uO1xuXHRibGVuZENvbG9yU3JjRmFjdG9yPzogQmxlbmRGYWN0b3I7XG5cdGJsZW5kQ29sb3JEc3RGYWN0b3I/OiBCbGVuZEZhY3Rvcjtcblx0YmxlbmRBbHBoYU9wZXJhdGlvbj86IEJsZW5kT3BlcmF0aW9uO1xuXHRibGVuZEFscGhhU3JjRmFjdG9yPzogQmxlbmRGYWN0b3I7XG5cdGJsZW5kQWxwaGFEc3RGYWN0b3I/OiBCbGVuZEZhY3Rvcjtcblx0d3JpdGVNYXNrPzogR1BVQ29sb3JXcml0ZTtcbn07XG5leHBvcnQgdHlwZSBSZW5kZXJTdGF0ZVBhcmFtcyA9IHtcblx0c2Npc3NvclRlc3Q/OiBTY2lzc29yVGVzdDtcblx0dmlld3BvcnQ/OiBWaWV3UG9ydDtcblx0dGFyZ2V0cz86IEFycmF5PFRhcmdldD47XG5cdGRlcHRoU3RlbmNpbD86IERlcHRoU3RlbmNpbDtcblx0YmxlbmRDb25zdGFudD86IEJsZW5kQ29uc3RhbnQ7XG5cdHN0ZW5jaWxSZWZlcmVuY2U/OiBudW1iZXI7XG5cdG11bHRpc2FtcGxlPzogTXVsdGlTYW1wbGU7XG5cdHByaW1pdGl2ZT86IFByaW1pdGl2ZTtcblx0c3RlbmNpbEVuYWJsZWQ/OiBib29sZWFuO1xuXHRzY2lzc29yVGVzdEVuYWJsZWQ/OiBib29sZWFuO1xufTtcbmV4cG9ydCB0eXBlIEJpbmRSZW5kZXJTdGF0ZSA9IHtcblx0cGFzc0VuY29kZXI6IEdQVVJlbmRlclBhc3NFbmNvZGVyO1xuXHR2aWV3UG9ydDogVmlld1BvcnQ7XG5cdHNjaXNzb3JUZXN0OiBTY2lzc29yVGVzdDtcbn07XG4iLCJpbXBvcnQgeyBUZXh0dXJlVXNhZ2UgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVDb25zdGFudFwiO1xuaW1wb3J0IHsgR1BVQ2FudmFzQ29tcG9zaXRpbmdBbHBoYU1vZGUsIENvbnRleHRPcHRpb25zIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcbmltcG9ydCB7IE1pcG1hcEdlbmVyYXRvciB9IGZyb20gXCIuLi91dGlscy9NaXBtYXBHZW5lcmF0b3JcIjtcbmltcG9ydCB7IFNjaXNzb3JUZXN0LCBWaWV3UG9ydCB9IGZyb20gXCIuL1JlbmRlclN0YXRlXCI7XG5cbmNsYXNzIENvbnRleHQge1xuXHRwdWJsaWMgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudDtcblxuXHRwdWJsaWMgY29udGV4dDogR1BVQ2FudmFzQ29udGV4dDtcblxuXHRwdWJsaWMgcGl4ZWxSYXRpbzogbnVtYmVyO1xuXG5cdHB1YmxpYyBkZXZpY2U6IEdQVURldmljZTtcblxuXHRwcml2YXRlIGFkYXB0ZXI6IEdQVUFkYXB0ZXI7XG5cblx0cHVibGljIHByZXNlbnRhdGlvblNpemU6IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXI7IGRlcHRoOiBudW1iZXIgfTtcblxuXHRwdWJsaWMgcHJlc2VudGF0aW9uRm9ybWF0OiBHUFVUZXh0dXJlRm9ybWF0O1xuXG5cdHB1YmxpYyBtaXBtYXBUb29sczogTWlwbWFwR2VuZXJhdG9yO1xuXG5cdHByaXZhdGUgX3ZpZXdQb3J0OiBWaWV3UG9ydDtcblxuXHRwcml2YXRlIF9zY2lzc29yVGVzdDogU2Npc3NvclRlc3Q7XG5cblx0cHVibGljIGdldCB2aWV3UG9ydCgpOiBWaWV3UG9ydCB7XG5cdFx0cmV0dXJuIHRoaXMuX3ZpZXdQb3J0O1xuXHR9XG5cblx0cHVibGljIGdldCBzY2lzc29yVGVzdCgpOiBTY2lzc29yVGVzdCB7XG5cdFx0cmV0dXJuIHRoaXMuX3NjaXNzb3JUZXN0O1xuXHR9XG5cdGNvbnN0cnVjdG9yKHsgY2FudmFzLCBjb250YWluZXIsIGNvbnRleHQsIHBpeGVsUmF0aW8gfTogQ29udGV4dE9wdGlvbnMgPSB7fSkge1xuXHRcdGlmICghY29udGFpbmVyLmNsaWVudFdpZHRoIHx8ICFjb250YWluZXIuY2xpZW50SGVpZ2h0KSB0aHJvdyBuZXcgRXJyb3IoXCJjb250YWluZXIgd2lkdGggb3IgaGVpZ2h0IGlsbGVnYWxpdHlcIik7XG5cdFx0dGhpcy5jYW52YXMgPSBjYW52YXMgfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcblx0XHQvLyB0aGlzLmNhbnZhcy5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuXHRcdHRoaXMucGl4ZWxSYXRpbyA9IHBpeGVsUmF0aW8gfHwgd2luZG93LmRldmljZVBpeGVsUmF0aW8gfHwgMTtcblx0XHRjb25zdCB3aWR0aCA9IGNvbnRhaW5lci5jbGllbnRXaWR0aCAqIHRoaXMucGl4ZWxSYXRpbztcblx0XHRjb25zdCBoZWlnaHQgPSBjb250YWluZXIuY2xpZW50SGVpZ2h0ICogdGhpcy5waXhlbFJhdGlvO1xuXHRcdHRoaXMuY2FudmFzLndpZHRoID0gd2lkdGg7XG5cdFx0dGhpcy5jYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuXHRcdHRoaXMuY2FudmFzLnN0eWxlLndpZHRoID0gY29udGFpbmVyLmNsaWVudFdpZHRoICsgXCJweFwiO1xuXHRcdHRoaXMuY2FudmFzLnN0eWxlLmhlaWdodCA9IGNvbnRhaW5lci5jbGllbnRIZWlnaHQgKyBcInB4XCI7XG5cdFx0Y29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMuY2FudmFzKTtcblx0XHR0aGlzLmNvbnRleHQgPSBjb250ZXh0IHx8ICh0aGlzLmNhbnZhcy5nZXRDb250ZXh0KFwid2ViZ3B1XCIpIGFzIEdQVUNhbnZhc0NvbnRleHQpO1xuXG5cdFx0dGhpcy5kZXZpY2UgPSB1bmRlZmluZWQ7XG5cdH1cblxuXHRwdWJsaWMgYXN5bmMgaW5pdChcblx0XHRyZXF1ZXN0QWRhcHRlciA9IHt9LFxuXHRcdGRldmljZURlc2NyaXB0b3IgPSB7fSxcblx0XHRwcmVzZW50YXRpb25Db250ZXh0RGVzY3JpcHRvciA9IHt9XG5cdCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuXHRcdHRyeSB7XG5cdFx0XHRpZiAoIXRoaXMuY29udGV4dCkge1xuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBpbnN0YW50aWF0ZSBcIndlYmdwdVwiIGNvbnRleHQuYCk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIW5hdmlnYXRvci5ncHUpIHtcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKGBNaXNzaW5nIFwibmF2aWdhdG9yLmdwdVwiLmApO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLmFkYXB0ZXIgPSBhd2FpdCBuYXZpZ2F0b3IuZ3B1LnJlcXVlc3RBZGFwdGVyKCk7XG5cdFx0XHR0aGlzLmRldmljZSA9IGF3YWl0IHRoaXMuYWRhcHRlci5yZXF1ZXN0RGV2aWNlKCk7XG5cdFx0XHR0aGlzLnByZXNlbnRhdGlvblNpemUgPSB7XG5cdFx0XHRcdHdpZHRoOiB0aGlzLmNhbnZhcy5jbGllbnRXaWR0aCAqIHRoaXMucGl4ZWxSYXRpbyxcblx0XHRcdFx0aGVpZ2h0OiB0aGlzLmNhbnZhcy5jbGllbnRIZWlnaHQgKiB0aGlzLnBpeGVsUmF0aW8sXG5cdFx0XHRcdGRlcHRoOiAxXG5cdFx0XHR9O1xuXHRcdFx0dGhpcy5wcmVzZW50YXRpb25Gb3JtYXQgPSBuYXZpZ2F0b3IuZ3B1LmdldFByZWZlcnJlZENhbnZhc0Zvcm1hdCgpO1xuXHRcdFx0dGhpcy5kZXZpY2UuYWRkRXZlbnRMaXN0ZW5lcihcInVuY2FwdHVyZWRlcnJvclwiLCAoZXJyb3IpID0+IHtcblx0XHRcdFx0Y29uc29sZS5lcnJvcihlcnJvcik7XG5cdFx0XHRcdC8vIFN0YXRlLmVycm9yID0gdHJ1ZTtcblx0XHRcdH0pO1xuXHRcdFx0dGhpcy5taXBtYXBUb29scyA9IG5ldyBNaXBtYXBHZW5lcmF0b3IodGhpcy5kZXZpY2UpO1xuXHRcdFx0dGhpcy5jb250ZXh0LmNvbmZpZ3VyZSh7XG5cdFx0XHRcdGRldmljZTogdGhpcy5kZXZpY2UsXG5cdFx0XHRcdGZvcm1hdDogdGhpcy5wcmVzZW50YXRpb25Gb3JtYXQsXG5cdFx0XHRcdHVzYWdlOiBUZXh0dXJlVXNhZ2UuUmVuZGVyQXR0YWNobWVudCxcblx0XHRcdFx0YWxwaGFNb2RlOiBcInByZW11bHRpcGxpZWRcIixcblx0XHRcdFx0Li4ucHJlc2VudGF0aW9uQ29udGV4dERlc2NyaXB0b3Jcblx0XHRcdH0pO1xuXHRcdFx0dGhpcy5fdmlld1BvcnQgPSBuZXcgVmlld1BvcnQoXG5cdFx0XHRcdDAsXG5cdFx0XHRcdDAsXG5cdFx0XHRcdHRoaXMuY2FudmFzLmNsaWVudFdpZHRoICogdGhpcy5waXhlbFJhdGlvLFxuXHRcdFx0XHR0aGlzLmNhbnZhcy5jbGllbnRIZWlnaHQgKiB0aGlzLnBpeGVsUmF0aW9cblx0XHRcdCk7XG5cdFx0XHR0aGlzLl9zY2lzc29yVGVzdCA9IG5ldyBTY2lzc29yVGVzdChcblx0XHRcdFx0MCxcblx0XHRcdFx0MCxcblx0XHRcdFx0dGhpcy5jYW52YXMuY2xpZW50V2lkdGggKiB0aGlzLnBpeGVsUmF0aW8sXG5cdFx0XHRcdHRoaXMuY2FudmFzLmNsaWVudEhlaWdodCAqIHRoaXMucGl4ZWxSYXRpb1xuXHRcdFx0KTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0Y29uc29sZS5lcnJvcihlcnJvcik7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblx0cHVibGljIHNldFZpZXdQb3J0KHg6IG51bWJlciwgeTogbnVtYmVyLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuXHRcdHRoaXMuX3ZpZXdQb3J0LnNldCh4LCB5LCB3aWR0aCwgaGVpZ2h0KTtcblx0fVxuXG5cdHB1YmxpYyByZXNldFZpZXdQb3J0VG9GdWxsQ2FudmFzKCkge1xuXHRcdHRoaXMuX3ZpZXdQb3J0LnNldCgwLCAwLCB0aGlzLmNhbnZhcy5jbGllbnRXaWR0aCAqIHRoaXMucGl4ZWxSYXRpbywgdGhpcy5jYW52YXMuY2xpZW50SGVpZ2h0ICogdGhpcy5waXhlbFJhdGlvKTtcblx0fVxuXG5cdHB1YmxpYyBzZXRTY2lzc29yVGVzdCh4OiBudW1iZXIsIHk6IG51bWJlciwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcblx0XHR0aGlzLl9zY2lzc29yVGVzdC5zZXQoeCwgeSwgd2lkdGgsIGhlaWdodCk7XG5cdH1cblx0cHVibGljIHJlc2l6ZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgcHJlc2VudGF0aW9uQ29udGV4dERlc2NyaXB0b3IgPSB7fSk6IHZvaWQge1xuXHRcdGNvbnN0IHcgPSB3aWR0aCAqIHRoaXMucGl4ZWxSYXRpbztcblx0XHRjb25zdCBoID0gaGVpZ2h0ICogdGhpcy5waXhlbFJhdGlvO1xuXHRcdHRoaXMuY2FudmFzLnN0eWxlLndpZHRoID0gdyArIFwicHhcIjtcblx0XHR0aGlzLmNhbnZhcy5zdHlsZS5oZWlnaHQgPSBoICsgXCJweFwiO1xuXHRcdHRoaXMuY2FudmFzLndpZHRoID0gdztcblx0XHR0aGlzLmNhbnZhcy5oZWlnaHQgPSBoO1xuXHRcdHRoaXMucHJlc2VudGF0aW9uU2l6ZSA9IHtcblx0XHRcdHdpZHRoOiB3LFxuXHRcdFx0aGVpZ2h0OiBoLFxuXHRcdFx0ZGVwdGg6IDFcblx0XHR9O1xuXHRcdHRoaXMuY29udGV4dC5jb25maWd1cmUoe1xuXHRcdFx0ZGV2aWNlOiB0aGlzLmRldmljZSxcblx0XHRcdGZvcm1hdDogbmF2aWdhdG9yLmdwdS5nZXRQcmVmZXJyZWRDYW52YXNGb3JtYXQoKSxcblx0XHRcdHVzYWdlOiBUZXh0dXJlVXNhZ2UuUmVuZGVyQXR0YWNobWVudCxcblx0XHRcdGFscGhhTW9kZTogR1BVQ2FudmFzQ29tcG9zaXRpbmdBbHBoYU1vZGUuUHJlbXVsdGlwbGllZCxcblx0XHRcdC4uLnByZXNlbnRhdGlvbkNvbnRleHREZXNjcmlwdG9yXG5cdFx0fSk7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ29udGV4dDtcbiIsImltcG9ydCB7IFN0b3JhZ2VUZXh0dXJlQWNjZXNzLCBUZXh0dXJlRm9ybWF0IH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVQ29uc3RhbnRcIjtcbmltcG9ydCB7IFdlYkdQVVRleHR1cmVQcm9wcywgSW1hZ2VEYXRhIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcbmltcG9ydCBkZWZhdWx0VmFsdWUgZnJvbSBcIi4uL3V0aWxzL2RlZmF1bHRWYWx1ZVwiO1xuaW1wb3J0IHsgTWlwbWFwR2VuZXJhdG9yIH0gZnJvbSBcIi4uL3V0aWxzL01pcG1hcEdlbmVyYXRvclwiO1xuaW1wb3J0IENvbnRleHQgZnJvbSBcIi4vQ29udGV4dFwiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZXh0dXJlIHtcblx0W3g6IHN0cmluZ106IGFueTtcblx0cHJpdmF0ZSBfdGV4dHVyZVZpZXc6IEdQVVRleHR1cmVWaWV3O1xuXHRwdWJsaWMgZ3B1VGV4dHVyZT86IEdQVVRleHR1cmU7XG5cdHB1YmxpYyBtaXBMZXZlbENvdW50PzogbnVtYmVyO1xuXHRwdWJsaWMgY29udGV4dD86IENvbnRleHQ7XG5cdHB1YmxpYyBkZXZpY2U/OiBHUFVEZXZpY2U7XG5cdHB1YmxpYyB0ZXh0dXJlUHJvcD86IFdlYkdQVVRleHR1cmVQcm9wcztcblx0cHVibGljIGRpcnR5OiBib29sZWFuO1xuXHRwdWJsaWMgZml4ZWRTaXplOiBib29sZWFuO1xuXHRwdWJsaWMgc3RhdGljIG1pcG1hcFRvb2xzOiBNaXBtYXBHZW5lcmF0b3I7XG5cdGNvbnN0cnVjdG9yKHRleHR1cmVQcm9wOiBXZWJHUFVUZXh0dXJlUHJvcHMpIHtcblx0XHR0aGlzLnRleHR1cmVQcm9wID0gT2JqZWN0LmFzc2lnbihcblx0XHRcdHtcblx0XHRcdFx0Zm9ybWF0OiBUZXh0dXJlRm9ybWF0LlJHQkE4VW5vcm0sXG5cdFx0XHRcdHVzYWdlOiBHUFVUZXh0dXJlVXNhZ2UuVEVYVFVSRV9CSU5ESU5HIHwgR1BVVGV4dHVyZVVzYWdlLkNPUFlfRFNUIHwgR1BVVGV4dHVyZVVzYWdlLlJFTkRFUl9BVFRBQ0hNRU5ULFxuXHRcdFx0XHRkYXRhSXNUZXh0dXJlOiBmYWxzZVxuXHRcdFx0fSxcblx0XHRcdHRleHR1cmVQcm9wXG5cdFx0KTtcblx0XHR0aGlzLmRpcnR5ID0gdHJ1ZTtcblx0XHR0aGlzLmZpeGVkU2l6ZSA9IHRleHR1cmVQcm9wLmZpeGVkU2l6ZSB8fCBmYWxzZTtcblx0fVxuXHRnZXQgbGF5b3V0VHlwZSgpIHtcblx0XHRjb25zdCB7IHZpZXdGb3JtYXRzLCBzYW1wbGVUeXBlLCBzYW1wbGVDb3VudCB9ID0gdGhpcy50ZXh0dXJlUHJvcDtcblx0XHQvLyBjb25zdFxuXHRcdHJldHVybiB7XG5cdFx0XHRzYW1wbGVUeXBlOiBkZWZhdWx0VmFsdWUoc2FtcGxlVHlwZSwgXCJmbG9hdFwiKSxcblx0XHRcdHZpZXdEaW1lbnNpb246IGRlZmF1bHRWYWx1ZSh2aWV3Rm9ybWF0cywgXCIyZFwiKSxcblx0XHRcdG11bHRpc2FtcGxlZDogc2FtcGxlQ291bnQgJiYgc2FtcGxlQ291bnQgPiAxID8gdHJ1ZSA6IGZhbHNlXG5cdFx0fTtcblx0fVxuXHRnZXQgc3RvcmFnZVRleHR1cmVMYXlvdXRUeXBlKCkge1xuXHRcdGNvbnN0IHsgYWNjZXNzID0gU3RvcmFnZVRleHR1cmVBY2Nlc3MuV3JpdGVPbmx5LCB2aWV3Rm9ybWF0cywgZm9ybWF0IH0gPSB0aGlzLnRleHR1cmVQcm9wO1xuXHRcdHJldHVybiB7XG5cdFx0XHR2aWV3RGltZW5zaW9uOiBkZWZhdWx0VmFsdWUodmlld0Zvcm1hdHMsIFwiMmRcIiksXG5cdFx0XHRhY2Nlc3MsXG5cdFx0XHRmb3JtYXRcblx0XHR9O1xuXHR9XG5cdGdldCB0ZXh0dXJlVmlldygpIHtcblx0XHRpZiAoIXRoaXMuX3RleHR1cmVWaWV3KVxuXHRcdFx0dGhpcy5fdGV4dHVyZVZpZXcgPSB0aGlzLmdwdVRleHR1cmUuY3JlYXRlVmlldyh7XG5cdFx0XHRcdGRpbWVuc2lvbjogPEdQVVRleHR1cmVWaWV3RGltZW5zaW9uPmRlZmF1bHRWYWx1ZSh0aGlzLnRleHR1cmVQcm9wLnZpZXdGb3JtYXRzLCBcIjJkXCIpXG5cdFx0XHR9KTtcblx0XHRyZXR1cm4gdGhpcy5fdGV4dHVyZVZpZXc7XG5cdH1cblx0dXBkYXRlKGRldmljZTogR1BVRGV2aWNlKSB7XG5cdFx0aWYgKCF0aGlzLmRldmljZSkgdGhpcy5kZXZpY2UgPSBkZXZpY2U7XG5cdFx0aWYgKHRoaXMuZGlydHkpIHtcblx0XHRcdHRoaXMuY2hlY2tOZWVkQ3JlYXRlVGV4dHVyZSgpO1xuXHRcdFx0dGhpcy5kaXJ0eSA9IGZhbHNlO1xuXHRcdFx0aWYgKHRoaXMudGV4dHVyZVByb3AuZGF0YSkge1xuXHRcdFx0XHRpZiAoQXJyYXkuaXNBcnJheSh0aGlzLnRleHR1cmVQcm9wLmRhdGEpKSB7XG5cdFx0XHRcdFx0dGhpcy50ZXh0dXJlUHJvcC5kYXRhLmZvckVhY2goKGltYWdlRGF0YSkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5zZXREYXRhKGltYWdlRGF0YSk7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGhpcy5zZXREYXRhKHRoaXMudGV4dHVyZVByb3AuZGF0YSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmICh0aGlzLnRleHR1cmVQcm9wLm5lZWRNaXBNYXApIHtcblx0XHRcdFx0aWYgKCFUZXh0dXJlLm1pcG1hcFRvb2xzKSBUZXh0dXJlLm1pcG1hcFRvb2xzID0gbmV3IE1pcG1hcEdlbmVyYXRvcih0aGlzLmRldmljZSk7XG5cdFx0XHRcdHRoaXMuZ3B1VGV4dHVyZSA9IFRleHR1cmUubWlwbWFwVG9vbHMuZ2VuZXJhdGVNaXBtYXAodGhpcyk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHByaXZhdGUgc2V0RGF0YShvcHRpb25zOiBJbWFnZURhdGEpIHtcblx0XHRjb25zdCB7XG5cdFx0XHRzb3VyY2UsXG5cdFx0XHR3aWR0aCA9IG9wdGlvbnMuc291cmNlLndpZHRoLFxuXHRcdFx0aGVpZ2h0ID0gb3B0aW9ucy5zb3VyY2UuaGVpZ2h0LFxuXHRcdFx0ZGVwdGggPSAxLFxuXHRcdFx0c291cmNlWCA9IDAsXG5cdFx0XHRzb3VyY2VZID0gMCxcblx0XHRcdG1pcExldmVsID0gMCxcblx0XHRcdHggPSAwLFxuXHRcdFx0eSA9IDAsXG5cdFx0XHR6ID0gMCxcblx0XHRcdGFzcGVjdCA9IFwiYWxsXCIsXG5cdFx0XHRjb2xvclNwYWNlID0gXCJzcmdiXCIsXG5cdFx0XHRwcmVtdWx0aXBsaWVkQWxwaGEgPSBmYWxzZVxuXHRcdH0gPSBvcHRpb25zO1xuXHRcdGlmIChzb3VyY2UgaW5zdGFuY2VvZiBUZXh0dXJlKSB7XG5cdFx0XHRsZXQgY29tbWFuZEVuY29kZXIgPSB0aGlzLmRldmljZS5jcmVhdGVDb21tYW5kRW5jb2RlcigpO1xuXHRcdFx0Y29tbWFuZEVuY29kZXIuY29weVRleHR1cmVUb1RleHR1cmUoXG5cdFx0XHRcdHtcblx0XHRcdFx0XHR0ZXh0dXJlOiA8R1BVVGV4dHVyZT5zb3VyY2UuZ3B1VGV4dHVyZSxcblx0XHRcdFx0XHRvcmlnaW46IFtzb3VyY2VYLCBzb3VyY2VZXVxuXHRcdFx0XHRcdC8vIGFzcGVjdFxuXHRcdFx0XHR9LFxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0dGV4dHVyZTogdGhpcy5ncHVUZXh0dXJlLFxuXHRcdFx0XHRcdG9yaWdpbjogeyB4OiAwLCB5OiAwLCB6IH0sXG5cdFx0XHRcdFx0bWlwTGV2ZWxcblx0XHRcdFx0XHQvLyBhc3BlY3Rcblx0XHRcdFx0fSxcblx0XHRcdFx0e1xuXHRcdFx0XHRcdHdpZHRoLFxuXHRcdFx0XHRcdGhlaWdodCxcblx0XHRcdFx0XHRkZXB0aE9yQXJyYXlMYXllcnM6IDFcblx0XHRcdFx0fVxuXHRcdFx0KTtcblx0XHRcdHRoaXMuZGV2aWNlLnF1ZXVlLnN1Ym1pdChbY29tbWFuZEVuY29kZXIuZmluaXNoKCldKTtcblx0XHRcdGNvbW1hbmRFbmNvZGVyID0gbnVsbDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5kZXZpY2UucXVldWUuY29weUV4dGVybmFsSW1hZ2VUb1RleHR1cmUoXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRzb3VyY2UsXG5cdFx0XHRcdFx0b3JpZ2luOiBbc291cmNlWCwgc291cmNlWV1cblx0XHRcdFx0fSxcblx0XHRcdFx0e1xuXHRcdFx0XHRcdHRleHR1cmU6IHRoaXMuZ3B1VGV4dHVyZSxcblx0XHRcdFx0XHRvcmlnaW46IFt4LCB5LCB6XSxcblx0XHRcdFx0XHRtaXBMZXZlbCxcblx0XHRcdFx0XHRhc3BlY3QsXG5cdFx0XHRcdFx0Y29sb3JTcGFjZSxcblx0XHRcdFx0XHRwcmVtdWx0aXBsaWVkQWxwaGFcblx0XHRcdFx0fSxcblx0XHRcdFx0W3dpZHRoLCBoZWlnaHQsIGRlcHRoXVxuXHRcdFx0KTtcblx0XHR9XG5cdH1cblx0c2V0U2l6ZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgZGVwdGg/OiBudW1iZXIpIHtcblx0XHRpZiAodGhpcy5maXhlZFNpemUpIHJldHVybjtcblx0XHR0aGlzLnRleHR1cmVQcm9wLnNpemUud2lkdGggPSB3aWR0aDtcblx0XHR0aGlzLnRleHR1cmVQcm9wLnNpemUuaGVpZ2h0ID0gaGVpZ2h0O1xuXHRcdGlmIChkZXB0aCkgdGhpcy50ZXh0dXJlUHJvcC5zaXplLmRlcHRoID0gZGVwdGg7XG5cdFx0dGhpcy5kaXJ0eSA9IHRydWU7XG5cdH1cblx0ZGVzdHJveSgpOiB2b2lkIHtcblx0XHR0aGlzLmdwdVRleHR1cmUuZGVzdHJveSgpO1xuXHR9XG5cdHByaXZhdGUgY3JlYXRlR1BVVGV4dHVyZSgpIHtcblx0XHRpZiAodHlwZW9mIHRoaXMudGV4dHVyZVByb3AuZm9ybWF0ID09PSBcIm51bWJlclwiKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJudW1iZXIgZm9ybWF0XCIpO1xuXHRcdH1cblx0XHRjb25zdCB7IHdpZHRoLCBoZWlnaHQsIGRlcHRoIH0gPSB0aGlzLnRleHR1cmVQcm9wLnNpemU7XG5cdFx0cmV0dXJuIHRoaXMuZGV2aWNlLmNyZWF0ZVRleHR1cmUoe1xuXHRcdFx0bGFiZWw6IHRoaXMudGV4dHVyZVByb3A/LmxhYmVsIHx8IFwidW5kZWZpbmVkXCIsXG5cdFx0XHRzaXplOiBbd2lkdGgsIGhlaWdodCwgZGVwdGhdLFxuXHRcdFx0ZGltZW5zaW9uOiB0aGlzLnRleHR1cmVQcm9wLmRpbWVuc2lvbiB8fCBcIjJkXCIsXG5cdFx0XHRmb3JtYXQ6IHRoaXMudGV4dHVyZVByb3AuZm9ybWF0IGFzIEdQVVRleHR1cmVGb3JtYXQsXG5cdFx0XHR1c2FnZTogdGhpcy50ZXh0dXJlUHJvcC51c2FnZSxcblx0XHRcdG1pcExldmVsQ291bnQ6IHRoaXMudGV4dHVyZVByb3AubWlwTGV2ZWxDb3VudCB8fCAxLFxuXHRcdFx0c2FtcGxlQ291bnQ6IHRoaXMudGV4dHVyZVByb3Auc2FtcGxlQ291bnQgfHwgMVxuXHRcdH0pO1xuXHR9XG5cdHByaXZhdGUgY2hlY2tOZWVkQ3JlYXRlVGV4dHVyZSgpIHtcblx0XHRjb25zdCB7IHdpZHRoLCBoZWlnaHQsIGRlcHRoIH0gPSB0aGlzLnRleHR1cmVQcm9wLnNpemU7XG5cdFx0aWYgKHRoaXMuZ3B1VGV4dHVyZSkge1xuXHRcdFx0aWYgKHdpZHRoICE9IHRoaXMuZ3B1VGV4dHVyZS53aWR0aCB8fCBoZWlnaHQgIT0gdGhpcy5ncHVUZXh0dXJlLmhlaWdodCkge1xuXHRcdFx0XHR0aGlzLl90ZXh0dXJlVmlldyA9IHVuZGVmaW5lZDtcblx0XHRcdFx0dGhpcy5ncHVUZXh0dXJlLmRlc3Ryb3koKTtcblx0XHRcdFx0dGhpcy5ncHVUZXh0dXJlID0gdGhpcy5jcmVhdGVHUFVUZXh0dXJlKCk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuZ3B1VGV4dHVyZSA9IHRoaXMuY3JlYXRlR1BVVGV4dHVyZSgpO1xuXHRcdH1cblx0fVxufVxuIiwiY2xhc3MgU2FtcGxlciB7XG5cdHB1YmxpYyBncHVTYW1wbGVyOiBHUFVTYW1wbGVyO1xuXHRwdWJsaWMgbGF5b3V0VHlwZTogR1BVU2FtcGxlckJpbmRpbmdMYXlvdXQ7XG5cblx0c3RhdGljIGJhc2VTYW1wbGVyID0gbmV3IFNhbXBsZXIoe1xuXHRcdG1hZ0ZpbHRlcjogXCJsaW5lYXJcIixcblx0XHRtaW5GaWx0ZXI6IFwibGluZWFyXCJcblx0fSk7XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0cHVibGljIGRlc2NyaXB0b3I/OiBHUFVTYW1wbGVyRGVzY3JpcHRvcixcblx0XHRsYXlvdXRUeXBlOiBHUFVTYW1wbGVyQmluZGluZ0xheW91dCA9IHtcblx0XHRcdHR5cGU6IFwiZmlsdGVyaW5nXCJcblx0XHR9XG5cdCkge1xuXHRcdHRoaXMuZGVzY3JpcHRvciA9IHt9O1xuXHRcdE9iamVjdC5hc3NpZ24oXG5cdFx0XHR0aGlzLmRlc2NyaXB0b3IsXG5cdFx0XHR7XG5cdFx0XHRcdG1hZ0ZpbHRlcjogXCJsaW5lYXJcIixcblx0XHRcdFx0bWluRmlsdGVyOiBcImxpbmVhclwiLFxuXHRcdFx0XHQvLyBtaXBtYXBGaWx0ZXI6IFwibGluZWFyXCIsXG5cdFx0XHRcdGFkZHJlc3NNb2RlVTogXCJjbGFtcC10by1lZGdlXCIsXG5cdFx0XHRcdGFkZHJlc3NNb2RlVjogXCJjbGFtcC10by1lZGdlXCJcblx0XHRcdFx0Ly8gYWRkcmVzc01vZGVXOiBcImNsYW1wLXRvLWVkZ2VcIixcblx0XHRcdH0sXG5cdFx0XHRkZXNjcmlwdG9yXG5cdFx0KTtcblx0XHR0aGlzLmxheW91dFR5cGUgPSBsYXlvdXRUeXBlO1xuXHR9XG5cdHVwZGF0ZShkZXZpY2U6IEdQVURldmljZSkge1xuXHRcdGlmICghdGhpcy5ncHVTYW1wbGVyKSB0aGlzLmdwdVNhbXBsZXIgPSBkZXZpY2UuY3JlYXRlU2FtcGxlcih0aGlzLmRlc2NyaXB0b3IpO1xuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNhbXBsZXI7XG4iLCJpbXBvcnQgeyBBdHRhY2htZW50T3B0aW9ucyB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XG5pbXBvcnQgVGV4dHVyZSBmcm9tIFwiLi9UZXh0dXJlXCI7XG5cbmNsYXNzIEF0dGFjaG1lbnQge1xuXHRwdWJsaWMgb3A6IEdQVUxvYWRPcCA9IFwiY2xlYXJcIjtcblx0cHVibGljIHN0b3JlT3A6IEdQVVN0b3JlT3AgPSBcInN0b3JlXCI7XG5cblx0cHVibGljIHRleHR1cmU/OiBUZXh0dXJlO1xuXHRwdWJsaWMgcmVzb2x2ZVRhcmdldD86IFRleHR1cmU7XG5cdHB1YmxpYyB0ZXh0dXJlVmlldz86ICgpID0+IEdQVVRleHR1cmVWaWV3O1xuXHRwdWJsaWMgcmVhZE9ubHk/OiBib29sZWFuO1xuXG5cdGNvbnN0cnVjdG9yKHB1YmxpYyB2YWx1ZTogR1BVQ29sb3JEaWN0IHwgR1BVQ29sb3IgfCBudW1iZXIsIG9wdGlvbnM/OiBBdHRhY2htZW50T3B0aW9ucykge1xuXHRcdE9iamVjdC5hc3NpZ24odGhpcywgb3B0aW9ucyk7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQXR0YWNobWVudDtcbiIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGRlZmluZWQodmFsdWUpIHtcblx0cmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGw7XG59XG4iLCIvKlxuICBodHRwczovL2dpdGh1Yi5jb20vYmFua3NlYW4gd3JhcHBlZCBNYWtvdG8gTWF0c3Vtb3RvIGFuZCBUYWt1amkgTmlzaGltdXJhJ3MgY29kZSBpbiBhIG5hbWVzcGFjZVxuICBzbyBpdCdzIGJldHRlciBlbmNhcHN1bGF0ZWQuIE5vdyB5b3UgY2FuIGhhdmUgbXVsdGlwbGUgcmFuZG9tIG51bWJlciBnZW5lcmF0b3JzXG4gIGFuZCB0aGV5IHdvbid0IHN0b21wIGFsbCBvdmVyIGVhY2hvdGhlcidzIHN0YXRlLlxuXG4gIElmIHlvdSB3YW50IHRvIHVzZSB0aGlzIGFzIGEgc3Vic3RpdHV0ZSBmb3IgTWF0aC5yYW5kb20oKSwgdXNlIHRoZSByYW5kb20oKVxuICBtZXRob2QgbGlrZSBzbzpcblxuICB2YXIgbSA9IG5ldyBNZXJzZW5uZVR3aXN0ZXIoKTtcbiAgdmFyIHJhbmRvbU51bWJlciA9IG0ucmFuZG9tKCk7XG5cbiAgWW91IGNhbiBhbHNvIGNhbGwgdGhlIG90aGVyIGdlbnJhbmRfe2Zvb30oKSBtZXRob2RzIG9uIHRoZSBpbnN0YW5jZS5cblxuICBJZiB5b3Ugd2FudCB0byB1c2UgYSBzcGVjaWZpYyBzZWVkIGluIG9yZGVyIHRvIGdldCBhIHJlcGVhdGFibGUgcmFuZG9tXG4gIHNlcXVlbmNlLCBwYXNzIGFuIGludGVnZXIgaW50byB0aGUgY29uc3RydWN0b3I6XG5cbiAgdmFyIG0gPSBuZXcgTWVyc2VubmVUd2lzdGVyKDEyMyk7XG5cbiAgYW5kIHRoYXQgd2lsbCBhbHdheXMgcHJvZHVjZSB0aGUgc2FtZSByYW5kb20gc2VxdWVuY2UuXG5cbiAgU2VhbiBNY0N1bGxvdWdoIChiYW5rc2VhbkBnbWFpbC5jb20pXG4qL1xuXG4vKlxuICAgQSBDLXByb2dyYW0gZm9yIE1UMTk5MzcsIHdpdGggaW5pdGlhbGl6YXRpb24gaW1wcm92ZWQgMjAwMi8xLzI2LlxuICAgQ29kZWQgYnkgVGFrdWppIE5pc2hpbXVyYSBhbmQgTWFrb3RvIE1hdHN1bW90by5cblxuICAgQmVmb3JlIHVzaW5nLCBpbml0aWFsaXplIHRoZSBzdGF0ZSBieSB1c2luZyBpbml0X3NlZWQoc2VlZClcbiAgIG9yIGluaXRfYnlfYXJyYXkoaW5pdF9rZXksIGtleV9sZW5ndGgpLlxuXG4gICBDb3B5cmlnaHQgKEMpIDE5OTcgLSAyMDAyLCBNYWtvdG8gTWF0c3Vtb3RvIGFuZCBUYWt1amkgTmlzaGltdXJhLFxuICAgQWxsIHJpZ2h0cyByZXNlcnZlZC5cblxuICAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnNcbiAgIGFyZSBtZXQ6XG5cbiAgICAgMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuXG4gICAgIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiAgICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cblxuICAgICAzLiBUaGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycyBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlXG4gICAgICAgIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlblxuICAgICAgICBwZXJtaXNzaW9uLlxuXG4gICBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTXG4gICBcIkFTIElTXCIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UXG4gICBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1JcbiAgIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBPV05FUiBPUlxuICAgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsXG4gICBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sXG4gICBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1JcbiAgIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0ZcbiAgIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HXG4gICBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVNcbiAgIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuXG5cbiAgIEFueSBmZWVkYmFjayBpcyB2ZXJ5IHdlbGNvbWUuXG4gICBodHRwOi8vd3d3Lm1hdGguc2NpLmhpcm9zaGltYS11LmFjLmpwL35tLW1hdC9NVC9lbXQuaHRtbFxuICAgZW1haWw6IG0tbWF0IEAgbWF0aC5zY2kuaGlyb3NoaW1hLXUuYWMuanAgKHJlbW92ZSBzcGFjZSlcbiovXG5cbnZhciBNZXJzZW5uZVR3aXN0ZXIgPSBmdW5jdGlvbihzZWVkKSB7XG5cdGlmIChzZWVkID09IHVuZGVmaW5lZCkge1xuXHRcdHNlZWQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblx0fVxuXG5cdC8qIFBlcmlvZCBwYXJhbWV0ZXJzICovXG5cdHRoaXMuTiA9IDYyNDtcblx0dGhpcy5NID0gMzk3O1xuXHR0aGlzLk1BVFJJWF9BID0gMHg5OTA4YjBkZjsgICAvKiBjb25zdGFudCB2ZWN0b3IgYSAqL1xuXHR0aGlzLlVQUEVSX01BU0sgPSAweDgwMDAwMDAwOyAvKiBtb3N0IHNpZ25pZmljYW50IHctciBiaXRzICovXG5cdHRoaXMuTE9XRVJfTUFTSyA9IDB4N2ZmZmZmZmY7IC8qIGxlYXN0IHNpZ25pZmljYW50IHIgYml0cyAqL1xuXG5cdHRoaXMubXQgPSBuZXcgQXJyYXkodGhpcy5OKTsgLyogdGhlIGFycmF5IGZvciB0aGUgc3RhdGUgdmVjdG9yICovXG5cdHRoaXMubXRpPXRoaXMuTisxOyAvKiBtdGk9PU4rMSBtZWFucyBtdFtOXSBpcyBub3QgaW5pdGlhbGl6ZWQgKi9cblxuXHRpZiAoc2VlZC5jb25zdHJ1Y3RvciA9PSBBcnJheSkge1xuXHRcdHRoaXMuaW5pdF9ieV9hcnJheShzZWVkLCBzZWVkLmxlbmd0aCk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0dGhpcy5pbml0X3NlZWQoc2VlZCk7XG5cdH1cbn1cblxuLyogaW5pdGlhbGl6ZXMgbXRbTl0gd2l0aCBhIHNlZWQgKi9cbi8qIG9yaWdpbiBuYW1lIGluaXRfZ2VucmFuZCAqL1xuTWVyc2VubmVUd2lzdGVyLnByb3RvdHlwZS5pbml0X3NlZWQgPSBmdW5jdGlvbihzKSB7XG5cdHRoaXMubXRbMF0gPSBzID4+PiAwO1xuXHRmb3IgKHRoaXMubXRpPTE7IHRoaXMubXRpPHRoaXMuTjsgdGhpcy5tdGkrKykge1xuXHRcdHZhciBzID0gdGhpcy5tdFt0aGlzLm10aS0xXSBeICh0aGlzLm10W3RoaXMubXRpLTFdID4+PiAzMCk7XG5cdFx0dGhpcy5tdFt0aGlzLm10aV0gPSAoKCgoKHMgJiAweGZmZmYwMDAwKSA+Pj4gMTYpICogMTgxMjQzMzI1MykgPDwgMTYpICsgKHMgJiAweDAwMDBmZmZmKSAqIDE4MTI0MzMyNTMpXG5cdFx0KyB0aGlzLm10aTtcblx0XHQvKiBTZWUgS251dGggVEFPQ1AgVm9sMi4gM3JkIEVkLiBQLjEwNiBmb3IgbXVsdGlwbGllci4gKi9cblx0XHQvKiBJbiB0aGUgcHJldmlvdXMgdmVyc2lvbnMsIE1TQnMgb2YgdGhlIHNlZWQgYWZmZWN0ICAgKi9cblx0XHQvKiBvbmx5IE1TQnMgb2YgdGhlIGFycmF5IG10W10uICAgICAgICAgICAgICAgICAgICAgICAgKi9cblx0XHQvKiAyMDAyLzAxLzA5IG1vZGlmaWVkIGJ5IE1ha290byBNYXRzdW1vdG8gICAgICAgICAgICAgKi9cblx0XHR0aGlzLm10W3RoaXMubXRpXSA+Pj49IDA7XG5cdFx0LyogZm9yID4zMiBiaXQgbWFjaGluZXMgKi9cblx0fVxufVxuXG4vKiBpbml0aWFsaXplIGJ5IGFuIGFycmF5IHdpdGggYXJyYXktbGVuZ3RoICovXG4vKiBpbml0X2tleSBpcyB0aGUgYXJyYXkgZm9yIGluaXRpYWxpemluZyBrZXlzICovXG4vKiBrZXlfbGVuZ3RoIGlzIGl0cyBsZW5ndGggKi9cbi8qIHNsaWdodCBjaGFuZ2UgZm9yIEMrKywgMjAwNC8yLzI2ICovXG5NZXJzZW5uZVR3aXN0ZXIucHJvdG90eXBlLmluaXRfYnlfYXJyYXkgPSBmdW5jdGlvbihpbml0X2tleSwga2V5X2xlbmd0aCkge1xuXHR2YXIgaSwgaiwgaztcblx0dGhpcy5pbml0X3NlZWQoMTk2NTAyMTgpO1xuXHRpPTE7IGo9MDtcblx0ayA9ICh0aGlzLk4+a2V5X2xlbmd0aCA/IHRoaXMuTiA6IGtleV9sZW5ndGgpO1xuXHRmb3IgKDsgazsgay0tKSB7XG5cdFx0dmFyIHMgPSB0aGlzLm10W2ktMV0gXiAodGhpcy5tdFtpLTFdID4+PiAzMClcblx0XHR0aGlzLm10W2ldID0gKHRoaXMubXRbaV0gXiAoKCgoKHMgJiAweGZmZmYwMDAwKSA+Pj4gMTYpICogMTY2NDUyNSkgPDwgMTYpICsgKChzICYgMHgwMDAwZmZmZikgKiAxNjY0NTI1KSkpXG5cdFx0KyBpbml0X2tleVtqXSArIGo7IC8qIG5vbiBsaW5lYXIgKi9cblx0XHR0aGlzLm10W2ldID4+Pj0gMDsgLyogZm9yIFdPUkRTSVpFID4gMzIgbWFjaGluZXMgKi9cblx0XHRpKys7IGorKztcblx0XHRpZiAoaT49dGhpcy5OKSB7IHRoaXMubXRbMF0gPSB0aGlzLm10W3RoaXMuTi0xXTsgaT0xOyB9XG5cdFx0aWYgKGo+PWtleV9sZW5ndGgpIGo9MDtcblx0fVxuXHRmb3IgKGs9dGhpcy5OLTE7IGs7IGstLSkge1xuXHRcdHZhciBzID0gdGhpcy5tdFtpLTFdIF4gKHRoaXMubXRbaS0xXSA+Pj4gMzApO1xuXHRcdHRoaXMubXRbaV0gPSAodGhpcy5tdFtpXSBeICgoKCgocyAmIDB4ZmZmZjAwMDApID4+PiAxNikgKiAxNTY2MDgzOTQxKSA8PCAxNikgKyAocyAmIDB4MDAwMGZmZmYpICogMTU2NjA4Mzk0MSkpXG5cdFx0LSBpOyAvKiBub24gbGluZWFyICovXG5cdFx0dGhpcy5tdFtpXSA+Pj49IDA7IC8qIGZvciBXT1JEU0laRSA+IDMyIG1hY2hpbmVzICovXG5cdFx0aSsrO1xuXHRcdGlmIChpPj10aGlzLk4pIHsgdGhpcy5tdFswXSA9IHRoaXMubXRbdGhpcy5OLTFdOyBpPTE7IH1cblx0fVxuXG5cdHRoaXMubXRbMF0gPSAweDgwMDAwMDAwOyAvKiBNU0IgaXMgMTsgYXNzdXJpbmcgbm9uLXplcm8gaW5pdGlhbCBhcnJheSAqL1xufVxuXG4vKiBnZW5lcmF0ZXMgYSByYW5kb20gbnVtYmVyIG9uIFswLDB4ZmZmZmZmZmZdLWludGVydmFsICovXG4vKiBvcmlnaW4gbmFtZSBnZW5yYW5kX2ludDMyICovXG5NZXJzZW5uZVR3aXN0ZXIucHJvdG90eXBlLnJhbmRvbV9pbnQgPSBmdW5jdGlvbigpIHtcblx0dmFyIHk7XG5cdHZhciBtYWcwMSA9IG5ldyBBcnJheSgweDAsIHRoaXMuTUFUUklYX0EpO1xuXHQvKiBtYWcwMVt4XSA9IHggKiBNQVRSSVhfQSAgZm9yIHg9MCwxICovXG5cblx0aWYgKHRoaXMubXRpID49IHRoaXMuTikgeyAvKiBnZW5lcmF0ZSBOIHdvcmRzIGF0IG9uZSB0aW1lICovXG5cdFx0dmFyIGtrO1xuXG5cdFx0aWYgKHRoaXMubXRpID09IHRoaXMuTisxKSAgLyogaWYgaW5pdF9zZWVkKCkgaGFzIG5vdCBiZWVuIGNhbGxlZCwgKi9cblx0XHRcdHRoaXMuaW5pdF9zZWVkKDU0ODkpOyAgLyogYSBkZWZhdWx0IGluaXRpYWwgc2VlZCBpcyB1c2VkICovXG5cblx0XHRmb3IgKGtrPTA7a2s8dGhpcy5OLXRoaXMuTTtraysrKSB7XG5cdFx0XHR5ID0gKHRoaXMubXRba2tdJnRoaXMuVVBQRVJfTUFTSyl8KHRoaXMubXRba2srMV0mdGhpcy5MT1dFUl9NQVNLKTtcblx0XHRcdHRoaXMubXRba2tdID0gdGhpcy5tdFtrayt0aGlzLk1dIF4gKHkgPj4+IDEpIF4gbWFnMDFbeSAmIDB4MV07XG5cdFx0fVxuXHRcdGZvciAoO2trPHRoaXMuTi0xO2trKyspIHtcblx0XHRcdHkgPSAodGhpcy5tdFtra10mdGhpcy5VUFBFUl9NQVNLKXwodGhpcy5tdFtraysxXSZ0aGlzLkxPV0VSX01BU0spO1xuXHRcdFx0dGhpcy5tdFtra10gPSB0aGlzLm10W2trKyh0aGlzLk0tdGhpcy5OKV0gXiAoeSA+Pj4gMSkgXiBtYWcwMVt5ICYgMHgxXTtcblx0XHR9XG5cdFx0eSA9ICh0aGlzLm10W3RoaXMuTi0xXSZ0aGlzLlVQUEVSX01BU0spfCh0aGlzLm10WzBdJnRoaXMuTE9XRVJfTUFTSyk7XG5cdFx0dGhpcy5tdFt0aGlzLk4tMV0gPSB0aGlzLm10W3RoaXMuTS0xXSBeICh5ID4+PiAxKSBeIG1hZzAxW3kgJiAweDFdO1xuXG5cdFx0dGhpcy5tdGkgPSAwO1xuXHR9XG5cblx0eSA9IHRoaXMubXRbdGhpcy5tdGkrK107XG5cblx0LyogVGVtcGVyaW5nICovXG5cdHkgXj0gKHkgPj4+IDExKTtcblx0eSBePSAoeSA8PCA3KSAmIDB4OWQyYzU2ODA7XG5cdHkgXj0gKHkgPDwgMTUpICYgMHhlZmM2MDAwMDtcblx0eSBePSAoeSA+Pj4gMTgpO1xuXG5cdHJldHVybiB5ID4+PiAwO1xufVxuXG4vKiBnZW5lcmF0ZXMgYSByYW5kb20gbnVtYmVyIG9uIFswLDB4N2ZmZmZmZmZdLWludGVydmFsICovXG4vKiBvcmlnaW4gbmFtZSBnZW5yYW5kX2ludDMxICovXG5NZXJzZW5uZVR3aXN0ZXIucHJvdG90eXBlLnJhbmRvbV9pbnQzMSA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gKHRoaXMucmFuZG9tX2ludCgpPj4+MSk7XG59XG5cbi8qIGdlbmVyYXRlcyBhIHJhbmRvbSBudW1iZXIgb24gWzAsMV0tcmVhbC1pbnRlcnZhbCAqL1xuLyogb3JpZ2luIG5hbWUgZ2VucmFuZF9yZWFsMSAqL1xuTWVyc2VubmVUd2lzdGVyLnByb3RvdHlwZS5yYW5kb21faW5jbCA9IGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gdGhpcy5yYW5kb21faW50KCkqKDEuMC80Mjk0OTY3Mjk1LjApO1xuXHQvKiBkaXZpZGVkIGJ5IDJeMzItMSAqL1xufVxuXG4vKiBnZW5lcmF0ZXMgYSByYW5kb20gbnVtYmVyIG9uIFswLDEpLXJlYWwtaW50ZXJ2YWwgKi9cbk1lcnNlbm5lVHdpc3Rlci5wcm90b3R5cGUucmFuZG9tID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiB0aGlzLnJhbmRvbV9pbnQoKSooMS4wLzQyOTQ5NjcyOTYuMCk7XG5cdC8qIGRpdmlkZWQgYnkgMl4zMiAqL1xufVxuXG4vKiBnZW5lcmF0ZXMgYSByYW5kb20gbnVtYmVyIG9uICgwLDEpLXJlYWwtaW50ZXJ2YWwgKi9cbi8qIG9yaWdpbiBuYW1lIGdlbnJhbmRfcmVhbDMgKi9cbk1lcnNlbm5lVHdpc3Rlci5wcm90b3R5cGUucmFuZG9tX2V4Y2wgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuICh0aGlzLnJhbmRvbV9pbnQoKSArIDAuNSkqKDEuMC80Mjk0OTY3Mjk2LjApO1xuXHQvKiBkaXZpZGVkIGJ5IDJeMzIgKi9cbn1cblxuLyogZ2VuZXJhdGVzIGEgcmFuZG9tIG51bWJlciBvbiBbMCwxKSB3aXRoIDUzLWJpdCByZXNvbHV0aW9uKi9cbi8qIG9yaWdpbiBuYW1lIGdlbnJhbmRfcmVzNTMgKi9cbk1lcnNlbm5lVHdpc3Rlci5wcm90b3R5cGUucmFuZG9tX2xvbmcgPSBmdW5jdGlvbigpIHtcblx0dmFyIGE9dGhpcy5yYW5kb21faW50KCk+Pj41LCBiPXRoaXMucmFuZG9tX2ludCgpPj4+Njtcblx0cmV0dXJuKGEqNjcxMDg4NjQuMCtiKSooMS4wLzkwMDcxOTkyNTQ3NDA5OTIuMCk7XG59XG5cbi8qIFRoZXNlIHJlYWwgdmVyc2lvbnMgYXJlIGR1ZSB0byBJc2FrdSBXYWRhLCAyMDAyLzAxLzA5IGFkZGVkICovXG5cbm1vZHVsZS5leHBvcnRzID0gTWVyc2VubmVUd2lzdGVyO1xuIiwiaW1wb3J0IE1lcnNlbm5lVHdpc3RlciBmcm9tIFwibWVyc2VubmUtdHdpc3RlclwiO1xyXG5pbXBvcnQgZGVmYXVsdFZhbHVlIGZyb20gXCIuLi91dGlscy9kZWZhdWx0VmFsdWVcIjtcclxuaW1wb3J0IGRlZmluZWQgZnJvbSBcIi4uL3V0aWxzL2RlZmluZWRcIjtcclxuXHJcbmNsYXNzIEdNYXRoIHtcclxuXHRwdWJsaWMgc3RhdGljIEVQU0lMT04xID0gMC4xO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIEVQU0lMT04yID0gMC4wMTtcclxuXHJcblx0cHVibGljIHN0YXRpYyBFUFNJTE9OMyA9IDAuMDAxO1xyXG5cdHB1YmxpYyBzdGF0aWMgRVBTSUxPTjQgPSAwLjAwMDE7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgRVBTSUxPTjUgPSAwLjAwMDAxO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIEVQU0lMT042ID0gMC4wMDAwMDE7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgRVBTSUxPTjcgPSAwLjAwMDAwMDE7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgRVBTSUxPTjggPSAwLjAwMDAwMDAxO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIEVQU0lMT045ID0gMC4wMDAwMDAwMDE7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgRVBTSUxPTjEwID0gMC4wMDAwMDAwMDAxO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIEVQU0lMT04xMSA9IDAuMDAwMDAwMDAwMDE7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgRVBTSUxPTjEyID0gMC4wMDAwMDAwMDAwMDE7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgRVBTSUxPTjEzID0gMC4wMDAwMDAwMDAwMDAxO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIEVQU0lMT04xNCA9IDAuMDAwMDAwMDAwMDAwMDE7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgRVBTSUxPTjE1ID0gMC4wMDAwMDAwMDAwMDAwMDE7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgRVBTSUxPTjE2ID0gMC4wMDAwMDAwMDAwMDAwMDAxO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIEVQU0lMT04xNyA9IDAuMDAwMDAwMDAwMDAwMDAwMDE7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgRVBTSUxPTjE4ID0gMC4wMDAwMDAwMDAwMDAwMDAwMDE7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgRVBTSUxPTjE5ID0gMC4wMDAwMDAwMDAwMDAwMDAwMDAxO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIEVQU0lMT04yMCA9IDAuMDAwMDAwMDAwMDAwMDAwMDAwMDE7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgRVBTSUxPTjIxID0gMC4wMDAwMDAwMDAwMDAwMDAwMDAwMDE7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgR1JBVklUQVRJT05BTFBBUkFNRVRFUiA9IDMuOTg2MDA0NDE4ZTE0O1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIFNJWFRZX0ZPVVJfS0lMT0JZVEVTID0gNjQgKiAxMDI0O1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIEZPVVJfR0lHQUJZVEVTID0gNCAqIDEwMjQgKiAxMDI0ICogMTAyNDtcclxuXHJcblx0c3RhdGljIHNpZ24gPSBkZWZhdWx0VmFsdWUoTWF0aC5zaWduLCBmdW5jdGlvbiBzaWduKHZhbHVlKSB7XHJcblx0XHR2YWx1ZSA9ICt2YWx1ZTsgLy8gY29lcmNlIHRvIG51bWJlclxyXG5cdFx0aWYgKHZhbHVlID09PSAwIHx8IHZhbHVlICE9PSB2YWx1ZSkge1xyXG5cdFx0XHQvLyB6ZXJvIG9yIE5hTlxyXG5cdFx0XHRyZXR1cm4gdmFsdWU7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gdmFsdWUgPiAwID8gMSA6IC0xO1xyXG5cdH0pO1xyXG5cclxuXHRzdGF0aWMgc2lnbk5vdFplcm8odmFsdWUpIHtcclxuXHRcdHJldHVybiB2YWx1ZSA8IDAuMCA/IC0xLjAgOiAxLjA7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgdG9TTm9ybSh2YWx1ZTogbnVtYmVyLCByYW5nZU1heGltdW06IG51bWJlcik6IG51bWJlciB7XHJcblx0XHRyYW5nZU1heGltdW0gPSBkZWZhdWx0VmFsdWUocmFuZ2VNYXhpbXVtLCAyNTUpO1xyXG5cdFx0cmV0dXJuIE1hdGgucm91bmQoKEdNYXRoLmNsYW1wKHZhbHVlLCAtMS4wLCAxLjApICogMC41ICsgMC41KSAqIHJhbmdlTWF4aW11bSk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZnJvbVNOb3JtKHZhbHVlOiBudW1iZXIsIHJhbmdlTWF4aW11bTogbnVtYmVyKTogbnVtYmVyIHtcclxuXHRcdHJhbmdlTWF4aW11bSA9IGRlZmF1bHRWYWx1ZShyYW5nZU1heGltdW0sIDI1NSk7XHJcblx0XHRyZXR1cm4gKEdNYXRoLmNsYW1wKHZhbHVlLCAwLjAsIHJhbmdlTWF4aW11bSkgLyByYW5nZU1heGltdW0pICogMi4wIC0gMS4wO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG5vcm1hbGl6ZSh2YWx1ZTogbnVtYmVyLCByYW5nZU1pbmltdW06IG51bWJlciwgcmFuZ2VNYXhpbXVtOiBudW1iZXIpOiBudW1iZXIge1xyXG5cdFx0cmFuZ2VNYXhpbXVtID0gTWF0aC5tYXgocmFuZ2VNYXhpbXVtIC0gcmFuZ2VNaW5pbXVtLCAwLjApO1xyXG5cdFx0cmV0dXJuIHJhbmdlTWF4aW11bSA9PT0gMC4wID8gMC4wIDogR01hdGguY2xhbXAoKHZhbHVlIC0gcmFuZ2VNaW5pbXVtKSAvIHJhbmdlTWF4aW11bSwgMC4wLCAxLjApO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIHNpbmggPSBkZWZhdWx0VmFsdWUoTWF0aC5zaW5oLCBmdW5jdGlvbiBzaW5oKHZhbHVlKSB7XHJcblx0XHRyZXR1cm4gKE1hdGguZXhwKHZhbHVlKSAtIE1hdGguZXhwKC12YWx1ZSkpIC8gMi4wO1xyXG5cdH0pO1xyXG5cclxuXHRzdGF0aWMgY29zaCA9IGRlZmF1bHRWYWx1ZShNYXRoLmNvc2gsIGZ1bmN0aW9uIGNvc2godmFsdWUpIHtcclxuXHRcdHJldHVybiAoTWF0aC5leHAodmFsdWUpICsgTWF0aC5leHAoLXZhbHVlKSkgLyAyLjA7XHJcblx0fSk7XHJcblxyXG5cdHN0YXRpYyBsZXJwKHA6IG51bWJlciwgcTogbnVtYmVyLCB0aW1lOiBudW1iZXIpOiBudW1iZXIge1xyXG5cdFx0cmV0dXJuICgxLjAgLSB0aW1lKSAqIHAgKyB0aW1lICogcTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBQSSA9IE1hdGguUEk7XHJcblxyXG5cdHN0YXRpYyBPTkVfT1ZFUl9QSSA9IDEuMCAvIE1hdGguUEk7XHJcblxyXG5cdHN0YXRpYyBQSV9PVkVSX1RXTyA9IE1hdGguUEkgLyAyLjA7XHJcblxyXG5cdHN0YXRpYyBQSV9PVkVSX1RIUkVFID0gTWF0aC5QSSAvIDMuMDtcclxuXHJcblx0c3RhdGljIFBJX09WRVJfRk9VUiA9IE1hdGguUEkgLyA0LjA7XHJcblxyXG5cdHN0YXRpYyBQSV9PVkVSX1NJWCA9IE1hdGguUEkgLyA2LjA7XHJcblxyXG5cdHN0YXRpYyBUSFJFRV9QSV9PVkVSX1RXTyA9ICgzLjAgKiBNYXRoLlBJKSAvIDIuMDtcclxuXHJcblx0c3RhdGljIFRXT19QSSA9IDIuMCAqIE1hdGguUEk7XHJcblxyXG5cdHN0YXRpYyBPTkVfT1ZFUl9UV09fUEkgPSAxLjAgLyAoMi4wICogTWF0aC5QSSk7XHJcblxyXG5cdHN0YXRpYyBSQURJQU5TX1BFUl9ERUdSRUUgPSBNYXRoLlBJIC8gMTgwLjA7XHJcblxyXG5cdHN0YXRpYyBERUdSRUVTX1BFUl9SQURJQU4gPSAxODAuMCAvIE1hdGguUEk7XHJcblxyXG5cdHN0YXRpYyBSQURJQU5TX1BFUl9BUkNTRUNPTkQgPSBHTWF0aC5SQURJQU5TX1BFUl9ERUdSRUUgLyAzNjAwLjA7XHJcblxyXG5cdHN0YXRpYyB0b1JhZGlhbnMoZGVncmVlczogbnVtYmVyKTogbnVtYmVyIHtcclxuXHRcdGlmICghZGVmaW5lZChkZWdyZWVzKSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJkZWdyZWVzIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBkZWdyZWVzICogR01hdGguUkFESUFOU19QRVJfREVHUkVFO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIHRvRGVncmVlcyhyYWRpYW5zOiBudW1iZXIpOiBudW1iZXIge1xyXG5cdFx0aWYgKCFkZWZpbmVkKHJhZGlhbnMpKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcInJhZGlhbnMgaXMgcmVxdWlyZWQuXCIpO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHJhZGlhbnMgKiBHTWF0aC5ERUdSRUVTX1BFUl9SQURJQU47XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbmVnYXRpdmVQaVRvUGkoYW5nbGU6IG51bWJlcik6IG51bWJlciB7XHJcblx0XHRpZiAoIWRlZmluZWQoYW5nbGUpKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcImFuZ2xlIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdGlmIChhbmdsZSA+PSAtR01hdGguUEkgJiYgYW5nbGUgPD0gR01hdGguUEkpIHtcclxuXHRcdFx0Ly8gRWFybHkgZXhpdCBpZiB0aGUgaW5wdXQgaXMgYWxyZWFkeSBpbnNpZGUgdGhlIHJhbmdlLiBUaGlzIGF2b2lkc1xyXG5cdFx0XHQvLyB1bm5lY2Vzc2FyeSBtYXRoIHdoaWNoIGNvdWxkIGludHJvZHVjZSBmbG9hdGluZyBwb2ludCBlcnJvci5cclxuXHRcdFx0cmV0dXJuIGFuZ2xlO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIEdNYXRoLnplcm9Ub1R3b1BpKGFuZ2xlICsgR01hdGguUEkpIC0gR01hdGguUEk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgemVyb1RvVHdvUGkoYW5nbGU6IG51bWJlcik6IG51bWJlciB7XHJcblx0XHRpZiAoIWRlZmluZWQoYW5nbGUpKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcImFuZ2xlIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdGlmIChhbmdsZSA+PSAwICYmIGFuZ2xlIDw9IEdNYXRoLlRXT19QSSkge1xyXG5cdFx0XHQvLyBFYXJseSBleGl0IGlmIHRoZSBpbnB1dCBpcyBhbHJlYWR5IGluc2lkZSB0aGUgcmFuZ2UuIFRoaXMgYXZvaWRzXHJcblx0XHRcdC8vIHVubmVjZXNzYXJ5IG1hdGggd2hpY2ggY291bGQgaW50cm9kdWNlIGZsb2F0aW5nIHBvaW50IGVycm9yLlxyXG5cdFx0XHRyZXR1cm4gYW5nbGU7XHJcblx0XHR9XHJcblx0XHRjb25zdCBtb2QgPSBHTWF0aC5tb2QoYW5nbGUsIEdNYXRoLlRXT19QSSk7XHJcblx0XHRpZiAoTWF0aC5hYnMobW9kKSA8IEdNYXRoLkVQU0lMT04xNCAmJiBNYXRoLmFicyhhbmdsZSkgPiBHTWF0aC5FUFNJTE9OMTQpIHtcclxuXHRcdFx0cmV0dXJuIEdNYXRoLlRXT19QSTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBtb2Q7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbW9kKG06IG51bWJlciwgbjogbnVtYmVyKTogbnVtYmVyIHtcclxuXHRcdGlmICghZGVmaW5lZChtKSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJtIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdGlmICghZGVmaW5lZChuKSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJuIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdGlmIChuID09PSAwLjApIHtcclxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiZGl2aXNvciBjYW5ub3QgYmUgMC5cIik7XHJcblx0XHR9XHJcblx0XHRpZiAoR01hdGguc2lnbihtKSA9PT0gR01hdGguc2lnbihuKSAmJiBNYXRoLmFicyhtKSA8IE1hdGguYWJzKG4pKSB7XHJcblx0XHRcdC8vIEVhcmx5IGV4aXQgaWYgdGhlIGlucHV0IGRvZXMgbm90IG5lZWQgdG8gYmUgbW9kZGVkLiBUaGlzIGF2b2lkc1xyXG5cdFx0XHQvLyB1bm5lY2Vzc2FyeSBtYXRoIHdoaWNoIGNvdWxkIGludHJvZHVjZSBmbG9hdGluZyBwb2ludCBlcnJvci5cclxuXHRcdFx0cmV0dXJuIG07XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuICgobSAlIG4pICsgbikgJSBuO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGVxdWFsc0Vwc2lsb24oXHJcblx0XHRsZWZ0OiBudW1iZXIsXHJcblx0XHRyaWdodDogbnVtYmVyLFxyXG5cdFx0cmVsYXRpdmVFcHNpbG9uOiBudW1iZXIsXHJcblx0XHRhYnNvbHV0ZUVwc2lsb246IG51bWJlciA9IHJlbGF0aXZlRXBzaWxvblxyXG5cdCk6IGJvb2xlYW4ge1xyXG5cdFx0aWYgKCFkZWZpbmVkKGxlZnQpKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcImxlZnQgaXMgcmVxdWlyZWQuXCIpO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCFkZWZpbmVkKHJpZ2h0KSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJyaWdodCBpcyByZXF1aXJlZC5cIik7XHJcblx0XHR9XHJcblxyXG5cdFx0cmVsYXRpdmVFcHNpbG9uID0gZGVmYXVsdFZhbHVlKHJlbGF0aXZlRXBzaWxvbiwgMC4wKTtcclxuXHRcdGFic29sdXRlRXBzaWxvbiA9IGRlZmF1bHRWYWx1ZShhYnNvbHV0ZUVwc2lsb24sIHJlbGF0aXZlRXBzaWxvbik7XHJcblx0XHRjb25zdCBhYnNEaWZmID0gTWF0aC5hYnMobGVmdCAtIHJpZ2h0KTtcclxuXHRcdHJldHVybiBhYnNEaWZmIDw9IGFic29sdXRlRXBzaWxvbiB8fCBhYnNEaWZmIDw9IHJlbGF0aXZlRXBzaWxvbiAqIE1hdGgubWF4KE1hdGguYWJzKGxlZnQpLCBNYXRoLmFicyhyaWdodCkpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGxlc3NUaGFuKGxlZnQ6IG51bWJlciwgcmlnaHQ6IG51bWJlciwgYWJzb2x1dGVFcHNpbG9uID0gMCk6IGJvb2xlYW4ge1xyXG5cdFx0aWYgKCFkZWZpbmVkKGxlZnQpKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcImZpcnN0IGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdGlmICghZGVmaW5lZChyaWdodCkpIHtcclxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwic2Vjb25kIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdGlmICghZGVmaW5lZChhYnNvbHV0ZUVwc2lsb24pKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcImFic29sdXRlRXBzaWxvbiBpcyByZXF1aXJlZC5cIik7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gbGVmdCAtIHJpZ2h0IDwgLWFic29sdXRlRXBzaWxvbjtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBsZXNzVGhhbk9yRXF1YWxzKGxlZnQ6IG51bWJlciwgcmlnaHQ6IG51bWJlciwgYWJzb2x1dGVFcHNpbG9uID0gMCk6IGJvb2xlYW4ge1xyXG5cdFx0aWYgKCFkZWZpbmVkKGxlZnQpKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcImZpcnN0IGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdGlmICghZGVmaW5lZChyaWdodCkpIHtcclxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwic2Vjb25kIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdGlmICghZGVmaW5lZChhYnNvbHV0ZUVwc2lsb24pKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcImFic29sdXRlRXBzaWxvbiBpcyByZXF1aXJlZC5cIik7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gbGVmdCAtIHJpZ2h0IDwgYWJzb2x1dGVFcHNpbG9uO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGdyZWF0ZXJUaGFuKGxlZnQ6IG51bWJlciwgcmlnaHQ6IG51bWJlciwgYWJzb2x1dGVFcHNpbG9uID0gMCk6IGJvb2xlYW4ge1xyXG5cdFx0aWYgKCFkZWZpbmVkKGxlZnQpKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcImZpcnN0IGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdGlmICghZGVmaW5lZChyaWdodCkpIHtcclxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwic2Vjb25kIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdGlmICghZGVmaW5lZChhYnNvbHV0ZUVwc2lsb24pKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcImFic29sdXRlRXBzaWxvbiBpcyByZXF1aXJlZC5cIik7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gbGVmdCAtIHJpZ2h0ID4gYWJzb2x1dGVFcHNpbG9uO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGdyZWF0ZXJUaGFuT3JFcXVhbHMobGVmdDogbnVtYmVyLCByaWdodDogbnVtYmVyLCBhYnNvbHV0ZUVwc2lsb24gPSAwKTogYm9vbGVhbiB7XHJcblx0XHRpZiAoIWRlZmluZWQobGVmdCkpIHtcclxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiZmlyc3QgaXMgcmVxdWlyZWQuXCIpO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCFkZWZpbmVkKHJpZ2h0KSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJzZWNvbmQgaXMgcmVxdWlyZWQuXCIpO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCFkZWZpbmVkKGFic29sdXRlRXBzaWxvbikpIHtcclxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiYWJzb2x1dGVFcHNpbG9uIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBsZWZ0IC0gcmlnaHQgPiAtYWJzb2x1dGVFcHNpbG9uO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGlzUG93ZXJPZlR3byhuOiBudW1iZXIpOiBib29sZWFuIHtcclxuXHRcdC8vID4+aW5jbHVkZVN0YXJ0KCdkZWJ1ZycsIHByYWdtYXMuZGVidWcpO1xyXG5cdFx0aWYgKHR5cGVvZiBuICE9PSBcIm51bWJlclwiIHx8IG4gPCAwIHx8IG4gPiA0Mjk0OTY3Mjk1KSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIkEgbnVtYmVyIGJldHdlZW4gMCBhbmQgKDJeMzIpLTEgaXMgcmVxdWlyZWQuXCIpO1xyXG5cdFx0fVxyXG5cdFx0Ly8gPj5pbmNsdWRlRW5kKCdkZWJ1ZycpO1xyXG5cclxuXHRcdHJldHVybiBuICE9PSAwICYmIChuICYgKG4gLSAxKSkgPT09IDA7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbmV4dFBvd2VyT2ZUd28objogbnVtYmVyKTogbnVtYmVyIHtcclxuXHRcdGlmICh0eXBlb2YgbiAhPT0gXCJudW1iZXJcIiB8fCBuIDwgMCB8fCBuID4gMjE0NzQ4MzY0OCkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJBIG51bWJlciBiZXR3ZWVuIDAgYW5kIDJeMzEgaXMgcmVxdWlyZWQuXCIpO1xyXG5cdFx0fVxyXG5cdFx0Ly8gRnJvbSBodHRwOi8vZ3JhcGhpY3Muc3RhbmZvcmQuZWR1L35zZWFuZGVyL2JpdGhhY2tzLmh0bWwjUm91bmRVcFBvd2VyT2YyXHJcblx0XHQtLW47XHJcblx0XHRuIHw9IG4gPj4gMTtcclxuXHRcdG4gfD0gbiA+PiAyO1xyXG5cdFx0biB8PSBuID4+IDQ7XHJcblx0XHRuIHw9IG4gPj4gODtcclxuXHRcdG4gfD0gbiA+PiAxNjtcclxuXHRcdCsrbjtcclxuXHJcblx0XHRyZXR1cm4gbjtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBwcmV2aW91c1Bvd2VyT2ZUd28objogbnVtYmVyKTogbnVtYmVyIHtcclxuXHRcdGlmICh0eXBlb2YgbiAhPT0gXCJudW1iZXJcIiB8fCBuIDwgMCB8fCBuID4gNDI5NDk2NzI5NSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJBIG51bWJlciBiZXR3ZWVuIDAgYW5kICgyXjMyKS0xIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHJcblx0XHRuIHw9IG4gPj4gMTtcclxuXHRcdG4gfD0gbiA+PiAyO1xyXG5cdFx0biB8PSBuID4+IDQ7XHJcblx0XHRuIHw9IG4gPj4gODtcclxuXHRcdG4gfD0gbiA+PiAxNjtcclxuXHRcdG4gfD0gbiA+PiAzMjtcclxuXHJcblx0XHQvLyBUaGUgcHJldmlvdXMgYml0d2lzZSBvcGVyYXRpb25zIGltcGxpY2l0bHkgY29udmVydCB0byBzaWduZWQgMzItYml0LiBVc2UgYD4+PmAgdG8gY29udmVydCB0byB1bnNpZ25lZFxyXG5cdFx0biA9IChuID4+PiAwKSAtIChuID4+PiAxKTtcclxuXHJcblx0XHRyZXR1cm4gbjtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBjbGFtcCh2YWx1ZTogbnVtYmVyLCBtaW46IG51bWJlciwgbWF4OiBudW1iZXIpOiBudW1iZXIge1xyXG5cdFx0cmV0dXJuIHZhbHVlIDwgbWluID8gbWluIDogdmFsdWUgPiBtYXggPyBtYXggOiB2YWx1ZTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBuZXh0UmFuZG9tTnVtYmVyID0gZnVuY3Rpb24gKCk6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gcmFuZG9tTnVtYmVyR2VuZXJhdG9yLnJhbmRvbSgpO1xyXG5cdH07XHJcblxyXG5cdHN0YXRpYyByYW5kb21CZXR3ZWVuID0gZnVuY3Rpb24gKG1pbjogbnVtYmVyLCBtYXg6IG51bWJlcik6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gR01hdGgubmV4dFJhbmRvbU51bWJlcigpICogKG1heCAtIG1pbikgKyBtaW47XHJcblx0fTtcclxuXHJcblx0c3RhdGljIGFjb3NDbGFtcGVkID0gZnVuY3Rpb24gKHZhbHVlOiBudW1iZXIpOiBudW1iZXIge1xyXG5cdFx0aWYgKCFkZWZpbmVkKHZhbHVlKSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJ2YWx1ZSBpcyByZXF1aXJlZC5cIik7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIE1hdGguYWNvcyhHTWF0aC5jbGFtcCh2YWx1ZSwgLTEuMCwgMS4wKSk7XHJcblx0fTtcclxuXHJcblx0c3RhdGljIGFzaW5DbGFtcGVkID0gZnVuY3Rpb24gKHZhbHVlOiBudW1iZXIpOiBudW1iZXIge1xyXG5cdFx0aWYgKCFkZWZpbmVkKHZhbHVlKSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJ2YWx1ZSBpcyByZXF1aXJlZC5cIik7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIE1hdGguYXNpbihHTWF0aC5jbGFtcCh2YWx1ZSwgLTEuMCwgMS4wKSk7XHJcblx0fTtcclxuXHJcblx0c3RhdGljIGNob3JkTGVuZ3RoID0gZnVuY3Rpb24gKGFuZ2xlOiBudW1iZXIsIHJhZGl1czogbnVtYmVyKTogbnVtYmVyIHtcclxuXHRcdGlmICghZGVmaW5lZChhbmdsZSkpIHtcclxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiYW5nbGUgaXMgcmVxdWlyZWQuXCIpO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCFkZWZpbmVkKHJhZGl1cykpIHtcclxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwicmFkaXVzIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gMi4wICogcmFkaXVzICogTWF0aC5zaW4oYW5nbGUgKiAwLjUpO1xyXG5cdH07XHJcblxyXG5cdHN0YXRpYyBsb2dCYXNlID0gZnVuY3Rpb24gKG51bWJlcjogbnVtYmVyLCBiYXNlOiBudW1iZXIpOiBudW1iZXIge1xyXG5cdFx0aWYgKCFkZWZpbmVkKG51bWJlcikpIHtcclxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwibnVtYmVyIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdGlmICghZGVmaW5lZChiYXNlKSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJiYXNlIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gTWF0aC5sb2cobnVtYmVyKSAvIE1hdGgubG9nKGJhc2UpO1xyXG5cdH07XHJcblxyXG5cdHN0YXRpYyBjYnJ0ID0gZGVmYXVsdFZhbHVlKE1hdGguY2JydCwgZnVuY3Rpb24gY2JydChudW1iZXIpIHtcclxuXHRcdGNvbnN0IHJlc3VsdCA9IE1hdGgucG93KE1hdGguYWJzKG51bWJlciksIDEuMCAvIDMuMCk7XHJcblx0XHRyZXR1cm4gbnVtYmVyIDwgMC4wID8gLXJlc3VsdCA6IHJlc3VsdDtcclxuXHR9KTtcclxuXHRzdGF0aWMgbG9nMiA9IGRlZmF1bHRWYWx1ZShNYXRoLmxvZzIsIGZ1bmN0aW9uIGxvZzIobnVtYmVyKSB7XHJcblx0XHRyZXR1cm4gTWF0aC5sb2cobnVtYmVyKSAqIE1hdGguTE9HMkU7XHJcblx0fSk7XHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0c3RhdGljIGZvZyhkaXN0YW5jZVRvQ2FtZXJhOiBudW1iZXIsIGRlbnNpdHk6IG51bWJlcik6IG51bWJlciB7XHJcblx0XHRjb25zdCBzY2FsYXIgPSBkaXN0YW5jZVRvQ2FtZXJhICogZGVuc2l0eTtcclxuXHRcdHJldHVybiAxLjAgLSBNYXRoLmV4cCgtKHNjYWxhciAqIHNjYWxhcikpO1xyXG5cdH1cclxufVxyXG5jb25zdCByYW5kb21OdW1iZXJHZW5lcmF0b3IgPSBuZXcgTWVyc2VubmVUd2lzdGVyKCk7XHJcbmNvbnN0IGZhY3RvcmlhbHMgPSBbMV07XHJcbmV4cG9ydCBkZWZhdWx0IEdNYXRoO1xyXG4iLCJpbXBvcnQgeyBBdHRyaWJ1dGUgfSBmcm9tIFwiLi4vcmVuZGVyL0F0dHJpYnV0ZVwiO1xyXG5pbXBvcnQgZGVmaW5lZCBmcm9tIFwiLi4vdXRpbHMvZGVmaW5lZFwiO1xyXG5pbXBvcnQgR01hdGggZnJvbSBcIi4vTWF0aFwiO1xyXG5pbXBvcnQgTWF0cml4MyBmcm9tIFwiLi9NYXRyaXgzXCI7XHJcbi8qKlxyXG4gKiBBIDJEIENhcnRlc2lhbiBwb2ludC5cclxuICogQGFsaWFzIFZlY3RvcjJcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBbeD0wLjBdIFRoZSBYIGNvbXBvbmVudC5cclxuICogQHBhcmFtIHtOdW1iZXJ9IFt5PTAuMF0gVGhlIFkgY29tcG9uZW50LlxyXG4gKlxyXG4gKi9cclxuY2xhc3MgVmVjdG9yMiB7XHJcblx0cHVibGljIHN0YXRpYyBaRVJPID0gT2JqZWN0LmZyZWV6ZShuZXcgVmVjdG9yMigwLjAsIDAuMCkpO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIE9ORSA9IE9iamVjdC5mcmVlemUobmV3IFZlY3RvcjIoMS4wLCAxLjApKTtcclxuXHJcblx0cHVibGljIHN0YXRpYyBVTklUX1ggPSBPYmplY3QuZnJlZXplKG5ldyBWZWN0b3IyKDEuMCwgMC4wKSk7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgVU5JVF9ZID0gT2JqZWN0LmZyZWV6ZShuZXcgVmVjdG9yMigwLjAsIDEuMCkpO1xyXG5cclxuXHRjb25zdHJ1Y3RvcihwdWJsaWMgeDogbnVtYmVyID0gMC4wLCBwdWJsaWMgeTogbnVtYmVyID0gMC4wKSB7XHJcblx0XHR0aGlzLnggPSB4O1xyXG5cdFx0dGhpcy55ID0geTtcclxuXHR9XHJcblx0c2V0KHg6IG51bWJlciwgeTogbnVtYmVyKTogVmVjdG9yMiB7XHJcblx0XHR0aGlzLnggPSB4O1xyXG5cdFx0dGhpcy55ID0geTtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHR0b0FycmF5KCkge1xyXG5cdFx0cmV0dXJuIFt0aGlzLngsIHRoaXMueV07XHJcblx0fVxyXG5cclxuXHRjbG9uZShyZXN1bHQ6IFZlY3RvcjIpOiBWZWN0b3IyIHtcclxuXHRcdHJldHVybiBWZWN0b3IyLmNsb25lKHRoaXMsIHJlc3VsdCk7XHJcblx0fVxyXG5cclxuXHRlcXVhbHMocmlnaHQ6IFZlY3RvcjIpOiBib29sZWFuIHtcclxuXHRcdHJldHVybiBWZWN0b3IyLmVxdWFscyh0aGlzLCByaWdodCk7XHJcblx0fVxyXG5cdGVxdWFsc0Vwc2lsb24ocmlnaHQ6IFZlY3RvcjIsIHJlbGF0aXZlRXBzaWxvbiA9IDAsIGFic29sdXRlRXBzaWxvbiA9IDApOiBib29sZWFuIHtcclxuXHRcdHJldHVybiBWZWN0b3IyLmVxdWFsc0Vwc2lsb24odGhpcywgcmlnaHQsIHJlbGF0aXZlRXBzaWxvbiwgYWJzb2x1dGVFcHNpbG9uKTtcclxuXHR9XHJcblxyXG5cdHRvU3RyaW5nKCkge1xyXG5cdFx0cmV0dXJuIGAoJHt0aGlzLnh9LCAke3RoaXMueX0pYDtcclxuXHR9XHJcblx0ZnJvbUJ1ZmZlckF0dHJpYnV0ZShhdHRyaWJ1dGU6IEF0dHJpYnV0ZSwgaW5kZXg6IG51bWJlcik6IFZlY3RvcjIge1xyXG5cdFx0dGhpcy54ID0gYXR0cmlidXRlLmdldFgoaW5kZXgpO1xyXG5cdFx0dGhpcy55ID0gYXR0cmlidXRlLmdldFkoaW5kZXgpO1xyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG5cdGFwcGx5TWF0cml4MyhtYXRyaXgzOiBNYXRyaXgzKTogVmVjdG9yMiB7XHJcblx0XHRjb25zdCB4ID0gdGhpcy54LFxyXG5cdFx0XHR5ID0gdGhpcy55O1xyXG5cdFx0dGhpcy54ID0gbWF0cml4M1swXSAqIHggKyBtYXRyaXgzWzNdICogeSArIG1hdHJpeDNbNl07XHJcblx0XHR0aGlzLnkgPSBtYXRyaXgzWzFdICogeCArIG1hdHJpeDNbNF0gKiB5ICsgbWF0cml4M1s3XTtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGZyb21FbGVtZW50cyh4OiBudW1iZXIsIHk6IG51bWJlciwgcmVzdWx0OiBWZWN0b3IyKTogVmVjdG9yMiB7XHJcblx0XHRpZiAoIWRlZmluZWQocmVzdWx0KSkge1xyXG5cdFx0XHRyZXR1cm4gbmV3IFZlY3RvcjIoeCwgeSk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmVzdWx0LnggPSB4O1xyXG5cdFx0cmVzdWx0LnkgPSB5O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBjbG9uZShjYXJ0ZXNpYW46IFZlY3RvcjIsIHJlc3VsdDogVmVjdG9yMik6IFZlY3RvcjIge1xyXG5cdFx0aWYgKCFkZWZpbmVkKGNhcnRlc2lhbikpIHtcclxuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJldHVybiBuZXcgVmVjdG9yMihjYXJ0ZXNpYW4ueCwgY2FydGVzaWFuLnkpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJlc3VsdC54ID0gY2FydGVzaWFuLng7XHJcblx0XHRyZXN1bHQueSA9IGNhcnRlc2lhbi55O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBtYXhpbXVtQ29tcG9uZW50KGNhcnRlc2lhbjogVmVjdG9yMik6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gTWF0aC5tYXgoY2FydGVzaWFuLngsIGNhcnRlc2lhbi55KTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBtaW5pbXVtQ29tcG9uZW50KGNhcnRlc2lhbjogVmVjdG9yMik6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gTWF0aC5taW4oY2FydGVzaWFuLngsIGNhcnRlc2lhbi55KTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBtaW5pbXVtQnlDb21wb25lbnQoZmlyc3Q6IFZlY3RvcjIsIHNlY29uZDogVmVjdG9yMiwgcmVzdWx0OiBWZWN0b3IyKTogVmVjdG9yMiB7XHJcblx0XHRyZXN1bHQueCA9IE1hdGgubWluKGZpcnN0LngsIHNlY29uZC54KTtcclxuXHRcdHJlc3VsdC55ID0gTWF0aC5taW4oZmlyc3QueSwgc2Vjb25kLnkpO1xyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbWF4aW11bUJ5Q29tcG9uZW50KGZpcnN0OiBWZWN0b3IyLCBzZWNvbmQ6IFZlY3RvcjIsIHJlc3VsdDogVmVjdG9yMik6IFZlY3RvcjIge1xyXG5cdFx0cmVzdWx0LnggPSBNYXRoLm1heChmaXJzdC54LCBzZWNvbmQueCk7XHJcblx0XHRyZXN1bHQueSA9IE1hdGgubWF4KGZpcnN0LnksIHNlY29uZC55KTtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgY2xhbXAodmFsdWU6IFZlY3RvcjIsIG1pbjogVmVjdG9yMiwgbWF4OiBWZWN0b3IyLCByZXN1bHQ6IFZlY3RvcjIpOiBWZWN0b3IyIHtcclxuXHRcdGNvbnN0IHggPSBHTWF0aC5jbGFtcCh2YWx1ZS54LCBtaW4ueCwgbWF4LngpO1xyXG5cdFx0Y29uc3QgeSA9IEdNYXRoLmNsYW1wKHZhbHVlLnksIG1pbi55LCBtYXgueSk7XHJcblxyXG5cdFx0cmVzdWx0LnggPSB4O1xyXG5cdFx0cmVzdWx0LnkgPSB5O1xyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbWFnbml0dWRlU3F1YXJlZChjYXJ0ZXNpYW46IFZlY3RvcjIpOiBudW1iZXIge1xyXG5cdFx0cmV0dXJuIGNhcnRlc2lhbi54ICogY2FydGVzaWFuLnggKyBjYXJ0ZXNpYW4ueSAqIGNhcnRlc2lhbi55O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG1hZ25pdHVkZShjYXJ0ZXNpYW46IFZlY3RvcjIpOiBudW1iZXIge1xyXG5cdFx0cmV0dXJuIE1hdGguc3FydChWZWN0b3IyLm1hZ25pdHVkZVNxdWFyZWQoY2FydGVzaWFuKSk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZGlzdGFuY2UobGVmdDogVmVjdG9yMiwgcmlnaHQ6IFZlY3RvcjIpOiBudW1iZXIge1xyXG5cdFx0VmVjdG9yMi5zdWJ0cmFjdChsZWZ0LCByaWdodCwgZGlzdGFuY2VTY3JhdGNoKTtcclxuXHRcdHJldHVybiBWZWN0b3IyLm1hZ25pdHVkZShkaXN0YW5jZVNjcmF0Y2gpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGRpc3RhbmNlU3F1YXJlZChsZWZ0OiBWZWN0b3IyLCByaWdodDogVmVjdG9yMik6IG51bWJlciB7XHJcblx0XHRWZWN0b3IyLnN1YnRyYWN0KGxlZnQsIHJpZ2h0LCBkaXN0YW5jZVNjcmF0Y2gpO1xyXG5cdFx0cmV0dXJuIFZlY3RvcjIubWFnbml0dWRlU3F1YXJlZChkaXN0YW5jZVNjcmF0Y2gpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG5vcm1hbGl6ZShjYXJ0ZXNpYW46IFZlY3RvcjIsIHJlc3VsdDogVmVjdG9yMik6IFZlY3RvcjIge1xyXG5cdFx0Y29uc3QgbWFnbml0dWRlID0gVmVjdG9yMi5tYWduaXR1ZGUoY2FydGVzaWFuKTtcclxuXHJcblx0XHRyZXN1bHQueCA9IGNhcnRlc2lhbi54IC8gbWFnbml0dWRlO1xyXG5cdFx0cmVzdWx0LnkgPSBjYXJ0ZXNpYW4ueSAvIG1hZ25pdHVkZTtcclxuXHJcblx0XHQvLyA+PmluY2x1ZGVTdGFydCgnZGVidWcnLCBwcmFnbWFzLmRlYnVnKTtcclxuXHRcdGlmIChpc05hTihyZXN1bHQueCkgfHwgaXNOYU4ocmVzdWx0LnkpKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIm5vcm1hbGl6ZWQgcmVzdWx0IGlzIG5vdCBhIG51bWJlclwiKTtcclxuXHRcdH1cclxuXHRcdC8vID4+aW5jbHVkZUVuZCgnZGVidWcnKTtcclxuXHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGRvdChsZWZ0OiBWZWN0b3IyLCByaWdodDogVmVjdG9yMik6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gbGVmdC54ICogcmlnaHQueCArIGxlZnQueSAqIHJpZ2h0Lnk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgY3Jvc3MobGVmdDogVmVjdG9yMiwgcmlnaHQ6IFZlY3RvcjIpOiBudW1iZXIge1xyXG5cdFx0cmV0dXJuIGxlZnQueCAqIHJpZ2h0LnkgLSBsZWZ0LnkgKiByaWdodC54O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG11bHRpcGx5Q29tcG9uZW50cyhsZWZ0OiBWZWN0b3IyLCByaWdodDogVmVjdG9yMiwgcmVzdWx0OiBWZWN0b3IyKTogVmVjdG9yMiB7XHJcblx0XHRyZXN1bHQueCA9IGxlZnQueCAqIHJpZ2h0Lng7XHJcblx0XHRyZXN1bHQueSA9IGxlZnQueSAqIHJpZ2h0Lnk7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGRpdmlkZUNvbXBvbmVudHMobGVmdDogVmVjdG9yMiwgcmlnaHQ6IFZlY3RvcjIsIHJlc3VsdDogVmVjdG9yMik6IFZlY3RvcjIge1xyXG5cdFx0cmVzdWx0LnggPSBsZWZ0LnggLyByaWdodC54O1xyXG5cdFx0cmVzdWx0LnkgPSBsZWZ0LnkgLyByaWdodC55O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBhZGQobGVmdDogVmVjdG9yMiwgcmlnaHQ6IFZlY3RvcjIsIHJlc3VsdDogVmVjdG9yMik6IFZlY3RvcjIge1xyXG5cdFx0cmVzdWx0LnggPSBsZWZ0LnggKyByaWdodC54O1xyXG5cdFx0cmVzdWx0LnkgPSBsZWZ0LnkgKyByaWdodC55O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBzdWJ0cmFjdChsZWZ0OiBWZWN0b3IyLCByaWdodDogVmVjdG9yMiwgcmVzdWx0OiBWZWN0b3IyKTogVmVjdG9yMiB7XHJcblx0XHRyZXN1bHQueCA9IGxlZnQueCAtIHJpZ2h0Lng7XHJcblx0XHRyZXN1bHQueSA9IGxlZnQueSAtIHJpZ2h0Lnk7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG11bHRpcGx5QnlTY2FsYXIoY2FydGVzaWFuOiBWZWN0b3IyLCBzY2FsYXI6IG51bWJlciwgcmVzdWx0OiBWZWN0b3IyKTogVmVjdG9yMiB7XHJcblx0XHRyZXN1bHQueCA9IGNhcnRlc2lhbi54ICogc2NhbGFyO1xyXG5cdFx0cmVzdWx0LnkgPSBjYXJ0ZXNpYW4ueSAqIHNjYWxhcjtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZGl2aWRlQnlTY2FsYXIoY2FydGVzaWFuOiBWZWN0b3IyLCBzY2FsYXI6IG51bWJlciwgcmVzdWx0OiBWZWN0b3IyKTogVmVjdG9yMiB7XHJcblx0XHRyZXN1bHQueCA9IGNhcnRlc2lhbi54IC8gc2NhbGFyO1xyXG5cdFx0cmVzdWx0LnkgPSBjYXJ0ZXNpYW4ueSAvIHNjYWxhcjtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbmVnYXRlKGNhcnRlc2lhbjogVmVjdG9yMiwgcmVzdWx0OiBWZWN0b3IyKTogVmVjdG9yMiB7XHJcblx0XHRyZXN1bHQueCA9IC1jYXJ0ZXNpYW4ueDtcclxuXHRcdHJlc3VsdC55ID0gLWNhcnRlc2lhbi55O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBhYnMoY2FydGVzaWFuOiBWZWN0b3IyLCByZXN1bHQ6IFZlY3RvcjIpOiBWZWN0b3IyIHtcclxuXHRcdHJlc3VsdC54ID0gTWF0aC5hYnMoY2FydGVzaWFuLngpO1xyXG5cdFx0cmVzdWx0LnkgPSBNYXRoLmFicyhjYXJ0ZXNpYW4ueSk7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGxlcnAoc3RhcnQ6IFZlY3RvcjIsIGVuZDogVmVjdG9yMiwgdDogbnVtYmVyLCByZXN1bHQ6IFZlY3RvcjIpOiBWZWN0b3IyIHtcclxuXHRcdFZlY3RvcjIubXVsdGlwbHlCeVNjYWxhcihlbmQsIHQsIGxlcnBTY3JhdGNoKTtcclxuXHRcdHJlc3VsdCA9IFZlY3RvcjIubXVsdGlwbHlCeVNjYWxhcihzdGFydCwgMS4wIC0gdCwgcmVzdWx0KTtcclxuXHRcdHJldHVybiBWZWN0b3IyLmFkZChsZXJwU2NyYXRjaCwgcmVzdWx0LCByZXN1bHQpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGFuZ2xlQmV0d2VlbihsZWZ0OiBWZWN0b3IyLCByaWdodDogVmVjdG9yMik6IG51bWJlciB7XHJcblx0XHRWZWN0b3IyLm5vcm1hbGl6ZShsZWZ0LCBhbmdsZUJldHdlZW5TY3JhdGNoKTtcclxuXHRcdFZlY3RvcjIubm9ybWFsaXplKHJpZ2h0LCBhbmdsZUJldHdlZW5TY3JhdGNoMik7XHJcblx0XHRyZXR1cm4gR01hdGguYWNvc0NsYW1wZWQoVmVjdG9yMi5kb3QoYW5nbGVCZXR3ZWVuU2NyYXRjaCwgYW5nbGVCZXR3ZWVuU2NyYXRjaDIpKTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBtb3N0T3J0aG9nb25hbEF4aXMoY2FydGVzaWFuOiBWZWN0b3IyLCByZXN1bHQ6IFZlY3RvcjIpOiBWZWN0b3IyIHtcclxuXHRcdGNvbnN0IGYgPSBWZWN0b3IyLm5vcm1hbGl6ZShjYXJ0ZXNpYW4sIG1vc3RPcnRob2dvbmFsQXhpc1NjcmF0Y2gpO1xyXG5cdFx0VmVjdG9yMi5hYnMoZiwgZik7XHJcblxyXG5cdFx0aWYgKGYueCA8PSBmLnkpIHtcclxuXHRcdFx0cmVzdWx0ID0gVmVjdG9yMi5jbG9uZShWZWN0b3IyLlVOSVRfWCwgcmVzdWx0KTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHJlc3VsdCA9IFZlY3RvcjIuY2xvbmUoVmVjdG9yMi5VTklUX1ksIHJlc3VsdCk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBlcXVhbHMobGVmdDogVmVjdG9yMiwgcmlnaHQ6IFZlY3RvcjIpOiBib29sZWFuIHtcclxuXHRcdHJldHVybiBsZWZ0ID09PSByaWdodCB8fCAoZGVmaW5lZChsZWZ0KSAmJiBkZWZpbmVkKHJpZ2h0KSAmJiBsZWZ0LnggPT09IHJpZ2h0LnggJiYgbGVmdC55ID09PSByaWdodC55KTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0c3RhdGljIGVxdWFsc0FycmF5KGNhcnRlc2lhbjogVmVjdG9yMiwgYXJyYXk6IG51bWJlcltdLCBvZmZzZXQ6IG51bWJlcik6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIGNhcnRlc2lhbi54ID09PSBhcnJheVtvZmZzZXRdICYmIGNhcnRlc2lhbi55ID09PSBhcnJheVtvZmZzZXQgKyAxXTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBlcXVhbHNFcHNpbG9uKGxlZnQ6IFZlY3RvcjIsIHJpZ2h0OiBWZWN0b3IyLCByZWxhdGl2ZUVwc2lsb24gPSAwLCBhYnNvbHV0ZUVwc2lsb24gPSAwKTogYm9vbGVhbiB7XHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHRsZWZ0ID09PSByaWdodCB8fFxyXG5cdFx0XHQoZGVmaW5lZChsZWZ0KSAmJlxyXG5cdFx0XHRcdGRlZmluZWQocmlnaHQpICYmXHJcblx0XHRcdFx0R01hdGguZXF1YWxzRXBzaWxvbihsZWZ0LngsIHJpZ2h0LngsIHJlbGF0aXZlRXBzaWxvbiwgYWJzb2x1dGVFcHNpbG9uKSAmJlxyXG5cdFx0XHRcdEdNYXRoLmVxdWFsc0Vwc2lsb24obGVmdC55LCByaWdodC55LCByZWxhdGl2ZUVwc2lsb24sIGFic29sdXRlRXBzaWxvbikpXHJcblx0XHQpO1xyXG5cdH1cclxufVxyXG5jb25zdCBkaXN0YW5jZVNjcmF0Y2ggPSBuZXcgVmVjdG9yMigpO1xyXG5jb25zdCBsZXJwU2NyYXRjaCA9IG5ldyBWZWN0b3IyKCk7XHJcbmNvbnN0IGFuZ2xlQmV0d2VlblNjcmF0Y2ggPSBuZXcgVmVjdG9yMigpO1xyXG5jb25zdCBhbmdsZUJldHdlZW5TY3JhdGNoMiA9IG5ldyBWZWN0b3IyKCk7XHJcbmNvbnN0IG1vc3RPcnRob2dvbmFsQXhpc1NjcmF0Y2ggPSBuZXcgVmVjdG9yMigpO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgVmVjdG9yMjtcclxuIiwiaW1wb3J0IHsgQXR0cmlidXRlIH0gZnJvbSBcIi4uL3JlbmRlci9BdHRyaWJ1dGVcIjtcclxuaW1wb3J0IGRlZmluZWQgZnJvbSBcIi4uL3V0aWxzL2RlZmluZWRcIjtcclxuaW1wb3J0IEdNYXRoIGZyb20gXCIuL01hdGhcIjtcclxuaW1wb3J0IE1hdHJpeDMgZnJvbSBcIi4vTWF0cml4M1wiO1xyXG5pbXBvcnQgTWF0cml4NCBmcm9tIFwiLi9NYXRyaXg0XCI7XHJcbmltcG9ydCB7IFF1YXRlcm5pb24gfSBmcm9tIFwiLi9RdWF0ZXJuaW9uXCI7XHJcbmltcG9ydCB7IFNwaGVyaWNhbCB9IGZyb20gXCIuL1NwaGVyaWNhbFwiO1xyXG5pbXBvcnQgVmVjdG9yNCBmcm9tIFwiLi9WZWN0b3I0XCI7XHJcbmNsYXNzIFZlY3RvcjMge1xyXG5cdHB1YmxpYyBzdGF0aWMgWkVSTyA9IE9iamVjdC5mcmVlemUobmV3IFZlY3RvcjMoMC4wLCAwLjAsIDAuMCkpO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIE9ORSA9IE9iamVjdC5mcmVlemUobmV3IFZlY3RvcjMoMS4wLCAxLjAsIDEuMCkpO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIFVOSVRfWCA9IE9iamVjdC5mcmVlemUobmV3IFZlY3RvcjMoMS4wLCAwLjAsIDAuMCkpO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIFVOSVRfWSA9IE9iamVjdC5mcmVlemUobmV3IFZlY3RvcjMoMC4wLCAxLjAsIDAuMCkpO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIFVOSVRfWiA9IE9iamVjdC5mcmVlemUobmV3IFZlY3RvcjMoMC4wLCAwLjAsIDEuMCkpO1xyXG5cdHg6IG51bWJlcjtcclxuXHR5OiBudW1iZXI7XHJcblx0ejogbnVtYmVyO1xyXG5cclxuXHRjb25zdHJ1Y3Rvcih4ID0gMCwgeSA9IDAsIHogPSAwKSB7XHJcblx0XHR0aGlzLnggPSB4O1xyXG5cdFx0dGhpcy55ID0geTtcclxuXHRcdHRoaXMueiA9IHo7XHJcblx0fVxyXG5cdHNldCh4OiBudW1iZXIsIHk6IG51bWJlciwgejogbnVtYmVyKTogVmVjdG9yMyB7XHJcblx0XHR0aGlzLnggPSB4O1xyXG5cdFx0dGhpcy55ID0geTtcclxuXHRcdHRoaXMueiA9IHo7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0dG9BcnJheSgpOiBudW1iZXJbXSB7XHJcblx0XHRyZXR1cm4gW3RoaXMueCwgdGhpcy55LCB0aGlzLnpdO1xyXG5cdH1cclxuXHJcblx0Y29weSh2OiBWZWN0b3IzKTogVmVjdG9yMyB7XHJcblx0XHR0aGlzLnggPSB2Lng7XHJcblx0XHR0aGlzLnkgPSB2Lnk7XHJcblx0XHR0aGlzLnogPSB2Lno7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0bGVycChlbmQ6IFZlY3RvcjMsIHQ6IG51bWJlcik6IFZlY3RvcjMge1xyXG5cdFx0VmVjdG9yMy5sZXJwKHRoaXMsIGVuZCwgdCwgdGhpcyk7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0YWRkKHY6IFZlY3RvcjMpOiBWZWN0b3IzIHtcclxuXHRcdFZlY3RvcjMuYWRkKHRoaXMsIHYsIHRoaXMpO1xyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG5cdGFkZFNjYWxlZFZlY3Rvcih2OiBWZWN0b3IzLCBzOiBudW1iZXIpOiBWZWN0b3IzIHtcclxuXHRcdHRoaXMueCArPSB2LnggKiBzO1xyXG5cdFx0dGhpcy55ICs9IHYueSAqIHM7XHJcblx0XHR0aGlzLnogKz0gdi56ICogcztcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHRzdWJ0cmFjdCh2OiBWZWN0b3IzKTogVmVjdG9yMyB7XHJcblx0XHRWZWN0b3IzLnN1YnRyYWN0KHRoaXMsIHYsIHRoaXMpO1xyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG5cdGFwcGx5UXVhdGVybmlvbihxOiBRdWF0ZXJuaW9uKTogVmVjdG9yMyB7XHJcblx0XHRjb25zdCB4ID0gdGhpcy54LFxyXG5cdFx0XHR5ID0gdGhpcy55LFxyXG5cdFx0XHR6ID0gdGhpcy56O1xyXG5cdFx0Y29uc3QgcXggPSBxLngsXHJcblx0XHRcdHF5ID0gcS55LFxyXG5cdFx0XHRxeiA9IHEueixcclxuXHRcdFx0cXcgPSBxLnc7XHJcblxyXG5cdFx0Ly8gY2FsY3VsYXRlIHF1YXQgKiB2ZWN0b3JcclxuXHJcblx0XHRjb25zdCBpeCA9IHF3ICogeCArIHF5ICogeiAtIHF6ICogeTtcclxuXHRcdGNvbnN0IGl5ID0gcXcgKiB5ICsgcXogKiB4IC0gcXggKiB6O1xyXG5cdFx0Y29uc3QgaXogPSBxdyAqIHogKyBxeCAqIHkgLSBxeSAqIHg7XHJcblx0XHRjb25zdCBpdyA9IC1xeCAqIHggLSBxeSAqIHkgLSBxeiAqIHo7XHJcblxyXG5cdFx0Ly8gY2FsY3VsYXRlIHJlc3VsdCAqIGludmVyc2UgcXVhdFxyXG5cclxuXHRcdHRoaXMueCA9IGl4ICogcXcgKyBpdyAqIC1xeCArIGl5ICogLXF6IC0gaXogKiAtcXk7XHJcblx0XHR0aGlzLnkgPSBpeSAqIHF3ICsgaXcgKiAtcXkgKyBpeiAqIC1xeCAtIGl4ICogLXF6O1xyXG5cdFx0dGhpcy56ID0gaXogKiBxdyArIGl3ICogLXF6ICsgaXggKiAtcXkgLSBpeSAqIC1xeDtcclxuXHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0c2V0RnJvbU1hdHJpeENvbHVtbihtOiBNYXRyaXgzIHwgTWF0cml4NCwgaW5kZXg6IG51bWJlcik6IFZlY3RvcjMge1xyXG5cdFx0cmV0dXJuIHRoaXMuZnJvbUFycmF5KG0sIGluZGV4ICogNCk7XHJcblx0fVxyXG5cdGZyb21BcnJheShhcnJheTogTWF0cml4MyB8IE1hdHJpeDQsIG9mZnNldCA9IDApOiBWZWN0b3IzIHtcclxuXHRcdHRoaXMueCA9IGFycmF5W29mZnNldF07XHJcblx0XHR0aGlzLnkgPSBhcnJheVtvZmZzZXQgKyAxXTtcclxuXHRcdHRoaXMueiA9IGFycmF5W29mZnNldCArIDJdO1xyXG5cclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHJcblx0bXVsdGlwbHlCeVNjYWxhcihzY2FsZTogbnVtYmVyKTogVmVjdG9yMyB7XHJcblx0XHRWZWN0b3IzLm11bHRpcGx5QnlTY2FsYXIodGhpcywgc2NhbGUsIHRoaXMpO1xyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG5cclxuXHRjbG9uZSgpOiBWZWN0b3IzIHtcclxuXHRcdHJldHVybiBWZWN0b3IzLmNsb25lKHRoaXMsIG5ldyBWZWN0b3IzKCkpO1xyXG5cdH1cclxuXHRsZW5ndGgoKTogbnVtYmVyIHtcclxuXHRcdHJldHVybiBNYXRoLnNxcnQodGhpcy54ICogdGhpcy54ICsgdGhpcy55ICogdGhpcy55ICsgdGhpcy56ICogdGhpcy56KTtcclxuXHR9XHJcblx0YXBwbHlNYXRyaXg0KG1hdHJpeDogTWF0cml4NCk6IFZlY3RvcjMge1xyXG5cdFx0Y29uc3QgeCA9IHRoaXMueCxcclxuXHRcdFx0eSA9IHRoaXMueSxcclxuXHRcdFx0eiA9IHRoaXMuejtcclxuXHRcdGNvbnN0IGUgPSBtYXRyaXg7XHJcblx0XHRjb25zdCB3ID0gMSAvIChlWzNdICogeCArIGVbN10gKiB5ICsgZVsxMV0gKiB6ICsgZVsxNV0pO1xyXG5cdFx0dGhpcy54ID0gKGVbMF0gKiB4ICsgZVs0XSAqIHkgKyBlWzhdICogeiArIGVbMTJdKSAqIHc7XHJcblx0XHR0aGlzLnkgPSAoZVsxXSAqIHggKyBlWzVdICogeSArIGVbOV0gKiB6ICsgZVsxM10pICogdztcclxuXHRcdHRoaXMueiA9IChlWzJdICogeCArIGVbNl0gKiB5ICsgZVsxMF0gKiB6ICsgZVsxNF0pICogdztcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHRhcHBseU1hdHJpeDMobWF0cml4OiBNYXRyaXgzKTogVmVjdG9yMyB7XHJcblx0XHRjb25zdCB4ID0gdGhpcy54LFxyXG5cdFx0XHR5ID0gdGhpcy55LFxyXG5cdFx0XHR6ID0gdGhpcy56O1xyXG5cdFx0dGhpcy54ID0geCAqIG1hdHJpeFswXSArIHkgKiBtYXRyaXhbM10gKyB6ICogbWF0cml4WzZdO1xyXG5cdFx0dGhpcy55ID0geCAqIG1hdHJpeFsxXSArIHkgKiBtYXRyaXhbNF0gKyB6ICogbWF0cml4WzddO1xyXG5cdFx0dGhpcy56ID0geCAqIG1hdHJpeFsyXSArIHkgKiBtYXRyaXhbNV0gKyB6ICogbWF0cml4WzhdO1xyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG5cdHRyYW5zZm9ybURpcmVjdGlvbihtYXRyaXg6IE1hdHJpeDMgfCBNYXRyaXg0KTogVmVjdG9yMyB7XHJcblx0XHRjb25zdCB4ID0gdGhpcy54LFxyXG5cdFx0XHR5ID0gdGhpcy55LFxyXG5cdFx0XHR6ID0gdGhpcy56O1xyXG5cdFx0Y29uc3QgZSA9IG1hdHJpeDtcclxuXHRcdHRoaXMueCA9IGVbMF0gKiB4ICsgZVs0XSAqIHkgKyBlWzhdICogejtcclxuXHRcdHRoaXMueSA9IGVbMV0gKiB4ICsgZVs1XSAqIHkgKyBlWzldICogejtcclxuXHRcdHRoaXMueiA9IGVbMl0gKiB4ICsgZVs2XSAqIHkgKyBlWzEwXSAqIHo7XHJcblx0XHRyZXR1cm4gdGhpcy5ub3JtYWxpemUoKTtcclxuXHR9XHJcblxyXG5cdHNldEZyb21NYXRyaXhQb3NpdGlvbihtYXRyaXg6IE1hdHJpeDQpIHtcclxuXHRcdGNvbnN0IGUgPSBtYXRyaXg7XHJcblxyXG5cdFx0dGhpcy54ID0gZVsxMl07XHJcblx0XHR0aGlzLnkgPSBlWzEzXTtcclxuXHRcdHRoaXMueiA9IGVbMTRdO1xyXG5cclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHJcblx0bm9ybWFsaXplKCk6IFZlY3RvcjMge1xyXG5cdFx0VmVjdG9yMy5ub3JtYWxpemUodGhpcywgdGhpcyk7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblxyXG5cdGVxdWFscyhyaWdodDogVmVjdG9yMyk6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIFZlY3RvcjMuZXF1YWxzKHRoaXMsIHJpZ2h0KTtcclxuXHR9XHJcblxyXG5cdGVxdWFsc0Vwc2lsb24ocmlnaHQ6IFZlY3RvcjMsIHJlbGF0aXZlRXBzaWxvbiA9IDAsIGFic29sdXRlRXBzaWxvbiA9IDApOiBib29sZWFuIHtcclxuXHRcdHJldHVybiBWZWN0b3IzLmVxdWFsc0Vwc2lsb24odGhpcywgcmlnaHQsIHJlbGF0aXZlRXBzaWxvbiwgYWJzb2x1dGVFcHNpbG9uKTtcclxuXHR9XHJcblxyXG5cdHRvU3RyaW5nKCkge1xyXG5cdFx0cmV0dXJuIGAoJHt0aGlzLnh9LCAke3RoaXMueX0sICR7dGhpcy56fSlgO1xyXG5cdH1cclxuXHRmcm9tQnVmZmVyQXR0cmlidXRlKGF0dHJpYnV0ZTogQXR0cmlidXRlLCBpbmRleDogbnVtYmVyKTogVmVjdG9yMyB7XHJcblx0XHR0aGlzLnggPSBhdHRyaWJ1dGUuZ2V0WChpbmRleCk7XHJcblx0XHR0aGlzLnkgPSBhdHRyaWJ1dGUuZ2V0WShpbmRleCk7XHJcblx0XHR0aGlzLnogPSBhdHRyaWJ1dGUuZ2V0WihpbmRleCk7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0c3RhdGljIGZyb21WZWN0b3I0KHZlYzQ6IFZlY3RvcjQsIHJlc3VsdDogVmVjdG9yMyk6IFZlY3RvcjMge1xyXG5cdFx0cmVzdWx0LnggPSB2ZWM0Lng7XHJcblx0XHRyZXN1bHQueSA9IHZlYzQueTtcclxuXHRcdHJlc3VsdC56ID0gdmVjNC56O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBmcm9tU3BoZXJpY2FsKHNwaGVyaWNhbDogU3BoZXJpY2FsLCByZXN1bHQ6IFZlY3RvcjMpOiBWZWN0b3IzIHtcclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJlc3VsdCA9IG5ldyBWZWN0b3IzKCk7XHJcblx0XHR9XHJcblx0XHRjb25zdCB7IHBoaSwgcmFkaXVzLCB0aGV0YSB9ID0gc3BoZXJpY2FsO1xyXG5cdFx0Y29uc3Qgc2luUGhpUmFkaXVzID0gTWF0aC5zaW4ocGhpKSAqIHJhZGl1cztcclxuXHRcdHJlc3VsdC54ID0gc2luUGhpUmFkaXVzICogTWF0aC5zaW4odGhldGEpO1xyXG5cdFx0cmVzdWx0LnkgPSBNYXRoLmNvcyhwaGkpICogcmFkaXVzO1xyXG5cdFx0cmVzdWx0LnogPSBzaW5QaGlSYWRpdXMgKiBNYXRoLmNvcyh0aGV0YSk7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGZyb21FbGVtZW50cyh4OiBudW1iZXIsIHk6IG51bWJlciwgejogbnVtYmVyLCByZXN1bHQ6IFZlY3RvcjMpOiBWZWN0b3IzIHtcclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJldHVybiBuZXcgVmVjdG9yMyh4LCB5LCB6KTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXN1bHQueCA9IHg7XHJcblx0XHRyZXN1bHQueSA9IHk7XHJcblx0XHRyZXN1bHQueiA9IHo7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGNsb25lKGNhcnRlc2lhbjogVmVjdG9yMywgcmVzdWx0OiBWZWN0b3IzID0gbmV3IFZlY3RvcjMoKSk6IFZlY3RvcjMge1xyXG5cdFx0aWYgKCFkZWZpbmVkKGNhcnRlc2lhbikpIHtcclxuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJldHVybiBuZXcgVmVjdG9yMyhjYXJ0ZXNpYW4ueCwgY2FydGVzaWFuLnksIGNhcnRlc2lhbi56KTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXN1bHQueCA9IGNhcnRlc2lhbi54O1xyXG5cdFx0cmVzdWx0LnkgPSBjYXJ0ZXNpYW4ueTtcclxuXHRcdHJlc3VsdC56ID0gY2FydGVzaWFuLno7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG1heGltdW1Db21wb25lbnQoY2FydGVzaWFuOiBWZWN0b3IzKTogbnVtYmVyIHtcclxuXHRcdHJldHVybiBNYXRoLm1heChjYXJ0ZXNpYW4ueCwgY2FydGVzaWFuLnksIGNhcnRlc2lhbi56KTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBtaW5pbXVtQ29tcG9uZW50KGNhcnRlc2lhbjogVmVjdG9yMyk6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gTWF0aC5taW4oY2FydGVzaWFuLngsIGNhcnRlc2lhbi55LCBjYXJ0ZXNpYW4ueik7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbWluaW11bUJ5Q29tcG9uZW50KGZpcnN0OiBWZWN0b3IzLCBzZWNvbmQ6IFZlY3RvcjMsIHJlc3VsdDogVmVjdG9yMyk6IFZlY3RvcjMge1xyXG5cdFx0cmVzdWx0LnggPSBNYXRoLm1pbihmaXJzdC54LCBzZWNvbmQueCk7XHJcblx0XHRyZXN1bHQueSA9IE1hdGgubWluKGZpcnN0LnksIHNlY29uZC55KTtcclxuXHRcdHJlc3VsdC56ID0gTWF0aC5taW4oZmlyc3Queiwgc2Vjb25kLnopO1xyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbWF4aW11bUJ5Q29tcG9uZW50KGZpcnN0OiBWZWN0b3IzLCBzZWNvbmQ6IFZlY3RvcjMsIHJlc3VsdDogVmVjdG9yMyk6IFZlY3RvcjMge1xyXG5cdFx0cmVzdWx0LnggPSBNYXRoLm1heChmaXJzdC54LCBzZWNvbmQueCk7XHJcblx0XHRyZXN1bHQueSA9IE1hdGgubWF4KGZpcnN0LnksIHNlY29uZC55KTtcclxuXHRcdHJlc3VsdC56ID0gTWF0aC5tYXgoZmlyc3Queiwgc2Vjb25kLnopO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBjbGFtcCh2YWx1ZTogVmVjdG9yMywgbWluOiBWZWN0b3IzLCBtYXg6IFZlY3RvcjMsIHJlc3VsdDogVmVjdG9yMyk6IFZlY3RvcjMge1xyXG5cdFx0Y29uc3QgeCA9IEdNYXRoLmNsYW1wKHZhbHVlLngsIG1pbi54LCBtYXgueCk7XHJcblx0XHRjb25zdCB5ID0gR01hdGguY2xhbXAodmFsdWUueSwgbWluLnksIG1heC55KTtcclxuXHRcdGNvbnN0IHogPSBHTWF0aC5jbGFtcCh2YWx1ZS56LCBtaW4ueiwgbWF4LnopO1xyXG5cclxuXHRcdHJlc3VsdC54ID0geDtcclxuXHRcdHJlc3VsdC55ID0geTtcclxuXHRcdHJlc3VsdC56ID0gejtcclxuXHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG1hZ25pdHVkZVNxdWFyZWQoY2FydGVzaWFuOiBWZWN0b3IzKTogbnVtYmVyIHtcclxuXHRcdHJldHVybiBjYXJ0ZXNpYW4ueCAqIGNhcnRlc2lhbi54ICsgY2FydGVzaWFuLnkgKiBjYXJ0ZXNpYW4ueSArIGNhcnRlc2lhbi56ICogY2FydGVzaWFuLno7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbWFnbml0dWRlKGNhcnRlc2lhbjogVmVjdG9yMyk6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gTWF0aC5zcXJ0KFZlY3RvcjMubWFnbml0dWRlU3F1YXJlZChjYXJ0ZXNpYW4pKTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBkaXN0YW5jZShsZWZ0OiBWZWN0b3IzLCByaWdodDogVmVjdG9yMyk6IG51bWJlciB7XHJcblx0XHRWZWN0b3IzLnN1YnRyYWN0KGxlZnQsIHJpZ2h0LCBkaXN0YW5jZVNjcmF0Y2gpO1xyXG5cdFx0cmV0dXJuIFZlY3RvcjMubWFnbml0dWRlKGRpc3RhbmNlU2NyYXRjaCk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZGlzdGFuY2VTcXVhcmVkKGxlZnQ6IFZlY3RvcjMsIHJpZ2h0OiBWZWN0b3IzKTogbnVtYmVyIHtcclxuXHRcdFZlY3RvcjMuc3VidHJhY3QobGVmdCwgcmlnaHQsIGRpc3RhbmNlU2NyYXRjaCk7XHJcblx0XHRyZXR1cm4gVmVjdG9yMy5tYWduaXR1ZGVTcXVhcmVkKGRpc3RhbmNlU2NyYXRjaCk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbm9ybWFsaXplKGNhcnRlc2lhbjogVmVjdG9yMywgcmVzdWx0OiBWZWN0b3IzKTogVmVjdG9yMyB7XHJcblx0XHRjb25zdCBtYWduaXR1ZGUgPSBWZWN0b3IzLm1hZ25pdHVkZShjYXJ0ZXNpYW4pO1xyXG5cclxuXHRcdHJlc3VsdC54ID0gY2FydGVzaWFuLnggLyBtYWduaXR1ZGU7XHJcblx0XHRyZXN1bHQueSA9IGNhcnRlc2lhbi55IC8gbWFnbml0dWRlO1xyXG5cdFx0cmVzdWx0LnogPSBjYXJ0ZXNpYW4ueiAvIG1hZ25pdHVkZTtcclxuXHJcblx0XHRpZiAoaXNOYU4ocmVzdWx0LngpIHx8IGlzTmFOKHJlc3VsdC55KSB8fCBpc05hTihyZXN1bHQueikpIHtcclxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwibm9ybWFsaXplZCByZXN1bHQgaXMgbm90IGEgbnVtYmVyXCIpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZG90KGxlZnQ6IFZlY3RvcjMsIHJpZ2h0OiBWZWN0b3IzKTogbnVtYmVyIHtcclxuXHRcdHJldHVybiBsZWZ0LnggKiByaWdodC54ICsgbGVmdC55ICogcmlnaHQueSArIGxlZnQueiAqIHJpZ2h0Lno7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbXVsdGlwbHlDb21wb25lbnRzKGxlZnQ6IFZlY3RvcjMsIHJpZ2h0OiBWZWN0b3IzLCByZXN1bHQ6IFZlY3RvcjMpOiBWZWN0b3IzIHtcclxuXHRcdHJlc3VsdC54ID0gbGVmdC54ICogcmlnaHQueDtcclxuXHRcdHJlc3VsdC55ID0gbGVmdC55ICogcmlnaHQueTtcclxuXHRcdHJlc3VsdC56ID0gbGVmdC56ICogcmlnaHQuejtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZGl2aWRlQ29tcG9uZW50cyhsZWZ0OiBWZWN0b3IzLCByaWdodDogVmVjdG9yMywgcmVzdWx0OiBWZWN0b3IzKSB7XHJcblx0XHRyZXN1bHQueCA9IGxlZnQueCAvIHJpZ2h0Lng7XHJcblx0XHRyZXN1bHQueSA9IGxlZnQueSAvIHJpZ2h0Lnk7XHJcblx0XHRyZXN1bHQueiA9IGxlZnQueiAvIHJpZ2h0Lno7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGFkZChsZWZ0OiBWZWN0b3IzLCByaWdodDogVmVjdG9yMywgcmVzdWx0OiBWZWN0b3IzKTogVmVjdG9yMyB7XHJcblx0XHRyZXN1bHQueCA9IGxlZnQueCArIHJpZ2h0Lng7XHJcblx0XHRyZXN1bHQueSA9IGxlZnQueSArIHJpZ2h0Lnk7XHJcblx0XHRyZXN1bHQueiA9IGxlZnQueiArIHJpZ2h0Lno7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIHN1YnRyYWN0KGxlZnQ6IFZlY3RvcjMsIHJpZ2h0OiBWZWN0b3IzLCByZXN1bHQ6IFZlY3RvcjMpOiBWZWN0b3IzIHtcclxuXHRcdHJlc3VsdC54ID0gbGVmdC54IC0gcmlnaHQueDtcclxuXHRcdHJlc3VsdC55ID0gbGVmdC55IC0gcmlnaHQueTtcclxuXHRcdHJlc3VsdC56ID0gbGVmdC56IC0gcmlnaHQuejtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbXVsdGlwbHlCeVNjYWxhcihjYXJ0ZXNpYW46IFZlY3RvcjMsIHNjYWxhcjogbnVtYmVyLCByZXN1bHQ6IFZlY3RvcjMpOiBWZWN0b3IzIHtcclxuXHRcdHJlc3VsdC54ID0gY2FydGVzaWFuLnggKiBzY2FsYXI7XHJcblx0XHRyZXN1bHQueSA9IGNhcnRlc2lhbi55ICogc2NhbGFyO1xyXG5cdFx0cmVzdWx0LnogPSBjYXJ0ZXNpYW4ueiAqIHNjYWxhcjtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZGl2aWRlQnlTY2FsYXIoY2FydGVzaWFuOiBWZWN0b3IzLCBzY2FsYXI6IG51bWJlciwgcmVzdWx0OiBWZWN0b3IzKTogVmVjdG9yMyB7XHJcblx0XHRyZXN1bHQueCA9IGNhcnRlc2lhbi54IC8gc2NhbGFyO1xyXG5cdFx0cmVzdWx0LnkgPSBjYXJ0ZXNpYW4ueSAvIHNjYWxhcjtcclxuXHRcdHJlc3VsdC56ID0gY2FydGVzaWFuLnogLyBzY2FsYXI7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG5lZ2F0ZShjYXJ0ZXNpYW46IFZlY3RvcjMsIHJlc3VsdDogVmVjdG9yMyk6IFZlY3RvcjMge1xyXG5cdFx0cmVzdWx0LnggPSAtY2FydGVzaWFuLng7XHJcblx0XHRyZXN1bHQueSA9IC1jYXJ0ZXNpYW4ueTtcclxuXHRcdHJlc3VsdC56ID0gLWNhcnRlc2lhbi56O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBhYnMoY2FydGVzaWFuOiBWZWN0b3IzLCByZXN1bHQ6IFZlY3RvcjMpOiBWZWN0b3IzIHtcclxuXHRcdHJlc3VsdC54ID0gTWF0aC5hYnMoY2FydGVzaWFuLngpO1xyXG5cdFx0cmVzdWx0LnkgPSBNYXRoLmFicyhjYXJ0ZXNpYW4ueSk7XHJcblx0XHRyZXN1bHQueiA9IE1hdGguYWJzKGNhcnRlc2lhbi56KTtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbGVycChzdGFydDogVmVjdG9yMywgZW5kOiBWZWN0b3IzLCB0OiBudW1iZXIsIHJlc3VsdDogVmVjdG9yMyk6IFZlY3RvcjMge1xyXG5cdFx0VmVjdG9yMy5tdWx0aXBseUJ5U2NhbGFyKGVuZCwgdCwgbGVycFNjcmF0Y2gpO1xyXG5cdFx0cmVzdWx0ID0gVmVjdG9yMy5tdWx0aXBseUJ5U2NhbGFyKHN0YXJ0LCAxLjAgLSB0LCByZXN1bHQpO1xyXG5cdFx0cmV0dXJuIFZlY3RvcjMuYWRkKGxlcnBTY3JhdGNoLCByZXN1bHQsIHJlc3VsdCk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgYW5nbGVCZXR3ZWVuKGxlZnQ6IFZlY3RvcjMsIHJpZ2h0OiBWZWN0b3IzKTogbnVtYmVyIHtcclxuXHRcdFZlY3RvcjMubm9ybWFsaXplKGxlZnQsIGFuZ2xlQmV0d2VlblNjcmF0Y2gpO1xyXG5cdFx0VmVjdG9yMy5ub3JtYWxpemUocmlnaHQsIGFuZ2xlQmV0d2VlblNjcmF0Y2gyKTtcclxuXHRcdGNvbnN0IGNvc2luZSA9IFZlY3RvcjMuZG90KGFuZ2xlQmV0d2VlblNjcmF0Y2gsIGFuZ2xlQmV0d2VlblNjcmF0Y2gyKTtcclxuXHRcdGNvbnN0IHNpbmUgPSBWZWN0b3IzLm1hZ25pdHVkZShWZWN0b3IzLmNyb3NzKGFuZ2xlQmV0d2VlblNjcmF0Y2gsIGFuZ2xlQmV0d2VlblNjcmF0Y2gyLCBhbmdsZUJldHdlZW5TY3JhdGNoKSk7XHJcblx0XHRyZXR1cm4gTWF0aC5hdGFuMihzaW5lLCBjb3NpbmUpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG1vc3RPcnRob2dvbmFsQXhpcyhjYXJ0ZXNpYW46IFZlY3RvcjMsIHJlc3VsdDogVmVjdG9yMyk6IFZlY3RvcjMge1xyXG5cdFx0Y29uc3QgZiA9IFZlY3RvcjMubm9ybWFsaXplKGNhcnRlc2lhbiwgbW9zdE9ydGhvZ29uYWxBeGlzU2NyYXRjaCk7XHJcblx0XHRWZWN0b3IzLmFicyhmLCBmKTtcclxuXHJcblx0XHRpZiAoZi54IDw9IGYueSkge1xyXG5cdFx0XHRpZiAoZi54IDw9IGYueikge1xyXG5cdFx0XHRcdHJlc3VsdCA9IFZlY3RvcjMuY2xvbmUoVmVjdG9yMy5VTklUX1gsIHJlc3VsdCk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0cmVzdWx0ID0gVmVjdG9yMy5jbG9uZShWZWN0b3IzLlVOSVRfWiwgcmVzdWx0KTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIGlmIChmLnkgPD0gZi56KSB7XHJcblx0XHRcdHJlc3VsdCA9IFZlY3RvcjMuY2xvbmUoVmVjdG9yMy5VTklUX1ksIHJlc3VsdCk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRyZXN1bHQgPSBWZWN0b3IzLmNsb25lKFZlY3RvcjMuVU5JVF9aLCByZXN1bHQpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgcHJvamVjdFZlY3RvcihhOiBWZWN0b3IzLCBiOiBWZWN0b3IzLCByZXN1bHQ6IFZlY3RvcjMpOiBWZWN0b3IzIHtcclxuXHRcdGNvbnN0IHNjYWxhciA9IFZlY3RvcjMuZG90KGEsIGIpIC8gVmVjdG9yMy5kb3QoYiwgYik7XHJcblx0XHRyZXR1cm4gVmVjdG9yMy5tdWx0aXBseUJ5U2NhbGFyKGIsIHNjYWxhciwgcmVzdWx0KTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBlcXVhbHMobGVmdDogVmVjdG9yMywgcmlnaHQ6IFZlY3RvcjMpOiBib29sZWFuIHtcclxuXHRcdHJldHVybiAoXHJcblx0XHRcdGxlZnQgPT09IHJpZ2h0IHx8XHJcblx0XHRcdChkZWZpbmVkKGxlZnQpICYmIGRlZmluZWQocmlnaHQpICYmIGxlZnQueCA9PT0gcmlnaHQueCAmJiBsZWZ0LnkgPT09IHJpZ2h0LnkgJiYgbGVmdC56ID09PSByaWdodC56KVxyXG5cdFx0KTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0c3RhdGljIGVxdWFsc0FycmF5KGNhcnRlc2lhbjogVmVjdG9yMywgYXJyYXk6IG51bWJlcltdLCBvZmZzZXQ6IG51bWJlcik6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIGNhcnRlc2lhbi54ID09PSBhcnJheVtvZmZzZXRdICYmIGNhcnRlc2lhbi55ID09PSBhcnJheVtvZmZzZXQgKyAxXSAmJiBjYXJ0ZXNpYW4ueiA9PT0gYXJyYXlbb2Zmc2V0ICsgMl07XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZXF1YWxzRXBzaWxvbihsZWZ0OiBWZWN0b3IzLCByaWdodDogVmVjdG9yMywgcmVsYXRpdmVFcHNpbG9uID0gMCwgYWJzb2x1dGVFcHNpbG9uID0gMCk6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0bGVmdCA9PT0gcmlnaHQgfHxcclxuXHRcdFx0KGRlZmluZWQobGVmdCkgJiZcclxuXHRcdFx0XHRkZWZpbmVkKHJpZ2h0KSAmJlxyXG5cdFx0XHRcdEdNYXRoLmVxdWFsc0Vwc2lsb24obGVmdC54LCByaWdodC54LCByZWxhdGl2ZUVwc2lsb24sIGFic29sdXRlRXBzaWxvbikgJiZcclxuXHRcdFx0XHRHTWF0aC5lcXVhbHNFcHNpbG9uKGxlZnQueSwgcmlnaHQueSwgcmVsYXRpdmVFcHNpbG9uLCBhYnNvbHV0ZUVwc2lsb24pICYmXHJcblx0XHRcdFx0R01hdGguZXF1YWxzRXBzaWxvbihsZWZ0LnosIHJpZ2h0LnosIHJlbGF0aXZlRXBzaWxvbiwgYWJzb2x1dGVFcHNpbG9uKSlcclxuXHRcdCk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgY3Jvc3MobGVmdDogVmVjdG9yMywgcmlnaHQ6IFZlY3RvcjMsIHJlc3VsdDogVmVjdG9yMyk6IFZlY3RvcjMge1xyXG5cdFx0Y29uc3QgbGVmdFggPSBsZWZ0Lng7XHJcblx0XHRjb25zdCBsZWZ0WSA9IGxlZnQueTtcclxuXHRcdGNvbnN0IGxlZnRaID0gbGVmdC56O1xyXG5cdFx0Y29uc3QgcmlnaHRYID0gcmlnaHQueDtcclxuXHRcdGNvbnN0IHJpZ2h0WSA9IHJpZ2h0Lnk7XHJcblx0XHRjb25zdCByaWdodFogPSByaWdodC56O1xyXG5cclxuXHRcdGNvbnN0IHggPSBsZWZ0WSAqIHJpZ2h0WiAtIGxlZnRaICogcmlnaHRZO1xyXG5cdFx0Y29uc3QgeSA9IGxlZnRaICogcmlnaHRYIC0gbGVmdFggKiByaWdodFo7XHJcblx0XHRjb25zdCB6ID0gbGVmdFggKiByaWdodFkgLSBsZWZ0WSAqIHJpZ2h0WDtcclxuXHJcblx0XHRyZXN1bHQueCA9IHg7XHJcblx0XHRyZXN1bHQueSA9IHk7XHJcblx0XHRyZXN1bHQueiA9IHo7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG1pZHBvaW50ID0gZnVuY3Rpb24gKGxlZnQ6IFZlY3RvcjMsIHJpZ2h0OiBWZWN0b3IzLCByZXN1bHQ6IFZlY3RvcjMpOiBWZWN0b3IzIHtcclxuXHRcdHJlc3VsdC54ID0gKGxlZnQueCArIHJpZ2h0LngpICogMC41O1xyXG5cdFx0cmVzdWx0LnkgPSAobGVmdC55ICsgcmlnaHQueSkgKiAwLjU7XHJcblx0XHRyZXN1bHQueiA9IChsZWZ0LnogKyByaWdodC56KSAqIDAuNTtcclxuXHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH07XHJcbn1cclxuY29uc3QgZGlzdGFuY2VTY3JhdGNoID0gbmV3IFZlY3RvcjMoKTtcclxuY29uc3QgbGVycFNjcmF0Y2ggPSBuZXcgVmVjdG9yMygpO1xyXG5jb25zdCBhbmdsZUJldHdlZW5TY3JhdGNoID0gbmV3IFZlY3RvcjMoKTtcclxuY29uc3QgYW5nbGVCZXR3ZWVuU2NyYXRjaDIgPSBuZXcgVmVjdG9yMygpO1xyXG5jb25zdCBtb3N0T3J0aG9nb25hbEF4aXNTY3JhdGNoID0gbmV3IFZlY3RvcjMoKTtcclxuZXhwb3J0IGRlZmF1bHQgVmVjdG9yMztcclxuIiwiaW1wb3J0IHsgVmVydGV4Rm9ybWF0IH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVQ29uc3RhbnRcIjtcbmltcG9ydCBWZWN0b3IyIGZyb20gXCIuLi9tYXRoL1ZlY3RvcjJcIjtcbmltcG9ydCBWZWN0b3IzIGZyb20gXCIuLi9tYXRoL1ZlY3RvcjNcIjtcbmltcG9ydCBCdWZmZXIgZnJvbSBcIi4uL3JlbmRlci9CdWZmZXJcIjtcblxuZXhwb3J0IGNsYXNzIEF0dHJpYnV0ZSB7XG5cdHB1YmxpYyBvZmZzZXQ6IG51bWJlcjtcblx0cHVibGljIHNoYWRlckxvY2F0aW9uOiBudW1iZXI7XG5cdHB1YmxpYyB0eXBlOiBzdHJpbmc7XG5cdHB1YmxpYyBmb3JtYXQ6IHN0cmluZztcblx0cHVibGljIGF0dHJpYnV0ZUJ5dGVTaXplOiBudW1iZXI7XG5cdHB1YmxpYyBhdHRyaWJ1dGVUeXBlOiBBdHRyaWJ1dGVUeXBlO1xuXHRwdWJsaWMgZGlydHk6IGJvb2xlYW47XG5cdHB1YmxpYyBzdGF0aWMgdjMgPSBuZXcgVmVjdG9yMygpO1xuXHRwdWJsaWMgc3RhdGljIHYyID0gbmV3IFZlY3RvcjIoKTtcblx0Y29uc3RydWN0b3IocHVibGljIG5hbWU6IHN0cmluZywgcHVibGljIHZhbHVlOiBBcnJheTxudW1iZXI+LCBwdWJsaWMgaXRlbVNpemU6IG51bWJlcikge1xuXHRcdHRoaXMubmFtZSA9IG5hbWU7XG5cdFx0dGhpcy5vZmZzZXQgPSAwO1xuXHRcdHRoaXMuc2hhZGVyTG9jYXRpb24gPSAwO1xuXHRcdHRoaXMuYXR0cmlidXRlVHlwZSA9IEF0dHJpYnV0ZVR5cGUuYXR0cmlidXRlO1xuXHRcdHRoaXMuZGlydHkgPSB0cnVlO1xuXHR9XG5cdGdldEdQVUF0dHJpYnV0ZSgpOiBBcnJheTxHUFVBdHRyaWJ1dGU+IHtcblx0XHRyZXR1cm4gW1xuXHRcdFx0e1xuXHRcdFx0XHRzaGFkZXJMb2NhdGlvbjogdGhpcy5zaGFkZXJMb2NhdGlvbixcblx0XHRcdFx0Zm9ybWF0OiB0aGlzLmZvcm1hdCxcblx0XHRcdFx0b2Zmc2V0OiB0aGlzLm9mZnNldFxuXHRcdFx0fVxuXHRcdF07XG5cdH1cblx0ZGVzdHJveSgpIHtcblx0XHR0aGlzLnZhbHVlID0gW107XG5cdH1cblx0YXBwbHlNYXRyaXgzKG1hdHJpeDMpIHtcblx0XHRpZiAodGhpcy5pdGVtU2l6ZSA9PT0gMikge1xuXHRcdFx0Zm9yIChsZXQgaSA9IDAsIGwgPSB0aGlzLnZhbHVlLmxlbmd0aCAvIHRoaXMuaXRlbVNpemU7IGkgPCBsOyBpKyspIHtcblx0XHRcdFx0QXR0cmlidXRlLnYyLmZyb21CdWZmZXJBdHRyaWJ1dGUodGhpcywgaSk7XG5cdFx0XHRcdEF0dHJpYnV0ZS52Mi5hcHBseU1hdHJpeDMobWF0cml4Myk7XG5cdFx0XHRcdHRoaXMuc2V0WFkoaSwgQXR0cmlidXRlLnYyLngsIEF0dHJpYnV0ZS52Mi55KTtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKHRoaXMuaXRlbVNpemUgPT09IDMpIHtcblx0XHRcdGZvciAobGV0IGkgPSAwLCBsID0gdGhpcy52YWx1ZS5sZW5ndGggLyB0aGlzLml0ZW1TaXplOyBpIDwgbDsgaSsrKSB7XG5cdFx0XHRcdEF0dHJpYnV0ZS52My5mcm9tQnVmZmVyQXR0cmlidXRlKHRoaXMsIGkpO1xuXHRcdFx0XHRBdHRyaWJ1dGUudjMuYXBwbHlNYXRyaXgzKG1hdHJpeDMpO1xuXHRcdFx0XHR0aGlzLnNldFhZWihpLCBBdHRyaWJ1dGUudjMueCwgQXR0cmlidXRlLnYzLnksIEF0dHJpYnV0ZS52My56KTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblx0YXBwbHlNYXRyaXg0KG1hdHJpeDQpIHtcblx0XHRmb3IgKGxldCBpID0gMCwgbCA9IHRoaXMudmFsdWUubGVuZ3RoIC8gdGhpcy5pdGVtU2l6ZTsgaSA8IGw7IGkrKykge1xuXHRcdFx0QXR0cmlidXRlLnYzLmZyb21CdWZmZXJBdHRyaWJ1dGUodGhpcywgaSk7XG5cdFx0XHRBdHRyaWJ1dGUudjMuYXBwbHlNYXRyaXg0KG1hdHJpeDQpO1xuXHRcdFx0dGhpcy5zZXRYWVooaSwgQXR0cmlidXRlLnYzLngsIEF0dHJpYnV0ZS52My55LCBBdHRyaWJ1dGUudjMueik7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cdHNldFgoaW5kZXgsIHgpIHtcblx0XHR0aGlzLnZhbHVlW2luZGV4ICogdGhpcy5pdGVtU2l6ZV0gPSB4O1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cdGdldFgoaW5kZXgpIHtcblx0XHRjb25zdCB4ID0gdGhpcy52YWx1ZVtpbmRleCAqIHRoaXMuaXRlbVNpemVdO1xuXHRcdHJldHVybiB4O1xuXHR9XG5cdHNldFkoaW5kZXgsIHkpIHtcblx0XHR0aGlzLnZhbHVlW2luZGV4ICogdGhpcy5pdGVtU2l6ZSArIDFdID0geTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXHRnZXRZKGluZGV4KSB7XG5cdFx0Y29uc3QgeSA9IHRoaXMudmFsdWVbaW5kZXggKiB0aGlzLml0ZW1TaXplICsgMV07XG5cdFx0cmV0dXJuIHk7XG5cdH1cblx0c2V0WihpbmRleCwgeikge1xuXHRcdHRoaXMudmFsdWVbaW5kZXggKiB0aGlzLml0ZW1TaXplICsgMl0gPSB6O1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cdGdldFooaW5kZXgpIHtcblx0XHRjb25zdCB6ID0gdGhpcy52YWx1ZVtpbmRleCAqIHRoaXMuaXRlbVNpemUgKyAyXTtcblx0XHRyZXR1cm4gejtcblx0fVxuXHRnZXRXKGluZGV4KSB7XG5cdFx0Y29uc3QgdyA9IHRoaXMudmFsdWVbaW5kZXggKiB0aGlzLml0ZW1TaXplICsgM107XG5cdFx0cmV0dXJuIHc7XG5cdH1cblx0c2V0WFkoaW5kZXgsIHgsIHkpIHtcblx0XHRpbmRleCAqPSB0aGlzLml0ZW1TaXplO1xuXHRcdHRoaXMudmFsdWVbaW5kZXggKyAwXSA9IHg7XG5cdFx0dGhpcy52YWx1ZVtpbmRleCArIDFdID0geTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXHRzZXRYWVooaW5kZXgsIHgsIHksIHopIHtcblx0XHRpbmRleCAqPSB0aGlzLml0ZW1TaXplO1xuXHRcdHRoaXMudmFsdWVbaW5kZXggKyAwXSA9IHg7XG5cdFx0dGhpcy52YWx1ZVtpbmRleCArIDFdID0geTtcblx0XHR0aGlzLnZhbHVlW2luZGV4ICsgMl0gPSB6O1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cdHNldFhZWlcoaW5kZXgsIHgsIHksIHosIHcpIHtcblx0XHRpbmRleCAqPSB0aGlzLml0ZW1TaXplO1xuXHRcdHRoaXMudmFsdWVbaW5kZXggKyAwXSA9IHg7XG5cdFx0dGhpcy52YWx1ZVtpbmRleCArIDFdID0geTtcblx0XHR0aGlzLnZhbHVlW2luZGV4ICsgMl0gPSB6O1xuXHRcdHRoaXMudmFsdWVbaW5kZXggKyAzXSA9IHc7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cbn1cblxuZXhwb3J0IGNsYXNzIEludGVybGVhdmVkQXR0cmlidXRlIHtcblx0cHVibGljIG5hbWVzOiBzdHJpbmdbXTtcblx0cHVibGljIHZhbHVlOiBBcnJheTxudW1iZXI+O1xuXHRwdWJsaWMgaXRlbVNpemVzOiBudW1iZXJbXTtcblx0cHVibGljIGZvcm1hdDogc3RyaW5nO1xuXHRwdWJsaWMgYnl0ZVNpemU6IG51bWJlcjtcblx0cHVibGljIGF0dHJpYnV0ZVR5cGU6IEF0dHJpYnV0ZVR5cGU7XG5cdHB1YmxpYyBkaXJ0eTogYm9vbGVhbjtcblx0Y29uc3RydWN0b3IobmFtZXM6IHN0cmluZ1tdLCB2YWx1ZTogQXJyYXk8bnVtYmVyPiwgaXRlbVNpemVzOiBudW1iZXJbXSkge1xuXHRcdHRoaXMubmFtZXMgPSBuYW1lcztcblx0XHR0aGlzLml0ZW1TaXplcyA9IGl0ZW1TaXplcztcblx0XHR0aGlzLnZhbHVlID0gdmFsdWU7XG5cdFx0dGhpcy5hdHRyaWJ1dGVUeXBlID0gQXR0cmlidXRlVHlwZS5pbnRlcmxlYXZlZEF0dHJpYnV0ZTtcblx0XHR0aGlzLmRpcnR5ID0gdHJ1ZTtcblx0fVxuXHRnZXRHUFVBdHRyaWJ1dGUoKTogQXJyYXk8R1BVQXR0cmlidXRlPiB7XG5cdFx0Y29uc3QgcmVzdWx0ID0gW107XG5cdFx0dGhpcy5pdGVtU2l6ZXMucmVkdWNlKCh0b3RhbCwgY3VycmVudCwgaW5kZXgpID0+IHtcblx0XHRcdHJlc3VsdC5wdXNoKHtcblx0XHRcdFx0c2hhZGVyTG9jYXRpb246IGluZGV4LFxuXHRcdFx0XHRmb3JtYXQ6IGN1cnJlbnQgPT0gMSA/IGAke3RoaXMuZm9ybWF0fWAgOiBgJHt0aGlzLmZvcm1hdH14JHtjdXJyZW50fWAsXG5cdFx0XHRcdG9mZnNldDogdG90YWwgKiB0aGlzLmJ5dGVTaXplXG5cdFx0XHR9KTtcblx0XHRcdHJldHVybiAodG90YWwgKz0gY3VycmVudCk7XG5cdFx0fSwgMCk7XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXHRkZXN0cm95KCkge1xuXHRcdHRoaXMudmFsdWUgPSBudWxsO1xuXHRcdHRoaXMubmFtZXMgPSBudWxsO1xuXHRcdHRoaXMuaXRlbVNpemVzID0gbnVsbDtcblx0fVxufVxuZXhwb3J0IGNsYXNzIEZsb2F0MzJBdHRyaWJ1dGUgZXh0ZW5kcyBBdHRyaWJ1dGUge1xuXHRjb25zdHJ1Y3RvcihuYW1lOiBzdHJpbmcsIHZhbHVlOiBBcnJheTxudW1iZXI+LCBpdGVtU2l6ZTogbnVtYmVyKSB7XG5cdFx0c3VwZXIobmFtZSwgdmFsdWUsIGl0ZW1TaXplKTtcblx0XHRjb25zdCB7IGZvcm1hdCwgdG90YWxCeXRlU2l6ZSB9ID0gZ2V0QXR0cmlidXRlRm9ybWF0KFZlcnRleEZvcm1hdC5GbG9hdDMyLCBpdGVtU2l6ZSk7XG5cdFx0dGhpcy5mb3JtYXQgPSBmb3JtYXQ7XG5cdFx0dGhpcy5hdHRyaWJ1dGVCeXRlU2l6ZSA9IHRvdGFsQnl0ZVNpemU7XG5cdH1cbn1cbmV4cG9ydCBjbGFzcyBJbnRlcmxlYXZlZEZsb2F0MzJBdHRyaWJ1dGUgZXh0ZW5kcyBJbnRlcmxlYXZlZEF0dHJpYnV0ZSB7XG5cdGNvbnN0cnVjdG9yKG5hbWVzOiBzdHJpbmdbXSwgdmFsdWU6IEFycmF5PG51bWJlcj4sIGl0ZW1TaXplczogbnVtYmVyW10pIHtcblx0XHRzdXBlcihuYW1lcywgdmFsdWUsIGl0ZW1TaXplcyk7XG5cdFx0dGhpcy5mb3JtYXQgPSBWZXJ0ZXhGb3JtYXQuRmxvYXQzMjtcblx0XHR0aGlzLmJ5dGVTaXplID0gRmxvYXQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5UO1xuXHR9XG59XG5leHBvcnQgY2xhc3MgQnVmZmVyRmxvYXQzMkF0dHJpYnV0ZSBleHRlbmRzIEludGVybGVhdmVkRmxvYXQzMkF0dHJpYnV0ZSB7XG5cdHB1YmxpYyBidWZmZXI6IEJ1ZmZlcjtcblx0Y29uc3RydWN0b3IobmFtZXM6IHN0cmluZ1tdLCBidWZmZXI6IEJ1ZmZlciwgaXRlbVNpemVzOiBudW1iZXJbXSkge1xuXHRcdHN1cGVyKG5hbWVzLCB1bmRlZmluZWQsIGl0ZW1TaXplcyk7XG5cdFx0dGhpcy5idWZmZXIgPSBidWZmZXI7XG5cdH1cbn1cbmV4cG9ydCBlbnVtIEF0dHJpYnV0ZVR5cGUge1xuXHRpbnRlcmxlYXZlZEF0dHJpYnV0ZSA9IDAsXG5cdGF0dHJpYnV0ZSA9IDFcbn1cbmV4cG9ydCB0eXBlIEdQVUF0dHJpYnV0ZSA9IHtcblx0c2hhZGVyTG9jYXRpb246IG51bWJlcjtcblx0Zm9ybWF0OiBzdHJpbmc7XG5cdG9mZnNldDogbnVtYmVyO1xufTtcbmZ1bmN0aW9uIGdldEF0dHJpYnV0ZUZvcm1hdCh0eXBlOiBzdHJpbmcsIGl0ZW1TaXplOiBudW1iZXIpIHtcblx0Y29uc3Qga2V5ID0gYCR7dHlwZX14JHtpdGVtU2l6ZX1gO1xuXHRyZXR1cm4ge1xuXHRcdFtWZXJ0ZXhGb3JtYXQuRmxvYXQzMl06IHtcblx0XHRcdGZvcm1hdDogXCJmbG9hdDMyXCIsXG5cdFx0XHR0b3RhbEJ5dGVTaXplOiBGbG9hdDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQgKiBpdGVtU2l6ZSxcblx0XHRcdGJ5dGVTaXplOiBGbG9hdDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlRcblx0XHR9LFxuXHRcdFtWZXJ0ZXhGb3JtYXQuRmxvYXQzMngyXToge1xuXHRcdFx0Zm9ybWF0OiBcImZsb2F0MzJ4MlwiLFxuXHRcdFx0dG90YWxCeXRlU2l6ZTogRmxvYXQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5UICogaXRlbVNpemUsXG5cdFx0XHRieXRlU2l6ZTogRmxvYXQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5UXG5cdFx0fSxcblx0XHRbVmVydGV4Rm9ybWF0LkZsb2F0MzJ4M106IHtcblx0XHRcdGZvcm1hdDogXCJmbG9hdDMyeDNcIixcblx0XHRcdHRvdGFsQnl0ZVNpemU6IEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCAqIGl0ZW1TaXplLFxuXHRcdFx0Ynl0ZVNpemU6IEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVFxuXHRcdH0sXG5cdFx0W1ZlcnRleEZvcm1hdC5GbG9hdDMyeDRdOiB7XG5cdFx0XHRmb3JtYXQ6IFwiZmxvYXQzMng0XCIsXG5cdFx0XHR0b3RhbEJ5dGVTaXplOiBGbG9hdDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQgKiBpdGVtU2l6ZSxcblx0XHRcdGJ5dGVTaXplOiBGbG9hdDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlRcblx0XHR9XG5cdH1ba2V5XTtcbn1cbiIsImltcG9ydCB7IEJpbmRHcm91cENhY2hlT3B0aW9ucyB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XG5jb25zdCBiaW5kR3JvdXBDYWNoZSA9IG5ldyBNYXAoKTtcbmNsYXNzIEJpbmRHcm91cCB7XG5cdGRldmljZTogR1BVRGV2aWNlO1xuXHRncHVCaW5kR3JvdXA6IEdQVUJpbmRHcm91cDtcblx0bGFiZWw6IHN0cmluZztcblx0aW5kZXg6IG51bWJlcjtcblx0ZGlydHk6IGJvb2xlYW47XG5cdG9mZnNldD86IG51bWJlcjtcblx0Ly8gY29uc3QgdW5pZm9ybUJ5dGVzID0gNSAqIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVDtcblx0Ly8gY29uc3QgYWxpZ25lZFNpemVCeXRlcyA9IE1hdGguY2VpbCh1bmlmb3JtQnl0ZXMgLyAyNTYpICogMjU2O1xuXHQvLyBjb25zdCBhbGlnbmVkU2l6ZSA9YWxpZ25lZFNpemVCeXRlcyAvIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVDtcblx0YWxpZ25lZFNpemU/OiBudW1iZXI7XG5cdG1heE9mZnNldD86IG51bWJlcjtcblx0ZHluYW1pYz86IGJvb2xlYW47XG5cdGNvbnN0cnVjdG9yKG9wdGlvbnM6IEJpbmRHcm91cENhY2hlT3B0aW9ucykge1xuXHRcdHRoaXMuaW5kZXggPSBvcHRpb25zLmluZGV4IHx8IDA7XG5cdFx0dGhpcy5vZmZzZXQgPSBvcHRpb25zLm9mZnNldCA/PyAwO1xuXHRcdHRoaXMuYWxpZ25lZFNpemUgPSBvcHRpb25zLmFsaWduZWRTaXplID8/IDA7XG5cdFx0dGhpcy5tYXhPZmZzZXQgPSBvcHRpb25zLm1heE9mZnNldCA/PyAwO1xuXHRcdHRoaXMuZHluYW1pYyA9IG9wdGlvbnMuZHluYW1pYyA/PyBmYWxzZTtcblx0XHR0aGlzLmdwdUJpbmRHcm91cCA9IG9wdGlvbnMuZGV2aWNlLmNyZWF0ZUJpbmRHcm91cCh7XG5cdFx0XHRsYWJlbDogb3B0aW9ucy5sYWJlbCxcblx0XHRcdGxheW91dDogb3B0aW9ucy5sYXlvdXQuZ3B1QmluZEdyb3VwTGF5b3V0LFxuXHRcdFx0ZW50cmllczogb3B0aW9ucy5lbnRpcmVzLm1hcCgoZW50aXR5KSA9PiAoe1xuXHRcdFx0XHRiaW5kaW5nOiBlbnRpdHkuYmluZGluZyxcblx0XHRcdFx0cmVzb3VyY2U6IGVudGl0eS5yZXNvdXJjZVxuXHRcdFx0fSkpXG5cdFx0fSk7XG5cdH1cblx0YmluZChwYXNzRW5jb2RlcjogR1BVUmVuZGVyUGFzc0VuY29kZXIgfCBHUFVDb21wdXRlUGFzc0VuY29kZXIpIHtcblx0XHQvLyBkeW5hbWljIHVuaWZvcm1zIG11c3QgYmluZCBtdWx0aXBsZSB0aW1lc1xuXHRcdGlmICh0aGlzLmR5bmFtaWMpIHtcblx0XHRcdGNvbnN0IGR5bmFtaWNPZmZzZXRzID0gWzBdO1xuXHRcdFx0ZHluYW1pY09mZnNldHNbMF0gPSB0aGlzLm9mZnNldCAqIHRoaXMuYWxpZ25lZFNpemU7XG5cdFx0XHR0aGlzLm9mZnNldCA9ICsrdGhpcy5vZmZzZXQgPCB0aGlzLm1heE9mZnNldCA/IHRoaXMub2Zmc2V0IDogMDtcblx0XHRcdHBhc3NFbmNvZGVyLnNldEJpbmRHcm91cCh0aGlzLmluZGV4LCB0aGlzLmdwdUJpbmRHcm91cCwgZHluYW1pY09mZnNldHMpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwYXNzRW5jb2Rlci5zZXRCaW5kR3JvdXAodGhpcy5pbmRleCwgdGhpcy5ncHVCaW5kR3JvdXApO1xuXHRcdH1cblx0fVxuXHRkZXN0cm95KCkge1xuXHRcdHRoaXMuZ3B1QmluZEdyb3VwID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMuZGV2aWNlID0gdW5kZWZpbmVkO1xuXHR9XG5cdHN0YXRpYyBnZXRCaW5kR3JvdXBGcm9tQ2FjaGUob3B0aW9uczogQmluZEdyb3VwQ2FjaGVPcHRpb25zKTogQmluZEdyb3VwIHtcblx0XHRpZiAoYmluZEdyb3VwQ2FjaGUuaGFzKG9wdGlvbnMubGFiZWwpKSB7XG5cdFx0XHRyZXR1cm4gYmluZEdyb3VwQ2FjaGUuZ2V0KG9wdGlvbnMubGFiZWwpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCBiaW5kR3JvdXAgPSBuZXcgQmluZEdyb3VwKG9wdGlvbnMpO1xuXHRcdFx0YmluZEdyb3VwQ2FjaGUuc2V0KG9wdGlvbnMubGFiZWwsIGJpbmRHcm91cCk7XG5cdFx0XHRyZXR1cm4gYmluZEdyb3VwO1xuXHRcdH1cblx0fVxuXHRzdGF0aWMgcmVtb3ZlQmluZEdyb3VwRnJvbUNhY2hlKGJpbmRHcm91cDogQmluZEdyb3VwKSB7XG5cdFx0YmluZEdyb3VwQ2FjaGUuZGVsZXRlKGJpbmRHcm91cCk7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQmluZEdyb3VwO1xuIiwiaW1wb3J0IHsgQmluZEdyb3VwRW50aXR5T3B0aW9ucyB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCaW5kR3JvdXBFbnRpdHkge1xuXHRiaW5kaW5nOiBudW1iZXI7XG5cdHJlc291cmNlOiBHUFVCaW5kaW5nUmVzb3VyY2U7XG5cdGNvbnN0cnVjdG9yKG9wdGlvbnM6IEJpbmRHcm91cEVudGl0eU9wdGlvbnMpIHtcblx0XHR0aGlzLmJpbmRpbmcgPSBvcHRpb25zLmJpbmRpbmc7XG5cdFx0dGhpcy5yZXNvdXJjZSA9IG9wdGlvbnMucmVzb3VyY2U7XG5cdH1cblx0cHVibGljIGdldEdQVUdyb3VwRW50aXR5KCkge1xuXHRcdHJldHVybiB7XG5cdFx0XHRiaW5kaW5nOiB0aGlzLmJpbmRpbmcsXG5cdFx0XHRyZXNvdXJjZTogdGhpcy5yZXNvdXJjZVxuXHRcdH07XG5cdH1cbn1cbiIsImltcG9ydCB7IFBhc3NUeXBlIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcbmltcG9ydCBBdHRhY2htZW50IGZyb20gXCIuL0F0dGFjaG1lbnRcIjtcbmltcG9ydCBRdWVyeVNldCBmcm9tIFwiLi9RdWVyeVNldFwiO1xuaW1wb3J0IFRleHR1cmUgZnJvbSBcIi4vVGV4dHVyZVwiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZW5kZXJUYXJnZXQge1xuXHRwdWJsaWMgZGV2aWNlOiBHUFVEZXZpY2U7XG5cdHB1YmxpYyBjb21tYW5kRW5jb2RlcjogR1BVQ29tbWFuZEVuY29kZXIgfCBudWxsO1xuXHRwcml2YXRlIF9yZW5kZXJQYXNzRGVzY3JpcHRvcjogR1BVUmVuZGVyUGFzc0Rlc2NyaXB0b3I7XG5cdHByaXZhdGUgcmVuZGVyRW5jb2RlcjogR1BVUmVuZGVyUGFzc0VuY29kZXI7XG5cdHByaXZhdGUgY29tcHV0ZUVuY29kZXI6IEdQVUNvbXB1dGVQYXNzRW5jb2Rlcjtcblx0Y29uc3RydWN0b3IoXG5cdFx0cHVibGljIHR5cGU6IFBhc3NUeXBlLFxuXHRcdHB1YmxpYyBjb2xvckF0dGFjaG1lbnRzOiBBdHRhY2htZW50W10sXG5cdFx0cHVibGljIGRlcHRoQXR0YWNobWVudD86IEF0dGFjaG1lbnQsXG5cdFx0cHVibGljIHN0ZW5jaWxBdHRhY2htZW50PzogQXR0YWNobWVudCxcblx0XHRwdWJsaWMgcXVlcnlTZXQ/OiBRdWVyeVNldCxcblx0XHRwdWJsaWMgZml4ZWRTaXplPzogYm9vbGVhblxuXHQpIHtcblx0XHR0aGlzLnJlbmRlckVuY29kZXIgPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy5jb21wdXRlRW5jb2RlciA9IHVuZGVmaW5lZDtcblx0XHR0aGlzLl9yZW5kZXJQYXNzRGVzY3JpcHRvciA9IHVuZGVmaW5lZDtcblx0XHR0aGlzLmNvbW1hbmRFbmNvZGVyID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMuZGV2aWNlID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMuZml4ZWRTaXplID0gZmFsc2U7XG5cdH1cblx0Z2V0IHJlbmRlclBhc3NEZXNjcmlwdG9yKCkge1xuXHRcdHRoaXMuX3JlbmRlclBhc3NEZXNjcmlwdG9yID0gdGhpcy5nZXRSZW5kZXJQYXNzRGVzY3JpcHRvcigpO1xuXHRcdHJldHVybiB0aGlzLl9yZW5kZXJQYXNzRGVzY3JpcHRvcjtcblx0fVxuXHRwdWJsaWMgZ2V0Q29sb3JUZXh0dXJlKGluZGV4ID0gMCk6IFRleHR1cmUge1xuXHRcdGNvbnN0IGNvbEF0dCA9IHRoaXMuY29sb3JBdHRhY2htZW50c1tpbmRleF07XG5cdFx0aWYgKGNvbEF0dCkge1xuXHRcdFx0cmV0dXJuIGNvbEF0dC50ZXh0dXJlIGFzIFRleHR1cmU7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH1cblx0fVxuXHRwdWJsaWMgZ2V0RGVwdGhUZXh0dXJlKCk6IFRleHR1cmUge1xuXHRcdGlmICh0aGlzLmRlcHRoQXR0YWNobWVudCkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZGVwdGhBdHRhY2htZW50LnRleHR1cmUgYXMgVGV4dHVyZTtcblx0XHR9XG5cdH1cblx0cHJpdmF0ZSBnZXRSZW5kZXJQYXNzRGVzY3JpcHRvcigpOiBHUFVSZW5kZXJQYXNzRGVzY3JpcHRvciB8IG51bGwge1xuXHRcdHRoaXMuZGVwdGhBdHRhY2htZW50Py50ZXh0dXJlPy51cGRhdGUodGhpcy5kZXZpY2UpO1xuXHRcdHRoaXM/LnF1ZXJ5U2V0Py51cGRhdGUodGhpcy5kZXZpY2UpO1xuXHRcdHJldHVybiB7XG5cdFx0XHQuLi4odGhpcy5jb2xvckF0dGFjaG1lbnRzICYmIHtcblx0XHRcdFx0Y29sb3JBdHRhY2htZW50czogdGhpcy5jb2xvckF0dGFjaG1lbnRzLm1hcCgoY29sb3JBdHRhY2htZW50KSA9PiB7XG5cdFx0XHRcdFx0Y29sb3JBdHRhY2htZW50Py50ZXh0dXJlPy51cGRhdGUgJiYgY29sb3JBdHRhY2htZW50Py50ZXh0dXJlPy51cGRhdGUodGhpcy5kZXZpY2UpO1xuXHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHR2aWV3OlxuXHRcdFx0XHRcdFx0XHQvLyDmmoLml7bov5nkuYjlhplcblx0XHRcdFx0XHRcdFx0Y29sb3JBdHRhY2htZW50Py50ZXh0dXJlVmlldz8uKCkgPz8gY29sb3JBdHRhY2htZW50LnRleHR1cmUudGV4dHVyZVZpZXcsXG5cdFx0XHRcdFx0XHRyZXNvbHZlVGFyZ2V0OlxuXHRcdFx0XHRcdFx0XHRjb2xvckF0dGFjaG1lbnQucmVzb2x2ZVRhcmdldCAhPSB1bmRlZmluZWRcblx0XHRcdFx0XHRcdFx0XHQ/IGNvbG9yQXR0YWNobWVudC5yZXNvbHZlVGFyZ2V0LnRleHR1cmVWaWV3XG5cdFx0XHRcdFx0XHRcdFx0OiB1bmRlZmluZWQsXG5cdFx0XHRcdFx0XHRjbGVhclZhbHVlOiBjb2xvckF0dGFjaG1lbnQudmFsdWUsXG5cdFx0XHRcdFx0XHRsb2FkT3A6IGNvbG9yQXR0YWNobWVudC5vcCxcblx0XHRcdFx0XHRcdHN0b3JlT3A6IGNvbG9yQXR0YWNobWVudC5zdG9yZU9wXG5cdFx0XHRcdFx0fSBhcyBHUFVSZW5kZXJQYXNzQ29sb3JBdHRhY2htZW50O1xuXHRcdFx0XHR9KVxuXHRcdFx0fSksXG5cdFx0XHQuLi4oKHRoaXMuZGVwdGhBdHRhY2htZW50IHx8IHRoaXMuc3RlbmNpbEF0dGFjaG1lbnQpICYmIHtcblx0XHRcdFx0ZGVwdGhTdGVuY2lsQXR0YWNobWVudDoge1xuXHRcdFx0XHRcdHZpZXc6IHRoaXMuZGVwdGhBdHRhY2htZW50Py50ZXh0dXJlPy50ZXh0dXJlVmlldyB8fCB1bmRlZmluZWQsXG5cdFx0XHRcdFx0ZGVwdGhMb2FkT3A6IHRoaXMuZGVwdGhBdHRhY2htZW50Py5vcCB8fCBcImNsZWFyXCIsXG5cdFx0XHRcdFx0ZGVwdGhDbGVhclZhbHVlOiB0aGlzLmRlcHRoQXR0YWNobWVudD8udmFsdWUgfHwgMS4wLFxuXHRcdFx0XHRcdGRlcHRoU3RvcmVPcDogdGhpcy5kZXB0aEF0dGFjaG1lbnQ/LnN0b3JlT3AgfHwgXCJzdG9yZVwiLFxuXHRcdFx0XHRcdGRlcHRoUmVhZE9ubHk6IHRoaXMuZGVwdGhBdHRhY2htZW50Py5yZWFkT25seSB8fCBmYWxzZVxuXHRcdFx0XHRcdC8vIHN0ZW5jaWxMb2FkT3A6IHRoaXMuc3RlbmNpbEF0dGFjaG1lbnQ/Lm9wIHx8IFwiY2xlYXJcIixcblx0XHRcdFx0XHQvLyBzdGVuY2lsQ2xlYXJWYWx1ZTogdGhpcy5zdGVuY2lsQXR0YWNobWVudD8udmFsdWUgfHwgMCxcblx0XHRcdFx0XHQvLyBzdGVuY2lsU3RvcmVPcDogdGhpcy5zdGVuY2lsQXR0YWNobWVudD8uc3RvcmVPcCB8fCBcInN0b3JlXCIsXG5cdFx0XHRcdH0gYXMgR1BVUmVuZGVyUGFzc0RlcHRoU3RlbmNpbEF0dGFjaG1lbnRcblx0XHRcdH0pLFxuXHRcdFx0Li4uKHRoaXMucXVlcnlTZXQgJiYgeyBvY2NsdXNpb25RdWVyeVNldDogdGhpcy5xdWVyeVNldC5ncHVRdWVyeVNldCB9KVxuXHRcdH07XG5cdH1cblxuXHRwdWJsaWMgYmVnaW5SZW5kZXJQYXNzKGRldmljZTogR1BVRGV2aWNlKSB7XG5cdFx0aWYgKCF0aGlzLmRldmljZSkgdGhpcy5kZXZpY2UgPSBkZXZpY2U7XG5cdFx0dGhpcy5jb21tYW5kRW5jb2RlciA9IHRoaXMuZGV2aWNlLmNyZWF0ZUNvbW1hbmRFbmNvZGVyKCk7XG5cdFx0dGhpcy5yZW5kZXJFbmNvZGVyID0gdGhpcy5jb21tYW5kRW5jb2Rlci5iZWdpblJlbmRlclBhc3ModGhpcy5yZW5kZXJQYXNzRGVzY3JpcHRvcik7XG5cdFx0cmV0dXJuIHRoaXMucmVuZGVyRW5jb2Rlcjtcblx0fVxuXHRwdWJsaWMgZW5kUmVuZGVyUGFzcygpIHtcblx0XHR0aGlzLnJlbmRlckVuY29kZXI/LmVuZCgpO1xuXHRcdHRoaXMuZGV2aWNlLnF1ZXVlLnN1Ym1pdChbdGhpcy5jb21tYW5kRW5jb2Rlci5maW5pc2goKV0pO1xuXHRcdHRoaXMuY29tbWFuZEVuY29kZXIgPSBudWxsO1xuXHRcdHRoaXMucmVuZGVyRW5jb2RlciA9IG51bGw7XG5cdH1cblx0cHVibGljIGJlZ2luQ29tcHV0ZVBhc3NFbmNvZGVyKGRldmljZTogR1BVRGV2aWNlKSB7XG5cdFx0aWYgKCF0aGlzLmRldmljZSkgdGhpcy5kZXZpY2UgPSBkZXZpY2U7XG5cdFx0dGhpcy5jb21tYW5kRW5jb2RlciA9IHRoaXMuZGV2aWNlLmNyZWF0ZUNvbW1hbmRFbmNvZGVyKCk7XG5cdFx0dGhpcy5jb21wdXRlRW5jb2RlciA9IHRoaXMuY29tbWFuZEVuY29kZXIuYmVnaW5Db21wdXRlUGFzcygpO1xuXHRcdHJldHVybiB0aGlzLmNvbXB1dGVFbmNvZGVyO1xuXHR9XG5cdHB1YmxpYyBlbmRDb21wdXRlUGFzc0VuY29kZXIoKSB7XG5cdFx0dGhpcy5jb21wdXRlRW5jb2Rlcj8uZW5kKCk7XG5cdFx0dGhpcy5kZXZpY2UucXVldWUuc3VibWl0KFt0aGlzLmNvbW1hbmRFbmNvZGVyLmZpbmlzaCgpXSk7XG5cdFx0dGhpcy5jb21tYW5kRW5jb2RlciA9IG51bGw7XG5cdFx0dGhpcy5yZW5kZXJFbmNvZGVyID0gbnVsbDtcblx0fVxuXHRwdWJsaWMgc2V0U2l6ZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgZGVwdGggPSAxKSB7XG5cdFx0aWYgKHRoaXMuZml4ZWRTaXplKSByZXR1cm47XG5cdFx0dGhpcz8uZGVwdGhBdHRhY2htZW50Py50ZXh0dXJlPy5zZXRTaXplPy4od2lkdGgsIGhlaWdodCwgZGVwdGgpO1xuXHRcdHRoaXM/LmNvbG9yQXR0YWNobWVudHM/LmZvckVhY2g/LigoY29sb3JBdHRhY2htZW50KSA9PlxuXHRcdFx0Y29sb3JBdHRhY2htZW50Py50ZXh0dXJlPy5zZXRTaXplPy4od2lkdGgsIGhlaWdodCwgZGVwdGgpXG5cdFx0KTtcblx0fVxuXHRkZXN0cm95KCkge1xuXHRcdGlmICh0aGlzLmNvbG9yQXR0YWNobWVudHMpIHtcblx0XHRcdHRoaXMuY29sb3JBdHRhY2htZW50cy5mb3JFYWNoKChjb2xvckF0dGFjaG1lbnQpID0+IHtcblx0XHRcdFx0aWYgKGNvbG9yQXR0YWNobWVudC50ZXh0dXJlKSB7XG5cdFx0XHRcdFx0Y29sb3JBdHRhY2htZW50LnRleHR1cmUuZGVzdHJveSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0aWYgKHRoaXMuZGVwdGhBdHRhY2htZW50LnRleHR1cmUpIHRoaXMuZGVwdGhBdHRhY2htZW50LnRleHR1cmUuZGVzdHJveSgpO1xuXHR9XG59XG4iLCJpbXBvcnQgZGVmYXVsdFZhbHVlIGZyb20gXCIuLi91dGlscy9kZWZhdWx0VmFsdWVcIjtcclxuaW1wb3J0IGRlZmluZWQgZnJvbSBcIi4uL3V0aWxzL2RlZmluZWRcIjtcclxuaW1wb3J0IEdNYXRoIGZyb20gXCIuL01hdGhcIjtcclxuaW1wb3J0IE1hdHJpeDQgZnJvbSBcIi4vTWF0cml4NFwiO1xyXG5pbXBvcnQgeyBRdWF0ZXJuaW9uIH0gZnJvbSBcIi4vUXVhdGVybmlvblwiO1xyXG5pbXBvcnQgVmVjdG9yMyBmcm9tIFwiLi9WZWN0b3IzXCI7XHJcbi8qKlxyXG4gKiBBIDN4MyBtYXRyaXgsIGluZGV4YWJsZSBhcyBhIGNvbHVtbi1tYWpvciBvcmRlciBhcnJheS5cclxuICogQHBhcmFtIHtOdW1iZXJ9IFtjb2x1bW4wUm93MD0wLjBdIFRoZSB2YWx1ZSBmb3IgY29sdW1uIDAsIHJvdyAwLlxyXG4gKiBAcGFyYW0ge051bWJlcn0gW2NvbHVtbjFSb3cwPTAuMF0gVGhlIHZhbHVlIGZvciBjb2x1bW4gMSwgcm93IDAuXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBbY29sdW1uMlJvdzA9MC4wXSBUaGUgdmFsdWUgZm9yIGNvbHVtbiAyLCByb3cgMC5cclxuICogQHBhcmFtIHtOdW1iZXJ9IFtjb2x1bW4wUm93MT0wLjBdIFRoZSB2YWx1ZSBmb3IgY29sdW1uIDAsIHJvdyAxLlxyXG4gKiBAcGFyYW0ge051bWJlcn0gW2NvbHVtbjFSb3cxPTAuMF0gVGhlIHZhbHVlIGZvciBjb2x1bW4gMSwgcm93IDEuXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBbY29sdW1uMlJvdzE9MC4wXSBUaGUgdmFsdWUgZm9yIGNvbHVtbiAyLCByb3cgMS5cclxuICogQHBhcmFtIHtOdW1iZXJ9IFtjb2x1bW4wUm93Mj0wLjBdIFRoZSB2YWx1ZSBmb3IgY29sdW1uIDAsIHJvdyAyLlxyXG4gKiBAcGFyYW0ge051bWJlcn0gW2NvbHVtbjFSb3cyPTAuMF0gVGhlIHZhbHVlIGZvciBjb2x1bW4gMSwgcm93IDIuXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBbY29sdW1uMlJvdzI9MC4wXSBUaGUgdmFsdWUgZm9yIGNvbHVtbiAyLCByb3cgMi5cclxuICovXHJcbmNsYXNzIE1hdHJpeDMge1xyXG5cdGNvbnN0cnVjdG9yKFxyXG5cdFx0Y29sdW1uMFJvdzAgPSAwLFxyXG5cdFx0Y29sdW1uMVJvdzAgPSAwLFxyXG5cdFx0Y29sdW1uMlJvdzAgPSAwLFxyXG5cdFx0Y29sdW1uMFJvdzEgPSAwLFxyXG5cdFx0Y29sdW1uMVJvdzEgPSAwLFxyXG5cdFx0Y29sdW1uMlJvdzEgPSAwLFxyXG5cdFx0Y29sdW1uMFJvdzIgPSAwLFxyXG5cdFx0Y29sdW1uMVJvdzIgPSAwLFxyXG5cdFx0Y29sdW1uMlJvdzIgPSAwXHJcblx0KSB7XHJcblx0XHR0aGlzWzBdID0gY29sdW1uMFJvdzA7XHJcblx0XHR0aGlzWzFdID0gY29sdW1uMFJvdzE7XHJcblx0XHR0aGlzWzJdID0gY29sdW1uMFJvdzI7XHJcblx0XHR0aGlzWzNdID0gY29sdW1uMVJvdzA7XHJcblx0XHR0aGlzWzRdID0gY29sdW1uMVJvdzE7XHJcblx0XHR0aGlzWzVdID0gY29sdW1uMVJvdzI7XHJcblx0XHR0aGlzWzZdID0gY29sdW1uMlJvdzA7XHJcblx0XHR0aGlzWzddID0gY29sdW1uMlJvdzE7XHJcblx0XHR0aGlzWzhdID0gY29sdW1uMlJvdzI7XHJcblx0fVxyXG5cdHNldEZyb21NYXRyaXg0KG1hdHJpeDogTWF0cml4NCk6IE1hdHJpeDMge1xyXG5cdFx0dGhpc1swXSA9IG1hdHJpeFswXTtcclxuXHRcdHRoaXNbMV0gPSBtYXRyaXhbMV07XHJcblx0XHR0aGlzWzJdID0gbWF0cml4WzJdO1xyXG5cdFx0dGhpc1szXSA9IG1hdHJpeFs0XTtcclxuXHRcdHRoaXNbNF0gPSBtYXRyaXhbNV07XHJcblx0XHR0aGlzWzVdID0gbWF0cml4WzJdO1xyXG5cdFx0dGhpc1s2XSA9IG1hdHJpeFs4XTtcclxuXHRcdHRoaXNbN10gPSBtYXRyaXhbOV07XHJcblx0XHR0aGlzWzhdID0gbWF0cml4WzEwXTtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHRnZXROb3JtYWxNYXRyaXgobWF0cml4NDogTWF0cml4NCk6IE1hdHJpeDMge1xyXG5cdFx0dGhpcy5zZXRGcm9tTWF0cml4NChtYXRyaXg0KTtcclxuXHRcdE1hdHJpeDMuaW52ZXJzZSh0aGlzLCB0aGlzKTtcclxuXHRcdE1hdHJpeDMudHJhbnNwb3NlKHRoaXMsIHRoaXMpO1xyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgY2xvbmUobWF0cml4OiBNYXRyaXgzIHwgbnVtYmVyW10sIHJlc3VsdDogTWF0cml4Myk6IE1hdHJpeDMge1xyXG5cdFx0aWYgKCFkZWZpbmVkKG1hdHJpeCkpIHtcclxuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJldHVybiBuZXcgTWF0cml4MyhcclxuXHRcdFx0XHRtYXRyaXhbMF0sXHJcblx0XHRcdFx0bWF0cml4WzNdLFxyXG5cdFx0XHRcdG1hdHJpeFs2XSxcclxuXHRcdFx0XHRtYXRyaXhbMV0sXHJcblx0XHRcdFx0bWF0cml4WzRdLFxyXG5cdFx0XHRcdG1hdHJpeFs3XSxcclxuXHRcdFx0XHRtYXRyaXhbMl0sXHJcblx0XHRcdFx0bWF0cml4WzVdLFxyXG5cdFx0XHRcdG1hdHJpeFs4XVxyXG5cdFx0XHQpO1xyXG5cdFx0fVxyXG5cdFx0cmVzdWx0WzBdID0gbWF0cml4WzBdO1xyXG5cdFx0cmVzdWx0WzFdID0gbWF0cml4WzFdO1xyXG5cdFx0cmVzdWx0WzJdID0gbWF0cml4WzJdO1xyXG5cdFx0cmVzdWx0WzNdID0gbWF0cml4WzNdO1xyXG5cdFx0cmVzdWx0WzRdID0gbWF0cml4WzRdO1xyXG5cdFx0cmVzdWx0WzVdID0gbWF0cml4WzVdO1xyXG5cdFx0cmVzdWx0WzZdID0gbWF0cml4WzZdO1xyXG5cdFx0cmVzdWx0WzddID0gbWF0cml4WzddO1xyXG5cdFx0cmVzdWx0WzhdID0gbWF0cml4WzhdO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBmcm9tQ29sdW1uTWFqb3JBcnJheSh2YWx1ZXM6IEFycmF5PG51bWJlcj4sIHJlc3VsdD86IE1hdHJpeDMpOiBNYXRyaXgzIHtcclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJlc3VsdCA9IG5ldyBNYXRyaXgzKCk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gTWF0cml4My5jbG9uZSh2YWx1ZXMsIHJlc3VsdCk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZnJvbVJvd01ham9yQXJyYXkodmFsdWVzOiBBcnJheTxudW1iZXI+LCByZXN1bHQ/OiBNYXRyaXgzKTogTWF0cml4MyB7XHJcblx0XHRpZiAoIWRlZmluZWQocmVzdWx0KSkge1xyXG5cdFx0XHRyZXR1cm4gbmV3IE1hdHJpeDMoXHJcblx0XHRcdFx0dmFsdWVzWzBdLFxyXG5cdFx0XHRcdHZhbHVlc1sxXSxcclxuXHRcdFx0XHR2YWx1ZXNbMl0sXHJcblx0XHRcdFx0dmFsdWVzWzNdLFxyXG5cdFx0XHRcdHZhbHVlc1s0XSxcclxuXHRcdFx0XHR2YWx1ZXNbNV0sXHJcblx0XHRcdFx0dmFsdWVzWzZdLFxyXG5cdFx0XHRcdHZhbHVlc1s3XSxcclxuXHRcdFx0XHR2YWx1ZXNbOF1cclxuXHRcdFx0KTtcclxuXHRcdH1cclxuXHRcdHJlc3VsdFswXSA9IHZhbHVlc1swXTtcclxuXHRcdHJlc3VsdFsxXSA9IHZhbHVlc1szXTtcclxuXHRcdHJlc3VsdFsyXSA9IHZhbHVlc1s2XTtcclxuXHRcdHJlc3VsdFszXSA9IHZhbHVlc1sxXTtcclxuXHRcdHJlc3VsdFs0XSA9IHZhbHVlc1s0XTtcclxuXHRcdHJlc3VsdFs1XSA9IHZhbHVlc1s3XTtcclxuXHRcdHJlc3VsdFs2XSA9IHZhbHVlc1syXTtcclxuXHRcdHJlc3VsdFs3XSA9IHZhbHVlc1s1XTtcclxuXHRcdHJlc3VsdFs4XSA9IHZhbHVlc1s4XTtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZnJvbVF1YXRlcm5pb24ocXVhdGVybmlvbjogUXVhdGVybmlvbiwgcmVzdWx0PzogTWF0cml4Myk6IE1hdHJpeDMge1xyXG5cdFx0Y29uc3QgeDIgPSBxdWF0ZXJuaW9uLnggKiBxdWF0ZXJuaW9uLng7XHJcblx0XHRjb25zdCB4eSA9IHF1YXRlcm5pb24ueCAqIHF1YXRlcm5pb24ueTtcclxuXHRcdGNvbnN0IHh6ID0gcXVhdGVybmlvbi54ICogcXVhdGVybmlvbi56O1xyXG5cdFx0Y29uc3QgeHcgPSBxdWF0ZXJuaW9uLnggKiBxdWF0ZXJuaW9uLnc7XHJcblx0XHRjb25zdCB5MiA9IHF1YXRlcm5pb24ueSAqIHF1YXRlcm5pb24ueTtcclxuXHRcdGNvbnN0IHl6ID0gcXVhdGVybmlvbi55ICogcXVhdGVybmlvbi56O1xyXG5cdFx0Y29uc3QgeXcgPSBxdWF0ZXJuaW9uLnkgKiBxdWF0ZXJuaW9uLnc7XHJcblx0XHRjb25zdCB6MiA9IHF1YXRlcm5pb24ueiAqIHF1YXRlcm5pb24uejtcclxuXHRcdGNvbnN0IHp3ID0gcXVhdGVybmlvbi56ICogcXVhdGVybmlvbi53O1xyXG5cdFx0Y29uc3QgdzIgPSBxdWF0ZXJuaW9uLncgKiBxdWF0ZXJuaW9uLnc7XHJcblxyXG5cdFx0Y29uc3QgbTAwID0geDIgLSB5MiAtIHoyICsgdzI7XHJcblx0XHRjb25zdCBtMDEgPSAyLjAgKiAoeHkgLSB6dyk7XHJcblx0XHRjb25zdCBtMDIgPSAyLjAgKiAoeHogKyB5dyk7XHJcblxyXG5cdFx0Y29uc3QgbTEwID0gMi4wICogKHh5ICsgencpO1xyXG5cdFx0Y29uc3QgbTExID0gLXgyICsgeTIgLSB6MiArIHcyO1xyXG5cdFx0Y29uc3QgbTEyID0gMi4wICogKHl6IC0geHcpO1xyXG5cclxuXHRcdGNvbnN0IG0yMCA9IDIuMCAqICh4eiAtIHl3KTtcclxuXHRcdGNvbnN0IG0yMSA9IDIuMCAqICh5eiArIHh3KTtcclxuXHRcdGNvbnN0IG0yMiA9IC14MiAtIHkyICsgejIgKyB3MjtcclxuXHJcblx0XHRpZiAoIWRlZmluZWQocmVzdWx0KSkge1xyXG5cdFx0XHRyZXR1cm4gbmV3IE1hdHJpeDMobTAwLCBtMDEsIG0wMiwgbTEwLCBtMTEsIG0xMiwgbTIwLCBtMjEsIG0yMik7XHJcblx0XHR9XHJcblx0XHRyZXN1bHRbMF0gPSBtMDA7XHJcblx0XHRyZXN1bHRbMV0gPSBtMTA7XHJcblx0XHRyZXN1bHRbMl0gPSBtMjA7XHJcblx0XHRyZXN1bHRbM10gPSBtMDE7XHJcblx0XHRyZXN1bHRbNF0gPSBtMTE7XHJcblx0XHRyZXN1bHRbNV0gPSBtMjE7XHJcblx0XHRyZXN1bHRbNl0gPSBtMDI7XHJcblx0XHRyZXN1bHRbN10gPSBtMTI7XHJcblx0XHRyZXN1bHRbOF0gPSBtMjI7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGZyb21TY2FsZShzY2FsZTogVmVjdG9yMywgcmVzdWx0OiBNYXRyaXgzKTogTWF0cml4MyB7XHJcblx0XHRpZiAoIWRlZmluZWQocmVzdWx0KSkge1xyXG5cdFx0XHRyZXR1cm4gbmV3IE1hdHJpeDMoc2NhbGUueCwgMC4wLCAwLjAsIDAuMCwgc2NhbGUueSwgMC4wLCAwLjAsIDAuMCwgc2NhbGUueik7XHJcblx0XHR9XHJcblxyXG5cdFx0cmVzdWx0WzBdID0gc2NhbGUueDtcclxuXHRcdHJlc3VsdFsxXSA9IDAuMDtcclxuXHRcdHJlc3VsdFsyXSA9IDAuMDtcclxuXHRcdHJlc3VsdFszXSA9IDAuMDtcclxuXHRcdHJlc3VsdFs0XSA9IHNjYWxlLnk7XHJcblx0XHRyZXN1bHRbNV0gPSAwLjA7XHJcblx0XHRyZXN1bHRbNl0gPSAwLjA7XHJcblx0XHRyZXN1bHRbN10gPSAwLjA7XHJcblx0XHRyZXN1bHRbOF0gPSBzY2FsZS56O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBmcm9tUm90YXRpb25YKGFuZ2xlOiBudW1iZXIsIHJlc3VsdDogTWF0cml4Myk6IE1hdHJpeDMge1xyXG5cdFx0Y29uc3QgY29zQW5nbGUgPSBNYXRoLmNvcyhhbmdsZSk7XHJcblx0XHRjb25zdCBzaW5BbmdsZSA9IE1hdGguc2luKGFuZ2xlKTtcclxuXHJcblx0XHRpZiAoIWRlZmluZWQocmVzdWx0KSkge1xyXG5cdFx0XHRyZXR1cm4gbmV3IE1hdHJpeDMoMS4wLCAwLjAsIDAuMCwgMC4wLCBjb3NBbmdsZSwgLXNpbkFuZ2xlLCAwLjAsIHNpbkFuZ2xlLCBjb3NBbmdsZSk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmVzdWx0WzBdID0gMS4wO1xyXG5cdFx0cmVzdWx0WzFdID0gMC4wO1xyXG5cdFx0cmVzdWx0WzJdID0gMC4wO1xyXG5cdFx0cmVzdWx0WzNdID0gMC4wO1xyXG5cdFx0cmVzdWx0WzRdID0gY29zQW5nbGU7XHJcblx0XHRyZXN1bHRbNV0gPSBzaW5BbmdsZTtcclxuXHRcdHJlc3VsdFs2XSA9IDAuMDtcclxuXHRcdHJlc3VsdFs3XSA9IC1zaW5BbmdsZTtcclxuXHRcdHJlc3VsdFs4XSA9IGNvc0FuZ2xlO1xyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZnJvbVJvdGF0aW9uWShhbmdsZTogbnVtYmVyLCByZXN1bHQ6IE1hdHJpeDMpOiBNYXRyaXgzIHtcclxuXHRcdGNvbnN0IGNvc0FuZ2xlID0gTWF0aC5jb3MoYW5nbGUpO1xyXG5cdFx0Y29uc3Qgc2luQW5nbGUgPSBNYXRoLnNpbihhbmdsZSk7XHJcblxyXG5cdFx0aWYgKCFkZWZpbmVkKHJlc3VsdCkpIHtcclxuXHRcdFx0cmV0dXJuIG5ldyBNYXRyaXgzKGNvc0FuZ2xlLCAwLjAsIHNpbkFuZ2xlLCAwLjAsIDEuMCwgMC4wLCAtc2luQW5nbGUsIDAuMCwgY29zQW5nbGUpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJlc3VsdFswXSA9IGNvc0FuZ2xlO1xyXG5cdFx0cmVzdWx0WzFdID0gMC4wO1xyXG5cdFx0cmVzdWx0WzJdID0gLXNpbkFuZ2xlO1xyXG5cdFx0cmVzdWx0WzNdID0gMC4wO1xyXG5cdFx0cmVzdWx0WzRdID0gMS4wO1xyXG5cdFx0cmVzdWx0WzVdID0gMC4wO1xyXG5cdFx0cmVzdWx0WzZdID0gc2luQW5nbGU7XHJcblx0XHRyZXN1bHRbN10gPSAwLjA7XHJcblx0XHRyZXN1bHRbOF0gPSBjb3NBbmdsZTtcclxuXHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGZyb21Sb3RhdGlvblpzdGF0aWMoYW5nbGU6IG51bWJlciwgcmVzdWx0OiBNYXRyaXgzKTogTWF0cml4MyB7XHJcblx0XHRjb25zdCBjb3NBbmdsZSA9IE1hdGguY29zKGFuZ2xlKTtcclxuXHRcdGNvbnN0IHNpbkFuZ2xlID0gTWF0aC5zaW4oYW5nbGUpO1xyXG5cclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJldHVybiBuZXcgTWF0cml4Myhjb3NBbmdsZSwgLXNpbkFuZ2xlLCAwLjAsIHNpbkFuZ2xlLCBjb3NBbmdsZSwgMC4wLCAwLjAsIDAuMCwgMS4wKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXN1bHRbMF0gPSBjb3NBbmdsZTtcclxuXHRcdHJlc3VsdFsxXSA9IHNpbkFuZ2xlO1xyXG5cdFx0cmVzdWx0WzJdID0gMC4wO1xyXG5cdFx0cmVzdWx0WzNdID0gLXNpbkFuZ2xlO1xyXG5cdFx0cmVzdWx0WzRdID0gY29zQW5nbGU7XHJcblx0XHRyZXN1bHRbNV0gPSAwLjA7XHJcblx0XHRyZXN1bHRbNl0gPSAwLjA7XHJcblx0XHRyZXN1bHRbN10gPSAwLjA7XHJcblx0XHRyZXN1bHRbOF0gPSAxLjA7XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblx0dG9BcnJheSgpIHtcclxuXHRcdGNvbnN0IHJlc3VsdCA9IFtdO1xyXG5cdFx0TWF0cml4My50b0FycmF5KHRoaXMsIHJlc3VsdCk7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIHRvQXJyYXkobWF0cml4OiBNYXRyaXgzLCByZXN1bHQ6IG51bWJlcltdKTogbnVtYmVyW10ge1xyXG5cdFx0aWYgKCFkZWZpbmVkKHJlc3VsdCkpIHtcclxuXHRcdFx0cmV0dXJuIFttYXRyaXhbMF0sIG1hdHJpeFsxXSwgbWF0cml4WzJdLCBtYXRyaXhbM10sIG1hdHJpeFs0XSwgbWF0cml4WzVdLCBtYXRyaXhbNl0sIG1hdHJpeFs3XSwgbWF0cml4WzhdXTtcclxuXHRcdH1cclxuXHRcdHJlc3VsdFswXSA9IG1hdHJpeFswXTtcclxuXHRcdHJlc3VsdFsxXSA9IG1hdHJpeFsxXTtcclxuXHRcdHJlc3VsdFsyXSA9IG1hdHJpeFsyXTtcclxuXHRcdHJlc3VsdFszXSA9IG1hdHJpeFszXTtcclxuXHRcdHJlc3VsdFs0XSA9IG1hdHJpeFs0XTtcclxuXHRcdHJlc3VsdFs1XSA9IG1hdHJpeFs1XTtcclxuXHRcdHJlc3VsdFs2XSA9IG1hdHJpeFs2XTtcclxuXHRcdHJlc3VsdFs3XSA9IG1hdHJpeFs3XTtcclxuXHRcdHJlc3VsdFs4XSA9IG1hdHJpeFs4XTtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZ2V0RWxlbWVudEluZGV4KGNvbHVtbjogbnVtYmVyLCByb3c6IG51bWJlcik6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gY29sdW1uICogMyArIHJvdztcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBnZXRDb2x1bW4obWF0cml4OiBNYXRyaXgzLCBpbmRleDogbnVtYmVyLCByZXN1bHQ6IFZlY3RvcjMpOiBWZWN0b3IzIHtcclxuXHRcdGNvbnN0IHN0YXJ0SW5kZXggPSBpbmRleCAqIDM7XHJcblx0XHRjb25zdCB4ID0gbWF0cml4W3N0YXJ0SW5kZXhdO1xyXG5cdFx0Y29uc3QgeSA9IG1hdHJpeFtzdGFydEluZGV4ICsgMV07XHJcblx0XHRjb25zdCB6ID0gbWF0cml4W3N0YXJ0SW5kZXggKyAyXTtcclxuXHJcblx0XHRyZXN1bHQueCA9IHg7XHJcblx0XHRyZXN1bHQueSA9IHk7XHJcblx0XHRyZXN1bHQueiA9IHo7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIHNldENvbHVtbihtYXRyaXg6IE1hdHJpeDMsIGluZGV4OiBudW1iZXIsIGNhcnRlc2lhbjogVmVjdG9yMywgcmVzdWx0OiBNYXRyaXgzKTogTWF0cml4MyB7XHJcblx0XHRyZXN1bHQgPSBNYXRyaXgzLmNsb25lKG1hdHJpeCwgcmVzdWx0KTtcclxuXHRcdGNvbnN0IHN0YXJ0SW5kZXggPSBpbmRleCAqIDM7XHJcblx0XHRyZXN1bHRbc3RhcnRJbmRleF0gPSBjYXJ0ZXNpYW4ueDtcclxuXHRcdHJlc3VsdFtzdGFydEluZGV4ICsgMV0gPSBjYXJ0ZXNpYW4ueTtcclxuXHRcdHJlc3VsdFtzdGFydEluZGV4ICsgMl0gPSBjYXJ0ZXNpYW4uejtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZ2V0Um93KG1hdHJpeDogTWF0cml4MywgaW5kZXg6IG51bWJlciwgcmVzdWx0OiBWZWN0b3IzKTogVmVjdG9yMyB7XHJcblx0XHRjb25zdCB4ID0gbWF0cml4W2luZGV4XTtcclxuXHRcdGNvbnN0IHkgPSBtYXRyaXhbaW5kZXggKyAzXTtcclxuXHRcdGNvbnN0IHogPSBtYXRyaXhbaW5kZXggKyA2XTtcclxuXHJcblx0XHRyZXN1bHQueCA9IHg7XHJcblx0XHRyZXN1bHQueSA9IHk7XHJcblx0XHRyZXN1bHQueiA9IHo7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIHNldFJvdyhtYXRyaXg6IE1hdHJpeDMsIGluZGV4OiBudW1iZXIsIGNhcnRlc2lhbjogVmVjdG9yMywgcmVzdWx0OiBNYXRyaXgzKTogTWF0cml4MyB7XHJcblx0XHRyZXN1bHQgPSBNYXRyaXgzLmNsb25lKG1hdHJpeCwgcmVzdWx0KTtcclxuXHRcdHJlc3VsdFtpbmRleF0gPSBjYXJ0ZXNpYW4ueDtcclxuXHRcdHJlc3VsdFtpbmRleCArIDNdID0gY2FydGVzaWFuLnk7XHJcblx0XHRyZXN1bHRbaW5kZXggKyA2XSA9IGNhcnRlc2lhbi56O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBzZXRTY2FsZShtYXRyaXg6IE1hdHJpeDMsIHNjYWxlOiBWZWN0b3IzLCByZXN1bHQ6IE1hdHJpeDMpOiBNYXRyaXgzIHtcclxuXHRcdGNvbnN0IGV4aXN0aW5nU2NhbGUgPSBNYXRyaXgzLmdldFNjYWxlKG1hdHJpeCwgc2NhbGVTY3JhdGNoMSk7XHJcblx0XHRjb25zdCBzY2FsZVJhdGlvWCA9IHNjYWxlLnggLyBleGlzdGluZ1NjYWxlLng7XHJcblx0XHRjb25zdCBzY2FsZVJhdGlvWSA9IHNjYWxlLnkgLyBleGlzdGluZ1NjYWxlLnk7XHJcblx0XHRjb25zdCBzY2FsZVJhdGlvWiA9IHNjYWxlLnogLyBleGlzdGluZ1NjYWxlLno7XHJcblxyXG5cdFx0cmVzdWx0WzBdID0gbWF0cml4WzBdICogc2NhbGVSYXRpb1g7XHJcblx0XHRyZXN1bHRbMV0gPSBtYXRyaXhbMV0gKiBzY2FsZVJhdGlvWDtcclxuXHRcdHJlc3VsdFsyXSA9IG1hdHJpeFsyXSAqIHNjYWxlUmF0aW9YO1xyXG5cdFx0cmVzdWx0WzNdID0gbWF0cml4WzNdICogc2NhbGVSYXRpb1k7XHJcblx0XHRyZXN1bHRbNF0gPSBtYXRyaXhbNF0gKiBzY2FsZVJhdGlvWTtcclxuXHRcdHJlc3VsdFs1XSA9IG1hdHJpeFs1XSAqIHNjYWxlUmF0aW9ZO1xyXG5cdFx0cmVzdWx0WzZdID0gbWF0cml4WzZdICogc2NhbGVSYXRpb1o7XHJcblx0XHRyZXN1bHRbN10gPSBtYXRyaXhbN10gKiBzY2FsZVJhdGlvWjtcclxuXHRcdHJlc3VsdFs4XSA9IG1hdHJpeFs4XSAqIHNjYWxlUmF0aW9aO1xyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZ2V0U2NhbGUobWF0cml4OiBNYXRyaXgzLCByZXN1bHQ6IFZlY3RvcjMpOiBWZWN0b3IzIHtcclxuXHRcdHJlc3VsdC54ID0gVmVjdG9yMy5tYWduaXR1ZGUoVmVjdG9yMy5mcm9tRWxlbWVudHMobWF0cml4WzBdLCBtYXRyaXhbMV0sIG1hdHJpeFsyXSwgc2NyYXRjaENvbHVtbikpO1xyXG5cdFx0cmVzdWx0LnkgPSBWZWN0b3IzLm1hZ25pdHVkZShWZWN0b3IzLmZyb21FbGVtZW50cyhtYXRyaXhbM10sIG1hdHJpeFs0XSwgbWF0cml4WzVdLCBzY3JhdGNoQ29sdW1uKSk7XHJcblx0XHRyZXN1bHQueiA9IFZlY3RvcjMubWFnbml0dWRlKFZlY3RvcjMuZnJvbUVsZW1lbnRzKG1hdHJpeFs2XSwgbWF0cml4WzddLCBtYXRyaXhbOF0sIHNjcmF0Y2hDb2x1bW4pKTtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZ2V0TWF4aW11bVNjYWxlKG1hdHJpeDogTWF0cml4Myk6IG51bWJlciB7XHJcblx0XHRNYXRyaXgzLmdldFNjYWxlKG1hdHJpeCwgc2NhbGVTY3JhdGNoMyk7XHJcblx0XHRyZXR1cm4gVmVjdG9yMy5tYXhpbXVtQ29tcG9uZW50KHNjYWxlU2NyYXRjaDMpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIHNldFJvdGF0aW9uKG1hdHJpeDogTWF0cml4Mywgcm90YXRpb246IE1hdHJpeDMsIHJlc3VsdDogTWF0cml4Myk6IE1hdHJpeDMge1xyXG5cdFx0Y29uc3Qgc2NhbGUgPSBNYXRyaXgzLmdldFNjYWxlKG1hdHJpeCwgc2NhbGVTY3JhdGNoNCk7XHJcblxyXG5cdFx0cmVzdWx0WzBdID0gcm90YXRpb25bMF0gKiBzY2FsZS54O1xyXG5cdFx0cmVzdWx0WzFdID0gcm90YXRpb25bMV0gKiBzY2FsZS54O1xyXG5cdFx0cmVzdWx0WzJdID0gcm90YXRpb25bMl0gKiBzY2FsZS54O1xyXG5cdFx0cmVzdWx0WzNdID0gcm90YXRpb25bM10gKiBzY2FsZS55O1xyXG5cdFx0cmVzdWx0WzRdID0gcm90YXRpb25bNF0gKiBzY2FsZS55O1xyXG5cdFx0cmVzdWx0WzVdID0gcm90YXRpb25bNV0gKiBzY2FsZS55O1xyXG5cdFx0cmVzdWx0WzZdID0gcm90YXRpb25bNl0gKiBzY2FsZS56O1xyXG5cdFx0cmVzdWx0WzddID0gcm90YXRpb25bN10gKiBzY2FsZS56O1xyXG5cdFx0cmVzdWx0WzhdID0gcm90YXRpb25bOF0gKiBzY2FsZS56O1xyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZ2V0Um90YXRpb24obWF0cml4OiBNYXRyaXgzLCByZXN1bHQ6IE1hdHJpeDMpOiBNYXRyaXgzIHtcclxuXHRcdGNvbnN0IHNjYWxlID0gTWF0cml4My5nZXRTY2FsZShtYXRyaXgsIHNjYWxlU2NyYXRjaDUpO1xyXG5cclxuXHRcdHJlc3VsdFswXSA9IG1hdHJpeFswXSAvIHNjYWxlLng7XHJcblx0XHRyZXN1bHRbMV0gPSBtYXRyaXhbMV0gLyBzY2FsZS54O1xyXG5cdFx0cmVzdWx0WzJdID0gbWF0cml4WzJdIC8gc2NhbGUueDtcclxuXHRcdHJlc3VsdFszXSA9IG1hdHJpeFszXSAvIHNjYWxlLnk7XHJcblx0XHRyZXN1bHRbNF0gPSBtYXRyaXhbNF0gLyBzY2FsZS55O1xyXG5cdFx0cmVzdWx0WzVdID0gbWF0cml4WzVdIC8gc2NhbGUueTtcclxuXHRcdHJlc3VsdFs2XSA9IG1hdHJpeFs2XSAvIHNjYWxlLno7XHJcblx0XHRyZXN1bHRbN10gPSBtYXRyaXhbN10gLyBzY2FsZS56O1xyXG5cdFx0cmVzdWx0WzhdID0gbWF0cml4WzhdIC8gc2NhbGUuejtcclxuXHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG11bHRpcGx5KGxlZnQ6IE1hdHJpeDMsIHJpZ2h0OiBNYXRyaXgzLCByZXN1bHQ6IE1hdHJpeDMpOiBNYXRyaXgzIHtcclxuXHRcdGNvbnN0IGNvbHVtbjBSb3cwID0gbGVmdFswXSAqIHJpZ2h0WzBdICsgbGVmdFszXSAqIHJpZ2h0WzFdICsgbGVmdFs2XSAqIHJpZ2h0WzJdO1xyXG5cdFx0Y29uc3QgY29sdW1uMFJvdzEgPSBsZWZ0WzFdICogcmlnaHRbMF0gKyBsZWZ0WzRdICogcmlnaHRbMV0gKyBsZWZ0WzddICogcmlnaHRbMl07XHJcblx0XHRjb25zdCBjb2x1bW4wUm93MiA9IGxlZnRbMl0gKiByaWdodFswXSArIGxlZnRbNV0gKiByaWdodFsxXSArIGxlZnRbOF0gKiByaWdodFsyXTtcclxuXHJcblx0XHRjb25zdCBjb2x1bW4xUm93MCA9IGxlZnRbMF0gKiByaWdodFszXSArIGxlZnRbM10gKiByaWdodFs0XSArIGxlZnRbNl0gKiByaWdodFs1XTtcclxuXHRcdGNvbnN0IGNvbHVtbjFSb3cxID0gbGVmdFsxXSAqIHJpZ2h0WzNdICsgbGVmdFs0XSAqIHJpZ2h0WzRdICsgbGVmdFs3XSAqIHJpZ2h0WzVdO1xyXG5cdFx0Y29uc3QgY29sdW1uMVJvdzIgPSBsZWZ0WzJdICogcmlnaHRbM10gKyBsZWZ0WzVdICogcmlnaHRbNF0gKyBsZWZ0WzhdICogcmlnaHRbNV07XHJcblxyXG5cdFx0Y29uc3QgY29sdW1uMlJvdzAgPSBsZWZ0WzBdICogcmlnaHRbNl0gKyBsZWZ0WzNdICogcmlnaHRbN10gKyBsZWZ0WzZdICogcmlnaHRbOF07XHJcblx0XHRjb25zdCBjb2x1bW4yUm93MSA9IGxlZnRbMV0gKiByaWdodFs2XSArIGxlZnRbNF0gKiByaWdodFs3XSArIGxlZnRbN10gKiByaWdodFs4XTtcclxuXHRcdGNvbnN0IGNvbHVtbjJSb3cyID0gbGVmdFsyXSAqIHJpZ2h0WzZdICsgbGVmdFs1XSAqIHJpZ2h0WzddICsgbGVmdFs4XSAqIHJpZ2h0WzhdO1xyXG5cclxuXHRcdHJlc3VsdFswXSA9IGNvbHVtbjBSb3cwO1xyXG5cdFx0cmVzdWx0WzFdID0gY29sdW1uMFJvdzE7XHJcblx0XHRyZXN1bHRbMl0gPSBjb2x1bW4wUm93MjtcclxuXHRcdHJlc3VsdFszXSA9IGNvbHVtbjFSb3cwO1xyXG5cdFx0cmVzdWx0WzRdID0gY29sdW1uMVJvdzE7XHJcblx0XHRyZXN1bHRbNV0gPSBjb2x1bW4xUm93MjtcclxuXHRcdHJlc3VsdFs2XSA9IGNvbHVtbjJSb3cwO1xyXG5cdFx0cmVzdWx0WzddID0gY29sdW1uMlJvdzE7XHJcblx0XHRyZXN1bHRbOF0gPSBjb2x1bW4yUm93MjtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgYWRkKGxlZnQ6IE1hdHJpeDMsIHJpZ2h0OiBNYXRyaXgzLCByZXN1bHQ6IE1hdHJpeDMpOiBNYXRyaXgzIHtcclxuXHRcdHJlc3VsdFswXSA9IGxlZnRbMF0gKyByaWdodFswXTtcclxuXHRcdHJlc3VsdFsxXSA9IGxlZnRbMV0gKyByaWdodFsxXTtcclxuXHRcdHJlc3VsdFsyXSA9IGxlZnRbMl0gKyByaWdodFsyXTtcclxuXHRcdHJlc3VsdFszXSA9IGxlZnRbM10gKyByaWdodFszXTtcclxuXHRcdHJlc3VsdFs0XSA9IGxlZnRbNF0gKyByaWdodFs0XTtcclxuXHRcdHJlc3VsdFs1XSA9IGxlZnRbNV0gKyByaWdodFs1XTtcclxuXHRcdHJlc3VsdFs2XSA9IGxlZnRbNl0gKyByaWdodFs2XTtcclxuXHRcdHJlc3VsdFs3XSA9IGxlZnRbN10gKyByaWdodFs3XTtcclxuXHRcdHJlc3VsdFs4XSA9IGxlZnRbOF0gKyByaWdodFs4XTtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgc3VidHJhY3QobGVmdDogTWF0cml4MywgcmlnaHQ6IE1hdHJpeDMsIHJlc3VsdDogTWF0cml4Mykge1xyXG5cdFx0cmVzdWx0WzBdID0gbGVmdFswXSAtIHJpZ2h0WzBdO1xyXG5cdFx0cmVzdWx0WzFdID0gbGVmdFsxXSAtIHJpZ2h0WzFdO1xyXG5cdFx0cmVzdWx0WzJdID0gbGVmdFsyXSAtIHJpZ2h0WzJdO1xyXG5cdFx0cmVzdWx0WzNdID0gbGVmdFszXSAtIHJpZ2h0WzNdO1xyXG5cdFx0cmVzdWx0WzRdID0gbGVmdFs0XSAtIHJpZ2h0WzRdO1xyXG5cdFx0cmVzdWx0WzVdID0gbGVmdFs1XSAtIHJpZ2h0WzVdO1xyXG5cdFx0cmVzdWx0WzZdID0gbGVmdFs2XSAtIHJpZ2h0WzZdO1xyXG5cdFx0cmVzdWx0WzddID0gbGVmdFs3XSAtIHJpZ2h0WzddO1xyXG5cdFx0cmVzdWx0WzhdID0gbGVmdFs4XSAtIHJpZ2h0WzhdO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBtdWx0aXBseUJ5VmVjdG9yKG1hdHJpeDogTWF0cml4MywgY2FydGVzaWFuOiBWZWN0b3IzLCByZXN1bHQ6IFZlY3RvcjMpOiBWZWN0b3IzIHtcclxuXHRcdGNvbnN0IHZYID0gY2FydGVzaWFuLng7XHJcblx0XHRjb25zdCB2WSA9IGNhcnRlc2lhbi55O1xyXG5cdFx0Y29uc3QgdlogPSBjYXJ0ZXNpYW4uejtcclxuXHJcblx0XHRjb25zdCB4ID0gbWF0cml4WzBdICogdlggKyBtYXRyaXhbM10gKiB2WSArIG1hdHJpeFs2XSAqIHZaO1xyXG5cdFx0Y29uc3QgeSA9IG1hdHJpeFsxXSAqIHZYICsgbWF0cml4WzRdICogdlkgKyBtYXRyaXhbN10gKiB2WjtcclxuXHRcdGNvbnN0IHogPSBtYXRyaXhbMl0gKiB2WCArIG1hdHJpeFs1XSAqIHZZICsgbWF0cml4WzhdICogdlo7XHJcblxyXG5cdFx0cmVzdWx0LnggPSB4O1xyXG5cdFx0cmVzdWx0LnkgPSB5O1xyXG5cdFx0cmVzdWx0LnogPSB6O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBtdWx0aXBseUJ5U2NhbGFyKG1hdHJpeDogTWF0cml4Mywgc2NhbGFyOiBudW1iZXIsIHJlc3VsdDogTWF0cml4Myk6IE1hdHJpeDMge1xyXG5cdFx0cmVzdWx0WzBdID0gbWF0cml4WzBdICogc2NhbGFyO1xyXG5cdFx0cmVzdWx0WzFdID0gbWF0cml4WzFdICogc2NhbGFyO1xyXG5cdFx0cmVzdWx0WzJdID0gbWF0cml4WzJdICogc2NhbGFyO1xyXG5cdFx0cmVzdWx0WzNdID0gbWF0cml4WzNdICogc2NhbGFyO1xyXG5cdFx0cmVzdWx0WzRdID0gbWF0cml4WzRdICogc2NhbGFyO1xyXG5cdFx0cmVzdWx0WzVdID0gbWF0cml4WzVdICogc2NhbGFyO1xyXG5cdFx0cmVzdWx0WzZdID0gbWF0cml4WzZdICogc2NhbGFyO1xyXG5cdFx0cmVzdWx0WzddID0gbWF0cml4WzddICogc2NhbGFyO1xyXG5cdFx0cmVzdWx0WzhdID0gbWF0cml4WzhdICogc2NhbGFyO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBtdWx0aXBseUJ5U2NhbGUobWF0cml4OiBNYXRyaXgzLCBzY2FsZTogVmVjdG9yMywgcmVzdWx0OiBNYXRyaXgzKTogTWF0cml4MyB7XHJcblx0XHRyZXN1bHRbMF0gPSBtYXRyaXhbMF0gKiBzY2FsZS54O1xyXG5cdFx0cmVzdWx0WzFdID0gbWF0cml4WzFdICogc2NhbGUueDtcclxuXHRcdHJlc3VsdFsyXSA9IG1hdHJpeFsyXSAqIHNjYWxlLng7XHJcblx0XHRyZXN1bHRbM10gPSBtYXRyaXhbM10gKiBzY2FsZS55O1xyXG5cdFx0cmVzdWx0WzRdID0gbWF0cml4WzRdICogc2NhbGUueTtcclxuXHRcdHJlc3VsdFs1XSA9IG1hdHJpeFs1XSAqIHNjYWxlLnk7XHJcblx0XHRyZXN1bHRbNl0gPSBtYXRyaXhbNl0gKiBzY2FsZS56O1xyXG5cdFx0cmVzdWx0WzddID0gbWF0cml4WzddICogc2NhbGUuejtcclxuXHRcdHJlc3VsdFs4XSA9IG1hdHJpeFs4XSAqIHNjYWxlLno7XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBuZWdhdGUobWF0cml4OiBNYXRyaXgzLCByZXN1bHQ6IE1hdHJpeDMpOiBNYXRyaXgzIHtcclxuXHRcdHJlc3VsdFswXSA9IC1tYXRyaXhbMF07XHJcblx0XHRyZXN1bHRbMV0gPSAtbWF0cml4WzFdO1xyXG5cdFx0cmVzdWx0WzJdID0gLW1hdHJpeFsyXTtcclxuXHRcdHJlc3VsdFszXSA9IC1tYXRyaXhbM107XHJcblx0XHRyZXN1bHRbNF0gPSAtbWF0cml4WzRdO1xyXG5cdFx0cmVzdWx0WzVdID0gLW1hdHJpeFs1XTtcclxuXHRcdHJlc3VsdFs2XSA9IC1tYXRyaXhbNl07XHJcblx0XHRyZXN1bHRbN10gPSAtbWF0cml4WzddO1xyXG5cdFx0cmVzdWx0WzhdID0gLW1hdHJpeFs4XTtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgdHJhbnNwb3NlKG1hdHJpeDogTWF0cml4MywgcmVzdWx0OiBNYXRyaXgzKTogTWF0cml4MyB7XHJcblx0XHRjb25zdCBjb2x1bW4wUm93MCA9IG1hdHJpeFswXTtcclxuXHRcdGNvbnN0IGNvbHVtbjBSb3cxID0gbWF0cml4WzNdO1xyXG5cdFx0Y29uc3QgY29sdW1uMFJvdzIgPSBtYXRyaXhbNl07XHJcblx0XHRjb25zdCBjb2x1bW4xUm93MCA9IG1hdHJpeFsxXTtcclxuXHRcdGNvbnN0IGNvbHVtbjFSb3cxID0gbWF0cml4WzRdO1xyXG5cdFx0Y29uc3QgY29sdW1uMVJvdzIgPSBtYXRyaXhbN107XHJcblx0XHRjb25zdCBjb2x1bW4yUm93MCA9IG1hdHJpeFsyXTtcclxuXHRcdGNvbnN0IGNvbHVtbjJSb3cxID0gbWF0cml4WzVdO1xyXG5cdFx0Y29uc3QgY29sdW1uMlJvdzIgPSBtYXRyaXhbOF07XHJcblxyXG5cdFx0cmVzdWx0WzBdID0gY29sdW1uMFJvdzA7XHJcblx0XHRyZXN1bHRbMV0gPSBjb2x1bW4wUm93MTtcclxuXHRcdHJlc3VsdFsyXSA9IGNvbHVtbjBSb3cyO1xyXG5cdFx0cmVzdWx0WzNdID0gY29sdW1uMVJvdzA7XHJcblx0XHRyZXN1bHRbNF0gPSBjb2x1bW4xUm93MTtcclxuXHRcdHJlc3VsdFs1XSA9IGNvbHVtbjFSb3cyO1xyXG5cdFx0cmVzdWx0WzZdID0gY29sdW1uMlJvdzA7XHJcblx0XHRyZXN1bHRbN10gPSBjb2x1bW4yUm93MTtcclxuXHRcdHJlc3VsdFs4XSA9IGNvbHVtbjJSb3cyO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBhYnMobWF0cml4OiBNYXRyaXgzLCByZXN1bHQ6IE1hdHJpeDMpOiBNYXRyaXgzIHtcclxuXHRcdHJlc3VsdFswXSA9IE1hdGguYWJzKG1hdHJpeFswXSk7XHJcblx0XHRyZXN1bHRbMV0gPSBNYXRoLmFicyhtYXRyaXhbMV0pO1xyXG5cdFx0cmVzdWx0WzJdID0gTWF0aC5hYnMobWF0cml4WzJdKTtcclxuXHRcdHJlc3VsdFszXSA9IE1hdGguYWJzKG1hdHJpeFszXSk7XHJcblx0XHRyZXN1bHRbNF0gPSBNYXRoLmFicyhtYXRyaXhbNF0pO1xyXG5cdFx0cmVzdWx0WzVdID0gTWF0aC5hYnMobWF0cml4WzVdKTtcclxuXHRcdHJlc3VsdFs2XSA9IE1hdGguYWJzKG1hdHJpeFs2XSk7XHJcblx0XHRyZXN1bHRbN10gPSBNYXRoLmFicyhtYXRyaXhbN10pO1xyXG5cdFx0cmVzdWx0WzhdID0gTWF0aC5hYnMobWF0cml4WzhdKTtcclxuXHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGRldGVybWluYW50KG1hdHJpeDogTWF0cml4Myk6IG51bWJlciB7XHJcblx0XHRjb25zdCBtMTEgPSBtYXRyaXhbMF07XHJcblx0XHRjb25zdCBtMjEgPSBtYXRyaXhbM107XHJcblx0XHRjb25zdCBtMzEgPSBtYXRyaXhbNl07XHJcblx0XHRjb25zdCBtMTIgPSBtYXRyaXhbMV07XHJcblx0XHRjb25zdCBtMjIgPSBtYXRyaXhbNF07XHJcblx0XHRjb25zdCBtMzIgPSBtYXRyaXhbN107XHJcblx0XHRjb25zdCBtMTMgPSBtYXRyaXhbMl07XHJcblx0XHRjb25zdCBtMjMgPSBtYXRyaXhbNV07XHJcblx0XHRjb25zdCBtMzMgPSBtYXRyaXhbOF07XHJcblxyXG5cdFx0cmV0dXJuIG0xMSAqIChtMjIgKiBtMzMgLSBtMjMgKiBtMzIpICsgbTEyICogKG0yMyAqIG0zMSAtIG0yMSAqIG0zMykgKyBtMTMgKiAobTIxICogbTMyIC0gbTIyICogbTMxKTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBpbnZlcnNlKG1hdHJpeDogTWF0cml4MywgcmVzdWx0OiBNYXRyaXgzKTogTWF0cml4MyB7XHJcblx0XHRjb25zdCBtMTEgPSBtYXRyaXhbMF07XHJcblx0XHRjb25zdCBtMjEgPSBtYXRyaXhbMV07XHJcblx0XHRjb25zdCBtMzEgPSBtYXRyaXhbMl07XHJcblx0XHRjb25zdCBtMTIgPSBtYXRyaXhbM107XHJcblx0XHRjb25zdCBtMjIgPSBtYXRyaXhbNF07XHJcblx0XHRjb25zdCBtMzIgPSBtYXRyaXhbNV07XHJcblx0XHRjb25zdCBtMTMgPSBtYXRyaXhbNl07XHJcblx0XHRjb25zdCBtMjMgPSBtYXRyaXhbN107XHJcblx0XHRjb25zdCBtMzMgPSBtYXRyaXhbOF07XHJcblxyXG5cdFx0Y29uc3QgZGV0ZXJtaW5hbnQgPSBNYXRyaXgzLmRldGVybWluYW50KG1hdHJpeCk7XHJcblxyXG5cdFx0Ly8gPj5pbmNsdWRlU3RhcnQoJ2RlYnVnJywgcHJhZ21hcy5kZWJ1Zyk7XHJcblx0XHRpZiAoTWF0aC5hYnMoZGV0ZXJtaW5hbnQpIDw9IEdNYXRoLkVQU0lMT04xNSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJtYXRyaXggaXMgbm90IGludmVydGlibGVcIik7XHJcblx0XHR9XHJcblx0XHQvLyA+PmluY2x1ZGVFbmQoJ2RlYnVnJyk7XHJcblxyXG5cdFx0cmVzdWx0WzBdID0gbTIyICogbTMzIC0gbTIzICogbTMyO1xyXG5cdFx0cmVzdWx0WzFdID0gbTIzICogbTMxIC0gbTIxICogbTMzO1xyXG5cdFx0cmVzdWx0WzJdID0gbTIxICogbTMyIC0gbTIyICogbTMxO1xyXG5cdFx0cmVzdWx0WzNdID0gbTEzICogbTMyIC0gbTEyICogbTMzO1xyXG5cdFx0cmVzdWx0WzRdID0gbTExICogbTMzIC0gbTEzICogbTMxO1xyXG5cdFx0cmVzdWx0WzVdID0gbTEyICogbTMxIC0gbTExICogbTMyO1xyXG5cdFx0cmVzdWx0WzZdID0gbTEyICogbTIzIC0gbTEzICogbTIyO1xyXG5cdFx0cmVzdWx0WzddID0gbTEzICogbTIxIC0gbTExICogbTIzO1xyXG5cdFx0cmVzdWx0WzhdID0gbTExICogbTIyIC0gbTEyICogbTIxO1xyXG5cclxuXHRcdGNvbnN0IHNjYWxlID0gMS4wIC8gZGV0ZXJtaW5hbnQ7XHJcblx0XHRyZXR1cm4gTWF0cml4My5tdWx0aXBseUJ5U2NhbGFyKHJlc3VsdCwgc2NhbGUsIHJlc3VsdCk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgaW52ZXJzZVRyYW5zcG9zZShtYXRyaXg6IE1hdHJpeDMsIHJlc3VsdDogTWF0cml4Mykge1xyXG5cdFx0cmV0dXJuIE1hdHJpeDMuaW52ZXJzZShNYXRyaXgzLnRyYW5zcG9zZShtYXRyaXgsIHNjcmF0Y2hUcmFuc3Bvc2VNYXRyaXgpLCByZXN1bHQpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGVxdWFscyhsZWZ0OiBNYXRyaXgzLCByaWdodDogTWF0cml4Myk6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0bGVmdCA9PT0gcmlnaHQgfHxcclxuXHRcdFx0KGRlZmluZWQobGVmdCkgJiZcclxuXHRcdFx0XHRkZWZpbmVkKHJpZ2h0KSAmJlxyXG5cdFx0XHRcdGxlZnRbMF0gPT09IHJpZ2h0WzBdICYmXHJcblx0XHRcdFx0bGVmdFsxXSA9PT0gcmlnaHRbMV0gJiZcclxuXHRcdFx0XHRsZWZ0WzJdID09PSByaWdodFsyXSAmJlxyXG5cdFx0XHRcdGxlZnRbM10gPT09IHJpZ2h0WzNdICYmXHJcblx0XHRcdFx0bGVmdFs0XSA9PT0gcmlnaHRbNF0gJiZcclxuXHRcdFx0XHRsZWZ0WzVdID09PSByaWdodFs1XSAmJlxyXG5cdFx0XHRcdGxlZnRbNl0gPT09IHJpZ2h0WzZdICYmXHJcblx0XHRcdFx0bGVmdFs3XSA9PT0gcmlnaHRbN10gJiZcclxuXHRcdFx0XHRsZWZ0WzhdID09PSByaWdodFs4XSlcclxuXHRcdCk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZXF1YWxzRXBzaWxvbihsZWZ0OiBNYXRyaXgzLCByaWdodDogTWF0cml4MywgZXBzaWxvbiA9IDApOiBib29sZWFuIHtcclxuXHRcdGVwc2lsb24gPSBkZWZhdWx0VmFsdWUoZXBzaWxvbiwgMCk7XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0bGVmdCA9PT0gcmlnaHQgfHxcclxuXHRcdFx0KGRlZmluZWQobGVmdCkgJiZcclxuXHRcdFx0XHRkZWZpbmVkKHJpZ2h0KSAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbMF0gLSByaWdodFswXSkgPD0gZXBzaWxvbiAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbMV0gLSByaWdodFsxXSkgPD0gZXBzaWxvbiAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbMl0gLSByaWdodFsyXSkgPD0gZXBzaWxvbiAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbM10gLSByaWdodFszXSkgPD0gZXBzaWxvbiAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbNF0gLSByaWdodFs0XSkgPD0gZXBzaWxvbiAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbNV0gLSByaWdodFs1XSkgPD0gZXBzaWxvbiAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbNl0gLSByaWdodFs2XSkgPD0gZXBzaWxvbiAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbN10gLSByaWdodFs3XSkgPD0gZXBzaWxvbiAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbOF0gLSByaWdodFs4XSkgPD0gZXBzaWxvbilcclxuXHRcdCk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgSURFTlRJVFkgPSBPYmplY3QuZnJlZXplKG5ldyBNYXRyaXgzKDEuMCwgMC4wLCAwLjAsIDAuMCwgMS4wLCAwLjAsIDAuMCwgMC4wLCAxLjApKTtcclxuXHJcblx0c3RhdGljIFpFUk8gPSBPYmplY3QuZnJlZXplKG5ldyBNYXRyaXgzKDAuMCwgMC4wLCAwLjAsIDAuMCwgMC4wLCAwLjAsIDAuMCwgMC4wLCAwLjApKTtcclxuXHJcblx0Y2xvbmUocmVzdWx0OiBNYXRyaXgzKTogTWF0cml4MyB7XHJcblx0XHRyZXR1cm4gTWF0cml4My5jbG9uZSh0aGlzLCByZXN1bHQpO1xyXG5cdH1cclxuXHJcblx0ZXF1YWxzKHJpZ2h0OiBNYXRyaXgzKTogYm9vbGVhbiB7XHJcblx0XHRyZXR1cm4gTWF0cml4My5lcXVhbHModGhpcywgcmlnaHQpO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRlcXVhbHNBcnJheShtYXRyaXg6IE1hdHJpeDMgfCBudW1iZXJbXSwgYXJyYXk6IG51bWJlcltdLCBvZmZzZXQ6IG51bWJlcik6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0bWF0cml4WzBdID09PSBhcnJheVtvZmZzZXRdICYmXHJcblx0XHRcdG1hdHJpeFsxXSA9PT0gYXJyYXlbb2Zmc2V0ICsgMV0gJiZcclxuXHRcdFx0bWF0cml4WzJdID09PSBhcnJheVtvZmZzZXQgKyAyXSAmJlxyXG5cdFx0XHRtYXRyaXhbM10gPT09IGFycmF5W29mZnNldCArIDNdICYmXHJcblx0XHRcdG1hdHJpeFs0XSA9PT0gYXJyYXlbb2Zmc2V0ICsgNF0gJiZcclxuXHRcdFx0bWF0cml4WzVdID09PSBhcnJheVtvZmZzZXQgKyA1XSAmJlxyXG5cdFx0XHRtYXRyaXhbNl0gPT09IGFycmF5W29mZnNldCArIDZdICYmXHJcblx0XHRcdG1hdHJpeFs3XSA9PT0gYXJyYXlbb2Zmc2V0ICsgN10gJiZcclxuXHRcdFx0bWF0cml4WzhdID09PSBhcnJheVtvZmZzZXQgKyA4XVxyXG5cdFx0KTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENvbXBhcmVzIHRoaXMgbWF0cml4IHRvIHRoZSBwcm92aWRlZCBtYXRyaXggY29tcG9uZW50d2lzZSBhbmQgcmV0dXJuc1xyXG5cdCAqIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZXkgYXJlIHdpdGhpbiB0aGUgcHJvdmlkZWQgZXBzaWxvbixcclxuXHQgKiA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlLlxyXG5cdCAqXHJcblx0ICogQHBhcmFtIHtNYXRyaXgzfSBbcmlnaHRdIFRoZSByaWdodCBoYW5kIHNpZGUgbWF0cml4LlxyXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBbZXBzaWxvbj0wXSBUaGUgZXBzaWxvbiB0byB1c2UgZm9yIGVxdWFsaXR5IHRlc3RpbmcuXHJcblx0ICogQHJldHVybnMge0Jvb2xlYW59IDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZXkgYXJlIHdpdGhpbiB0aGUgcHJvdmlkZWQgZXBzaWxvbiwgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS5cclxuXHQgKi9cclxuXHRlcXVhbHNFcHNpbG9uKHJpZ2h0LCBlcHNpbG9uKSB7XHJcblx0XHRyZXR1cm4gTWF0cml4My5lcXVhbHNFcHNpbG9uKHRoaXMsIHJpZ2h0LCBlcHNpbG9uKTtcclxuXHR9XHJcblxyXG5cdHRvU3RyaW5nKCkge1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0YCgke3RoaXNbMF19LCAke3RoaXNbM119LCAke3RoaXNbNl19KVxcbmAgK1xyXG5cdFx0XHRgKCR7dGhpc1sxXX0sICR7dGhpc1s0XX0sICR7dGhpc1s3XX0pXFxuYCArXHJcblx0XHRcdGAoJHt0aGlzWzJdfSwgJHt0aGlzWzVdfSwgJHt0aGlzWzhdfSlgXHJcblx0XHQpO1xyXG5cdH1cclxufVxyXG5cclxuY29uc3Qgc2NhbGVTY3JhdGNoMSA9IG5ldyBWZWN0b3IzKCk7XHJcbmNvbnN0IHNjYWxlU2NyYXRjaDIgPSBuZXcgVmVjdG9yMygpO1xyXG5jb25zdCBzY3JhdGNoQ29sdW1uID0gbmV3IFZlY3RvcjMoKTtcclxuY29uc3Qgc2NhbGVTY3JhdGNoMyA9IG5ldyBWZWN0b3IzKCk7XHJcbmNvbnN0IHNjYWxlU2NyYXRjaDQgPSBuZXcgVmVjdG9yMygpO1xyXG5jb25zdCBzY2FsZVNjcmF0Y2g1ID0gbmV3IFZlY3RvcjMoKTtcclxuXHJcbmZ1bmN0aW9uIGNvbXB1dGVGcm9iZW5pdXNOb3JtKG1hdHJpeCkge1xyXG5cdGxldCBub3JtID0gMC4wO1xyXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgOTsgKytpKSB7XHJcblx0XHRjb25zdCB0ZW1wID0gbWF0cml4W2ldO1xyXG5cdFx0bm9ybSArPSB0ZW1wICogdGVtcDtcclxuXHR9XHJcblxyXG5cdHJldHVybiBNYXRoLnNxcnQobm9ybSk7XHJcbn1cclxuXHJcbmNvbnN0IHJvd1ZhbCA9IFsxLCAwLCAwXTtcclxuY29uc3QgY29sVmFsID0gWzIsIDIsIDFdO1xyXG5cclxuZnVuY3Rpb24gb2ZmRGlhZ29uYWxGcm9iZW5pdXNOb3JtKG1hdHJpeCkge1xyXG5cdC8vIENvbXB1dGVzIHRoZSBcIm9mZi1kaWFnb25hbFwiIEZyb2Jlbml1cyBub3JtLlxyXG5cdC8vIEFzc3VtZXMgbWF0cml4IGlzIHN5bW1ldHJpYy5cclxuXHJcblx0bGV0IG5vcm0gPSAwLjA7XHJcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCAzOyArK2kpIHtcclxuXHRcdGNvbnN0IHRlbXAgPSBtYXRyaXhbTWF0cml4My5nZXRFbGVtZW50SW5kZXgoY29sVmFsW2ldLCByb3dWYWxbaV0pXTtcclxuXHRcdG5vcm0gKz0gMi4wICogdGVtcCAqIHRlbXA7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gTWF0aC5zcXJ0KG5vcm0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzaHVyRGVjb21wb3NpdGlvbihtYXRyaXgsIHJlc3VsdCkge1xyXG5cdC8vIFRoaXMgcm91dGluZSB3YXMgY3JlYXRlZCBiYXNlZCB1cG9uIE1hdHJpeCBDb21wdXRhdGlvbnMsIDNyZCBlZC4sIGJ5IEdvbHViIGFuZCBWYW4gTG9hbixcclxuXHQvLyBzZWN0aW9uIDguNC4yIFRoZSAyYnkyIFN5bW1ldHJpYyBTY2h1ciBEZWNvbXBvc2l0aW9uLlxyXG5cdC8vXHJcblx0Ly8gVGhlIHJvdXRpbmUgdGFrZXMgYSBtYXRyaXgsIHdoaWNoIGlzIGFzc3VtZWQgdG8gYmUgc3ltbWV0cmljLCBhbmRcclxuXHQvLyBmaW5kcyB0aGUgbGFyZ2VzdCBvZmYtZGlhZ29uYWwgdGVybSwgYW5kIHRoZW4gY3JlYXRlc1xyXG5cdC8vIGEgbWF0cml4IChyZXN1bHQpIHdoaWNoIGNhbiBiZSB1c2VkIHRvIGhlbHAgcmVkdWNlIGl0XHJcblxyXG5cdGNvbnN0IHRvbGVyYW5jZSA9IEdNYXRoLkVQU0lMT04xNTtcclxuXHJcblx0bGV0IG1heERpYWdvbmFsID0gMC4wO1xyXG5cdGxldCByb3RBeGlzID0gMTtcclxuXHJcblx0Ly8gZmluZCBwaXZvdCAocm90QXhpcykgYmFzZWQgb24gbWF4IGRpYWdvbmFsIG9mIG1hdHJpeFxyXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgMzsgKytpKSB7XHJcblx0XHRjb25zdCB0ZW1wID0gTWF0aC5hYnMobWF0cml4W01hdHJpeDMuZ2V0RWxlbWVudEluZGV4KGNvbFZhbFtpXSwgcm93VmFsW2ldKV0pO1xyXG5cdFx0aWYgKHRlbXAgPiBtYXhEaWFnb25hbCkge1xyXG5cdFx0XHRyb3RBeGlzID0gaTtcclxuXHRcdFx0bWF4RGlhZ29uYWwgPSB0ZW1wO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0bGV0IGMgPSAxLjA7XHJcblx0bGV0IHMgPSAwLjA7XHJcblxyXG5cdGNvbnN0IHAgPSByb3dWYWxbcm90QXhpc107XHJcblx0Y29uc3QgcSA9IGNvbFZhbFtyb3RBeGlzXTtcclxuXHJcblx0aWYgKE1hdGguYWJzKG1hdHJpeFtNYXRyaXgzLmdldEVsZW1lbnRJbmRleChxLCBwKV0pID4gdG9sZXJhbmNlKSB7XHJcblx0XHRjb25zdCBxcSA9IG1hdHJpeFtNYXRyaXgzLmdldEVsZW1lbnRJbmRleChxLCBxKV07XHJcblx0XHRjb25zdCBwcCA9IG1hdHJpeFtNYXRyaXgzLmdldEVsZW1lbnRJbmRleChwLCBwKV07XHJcblx0XHRjb25zdCBxcCA9IG1hdHJpeFtNYXRyaXgzLmdldEVsZW1lbnRJbmRleChxLCBwKV07XHJcblxyXG5cdFx0Y29uc3QgdGF1ID0gKHFxIC0gcHApIC8gMi4wIC8gcXA7XHJcblx0XHRsZXQgdDtcclxuXHJcblx0XHRpZiAodGF1IDwgMC4wKSB7XHJcblx0XHRcdHQgPSAtMS4wIC8gKC10YXUgKyBNYXRoLnNxcnQoMS4wICsgdGF1ICogdGF1KSk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR0ID0gMS4wIC8gKHRhdSArIE1hdGguc3FydCgxLjAgKyB0YXUgKiB0YXUpKTtcclxuXHRcdH1cclxuXHJcblx0XHRjID0gMS4wIC8gTWF0aC5zcXJ0KDEuMCArIHQgKiB0KTtcclxuXHRcdHMgPSB0ICogYztcclxuXHR9XHJcblxyXG5cdHJlc3VsdCA9IE1hdHJpeDMuY2xvbmUoTWF0cml4My5JREVOVElUWSwgcmVzdWx0KTtcclxuXHJcblx0cmVzdWx0W01hdHJpeDMuZ2V0RWxlbWVudEluZGV4KHAsIHApXSA9IHJlc3VsdFtNYXRyaXgzLmdldEVsZW1lbnRJbmRleChxLCBxKV0gPSBjO1xyXG5cdHJlc3VsdFtNYXRyaXgzLmdldEVsZW1lbnRJbmRleChxLCBwKV0gPSBzO1xyXG5cdHJlc3VsdFtNYXRyaXgzLmdldEVsZW1lbnRJbmRleChwLCBxKV0gPSAtcztcclxuXHJcblx0cmV0dXJuIHJlc3VsdDtcclxufVxyXG5jb25zdCBzY3JhdGNoVHJhbnNwb3NlTWF0cml4ID0gbmV3IE1hdHJpeDMoKTtcclxuZXhwb3J0IGRlZmF1bHQgTWF0cml4MztcclxuIiwiaW1wb3J0IHsgQXR0cmlidXRlIH0gZnJvbSBcIi4uL3JlbmRlci9BdHRyaWJ1dGVcIjtcclxuaW1wb3J0IGRlZmluZWQgZnJvbSBcIi4uL3V0aWxzL2RlZmluZWRcIjtcclxuaW1wb3J0IEdNYXRoIGZyb20gXCIuL01hdGhcIjtcclxuXHJcbmNsYXNzIFZlY3RvcjQge1xyXG5cdHB1YmxpYyBzdGF0aWMgWkVSTyA9IE9iamVjdC5mcmVlemUobmV3IFZlY3RvcjQoMC4wLCAwLjAsIDAuMCwgMC4wKSk7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgT05FID0gT2JqZWN0LmZyZWV6ZShuZXcgVmVjdG9yNCgxLjAsIDEuMCwgMS4wLCAxLjApKTtcclxuXHJcblx0cHVibGljIHN0YXRpYyBVTklUX1ggPSBPYmplY3QuZnJlZXplKG5ldyBWZWN0b3I0KDEuMCwgMC4wLCAwLjAsIDAuMCkpO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIFVOSVRfWSA9IE9iamVjdC5mcmVlemUobmV3IFZlY3RvcjQoMC4wLCAxLjAsIDAuMCwgMC4wKSk7XHJcblxyXG5cdHB1YmxpYyBzdGF0aWMgVU5JVF9aID0gT2JqZWN0LmZyZWV6ZShuZXcgVmVjdG9yNCgwLjAsIDAuMCwgMS4wLCAwLjApKTtcclxuXHJcblx0cHVibGljIHN0YXRpYyBVTklUX1cgPSBPYmplY3QuZnJlZXplKG5ldyBWZWN0b3I0KDAuMCwgMC4wLCAwLjAsIDEuMCkpO1xyXG5cdHg6IG51bWJlcjtcclxuXHR5OiBudW1iZXI7XHJcblx0ejogbnVtYmVyO1xyXG5cdHc6IG51bWJlcjtcclxuXHRjb25zdHJ1Y3Rvcih4ID0gMCwgeSA9IDAsIHogPSAwLCB3ID0gMCkge1xyXG5cdFx0dGhpcy54ID0geDtcclxuXHRcdHRoaXMueSA9IHk7XHJcblx0XHR0aGlzLnogPSB6O1xyXG5cdFx0dGhpcy53ID0gdztcclxuXHR9XHJcblx0c2V0KHg6IG51bWJlciwgeTogbnVtYmVyLCB6OiBudW1iZXIsIHc6IG51bWJlcik6IHZvaWQge1xyXG5cdFx0dGhpcy54ID0geDtcclxuXHRcdHRoaXMueSA9IHk7XHJcblx0XHR0aGlzLnogPSB6O1xyXG5cdFx0dGhpcy53ID0gdztcclxuXHR9XHJcblx0dG9BcnJheSgpOiBudW1iZXJbXSB7XHJcblx0XHRyZXR1cm4gW3RoaXMueCwgdGhpcy55LCB0aGlzLnosIHRoaXMud107XHJcblx0fVxyXG5cclxuXHRjbG9uZShyZXN1bHQ6IFZlY3RvcjQpOiBWZWN0b3I0IHtcclxuXHRcdHJldHVybiBWZWN0b3I0LmNsb25lKHRoaXMsIHJlc3VsdCk7XHJcblx0fVxyXG5cclxuXHRlcXVhbHMocmlnaHQ6IFZlY3RvcjQpOiBib29sZWFuIHtcclxuXHRcdHJldHVybiBWZWN0b3I0LmVxdWFscyh0aGlzLCByaWdodCk7XHJcblx0fVxyXG5cclxuXHRlcXVhbHNFcHNpbG9uKHJpZ2h0OiBWZWN0b3I0LCByZWxhdGl2ZUVwc2lsb24gPSAwLCBhYnNvbHV0ZUVwc2lsb24gPSAwKTogYm9vbGVhbiB7XHJcblx0XHRyZXR1cm4gVmVjdG9yNC5lcXVhbHNFcHNpbG9uKHRoaXMsIHJpZ2h0LCByZWxhdGl2ZUVwc2lsb24sIGFic29sdXRlRXBzaWxvbik7XHJcblx0fVxyXG5cclxuXHR0b1N0cmluZygpOiBzdHJpbmcge1xyXG5cdFx0cmV0dXJuIGAoJHt0aGlzLnh9LCAke3RoaXMueX0sICR7dGhpcy56fSwgJHt0aGlzLnd9KWA7XHJcblx0fVxyXG5cdGZyb21CdWZmZXJBdHRyaWJ1dGUoYXR0cmlidXRlOiBBdHRyaWJ1dGUsIGluZGV4OiBudW1iZXIpOiBWZWN0b3I0IHtcclxuXHRcdHRoaXMueCA9IGF0dHJpYnV0ZS5nZXRYKGluZGV4KTtcclxuXHRcdHRoaXMueSA9IGF0dHJpYnV0ZS5nZXRZKGluZGV4KTtcclxuXHRcdHRoaXMueiA9IGF0dHJpYnV0ZS5nZXRaKGluZGV4KTtcclxuXHRcdHRoaXMudyA9IGF0dHJpYnV0ZS5nZXRXKGluZGV4KTtcclxuXHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBmcm9tRWxlbWVudHMoeDogbnVtYmVyLCB5OiBudW1iZXIsIHo6IG51bWJlciwgdzogbnVtYmVyLCByZXN1bHQ6IFZlY3RvcjQpOiBWZWN0b3I0IHtcclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJldHVybiBuZXcgVmVjdG9yNCh4LCB5LCB6LCB3KTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXN1bHQueCA9IHg7XHJcblx0XHRyZXN1bHQueSA9IHk7XHJcblx0XHRyZXN1bHQueiA9IHo7XHJcblx0XHRyZXN1bHQudyA9IHc7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGNsb25lKGNhcnRlc2lhbjogVmVjdG9yNCwgcmVzdWx0OiBWZWN0b3I0KTogVmVjdG9yNCB7XHJcblx0XHRpZiAoIWRlZmluZWQoY2FydGVzaWFuKSkge1xyXG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJldHVybiBuZXcgVmVjdG9yNChjYXJ0ZXNpYW4ueCwgY2FydGVzaWFuLnksIGNhcnRlc2lhbi56LCBjYXJ0ZXNpYW4udyk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmVzdWx0LnggPSBjYXJ0ZXNpYW4ueDtcclxuXHRcdHJlc3VsdC55ID0gY2FydGVzaWFuLnk7XHJcblx0XHRyZXN1bHQueiA9IGNhcnRlc2lhbi56O1xyXG5cdFx0cmVzdWx0LncgPSBjYXJ0ZXNpYW4udztcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbWF4aW11bUNvbXBvbmVudChjYXJ0ZXNpYW46IFZlY3RvcjQpOiBudW1iZXIge1xyXG5cdFx0cmV0dXJuIE1hdGgubWF4KGNhcnRlc2lhbi54LCBjYXJ0ZXNpYW4ueSwgY2FydGVzaWFuLnosIGNhcnRlc2lhbi53KTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBtaW5pbXVtQ29tcG9uZW50KGNhcnRlc2lhbjogVmVjdG9yNCk6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gTWF0aC5taW4oY2FydGVzaWFuLngsIGNhcnRlc2lhbi55LCBjYXJ0ZXNpYW4ueiwgY2FydGVzaWFuLncpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG1pbmltdW1CeUNvbXBvbmVudChmaXJzdDogVmVjdG9yNCwgc2Vjb25kOiBWZWN0b3I0LCByZXN1bHQ6IFZlY3RvcjQpOiBWZWN0b3I0IHtcclxuXHRcdHJlc3VsdC54ID0gTWF0aC5taW4oZmlyc3QueCwgc2Vjb25kLngpO1xyXG5cdFx0cmVzdWx0LnkgPSBNYXRoLm1pbihmaXJzdC55LCBzZWNvbmQueSk7XHJcblx0XHRyZXN1bHQueiA9IE1hdGgubWluKGZpcnN0LnosIHNlY29uZC56KTtcclxuXHRcdHJlc3VsdC53ID0gTWF0aC5taW4oZmlyc3Qudywgc2Vjb25kLncpO1xyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbWF4aW11bUJ5Q29tcG9uZW50KGZpcnN0OiBWZWN0b3I0LCBzZWNvbmQ6IFZlY3RvcjQsIHJlc3VsdDogVmVjdG9yNCk6IFZlY3RvcjQge1xyXG5cdFx0cmVzdWx0LnggPSBNYXRoLm1heChmaXJzdC54LCBzZWNvbmQueCk7XHJcblx0XHRyZXN1bHQueSA9IE1hdGgubWF4KGZpcnN0LnksIHNlY29uZC55KTtcclxuXHRcdHJlc3VsdC56ID0gTWF0aC5tYXgoZmlyc3Queiwgc2Vjb25kLnopO1xyXG5cdFx0cmVzdWx0LncgPSBNYXRoLm1heChmaXJzdC53LCBzZWNvbmQudyk7XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBjbGFtcCh2YWx1ZTogVmVjdG9yNCwgbWluOiBWZWN0b3I0LCBtYXg6IFZlY3RvcjQsIHJlc3VsdDogVmVjdG9yNCk6IFZlY3RvcjQge1xyXG5cdFx0Y29uc3QgeCA9IEdNYXRoLmNsYW1wKHZhbHVlLngsIG1pbi54LCBtYXgueCk7XHJcblx0XHRjb25zdCB5ID0gR01hdGguY2xhbXAodmFsdWUueSwgbWluLnksIG1heC55KTtcclxuXHRcdGNvbnN0IHogPSBHTWF0aC5jbGFtcCh2YWx1ZS56LCBtaW4ueiwgbWF4LnopO1xyXG5cdFx0Y29uc3QgdyA9IEdNYXRoLmNsYW1wKHZhbHVlLncsIG1pbi53LCBtYXgudyk7XHJcblxyXG5cdFx0cmVzdWx0LnggPSB4O1xyXG5cdFx0cmVzdWx0LnkgPSB5O1xyXG5cdFx0cmVzdWx0LnogPSB6O1xyXG5cdFx0cmVzdWx0LncgPSB3O1xyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbWFnbml0dWRlU3F1YXJlZChjYXJ0ZXNpYW46IFZlY3RvcjQpOiBudW1iZXIge1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0Y2FydGVzaWFuLnggKiBjYXJ0ZXNpYW4ueCArXHJcblx0XHRcdGNhcnRlc2lhbi55ICogY2FydGVzaWFuLnkgK1xyXG5cdFx0XHRjYXJ0ZXNpYW4ueiAqIGNhcnRlc2lhbi56ICtcclxuXHRcdFx0Y2FydGVzaWFuLncgKiBjYXJ0ZXNpYW4ud1xyXG5cdFx0KTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBtYWduaXR1ZGUoY2FydGVzaWFuOiBWZWN0b3I0KTogbnVtYmVyIHtcclxuXHRcdHJldHVybiBNYXRoLnNxcnQoVmVjdG9yNC5tYWduaXR1ZGVTcXVhcmVkKGNhcnRlc2lhbikpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGRpc3RhbmNlKGxlZnQ6IFZlY3RvcjQsIHJpZ2h0OiBWZWN0b3I0KTogbnVtYmVyIHtcclxuXHRcdFZlY3RvcjQuc3VidHJhY3QobGVmdCwgcmlnaHQsIGRpc3RhbmNlU2NyYXRjaCk7XHJcblx0XHRyZXR1cm4gVmVjdG9yNC5tYWduaXR1ZGUoZGlzdGFuY2VTY3JhdGNoKTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBkaXN0YW5jZVNxdWFyZWQobGVmdDogVmVjdG9yNCwgcmlnaHQ6IFZlY3RvcjQpOiBudW1iZXIge1xyXG5cdFx0VmVjdG9yNC5zdWJ0cmFjdChsZWZ0LCByaWdodCwgZGlzdGFuY2VTY3JhdGNoKTtcclxuXHRcdHJldHVybiBWZWN0b3I0Lm1hZ25pdHVkZVNxdWFyZWQoZGlzdGFuY2VTY3JhdGNoKTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBub3JtYWxpemUoY2FydGVzaWFuOiBWZWN0b3I0LCByZXN1bHQ6IFZlY3RvcjQpOiBWZWN0b3I0IHtcclxuXHRcdGNvbnN0IG1hZ25pdHVkZSA9IFZlY3RvcjQubWFnbml0dWRlKGNhcnRlc2lhbik7XHJcblxyXG5cdFx0cmVzdWx0LnggPSBjYXJ0ZXNpYW4ueCAvIG1hZ25pdHVkZTtcclxuXHRcdHJlc3VsdC55ID0gY2FydGVzaWFuLnkgLyBtYWduaXR1ZGU7XHJcblx0XHRyZXN1bHQueiA9IGNhcnRlc2lhbi56IC8gbWFnbml0dWRlO1xyXG5cdFx0cmVzdWx0LncgPSBjYXJ0ZXNpYW4udyAvIG1hZ25pdHVkZTtcclxuXHJcblx0XHQvLyA+PmluY2x1ZGVTdGFydCgnZGVidWcnLCBwcmFnbWFzLmRlYnVnKTtcclxuXHRcdGlmIChpc05hTihyZXN1bHQueCkgfHwgaXNOYU4ocmVzdWx0LnkpIHx8IGlzTmFOKHJlc3VsdC56KSB8fCBpc05hTihyZXN1bHQudykpIHtcclxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwibm9ybWFsaXplZCByZXN1bHQgaXMgbm90IGEgbnVtYmVyXCIpO1xyXG5cdFx0fVxyXG5cdFx0Ly8gPj5pbmNsdWRlRW5kKCdkZWJ1ZycpO1xyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZG90KGxlZnQ6IFZlY3RvcjQsIHJpZ2h0OiBWZWN0b3I0KTogbnVtYmVyIHtcclxuXHRcdHJldHVybiBsZWZ0LnggKiByaWdodC54ICsgbGVmdC55ICogcmlnaHQueSArIGxlZnQueiAqIHJpZ2h0LnogKyBsZWZ0LncgKiByaWdodC53O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG11bHRpcGx5Q29tcG9uZW50cyhsZWZ0OiBWZWN0b3I0LCByaWdodDogVmVjdG9yNCwgcmVzdWx0OiBWZWN0b3I0KTogVmVjdG9yNCB7XHJcblx0XHRyZXN1bHQueCA9IGxlZnQueCAqIHJpZ2h0Lng7XHJcblx0XHRyZXN1bHQueSA9IGxlZnQueSAqIHJpZ2h0Lnk7XHJcblx0XHRyZXN1bHQueiA9IGxlZnQueiAqIHJpZ2h0Lno7XHJcblx0XHRyZXN1bHQudyA9IGxlZnQudyAqIHJpZ2h0Lnc7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGRpdmlkZUNvbXBvbmVudHMobGVmdDogVmVjdG9yNCwgcmlnaHQ6IFZlY3RvcjQsIHJlc3VsdDogVmVjdG9yNCk6IFZlY3RvcjQge1xyXG5cdFx0cmVzdWx0LnggPSBsZWZ0LnggLyByaWdodC54O1xyXG5cdFx0cmVzdWx0LnkgPSBsZWZ0LnkgLyByaWdodC55O1xyXG5cdFx0cmVzdWx0LnogPSBsZWZ0LnogLyByaWdodC56O1xyXG5cdFx0cmVzdWx0LncgPSBsZWZ0LncgLyByaWdodC53O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBhZGQobGVmdDogVmVjdG9yNCwgcmlnaHQ6IFZlY3RvcjQsIHJlc3VsdDogVmVjdG9yNCk6IFZlY3RvcjQge1xyXG5cdFx0cmVzdWx0LnggPSBsZWZ0LnggKyByaWdodC54O1xyXG5cdFx0cmVzdWx0LnkgPSBsZWZ0LnkgKyByaWdodC55O1xyXG5cdFx0cmVzdWx0LnogPSBsZWZ0LnogKyByaWdodC56O1xyXG5cdFx0cmVzdWx0LncgPSBsZWZ0LncgKyByaWdodC53O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBzdWJ0cmFjdChsZWZ0OiBWZWN0b3I0LCByaWdodDogVmVjdG9yNCwgcmVzdWx0OiBWZWN0b3I0KTogVmVjdG9yNCB7XHJcblx0XHRyZXN1bHQueCA9IGxlZnQueCAtIHJpZ2h0Lng7XHJcblx0XHRyZXN1bHQueSA9IGxlZnQueSAtIHJpZ2h0Lnk7XHJcblx0XHRyZXN1bHQueiA9IGxlZnQueiAtIHJpZ2h0Lno7XHJcblx0XHRyZXN1bHQudyA9IGxlZnQudyAtIHJpZ2h0Lnc7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG11bHRpcGx5QnlTY2FsYXIoY2FydGVzaWFuOiBWZWN0b3I0LCBzY2FsYXI6IG51bWJlciwgcmVzdWx0OiBWZWN0b3I0KTogVmVjdG9yNCB7XHJcblx0XHRyZXN1bHQueCA9IGNhcnRlc2lhbi54ICogc2NhbGFyO1xyXG5cdFx0cmVzdWx0LnkgPSBjYXJ0ZXNpYW4ueSAqIHNjYWxhcjtcclxuXHRcdHJlc3VsdC56ID0gY2FydGVzaWFuLnogKiBzY2FsYXI7XHJcblx0XHRyZXN1bHQudyA9IGNhcnRlc2lhbi53ICogc2NhbGFyO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBkaXZpZGVCeVNjYWxhcihjYXJ0ZXNpYW46IFZlY3RvcjQsIHNjYWxhcjogbnVtYmVyLCByZXN1bHQ6IFZlY3RvcjQpOiBWZWN0b3I0IHtcclxuXHRcdHJlc3VsdC54ID0gY2FydGVzaWFuLnggLyBzY2FsYXI7XHJcblx0XHRyZXN1bHQueSA9IGNhcnRlc2lhbi55IC8gc2NhbGFyO1xyXG5cdFx0cmVzdWx0LnogPSBjYXJ0ZXNpYW4ueiAvIHNjYWxhcjtcclxuXHRcdHJlc3VsdC53ID0gY2FydGVzaWFuLncgLyBzY2FsYXI7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG5lZ2F0ZShjYXJ0ZXNpYW46IFZlY3RvcjQsIHJlc3VsdDogVmVjdG9yNCk6IFZlY3RvcjQge1xyXG5cdFx0cmVzdWx0LnggPSAtY2FydGVzaWFuLng7XHJcblx0XHRyZXN1bHQueSA9IC1jYXJ0ZXNpYW4ueTtcclxuXHRcdHJlc3VsdC56ID0gLWNhcnRlc2lhbi56O1xyXG5cdFx0cmVzdWx0LncgPSAtY2FydGVzaWFuLnc7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGFicyhjYXJ0ZXNpYW46IFZlY3RvcjQsIHJlc3VsdDogVmVjdG9yNCk6IFZlY3RvcjQge1xyXG5cdFx0cmVzdWx0LnggPSBNYXRoLmFicyhjYXJ0ZXNpYW4ueCk7XHJcblx0XHRyZXN1bHQueSA9IE1hdGguYWJzKGNhcnRlc2lhbi55KTtcclxuXHRcdHJlc3VsdC56ID0gTWF0aC5hYnMoY2FydGVzaWFuLnopO1xyXG5cdFx0cmVzdWx0LncgPSBNYXRoLmFicyhjYXJ0ZXNpYW4udyk7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGxlcnAoc3RhcnQ6IFZlY3RvcjQsIGVuZDogVmVjdG9yNCwgdDogbnVtYmVyLCByZXN1bHQ6IFZlY3RvcjQpOiBWZWN0b3I0IHtcclxuXHRcdFZlY3RvcjQubXVsdGlwbHlCeVNjYWxhcihlbmQsIHQsIGxlcnBTY3JhdGNoKTtcclxuXHRcdHJlc3VsdCA9IFZlY3RvcjQubXVsdGlwbHlCeVNjYWxhcihzdGFydCwgMS4wIC0gdCwgcmVzdWx0KTtcclxuXHRcdHJldHVybiBWZWN0b3I0LmFkZChsZXJwU2NyYXRjaCwgcmVzdWx0LCByZXN1bHQpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGVxdWFscyhsZWZ0OiBWZWN0b3I0LCByaWdodDogVmVjdG9yNCk6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0bGVmdCA9PT0gcmlnaHQgfHxcclxuXHRcdFx0KGRlZmluZWQobGVmdCkgJiZcclxuXHRcdFx0XHRkZWZpbmVkKHJpZ2h0KSAmJlxyXG5cdFx0XHRcdGxlZnQueCA9PT0gcmlnaHQueCAmJlxyXG5cdFx0XHRcdGxlZnQueSA9PT0gcmlnaHQueSAmJlxyXG5cdFx0XHRcdGxlZnQueiA9PT0gcmlnaHQueiAmJlxyXG5cdFx0XHRcdGxlZnQudyA9PT0gcmlnaHQudylcclxuXHRcdCk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZXF1YWxzQXJyYXkoY2FydGVzaWFuOiBWZWN0b3I0LCBhcnJheTogbnVtYmVyW10sIG9mZnNldDogbnVtYmVyKTogYm9vbGVhbiB7XHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHRjYXJ0ZXNpYW4ueCA9PT0gYXJyYXlbb2Zmc2V0XSAmJlxyXG5cdFx0XHRjYXJ0ZXNpYW4ueSA9PT0gYXJyYXlbb2Zmc2V0ICsgMV0gJiZcclxuXHRcdFx0Y2FydGVzaWFuLnogPT09IGFycmF5W29mZnNldCArIDJdICYmXHJcblx0XHRcdGNhcnRlc2lhbi53ID09PSBhcnJheVtvZmZzZXQgKyAzXVxyXG5cdFx0KTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBlcXVhbHNFcHNpbG9uKGxlZnQ6IFZlY3RvcjQsIHJpZ2h0OiBWZWN0b3I0LCByZWxhdGl2ZUVwc2lsb24gPSAwLCBhYnNvbHV0ZUVwc2lsb24gPSAwKTogYm9vbGVhbiB7XHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHRsZWZ0ID09PSByaWdodCB8fFxyXG5cdFx0XHQoZGVmaW5lZChsZWZ0KSAmJlxyXG5cdFx0XHRcdGRlZmluZWQocmlnaHQpICYmXHJcblx0XHRcdFx0R01hdGguZXF1YWxzRXBzaWxvbihsZWZ0LngsIHJpZ2h0LngsIHJlbGF0aXZlRXBzaWxvbiwgYWJzb2x1dGVFcHNpbG9uKSAmJlxyXG5cdFx0XHRcdEdNYXRoLmVxdWFsc0Vwc2lsb24obGVmdC55LCByaWdodC55LCByZWxhdGl2ZUVwc2lsb24sIGFic29sdXRlRXBzaWxvbikgJiZcclxuXHRcdFx0XHRHTWF0aC5lcXVhbHNFcHNpbG9uKGxlZnQueiwgcmlnaHQueiwgcmVsYXRpdmVFcHNpbG9uLCBhYnNvbHV0ZUVwc2lsb24pICYmXHJcblx0XHRcdFx0R01hdGguZXF1YWxzRXBzaWxvbihsZWZ0LncsIHJpZ2h0LncsIHJlbGF0aXZlRXBzaWxvbiwgYWJzb2x1dGVFcHNpbG9uKSlcclxuXHRcdCk7XHJcblx0fVxyXG59XHJcblxyXG4vLyBzY3JhdGNoVThBcnJheSBhbmQgc2NyYXRjaEYzMkFycmF5IGFyZSB2aWV3cyBpbnRvIHRoZSBzYW1lIGJ1ZmZlclxyXG5jb25zdCBzY3JhdGNoRjMyQXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KDEpO1xyXG5jb25zdCBzY3JhdGNoVThBcnJheSA9IG5ldyBVaW50OEFycmF5KHNjcmF0Y2hGMzJBcnJheS5idWZmZXIpO1xyXG5cclxuY29uc3QgdGVzdFUzMiA9IG5ldyBVaW50MzJBcnJheShbMHgxMTIyMzM0NF0pO1xyXG5jb25zdCB0ZXN0VTggPSBuZXcgVWludDhBcnJheSh0ZXN0VTMyLmJ1ZmZlcik7XHJcbmNvbnN0IGxpdHRsZUVuZGlhbiA9IHRlc3RVOFswXSA9PT0gMHg0NDtcclxuY29uc3QgZGlzdGFuY2VTY3JhdGNoID0gbmV3IFZlY3RvcjQoKTtcclxuY29uc3QgbGVycFNjcmF0Y2ggPSBuZXcgVmVjdG9yNCgpO1xyXG5jb25zdCBtb3N0T3J0aG9nb25hbEF4aXNTY3JhdGNoID0gbmV3IFZlY3RvcjQoKTtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IFZlY3RvcjQ7XHJcbiIsImltcG9ydCBkZWZhdWx0VmFsdWUgZnJvbSBcIi4uL3V0aWxzL2RlZmF1bHRWYWx1ZVwiO1xuaW1wb3J0IGRlZmluZWQgZnJvbSBcIi4uL3V0aWxzL2RlZmluZWRcIjtcbmltcG9ydCBHTWF0aCBmcm9tIFwiLi9NYXRoXCI7XG5pbXBvcnQgTWF0cml4MyBmcm9tIFwiLi9NYXRyaXgzXCI7XG5pbXBvcnQgeyBRdWF0ZXJuaW9uIH0gZnJvbSBcIi4vUXVhdGVybmlvblwiO1xuaW1wb3J0IFZlY3RvcjMgZnJvbSBcIi4vVmVjdG9yM1wiO1xuaW1wb3J0IFZlY3RvcjQgZnJvbSBcIi4vVmVjdG9yNFwiO1xuY2xhc3MgTWF0cml4NCB7XG5cdHB1YmxpYyBzdGF0aWMgSURFTlRJVFkgPSBPYmplY3QuZnJlZXplKFxuXHRcdG5ldyBNYXRyaXg0KDEuMCwgMC4wLCAwLjAsIDAuMCwgMC4wLCAxLjAsIDAuMCwgMC4wLCAwLjAsIDAuMCwgMS4wLCAwLjAsIDAuMCwgMC4wLCAwLjAsIDEuMClcblx0KTtcblx0cHVibGljIHN0YXRpYyBaRVJPID0gT2JqZWN0LmZyZWV6ZShcblx0XHRuZXcgTWF0cml4NCgwLjAsIDAuMCwgMC4wLCAwLjAsIDAuMCwgMC4wLCAwLjAsIDAuMCwgMC4wLCAwLjAsIDAuMCwgMC4wLCAwLjAsIDAuMCwgMC4wLCAwLjApXG5cdCk7XG5cdC8qKlxuXHQgKiBBIDR4NCBtYXRyaXgsIGluZGV4YWJsZSBhcyBhIGNvbHVtbi1tYWpvciBvcmRlciBhcnJheS5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IFtjb2x1bW4wUm93MD0wLjBdIFRoZSB2YWx1ZSBmb3IgY29sdW1uIDAsIHJvdyAwLlxuXHQgKiBAcGFyYW0ge051bWJlcn0gW2NvbHVtbjFSb3cwPTAuMF0gVGhlIHZhbHVlIGZvciBjb2x1bW4gMSwgcm93IDAuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBbY29sdW1uMlJvdzA9MC4wXSBUaGUgdmFsdWUgZm9yIGNvbHVtbiAyLCByb3cgMC5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IFtjb2x1bW4zUm93MD0wLjBdIFRoZSB2YWx1ZSBmb3IgY29sdW1uIDMsIHJvdyAwLlxuXHQgKiBAcGFyYW0ge051bWJlcn0gW2NvbHVtbjBSb3cxPTAuMF0gVGhlIHZhbHVlIGZvciBjb2x1bW4gMCwgcm93IDEuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBbY29sdW1uMVJvdzE9MC4wXSBUaGUgdmFsdWUgZm9yIGNvbHVtbiAxLCByb3cgMS5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IFtjb2x1bW4yUm93MT0wLjBdIFRoZSB2YWx1ZSBmb3IgY29sdW1uIDIsIHJvdyAxLlxuXHQgKiBAcGFyYW0ge051bWJlcn0gW2NvbHVtbjNSb3cxPTAuMF0gVGhlIHZhbHVlIGZvciBjb2x1bW4gMywgcm93IDEuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBbY29sdW1uMFJvdzI9MC4wXSBUaGUgdmFsdWUgZm9yIGNvbHVtbiAwLCByb3cgMi5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IFtjb2x1bW4xUm93Mj0wLjBdIFRoZSB2YWx1ZSBmb3IgY29sdW1uIDEsIHJvdyAyLlxuXHQgKiBAcGFyYW0ge051bWJlcn0gW2NvbHVtbjJSb3cyPTAuMF0gVGhlIHZhbHVlIGZvciBjb2x1bW4gMiwgcm93IDIuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBbY29sdW1uM1JvdzI9MC4wXSBUaGUgdmFsdWUgZm9yIGNvbHVtbiAzLCByb3cgMi5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IFtjb2x1bW4wUm93Mz0wLjBdIFRoZSB2YWx1ZSBmb3IgY29sdW1uIDAsIHJvdyAzLlxuXHQgKiBAcGFyYW0ge051bWJlcn0gW2NvbHVtbjFSb3czPTAuMF0gVGhlIHZhbHVlIGZvciBjb2x1bW4gMSwgcm93IDMuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBbY29sdW1uMlJvdzM9MC4wXSBUaGUgdmFsdWUgZm9yIGNvbHVtbiAyLCByb3cgMy5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IFtjb2x1bW4zUm93Mz0wLjBdIFRoZSB2YWx1ZSBmb3IgY29sdW1uIDMsIHJvdyAzLlxuXHQgKi9cblx0Y29uc3RydWN0b3IoXG5cdFx0Y29sdW1uMFJvdzAgPSAwLFxuXHRcdGNvbHVtbjFSb3cwID0gMCxcblx0XHRjb2x1bW4yUm93MCA9IDAsXG5cdFx0Y29sdW1uM1JvdzAgPSAwLFxuXHRcdGNvbHVtbjBSb3cxID0gMCxcblx0XHRjb2x1bW4xUm93MSA9IDAsXG5cdFx0Y29sdW1uMlJvdzEgPSAwLFxuXHRcdGNvbHVtbjNSb3cxID0gMCxcblx0XHRjb2x1bW4wUm93MiA9IDAsXG5cdFx0Y29sdW1uMVJvdzIgPSAwLFxuXHRcdGNvbHVtbjJSb3cyID0gMCxcblx0XHRjb2x1bW4zUm93MiA9IDAsXG5cdFx0Y29sdW1uMFJvdzMgPSAwLFxuXHRcdGNvbHVtbjFSb3czID0gMCxcblx0XHRjb2x1bW4yUm93MyA9IDAsXG5cdFx0Y29sdW1uM1JvdzMgPSAwXG5cdCkge1xuXHRcdHRoaXNbMF0gPSBjb2x1bW4wUm93MDtcblx0XHR0aGlzWzFdID0gY29sdW1uMFJvdzE7XG5cdFx0dGhpc1syXSA9IGNvbHVtbjBSb3cyO1xuXHRcdHRoaXNbM10gPSBjb2x1bW4wUm93Mztcblx0XHR0aGlzWzRdID0gY29sdW1uMVJvdzA7XG5cdFx0dGhpc1s1XSA9IGNvbHVtbjFSb3cxO1xuXHRcdHRoaXNbNl0gPSBjb2x1bW4xUm93Mjtcblx0XHR0aGlzWzddID0gY29sdW1uMVJvdzM7XG5cdFx0dGhpc1s4XSA9IGNvbHVtbjJSb3cwO1xuXHRcdHRoaXNbOV0gPSBjb2x1bW4yUm93MTtcblx0XHR0aGlzWzEwXSA9IGNvbHVtbjJSb3cyO1xuXHRcdHRoaXNbMTFdID0gY29sdW1uMlJvdzM7XG5cdFx0dGhpc1sxMl0gPSBjb2x1bW4zUm93MDtcblx0XHR0aGlzWzEzXSA9IGNvbHVtbjNSb3cxO1xuXHRcdHRoaXNbMTRdID0gY29sdW1uM1JvdzI7XG5cdFx0dGhpc1sxNV0gPSBjb2x1bW4zUm93Mztcblx0fVxuXHQvLyA/Pz8/XG5cdGNsb25lKHJlc3VsdDogTWF0cml4NCA9IG5ldyBNYXRyaXg0KCkpOiBNYXRyaXg0IHtcblx0XHRyZXR1cm4gTWF0cml4NC5jbG9uZSh0aGlzLCByZXN1bHQpO1xuXHR9XG5cdHNldChtYXQ0OiBNYXRyaXg0KSB7XG5cdFx0TWF0cml4NC5jbG9uZShtYXQ0LCB0aGlzKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXHRlcXVhbHMocmlnaHQ6IE1hdHJpeDQpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gTWF0cml4NC5lcXVhbHModGhpcywgcmlnaHQpO1xuXHR9XG5cdGNvbXBvc2UocG9zaXRpb246IFZlY3RvcjMsIHF1YXRlcm5pb246IFF1YXRlcm5pb24sIHNjYWxlOiBWZWN0b3IzKTogTWF0cml4NCB7XG5cdFx0Y29uc3QgdGUgPSB0aGlzO1xuXG5cdFx0Y29uc3QgeCA9IHF1YXRlcm5pb24ueCxcblx0XHRcdHkgPSBxdWF0ZXJuaW9uLnksXG5cdFx0XHR6ID0gcXVhdGVybmlvbi56LFxuXHRcdFx0dyA9IHF1YXRlcm5pb24udztcblx0XHRjb25zdCB4MiA9IHggKyB4LFxuXHRcdFx0eTIgPSB5ICsgeSxcblx0XHRcdHoyID0geiArIHo7XG5cdFx0Y29uc3QgeHggPSB4ICogeDIsXG5cdFx0XHR4eSA9IHggKiB5Mixcblx0XHRcdHh6ID0geCAqIHoyO1xuXHRcdGNvbnN0IHl5ID0geSAqIHkyLFxuXHRcdFx0eXogPSB5ICogejIsXG5cdFx0XHR6eiA9IHogKiB6Mjtcblx0XHRjb25zdCB3eCA9IHcgKiB4Mixcblx0XHRcdHd5ID0gdyAqIHkyLFxuXHRcdFx0d3ogPSB3ICogejI7XG5cblx0XHRjb25zdCBzeCA9IHNjYWxlLngsXG5cdFx0XHRzeSA9IHNjYWxlLnksXG5cdFx0XHRzeiA9IHNjYWxlLno7XG5cblx0XHR0ZVswXSA9ICgxIC0gKHl5ICsgenopKSAqIHN4O1xuXHRcdHRlWzFdID0gKHh5ICsgd3opICogc3g7XG5cdFx0dGVbMl0gPSAoeHogLSB3eSkgKiBzeDtcblx0XHR0ZVszXSA9IDA7XG5cblx0XHR0ZVs0XSA9ICh4eSAtIHd6KSAqIHN5O1xuXHRcdHRlWzVdID0gKDEgLSAoeHggKyB6eikpICogc3k7XG5cdFx0dGVbNl0gPSAoeXogKyB3eCkgKiBzeTtcblx0XHR0ZVs3XSA9IDA7XG5cblx0XHR0ZVs4XSA9ICh4eiArIHd5KSAqIHN6O1xuXHRcdHRlWzldID0gKHl6IC0gd3gpICogc3o7XG5cdFx0dGVbMTBdID0gKDEgLSAoeHggKyB5eSkpICogc3o7XG5cdFx0dGVbMTFdID0gMDtcblxuXHRcdHRlWzEyXSA9IHBvc2l0aW9uLng7XG5cdFx0dGVbMTNdID0gcG9zaXRpb24ueTtcblx0XHR0ZVsxNF0gPSBwb3NpdGlvbi56O1xuXHRcdHRlWzE1XSA9IDE7XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXHRlcXVhbHNFcHNpbG9uKHJpZ2h0OiBNYXRyaXg0LCBlcHNpbG9uID0gMCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiBNYXRyaXg0LmVxdWFsc0Vwc2lsb24odGhpcywgcmlnaHQsIGVwc2lsb24pO1xuXHR9XG5cdGxvb2tBdChleWU6IFZlY3RvcjMsIHRhcmdldDogVmVjdG9yMywgdXA6IFZlY3RvcjMpOiBNYXRyaXg0IHtcblx0XHRjb25zdCBtYXRyaXggPSB0aGlzO1xuXHRcdFZlY3RvcjMuc3VidHJhY3QoZXllLCB0YXJnZXQsIHopO1xuXHRcdGlmICh6Lmxlbmd0aCgpID09PSAwKSB7XG5cdFx0XHQvLyBleWUgYW5kIHRhcmdldCBhcmUgaW4gdGhlIHNhbWUgcG9zaXRpb25cblx0XHRcdHoueiA9IDE7XG5cdFx0fVxuXHRcdHoubm9ybWFsaXplKCk7XG5cdFx0VmVjdG9yMy5jcm9zcyh1cCwgeiwgeCk7XG5cdFx0aWYgKHgubGVuZ3RoKCkgPT09IDApIHtcblx0XHRcdC8vIHVwIGFuZCB6IGFyZSBwYXJhbGxlbFxuXG5cdFx0XHRpZiAoTWF0aC5hYnModXAueikgPT09IDEpIHtcblx0XHRcdFx0ei54ICs9IDAuMDAwMTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHoueiArPSAwLjAwMDE7XG5cdFx0XHR9XG5cdFx0XHR6Lm5vcm1hbGl6ZSgpO1xuXHRcdFx0VmVjdG9yMy5jcm9zcyh1cCwgeiwgeCk7XG5cdFx0fVxuXHRcdHgubm9ybWFsaXplKCk7XG5cdFx0VmVjdG9yMy5jcm9zcyh6LCB4LCB5KTtcblx0XHRtYXRyaXhbMF0gPSB4Lng7XG5cdFx0bWF0cml4WzRdID0geS54O1xuXHRcdG1hdHJpeFs4XSA9IHoueDtcblx0XHRtYXRyaXhbMV0gPSB4Lnk7XG5cdFx0bWF0cml4WzVdID0geS55O1xuXHRcdG1hdHJpeFs5XSA9IHoueTtcblx0XHRtYXRyaXhbMl0gPSB4Lno7XG5cdFx0bWF0cml4WzZdID0geS56O1xuXHRcdG1hdHJpeFsxMF0gPSB6Lno7XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0YCgke3RoaXNbMF19LCAke3RoaXNbNF19LCAke3RoaXNbOF19LCAke3RoaXNbMTJdfSlcXG5gICtcblx0XHRcdGAoJHt0aGlzWzFdfSwgJHt0aGlzWzVdfSwgJHt0aGlzWzldfSwgJHt0aGlzWzEzXX0pXFxuYCArXG5cdFx0XHRgKCR7dGhpc1syXX0sICR7dGhpc1s2XX0sICR7dGhpc1sxMF19LCAke3RoaXNbMTRdfSlcXG5gICtcblx0XHRcdGAoJHt0aGlzWzNdfSwgJHt0aGlzWzddfSwgJHt0aGlzWzExXX0sICR7dGhpc1sxNV19KWBcblx0XHQpO1xuXHR9XG5cdHN0YXRpYyBjbG9uZShtYXRyaXg6IE1hdHJpeDQgfCBudW1iZXJbXSwgcmVzdWx0OiBNYXRyaXg0KTogTWF0cml4NCB7XG5cdFx0aWYgKCFkZWZpbmVkKG1hdHJpeCkpIHtcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XG5cdFx0XHRyZXR1cm4gbmV3IE1hdHJpeDQoXG5cdFx0XHRcdG1hdHJpeFswXSxcblx0XHRcdFx0bWF0cml4WzRdLFxuXHRcdFx0XHRtYXRyaXhbOF0sXG5cdFx0XHRcdG1hdHJpeFsxMl0sXG5cdFx0XHRcdG1hdHJpeFsxXSxcblx0XHRcdFx0bWF0cml4WzVdLFxuXHRcdFx0XHRtYXRyaXhbOV0sXG5cdFx0XHRcdG1hdHJpeFsxM10sXG5cdFx0XHRcdG1hdHJpeFsyXSxcblx0XHRcdFx0bWF0cml4WzZdLFxuXHRcdFx0XHRtYXRyaXhbMTBdLFxuXHRcdFx0XHRtYXRyaXhbMTRdLFxuXHRcdFx0XHRtYXRyaXhbM10sXG5cdFx0XHRcdG1hdHJpeFs3XSxcblx0XHRcdFx0bWF0cml4WzExXSxcblx0XHRcdFx0bWF0cml4WzE1XVxuXHRcdFx0KTtcblx0XHR9XG5cdFx0cmVzdWx0WzBdID0gbWF0cml4WzBdO1xuXHRcdHJlc3VsdFsxXSA9IG1hdHJpeFsxXTtcblx0XHRyZXN1bHRbMl0gPSBtYXRyaXhbMl07XG5cdFx0cmVzdWx0WzNdID0gbWF0cml4WzNdO1xuXHRcdHJlc3VsdFs0XSA9IG1hdHJpeFs0XTtcblx0XHRyZXN1bHRbNV0gPSBtYXRyaXhbNV07XG5cdFx0cmVzdWx0WzZdID0gbWF0cml4WzZdO1xuXHRcdHJlc3VsdFs3XSA9IG1hdHJpeFs3XTtcblx0XHRyZXN1bHRbOF0gPSBtYXRyaXhbOF07XG5cdFx0cmVzdWx0WzldID0gbWF0cml4WzldO1xuXHRcdHJlc3VsdFsxMF0gPSBtYXRyaXhbMTBdO1xuXHRcdHJlc3VsdFsxMV0gPSBtYXRyaXhbMTFdO1xuXHRcdHJlc3VsdFsxMl0gPSBtYXRyaXhbMTJdO1xuXHRcdHJlc3VsdFsxM10gPSBtYXRyaXhbMTNdO1xuXHRcdHJlc3VsdFsxNF0gPSBtYXRyaXhbMTRdO1xuXHRcdHJlc3VsdFsxNV0gPSBtYXRyaXhbMTVdO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRzdGF0aWMgZnJvbUNvbHVtbk1ham9yQXJyYXkodmFsdWVzOiBudW1iZXJbXSwgcmVzdWx0OiBNYXRyaXg0KTogTWF0cml4NCB7XG5cdFx0cmV0dXJuIE1hdHJpeDQuY2xvbmUodmFsdWVzLCByZXN1bHQpO1xuXHR9XG5cblx0c3RhdGljIGZyb21Sb3dNYWpvckFycmF5KHZhbHVlczogbnVtYmVyW10sIHJlc3VsdDogTWF0cml4NCk6IE1hdHJpeDQge1xuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XG5cdFx0XHRyZXR1cm4gbmV3IE1hdHJpeDQoXG5cdFx0XHRcdHZhbHVlc1swXSxcblx0XHRcdFx0dmFsdWVzWzFdLFxuXHRcdFx0XHR2YWx1ZXNbMl0sXG5cdFx0XHRcdHZhbHVlc1szXSxcblx0XHRcdFx0dmFsdWVzWzRdLFxuXHRcdFx0XHR2YWx1ZXNbNV0sXG5cdFx0XHRcdHZhbHVlc1s2XSxcblx0XHRcdFx0dmFsdWVzWzddLFxuXHRcdFx0XHR2YWx1ZXNbOF0sXG5cdFx0XHRcdHZhbHVlc1s5XSxcblx0XHRcdFx0dmFsdWVzWzEwXSxcblx0XHRcdFx0dmFsdWVzWzExXSxcblx0XHRcdFx0dmFsdWVzWzEyXSxcblx0XHRcdFx0dmFsdWVzWzEzXSxcblx0XHRcdFx0dmFsdWVzWzE0XSxcblx0XHRcdFx0dmFsdWVzWzE1XVxuXHRcdFx0KTtcblx0XHR9XG5cdFx0cmVzdWx0WzBdID0gdmFsdWVzWzBdO1xuXHRcdHJlc3VsdFsxXSA9IHZhbHVlc1s0XTtcblx0XHRyZXN1bHRbMl0gPSB2YWx1ZXNbOF07XG5cdFx0cmVzdWx0WzNdID0gdmFsdWVzWzEyXTtcblx0XHRyZXN1bHRbNF0gPSB2YWx1ZXNbMV07XG5cdFx0cmVzdWx0WzVdID0gdmFsdWVzWzVdO1xuXHRcdHJlc3VsdFs2XSA9IHZhbHVlc1s5XTtcblx0XHRyZXN1bHRbN10gPSB2YWx1ZXNbMTNdO1xuXHRcdHJlc3VsdFs4XSA9IHZhbHVlc1syXTtcblx0XHRyZXN1bHRbOV0gPSB2YWx1ZXNbNl07XG5cdFx0cmVzdWx0WzEwXSA9IHZhbHVlc1sxMF07XG5cdFx0cmVzdWx0WzExXSA9IHZhbHVlc1sxNF07XG5cdFx0cmVzdWx0WzEyXSA9IHZhbHVlc1szXTtcblx0XHRyZXN1bHRbMTNdID0gdmFsdWVzWzddO1xuXHRcdHJlc3VsdFsxNF0gPSB2YWx1ZXNbMTFdO1xuXHRcdHJlc3VsdFsxNV0gPSB2YWx1ZXNbMTVdO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRzdGF0aWMgZnJvbVJvdGF0aW9uVHJhbnNsYXRpb24ocm90YXRpb246IE1hdHJpeDMsIHRyYW5zbGF0aW9uOiBWZWN0b3IzLCByZXN1bHQ6IE1hdHJpeDQpOiBNYXRyaXg0IHtcblx0XHR0cmFuc2xhdGlvbiA9IGRlZmF1bHRWYWx1ZSh0cmFuc2xhdGlvbiwgVmVjdG9yMy5aRVJPKTtcblxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XG5cdFx0XHRyZXR1cm4gbmV3IE1hdHJpeDQoXG5cdFx0XHRcdHJvdGF0aW9uWzBdLFxuXHRcdFx0XHRyb3RhdGlvblszXSxcblx0XHRcdFx0cm90YXRpb25bNl0sXG5cdFx0XHRcdHRyYW5zbGF0aW9uLngsXG5cdFx0XHRcdHJvdGF0aW9uWzFdLFxuXHRcdFx0XHRyb3RhdGlvbls0XSxcblx0XHRcdFx0cm90YXRpb25bN10sXG5cdFx0XHRcdHRyYW5zbGF0aW9uLnksXG5cdFx0XHRcdHJvdGF0aW9uWzJdLFxuXHRcdFx0XHRyb3RhdGlvbls1XSxcblx0XHRcdFx0cm90YXRpb25bOF0sXG5cdFx0XHRcdHRyYW5zbGF0aW9uLnosXG5cdFx0XHRcdDAuMCxcblx0XHRcdFx0MC4wLFxuXHRcdFx0XHQwLjAsXG5cdFx0XHRcdDEuMFxuXHRcdFx0KTtcblx0XHR9XG5cblx0XHRyZXN1bHRbMF0gPSByb3RhdGlvblswXTtcblx0XHRyZXN1bHRbMV0gPSByb3RhdGlvblsxXTtcblx0XHRyZXN1bHRbMl0gPSByb3RhdGlvblsyXTtcblx0XHRyZXN1bHRbM10gPSAwLjA7XG5cdFx0cmVzdWx0WzRdID0gcm90YXRpb25bM107XG5cdFx0cmVzdWx0WzVdID0gcm90YXRpb25bNF07XG5cdFx0cmVzdWx0WzZdID0gcm90YXRpb25bNV07XG5cdFx0cmVzdWx0WzddID0gMC4wO1xuXHRcdHJlc3VsdFs4XSA9IHJvdGF0aW9uWzZdO1xuXHRcdHJlc3VsdFs5XSA9IHJvdGF0aW9uWzddO1xuXHRcdHJlc3VsdFsxMF0gPSByb3RhdGlvbls4XTtcblx0XHRyZXN1bHRbMTFdID0gMC4wO1xuXHRcdHJlc3VsdFsxMl0gPSB0cmFuc2xhdGlvbi54O1xuXHRcdHJlc3VsdFsxM10gPSB0cmFuc2xhdGlvbi55O1xuXHRcdHJlc3VsdFsxNF0gPSB0cmFuc2xhdGlvbi56O1xuXHRcdHJlc3VsdFsxNV0gPSAxLjA7XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyBmcm9tVHJhbnNsYXRpb25RdWF0ZXJuaW9uUm90YXRpb25TY2FsZShcblx0XHR0cmFuc2xhdGlvbjogVmVjdG9yMyxcblx0XHRyb3RhdGlvbjogUXVhdGVybmlvbixcblx0XHRzY2FsZTogVmVjdG9yMyxcblx0XHRyZXN1bHQ6IE1hdHJpeDRcblx0KTogTWF0cml4NCB7XG5cdFx0aWYgKCFkZWZpbmVkKHJlc3VsdCkpIHtcblx0XHRcdHJlc3VsdCA9IG5ldyBNYXRyaXg0KCk7XG5cdFx0fVxuXG5cdFx0Y29uc3Qgc2NhbGVYID0gc2NhbGUueDtcblx0XHRjb25zdCBzY2FsZVkgPSBzY2FsZS55O1xuXHRcdGNvbnN0IHNjYWxlWiA9IHNjYWxlLno7XG5cblx0XHRjb25zdCB4MiA9IHJvdGF0aW9uLnggKiByb3RhdGlvbi54O1xuXHRcdGNvbnN0IHh5ID0gcm90YXRpb24ueCAqIHJvdGF0aW9uLnk7XG5cdFx0Y29uc3QgeHogPSByb3RhdGlvbi54ICogcm90YXRpb24uejtcblx0XHRjb25zdCB4dyA9IHJvdGF0aW9uLnggKiByb3RhdGlvbi53O1xuXHRcdGNvbnN0IHkyID0gcm90YXRpb24ueSAqIHJvdGF0aW9uLnk7XG5cdFx0Y29uc3QgeXogPSByb3RhdGlvbi55ICogcm90YXRpb24uejtcblx0XHRjb25zdCB5dyA9IHJvdGF0aW9uLnkgKiByb3RhdGlvbi53O1xuXHRcdGNvbnN0IHoyID0gcm90YXRpb24ueiAqIHJvdGF0aW9uLno7XG5cdFx0Y29uc3QgencgPSByb3RhdGlvbi56ICogcm90YXRpb24udztcblx0XHRjb25zdCB3MiA9IHJvdGF0aW9uLncgKiByb3RhdGlvbi53O1xuXG5cdFx0Y29uc3QgbTAwID0geDIgLSB5MiAtIHoyICsgdzI7XG5cdFx0Y29uc3QgbTAxID0gMi4wICogKHh5IC0gencpO1xuXHRcdGNvbnN0IG0wMiA9IDIuMCAqICh4eiArIHl3KTtcblxuXHRcdGNvbnN0IG0xMCA9IDIuMCAqICh4eSArIHp3KTtcblx0XHRjb25zdCBtMTEgPSAteDIgKyB5MiAtIHoyICsgdzI7XG5cdFx0Y29uc3QgbTEyID0gMi4wICogKHl6IC0geHcpO1xuXG5cdFx0Y29uc3QgbTIwID0gMi4wICogKHh6IC0geXcpO1xuXHRcdGNvbnN0IG0yMSA9IDIuMCAqICh5eiArIHh3KTtcblx0XHRjb25zdCBtMjIgPSAteDIgLSB5MiArIHoyICsgdzI7XG5cblx0XHRyZXN1bHRbMF0gPSBtMDAgKiBzY2FsZVg7XG5cdFx0cmVzdWx0WzFdID0gbTEwICogc2NhbGVYO1xuXHRcdHJlc3VsdFsyXSA9IG0yMCAqIHNjYWxlWDtcblx0XHRyZXN1bHRbM10gPSAwLjA7XG5cdFx0cmVzdWx0WzRdID0gbTAxICogc2NhbGVZO1xuXHRcdHJlc3VsdFs1XSA9IG0xMSAqIHNjYWxlWTtcblx0XHRyZXN1bHRbNl0gPSBtMjEgKiBzY2FsZVk7XG5cdFx0cmVzdWx0WzddID0gMC4wO1xuXHRcdHJlc3VsdFs4XSA9IG0wMiAqIHNjYWxlWjtcblx0XHRyZXN1bHRbOV0gPSBtMTIgKiBzY2FsZVo7XG5cdFx0cmVzdWx0WzEwXSA9IG0yMiAqIHNjYWxlWjtcblx0XHRyZXN1bHRbMTFdID0gMC4wO1xuXHRcdHJlc3VsdFsxMl0gPSB0cmFuc2xhdGlvbi54O1xuXHRcdHJlc3VsdFsxM10gPSB0cmFuc2xhdGlvbi55O1xuXHRcdHJlc3VsdFsxNF0gPSB0cmFuc2xhdGlvbi56O1xuXHRcdHJlc3VsdFsxNV0gPSAxLjA7XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0c3RhdGljIGZyb21UcmFuc2xhdGlvblJvdGF0aW9uU2NhbGUoXG5cdFx0dHJhbnNsYXRpb25Sb3RhdGlvblNjYWxlOiB7XG5cdFx0XHR0cmFuc2xhdGlvbjogVmVjdG9yMztcblx0XHRcdHJvdGF0aW9uOiBRdWF0ZXJuaW9uO1xuXHRcdFx0c2NhbGU6IFZlY3RvcjM7XG5cdFx0fSxcblx0XHRyZXN1bHQ6IE1hdHJpeDRcblx0KTogTWF0cml4NCB7XG5cdFx0cmV0dXJuIE1hdHJpeDQuZnJvbVRyYW5zbGF0aW9uUXVhdGVybmlvblJvdGF0aW9uU2NhbGUoXG5cdFx0XHR0cmFuc2xhdGlvblJvdGF0aW9uU2NhbGUudHJhbnNsYXRpb24sXG5cdFx0XHR0cmFuc2xhdGlvblJvdGF0aW9uU2NhbGUucm90YXRpb24sXG5cdFx0XHR0cmFuc2xhdGlvblJvdGF0aW9uU2NhbGUuc2NhbGUsXG5cdFx0XHRyZXN1bHRcblx0XHQpO1xuXHR9XG5cblx0c3RhdGljIGZyb21UcmFuc2xhdGlvbih0cmFuc2xhdGlvbjogVmVjdG9yMywgcmVzdWx0OiBNYXRyaXg0KTogTWF0cml4NCB7XG5cdFx0cmV0dXJuIE1hdHJpeDQuZnJvbVJvdGF0aW9uVHJhbnNsYXRpb24oTWF0cml4My5JREVOVElUWSwgdHJhbnNsYXRpb24sIHJlc3VsdCk7XG5cdH1cblxuXHRzdGF0aWMgZnJvbVNjYWxlKHNjYWxlOiBWZWN0b3IzLCByZXN1bHQ6IE1hdHJpeDQpOiBNYXRyaXg0IHtcblx0XHRpZiAoIWRlZmluZWQocmVzdWx0KSkge1xuXHRcdFx0cmV0dXJuIG5ldyBNYXRyaXg0KFxuXHRcdFx0XHRzY2FsZS54LFxuXHRcdFx0XHQwLjAsXG5cdFx0XHRcdDAuMCxcblx0XHRcdFx0MC4wLFxuXHRcdFx0XHQwLjAsXG5cdFx0XHRcdHNjYWxlLnksXG5cdFx0XHRcdDAuMCxcblx0XHRcdFx0MC4wLFxuXHRcdFx0XHQwLjAsXG5cdFx0XHRcdDAuMCxcblx0XHRcdFx0c2NhbGUueixcblx0XHRcdFx0MC4wLFxuXHRcdFx0XHQwLjAsXG5cdFx0XHRcdDAuMCxcblx0XHRcdFx0MC4wLFxuXHRcdFx0XHQxLjBcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0cmVzdWx0WzBdID0gc2NhbGUueDtcblx0XHRyZXN1bHRbMV0gPSAwLjA7XG5cdFx0cmVzdWx0WzJdID0gMC4wO1xuXHRcdHJlc3VsdFszXSA9IDAuMDtcblx0XHRyZXN1bHRbNF0gPSAwLjA7XG5cdFx0cmVzdWx0WzVdID0gc2NhbGUueTtcblx0XHRyZXN1bHRbNl0gPSAwLjA7XG5cdFx0cmVzdWx0WzddID0gMC4wO1xuXHRcdHJlc3VsdFs4XSA9IDAuMDtcblx0XHRyZXN1bHRbOV0gPSAwLjA7XG5cdFx0cmVzdWx0WzEwXSA9IHNjYWxlLno7XG5cdFx0cmVzdWx0WzExXSA9IDAuMDtcblx0XHRyZXN1bHRbMTJdID0gMC4wO1xuXHRcdHJlc3VsdFsxM10gPSAwLjA7XG5cdFx0cmVzdWx0WzE0XSA9IDAuMDtcblx0XHRyZXN1bHRbMTVdID0gMS4wO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRzdGF0aWMgZnJvbVJvdGF0aW9uKHJvdGF0aW9uOiBNYXRyaXgzLCByZXN1bHQ6IE1hdHJpeDQpOiBNYXRyaXg0IHtcblx0XHRpZiAoIWRlZmluZWQocmVzdWx0KSkge1xuXHRcdFx0cmVzdWx0ID0gbmV3IE1hdHJpeDQoKTtcblx0XHR9XG5cdFx0cmVzdWx0WzBdID0gcm90YXRpb25bMF07XG5cdFx0cmVzdWx0WzFdID0gcm90YXRpb25bMV07XG5cdFx0cmVzdWx0WzJdID0gcm90YXRpb25bMl07XG5cdFx0cmVzdWx0WzNdID0gMC4wO1xuXG5cdFx0cmVzdWx0WzRdID0gcm90YXRpb25bM107XG5cdFx0cmVzdWx0WzVdID0gcm90YXRpb25bNF07XG5cdFx0cmVzdWx0WzZdID0gcm90YXRpb25bNV07XG5cdFx0cmVzdWx0WzddID0gMC4wO1xuXG5cdFx0cmVzdWx0WzhdID0gcm90YXRpb25bNl07XG5cdFx0cmVzdWx0WzldID0gcm90YXRpb25bN107XG5cdFx0cmVzdWx0WzEwXSA9IHJvdGF0aW9uWzhdO1xuXHRcdHJlc3VsdFsxMV0gPSAwLjA7XG5cblx0XHRyZXN1bHRbMTJdID0gMC4wO1xuXHRcdHJlc3VsdFsxM10gPSAwLjA7XG5cdFx0cmVzdWx0WzE0XSA9IDAuMDtcblx0XHRyZXN1bHRbMTVdID0gMS4wO1xuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyBtYWtlUGVyc3BlY3RpdmUoXG5cdFx0bGVmdDogbnVtYmVyLFxuXHRcdHJpZ2h0OiBudW1iZXIsXG5cdFx0dG9wOiBudW1iZXIsXG5cdFx0Ym90dG9tOiBudW1iZXIsXG5cdFx0bmVhcjogbnVtYmVyLFxuXHRcdGZhcjogbnVtYmVyXG5cdCk6IE1hdHJpeDQge1xuXHRcdC8vIGZyb20gdGhyZWUuanNcblx0XHRjb25zdCBtYXRyaXggPSBuZXcgTWF0cml4NCgpO1xuXHRcdGNvbnN0IHggPSAoMiAqIG5lYXIpIC8gKHJpZ2h0IC0gbGVmdCk7XG5cdFx0Y29uc3QgeSA9ICgyICogbmVhcikgLyAodG9wIC0gYm90dG9tKTtcblxuXHRcdGNvbnN0IGEgPSAocmlnaHQgKyBsZWZ0KSAvIChyaWdodCAtIGxlZnQpO1xuXHRcdGNvbnN0IGIgPSAodG9wICsgYm90dG9tKSAvICh0b3AgLSBib3R0b20pO1xuXHRcdGNvbnN0IGMgPSAtZmFyIC8gKGZhciAtIG5lYXIpO1xuXHRcdGNvbnN0IGQgPSAoLWZhciAqIG5lYXIpIC8gKGZhciAtIG5lYXIpO1xuXG5cdFx0bWF0cml4WzBdID0geDtcblx0XHRtYXRyaXhbNF0gPSAwO1xuXHRcdG1hdHJpeFs4XSA9IGE7XG5cdFx0bWF0cml4WzEyXSA9IDA7XG5cdFx0bWF0cml4WzFdID0gMDtcblx0XHRtYXRyaXhbNV0gPSB5O1xuXHRcdG1hdHJpeFs5XSA9IGI7XG5cdFx0bWF0cml4WzEzXSA9IDA7XG5cdFx0bWF0cml4WzJdID0gMDtcblx0XHRtYXRyaXhbNl0gPSAwO1xuXHRcdG1hdHJpeFsxMF0gPSBjO1xuXHRcdG1hdHJpeFsxNF0gPSBkO1xuXHRcdG1hdHJpeFszXSA9IDA7XG5cdFx0bWF0cml4WzddID0gMDtcblx0XHRtYXRyaXhbMTFdID0gLTE7XG5cdFx0bWF0cml4WzE1XSA9IDA7XG5cdFx0cmV0dXJuIG1hdHJpeDtcblx0fVxuXHRzdGF0aWMgbWFrZU9ydGhvZ3JhcGhpYyhcblx0XHRsZWZ0OiBudW1iZXIsXG5cdFx0cmlnaHQ6IG51bWJlcixcblx0XHR0b3A6IG51bWJlcixcblx0XHRib3R0b206IG51bWJlcixcblx0XHRuZWFyOiBudW1iZXIsXG5cdFx0ZmFyOiBudW1iZXJcblx0KTogTWF0cml4NCB7XG5cdFx0Y29uc3QgbWF0cml4ID0gbmV3IE1hdHJpeDQoKTtcblx0XHRjb25zdCB3ID0gMS4wIC8gKHJpZ2h0IC0gbGVmdCk7XG5cdFx0Y29uc3QgaCA9IDEuMCAvICh0b3AgLSBib3R0b20pO1xuXHRcdGNvbnN0IHAgPSAxLjAgLyAoZmFyIC0gbmVhcik7XG5cblx0XHRjb25zdCB4ID0gKHJpZ2h0ICsgbGVmdCkgKiB3O1xuXHRcdGNvbnN0IHkgPSAodG9wICsgYm90dG9tKSAqIGg7XG5cdFx0Y29uc3QgeiA9IG5lYXIgKiBwO1xuXG5cdFx0bWF0cml4WzBdID0gMiAqIHc7XG5cdFx0bWF0cml4WzRdID0gMDtcblx0XHRtYXRyaXhbOF0gPSAwO1xuXHRcdG1hdHJpeFsxMl0gPSAteDtcblx0XHRtYXRyaXhbMV0gPSAwO1xuXHRcdG1hdHJpeFs1XSA9IDIgKiBoO1xuXHRcdG1hdHJpeFs5XSA9IDA7XG5cdFx0bWF0cml4WzEzXSA9IC15O1xuXHRcdG1hdHJpeFsyXSA9IDA7XG5cdFx0bWF0cml4WzZdID0gMDtcblx0XHRtYXRyaXhbMTBdID0gLTEgKiBwO1xuXHRcdG1hdHJpeFsxNF0gPSAtejtcblx0XHRtYXRyaXhbM10gPSAwO1xuXHRcdG1hdHJpeFs3XSA9IDA7XG5cdFx0bWF0cml4WzExXSA9IDA7XG5cdFx0bWF0cml4WzE1XSA9IDE7XG5cdFx0cmV0dXJuIG1hdHJpeDtcblx0fVxuXHR0b0FycmF5KCkge1xuXHRcdGNvbnN0IHJlc3VsdCA9IFtdO1xuXHRcdE1hdHJpeDQudG9BcnJheSh0aGlzLCByZXN1bHQpO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblx0LyoqXG5cdCAqIENvbXB1dGVzIGFuIEFycmF5IGZyb20gdGhlIHByb3ZpZGVkIE1hdHJpeDQgaW5zdGFuY2UuXG5cdCAqIFRoZSBhcnJheSB3aWxsIGJlIGluIGNvbHVtbi1tYWpvciBvcmRlci5cblx0ICogQGV4YW1wbGVcblx0ICogLy9jcmVhdGUgYW4gYXJyYXkgZnJvbSBhbiBpbnN0YW5jZSBvZiBNYXRyaXg0XG5cdCAqIC8vIG0gPSBbMTAuMCwgMTQuMCwgMTguMCwgMjIuMF1cblx0ICogLy8gICAgIFsxMS4wLCAxNS4wLCAxOS4wLCAyMy4wXVxuXHQgKiAvLyAgICAgWzEyLjAsIDE2LjAsIDIwLjAsIDI0LjBdXG5cdCAqIC8vICAgICBbMTMuMCwgMTcuMCwgMjEuMCwgMjUuMF1cblx0ICogY29uc3QgYSA9IE1hdHJpeDQudG9BcnJheShtKTtcblx0ICpcblx0ICogLy8gbSByZW1haW5zIHRoZSBzYW1lXG5cdCAqIC8vY3JlYXRlcyBhID0gWzEwLjAsIDExLjAsIDEyLjAsIDEzLjAsIDE0LjAsIDE1LjAsIDE2LjAsIDE3LjAsIDE4LjAsIDE5LjAsIDIwLjAsIDIxLjAsIDIyLjAsIDIzLjAsIDI0LjAsIDI1LjBdXG5cdCAqL1xuXHRzdGF0aWMgdG9BcnJheShtYXRyaXg6IEFycmF5PG51bWJlcj4gfCBNYXRyaXg0LCByZXN1bHQ6IEFycmF5PG51bWJlcj4pOiBBcnJheTxudW1iZXI+IHtcblx0XHRpZiAoIWRlZmluZWQocmVzdWx0KSkge1xuXHRcdFx0cmV0dXJuIFtcblx0XHRcdFx0bWF0cml4WzBdLFxuXHRcdFx0XHRtYXRyaXhbMV0sXG5cdFx0XHRcdG1hdHJpeFsyXSxcblx0XHRcdFx0bWF0cml4WzNdLFxuXHRcdFx0XHRtYXRyaXhbNF0sXG5cdFx0XHRcdG1hdHJpeFs1XSxcblx0XHRcdFx0bWF0cml4WzZdLFxuXHRcdFx0XHRtYXRyaXhbN10sXG5cdFx0XHRcdG1hdHJpeFs4XSxcblx0XHRcdFx0bWF0cml4WzldLFxuXHRcdFx0XHRtYXRyaXhbMTBdLFxuXHRcdFx0XHRtYXRyaXhbMTFdLFxuXHRcdFx0XHRtYXRyaXhbMTJdLFxuXHRcdFx0XHRtYXRyaXhbMTNdLFxuXHRcdFx0XHRtYXRyaXhbMTRdLFxuXHRcdFx0XHRtYXRyaXhbMTVdXG5cdFx0XHRdO1xuXHRcdH1cblx0XHRyZXN1bHRbMF0gPSBtYXRyaXhbMF07XG5cdFx0cmVzdWx0WzFdID0gbWF0cml4WzFdO1xuXHRcdHJlc3VsdFsyXSA9IG1hdHJpeFsyXTtcblx0XHRyZXN1bHRbM10gPSBtYXRyaXhbM107XG5cdFx0cmVzdWx0WzRdID0gbWF0cml4WzRdO1xuXHRcdHJlc3VsdFs1XSA9IG1hdHJpeFs1XTtcblx0XHRyZXN1bHRbNl0gPSBtYXRyaXhbNl07XG5cdFx0cmVzdWx0WzddID0gbWF0cml4WzddO1xuXHRcdHJlc3VsdFs4XSA9IG1hdHJpeFs4XTtcblx0XHRyZXN1bHRbOV0gPSBtYXRyaXhbOV07XG5cdFx0cmVzdWx0WzEwXSA9IG1hdHJpeFsxMF07XG5cdFx0cmVzdWx0WzExXSA9IG1hdHJpeFsxMV07XG5cdFx0cmVzdWx0WzEyXSA9IG1hdHJpeFsxMl07XG5cdFx0cmVzdWx0WzEzXSA9IG1hdHJpeFsxM107XG5cdFx0cmVzdWx0WzE0XSA9IG1hdHJpeFsxNF07XG5cdFx0cmVzdWx0WzE1XSA9IG1hdHJpeFsxNV07XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyBnZXRFbGVtZW50SW5kZXgoY29sdW1uOiBudW1iZXIsIHJvdzogbnVtYmVyKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gY29sdW1uICogNCArIHJvdztcblx0fVxuXG5cdHN0YXRpYyBnZXRDb2x1bW4obWF0cml4OiBNYXRyaXg0LCBpbmRleDogbnVtYmVyLCByZXN1bHQ6IFZlY3RvcjQpOiBWZWN0b3I0IHtcblx0XHRjb25zdCBzdGFydEluZGV4ID0gaW5kZXggKiA0O1xuXHRcdGNvbnN0IHggPSBtYXRyaXhbc3RhcnRJbmRleF07XG5cdFx0Y29uc3QgeSA9IG1hdHJpeFtzdGFydEluZGV4ICsgMV07XG5cdFx0Y29uc3QgeiA9IG1hdHJpeFtzdGFydEluZGV4ICsgMl07XG5cdFx0Y29uc3QgdyA9IG1hdHJpeFtzdGFydEluZGV4ICsgM107XG5cblx0XHRyZXN1bHQueCA9IHg7XG5cdFx0cmVzdWx0LnkgPSB5O1xuXHRcdHJlc3VsdC56ID0gejtcblx0XHRyZXN1bHQudyA9IHc7XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyBzZXRDb2x1bW4obWF0cml4OiBNYXRyaXg0LCBpbmRleDogbnVtYmVyLCBjYXJ0ZXNpYW46IFZlY3RvcjQsIHJlc3VsdDogTWF0cml4NCk6IE1hdHJpeDQge1xuXHRcdHJlc3VsdCA9IE1hdHJpeDQuY2xvbmUobWF0cml4LCByZXN1bHQpO1xuXHRcdGNvbnN0IHN0YXJ0SW5kZXggPSBpbmRleCAqIDQ7XG5cdFx0cmVzdWx0W3N0YXJ0SW5kZXhdID0gY2FydGVzaWFuLng7XG5cdFx0cmVzdWx0W3N0YXJ0SW5kZXggKyAxXSA9IGNhcnRlc2lhbi55O1xuXHRcdHJlc3VsdFtzdGFydEluZGV4ICsgMl0gPSBjYXJ0ZXNpYW4uejtcblx0XHRyZXN1bHRbc3RhcnRJbmRleCArIDNdID0gY2FydGVzaWFuLnc7XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyBnZXRSb3cobWF0cml4OiBNYXRyaXg0LCBpbmRleDogbnVtYmVyLCByZXN1bHQ6IFZlY3RvcjQpOiBWZWN0b3I0IHtcblx0XHRjb25zdCB4ID0gbWF0cml4W2luZGV4XTtcblx0XHRjb25zdCB5ID0gbWF0cml4W2luZGV4ICsgNF07XG5cdFx0Y29uc3QgeiA9IG1hdHJpeFtpbmRleCArIDhdO1xuXHRcdGNvbnN0IHcgPSBtYXRyaXhbaW5kZXggKyAxMl07XG5cblx0XHRyZXN1bHQueCA9IHg7XG5cdFx0cmVzdWx0LnkgPSB5O1xuXHRcdHJlc3VsdC56ID0gejtcblx0XHRyZXN1bHQudyA9IHc7XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyBzZXRSb3cobWF0cml4OiBNYXRyaXg0LCBpbmRleDogbnVtYmVyLCBjYXJ0ZXNpYW46IFZlY3RvcjQsIHJlc3VsdDogTWF0cml4NCk6IE1hdHJpeDQge1xuXHRcdHJlc3VsdCA9IE1hdHJpeDQuY2xvbmUobWF0cml4LCByZXN1bHQpO1xuXHRcdHJlc3VsdFtpbmRleF0gPSBjYXJ0ZXNpYW4ueDtcblx0XHRyZXN1bHRbaW5kZXggKyA0XSA9IGNhcnRlc2lhbi55O1xuXHRcdHJlc3VsdFtpbmRleCArIDhdID0gY2FydGVzaWFuLno7XG5cdFx0cmVzdWx0W2luZGV4ICsgMTJdID0gY2FydGVzaWFuLnc7XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyBzZXRUcmFuc2xhdGlvbihtYXRyaXg6IE1hdHJpeDQsIHRyYW5zbGF0aW9uOiBWZWN0b3IzLCByZXN1bHQ6IE1hdHJpeDQpOiBNYXRyaXg0IHtcblx0XHRyZXN1bHRbMF0gPSBtYXRyaXhbMF07XG5cdFx0cmVzdWx0WzFdID0gbWF0cml4WzFdO1xuXHRcdHJlc3VsdFsyXSA9IG1hdHJpeFsyXTtcblx0XHRyZXN1bHRbM10gPSBtYXRyaXhbM107XG5cblx0XHRyZXN1bHRbNF0gPSBtYXRyaXhbNF07XG5cdFx0cmVzdWx0WzVdID0gbWF0cml4WzVdO1xuXHRcdHJlc3VsdFs2XSA9IG1hdHJpeFs2XTtcblx0XHRyZXN1bHRbN10gPSBtYXRyaXhbN107XG5cblx0XHRyZXN1bHRbOF0gPSBtYXRyaXhbOF07XG5cdFx0cmVzdWx0WzldID0gbWF0cml4WzldO1xuXHRcdHJlc3VsdFsxMF0gPSBtYXRyaXhbMTBdO1xuXHRcdHJlc3VsdFsxMV0gPSBtYXRyaXhbMTFdO1xuXG5cdFx0cmVzdWx0WzEyXSA9IHRyYW5zbGF0aW9uLng7XG5cdFx0cmVzdWx0WzEzXSA9IHRyYW5zbGF0aW9uLnk7XG5cdFx0cmVzdWx0WzE0XSA9IHRyYW5zbGF0aW9uLno7XG5cdFx0cmVzdWx0WzE1XSA9IG1hdHJpeFsxNV07XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0c3RhdGljIHNldFNjYWxlKG1hdHJpeDogTWF0cml4NCwgc2NhbGU6IFZlY3RvcjMsIHJlc3VsdDogTWF0cml4NCk6IE1hdHJpeDQge1xuXHRcdGNvbnN0IGV4aXN0aW5nU2NhbGUgPSBNYXRyaXg0LmdldFNjYWxlKG1hdHJpeCwgc2NhbGVTY3JhdGNoMSk7XG5cdFx0Y29uc3Qgc2NhbGVSYXRpb1ggPSBzY2FsZS54IC8gZXhpc3RpbmdTY2FsZS54O1xuXHRcdGNvbnN0IHNjYWxlUmF0aW9ZID0gc2NhbGUueSAvIGV4aXN0aW5nU2NhbGUueTtcblx0XHRjb25zdCBzY2FsZVJhdGlvWiA9IHNjYWxlLnogLyBleGlzdGluZ1NjYWxlLno7XG5cblx0XHRyZXN1bHRbMF0gPSBtYXRyaXhbMF0gKiBzY2FsZVJhdGlvWDtcblx0XHRyZXN1bHRbMV0gPSBtYXRyaXhbMV0gKiBzY2FsZVJhdGlvWDtcblx0XHRyZXN1bHRbMl0gPSBtYXRyaXhbMl0gKiBzY2FsZVJhdGlvWDtcblx0XHRyZXN1bHRbM10gPSBtYXRyaXhbM107XG5cblx0XHRyZXN1bHRbNF0gPSBtYXRyaXhbNF0gKiBzY2FsZVJhdGlvWTtcblx0XHRyZXN1bHRbNV0gPSBtYXRyaXhbNV0gKiBzY2FsZVJhdGlvWTtcblx0XHRyZXN1bHRbNl0gPSBtYXRyaXhbNl0gKiBzY2FsZVJhdGlvWTtcblx0XHRyZXN1bHRbN10gPSBtYXRyaXhbN107XG5cblx0XHRyZXN1bHRbOF0gPSBtYXRyaXhbOF0gKiBzY2FsZVJhdGlvWjtcblx0XHRyZXN1bHRbOV0gPSBtYXRyaXhbOV0gKiBzY2FsZVJhdGlvWjtcblx0XHRyZXN1bHRbMTBdID0gbWF0cml4WzEwXSAqIHNjYWxlUmF0aW9aO1xuXHRcdHJlc3VsdFsxMV0gPSBtYXRyaXhbMTFdO1xuXG5cdFx0cmVzdWx0WzEyXSA9IG1hdHJpeFsxMl07XG5cdFx0cmVzdWx0WzEzXSA9IG1hdHJpeFsxM107XG5cdFx0cmVzdWx0WzE0XSA9IG1hdHJpeFsxNF07XG5cdFx0cmVzdWx0WzE1XSA9IG1hdHJpeFsxNV07XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0c3RhdGljIGdldFNjYWxlKG1hdHJpeDogTWF0cml4NCwgcmVzdWx0OiBWZWN0b3IzKTogVmVjdG9yMyB7XG5cdFx0cmVzdWx0LnggPSBWZWN0b3IzLm1hZ25pdHVkZShWZWN0b3IzLmZyb21FbGVtZW50cyhtYXRyaXhbMF0sIG1hdHJpeFsxXSwgbWF0cml4WzJdLCBzY3JhdGNoQ29sdW1uKSk7XG5cdFx0cmVzdWx0LnkgPSBWZWN0b3IzLm1hZ25pdHVkZShWZWN0b3IzLmZyb21FbGVtZW50cyhtYXRyaXhbNF0sIG1hdHJpeFs1XSwgbWF0cml4WzZdLCBzY3JhdGNoQ29sdW1uKSk7XG5cdFx0cmVzdWx0LnogPSBWZWN0b3IzLm1hZ25pdHVkZShWZWN0b3IzLmZyb21FbGVtZW50cyhtYXRyaXhbOF0sIG1hdHJpeFs5XSwgbWF0cml4WzEwXSwgc2NyYXRjaENvbHVtbikpO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRzdGF0aWMgZ2V0TWF4aW11bVNjYWxlKG1hdHJpeDogTWF0cml4NCk6IG51bWJlciB7XG5cdFx0TWF0cml4NC5nZXRTY2FsZShtYXRyaXgsIHNjYWxlU2NyYXRjaDMpO1xuXHRcdHJldHVybiBWZWN0b3IzLm1heGltdW1Db21wb25lbnQoc2NhbGVTY3JhdGNoMyk7XG5cdH1cblxuXHRzdGF0aWMgc2V0Um90YXRpb24obWF0cml4OiBNYXRyaXg0LCByb3RhdGlvbjogTWF0cml4MywgcmVzdWx0OiBNYXRyaXg0KTogTWF0cml4NCB7XG5cdFx0Y29uc3Qgc2NhbGUgPSBNYXRyaXg0LmdldFNjYWxlKG1hdHJpeCwgc2NhbGVTY3JhdGNoNCk7XG5cblx0XHRyZXN1bHRbMF0gPSByb3RhdGlvblswXSAqIHNjYWxlLng7XG5cdFx0cmVzdWx0WzFdID0gcm90YXRpb25bMV0gKiBzY2FsZS54O1xuXHRcdHJlc3VsdFsyXSA9IHJvdGF0aW9uWzJdICogc2NhbGUueDtcblx0XHRyZXN1bHRbM10gPSBtYXRyaXhbM107XG5cblx0XHRyZXN1bHRbNF0gPSByb3RhdGlvblszXSAqIHNjYWxlLnk7XG5cdFx0cmVzdWx0WzVdID0gcm90YXRpb25bNF0gKiBzY2FsZS55O1xuXHRcdHJlc3VsdFs2XSA9IHJvdGF0aW9uWzVdICogc2NhbGUueTtcblx0XHRyZXN1bHRbN10gPSBtYXRyaXhbN107XG5cblx0XHRyZXN1bHRbOF0gPSByb3RhdGlvbls2XSAqIHNjYWxlLno7XG5cdFx0cmVzdWx0WzldID0gcm90YXRpb25bN10gKiBzY2FsZS56O1xuXHRcdHJlc3VsdFsxMF0gPSByb3RhdGlvbls4XSAqIHNjYWxlLno7XG5cdFx0cmVzdWx0WzExXSA9IG1hdHJpeFsxMV07XG5cblx0XHRyZXN1bHRbMTJdID0gbWF0cml4WzEyXTtcblx0XHRyZXN1bHRbMTNdID0gbWF0cml4WzEzXTtcblx0XHRyZXN1bHRbMTRdID0gbWF0cml4WzE0XTtcblx0XHRyZXN1bHRbMTVdID0gbWF0cml4WzE1XTtcblxuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRzdGF0aWMgZ2V0Um90YXRpb24obWF0cml4OiBNYXRyaXg0LCByZXN1bHQ6IFF1YXRlcm5pb24pOiBRdWF0ZXJuaW9uIHtcblx0XHRjb25zdCBzY2FsZSA9IE1hdHJpeDQuZ2V0U2NhbGUobWF0cml4LCBzY2FsZVNjcmF0Y2g1KTtcblxuXHRcdGNvbnN0IGlzMSA9IDEgLyBzY2FsZS54O1xuXHRcdGNvbnN0IGlzMiA9IDEgLyBzY2FsZS55O1xuXHRcdGNvbnN0IGlzMyA9IDEgLyBzY2FsZS56O1xuXG5cdFx0Y29uc3Qgc20xMSA9IG1hdHJpeFswXSAqIGlzMTtcblx0XHRjb25zdCBzbTEyID0gbWF0cml4WzFdICogaXMyO1xuXHRcdGNvbnN0IHNtMTMgPSBtYXRyaXhbMl0gKiBpczM7XG5cdFx0Y29uc3Qgc20yMSA9IG1hdHJpeFs0XSAqIGlzMTtcblx0XHRjb25zdCBzbTIyID0gbWF0cml4WzVdICogaXMyO1xuXHRcdGNvbnN0IHNtMjMgPSBtYXRyaXhbNl0gKiBpczM7XG5cdFx0Y29uc3Qgc20zMSA9IG1hdHJpeFs4XSAqIGlzMTtcblx0XHRjb25zdCBzbTMyID0gbWF0cml4WzldICogaXMyO1xuXHRcdGNvbnN0IHNtMzMgPSBtYXRyaXhbMTBdICogaXMzO1xuXG5cdFx0Y29uc3QgdHJhY2UgPSBzbTExICsgc20yMiArIHNtMzM7XG5cdFx0bGV0IFMgPSAwO1xuXG5cdFx0aWYgKHRyYWNlID4gMCkge1xuXHRcdFx0UyA9IE1hdGguc3FydCh0cmFjZSArIDEuMCkgKiAyO1xuXHRcdFx0cmVzdWx0LncgPSAwLjI1ICogUztcblx0XHRcdHJlc3VsdC54ID0gKHNtMjMgLSBzbTMyKSAvIFM7XG5cdFx0XHRyZXN1bHQueSA9IChzbTMxIC0gc20xMykgLyBTO1xuXHRcdFx0cmVzdWx0LnogPSAoc20xMiAtIHNtMjEpIC8gUztcblx0XHR9IGVsc2UgaWYgKHNtMTEgPiBzbTIyICYmIHNtMTEgPiBzbTMzKSB7XG5cdFx0XHRTID0gTWF0aC5zcXJ0KDEuMCArIHNtMTEgLSBzbTIyIC0gc20zMykgKiAyO1xuXHRcdFx0cmVzdWx0LncgPSAoc20yMyAtIHNtMzIpIC8gUztcblx0XHRcdHJlc3VsdC54ID0gMC4yNSAqIFM7XG5cdFx0XHRyZXN1bHQueSA9IChzbTEyICsgc20yMSkgLyBTO1xuXHRcdFx0cmVzdWx0LnogPSAoc20zMSArIHNtMTMpIC8gUztcblx0XHR9IGVsc2UgaWYgKHNtMjIgPiBzbTMzKSB7XG5cdFx0XHRTID0gTWF0aC5zcXJ0KDEuMCArIHNtMjIgLSBzbTExIC0gc20zMykgKiAyO1xuXHRcdFx0cmVzdWx0LncgPSAoc20zMSAtIHNtMTMpIC8gUztcblx0XHRcdHJlc3VsdC54ID0gKHNtMTIgKyBzbTIxKSAvIFM7XG5cdFx0XHRyZXN1bHQueSA9IDAuMjUgKiBTO1xuXHRcdFx0cmVzdWx0LnogPSAoc20yMyArIHNtMzIpIC8gUztcblx0XHR9IGVsc2Uge1xuXHRcdFx0UyA9IE1hdGguc3FydCgxLjAgKyBzbTMzIC0gc20xMSAtIHNtMjIpICogMjtcblx0XHRcdHJlc3VsdC53ID0gKHNtMTIgLSBzbTIxKSAvIFM7XG5cdFx0XHRyZXN1bHQueCA9IChzbTMxICsgc20xMykgLyBTO1xuXHRcdFx0cmVzdWx0LnkgPSAoc20yMyArIHNtMzIpIC8gUztcblx0XHRcdHJlc3VsdC56ID0gMC4yNSAqIFM7XG5cdFx0fVxuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRzdGF0aWMgbXVsdGlwbHkobGVmdDogTWF0cml4NCwgcmlnaHQ6IE1hdHJpeDQsIHJlc3VsdDogTWF0cml4NCk6IE1hdHJpeDQge1xuXHRcdGNvbnN0IGxlZnQwID0gbGVmdFswXTtcblx0XHRjb25zdCBsZWZ0MSA9IGxlZnRbMV07XG5cdFx0Y29uc3QgbGVmdDIgPSBsZWZ0WzJdO1xuXHRcdGNvbnN0IGxlZnQzID0gbGVmdFszXTtcblx0XHRjb25zdCBsZWZ0NCA9IGxlZnRbNF07XG5cdFx0Y29uc3QgbGVmdDUgPSBsZWZ0WzVdO1xuXHRcdGNvbnN0IGxlZnQ2ID0gbGVmdFs2XTtcblx0XHRjb25zdCBsZWZ0NyA9IGxlZnRbN107XG5cdFx0Y29uc3QgbGVmdDggPSBsZWZ0WzhdO1xuXHRcdGNvbnN0IGxlZnQ5ID0gbGVmdFs5XTtcblx0XHRjb25zdCBsZWZ0MTAgPSBsZWZ0WzEwXTtcblx0XHRjb25zdCBsZWZ0MTEgPSBsZWZ0WzExXTtcblx0XHRjb25zdCBsZWZ0MTIgPSBsZWZ0WzEyXTtcblx0XHRjb25zdCBsZWZ0MTMgPSBsZWZ0WzEzXTtcblx0XHRjb25zdCBsZWZ0MTQgPSBsZWZ0WzE0XTtcblx0XHRjb25zdCBsZWZ0MTUgPSBsZWZ0WzE1XTtcblxuXHRcdGNvbnN0IHJpZ2h0MCA9IHJpZ2h0WzBdO1xuXHRcdGNvbnN0IHJpZ2h0MSA9IHJpZ2h0WzFdO1xuXHRcdGNvbnN0IHJpZ2h0MiA9IHJpZ2h0WzJdO1xuXHRcdGNvbnN0IHJpZ2h0MyA9IHJpZ2h0WzNdO1xuXHRcdGNvbnN0IHJpZ2h0NCA9IHJpZ2h0WzRdO1xuXHRcdGNvbnN0IHJpZ2h0NSA9IHJpZ2h0WzVdO1xuXHRcdGNvbnN0IHJpZ2h0NiA9IHJpZ2h0WzZdO1xuXHRcdGNvbnN0IHJpZ2h0NyA9IHJpZ2h0WzddO1xuXHRcdGNvbnN0IHJpZ2h0OCA9IHJpZ2h0WzhdO1xuXHRcdGNvbnN0IHJpZ2h0OSA9IHJpZ2h0WzldO1xuXHRcdGNvbnN0IHJpZ2h0MTAgPSByaWdodFsxMF07XG5cdFx0Y29uc3QgcmlnaHQxMSA9IHJpZ2h0WzExXTtcblx0XHRjb25zdCByaWdodDEyID0gcmlnaHRbMTJdO1xuXHRcdGNvbnN0IHJpZ2h0MTMgPSByaWdodFsxM107XG5cdFx0Y29uc3QgcmlnaHQxNCA9IHJpZ2h0WzE0XTtcblx0XHRjb25zdCByaWdodDE1ID0gcmlnaHRbMTVdO1xuXG5cdFx0Y29uc3QgY29sdW1uMFJvdzAgPSBsZWZ0MCAqIHJpZ2h0MCArIGxlZnQ0ICogcmlnaHQxICsgbGVmdDggKiByaWdodDIgKyBsZWZ0MTIgKiByaWdodDM7XG5cdFx0Y29uc3QgY29sdW1uMFJvdzEgPSBsZWZ0MSAqIHJpZ2h0MCArIGxlZnQ1ICogcmlnaHQxICsgbGVmdDkgKiByaWdodDIgKyBsZWZ0MTMgKiByaWdodDM7XG5cdFx0Y29uc3QgY29sdW1uMFJvdzIgPSBsZWZ0MiAqIHJpZ2h0MCArIGxlZnQ2ICogcmlnaHQxICsgbGVmdDEwICogcmlnaHQyICsgbGVmdDE0ICogcmlnaHQzO1xuXHRcdGNvbnN0IGNvbHVtbjBSb3czID0gbGVmdDMgKiByaWdodDAgKyBsZWZ0NyAqIHJpZ2h0MSArIGxlZnQxMSAqIHJpZ2h0MiArIGxlZnQxNSAqIHJpZ2h0MztcblxuXHRcdGNvbnN0IGNvbHVtbjFSb3cwID0gbGVmdDAgKiByaWdodDQgKyBsZWZ0NCAqIHJpZ2h0NSArIGxlZnQ4ICogcmlnaHQ2ICsgbGVmdDEyICogcmlnaHQ3O1xuXHRcdGNvbnN0IGNvbHVtbjFSb3cxID0gbGVmdDEgKiByaWdodDQgKyBsZWZ0NSAqIHJpZ2h0NSArIGxlZnQ5ICogcmlnaHQ2ICsgbGVmdDEzICogcmlnaHQ3O1xuXHRcdGNvbnN0IGNvbHVtbjFSb3cyID0gbGVmdDIgKiByaWdodDQgKyBsZWZ0NiAqIHJpZ2h0NSArIGxlZnQxMCAqIHJpZ2h0NiArIGxlZnQxNCAqIHJpZ2h0Nztcblx0XHRjb25zdCBjb2x1bW4xUm93MyA9IGxlZnQzICogcmlnaHQ0ICsgbGVmdDcgKiByaWdodDUgKyBsZWZ0MTEgKiByaWdodDYgKyBsZWZ0MTUgKiByaWdodDc7XG5cblx0XHRjb25zdCBjb2x1bW4yUm93MCA9IGxlZnQwICogcmlnaHQ4ICsgbGVmdDQgKiByaWdodDkgKyBsZWZ0OCAqIHJpZ2h0MTAgKyBsZWZ0MTIgKiByaWdodDExO1xuXHRcdGNvbnN0IGNvbHVtbjJSb3cxID0gbGVmdDEgKiByaWdodDggKyBsZWZ0NSAqIHJpZ2h0OSArIGxlZnQ5ICogcmlnaHQxMCArIGxlZnQxMyAqIHJpZ2h0MTE7XG5cdFx0Y29uc3QgY29sdW1uMlJvdzIgPSBsZWZ0MiAqIHJpZ2h0OCArIGxlZnQ2ICogcmlnaHQ5ICsgbGVmdDEwICogcmlnaHQxMCArIGxlZnQxNCAqIHJpZ2h0MTE7XG5cdFx0Y29uc3QgY29sdW1uMlJvdzMgPSBsZWZ0MyAqIHJpZ2h0OCArIGxlZnQ3ICogcmlnaHQ5ICsgbGVmdDExICogcmlnaHQxMCArIGxlZnQxNSAqIHJpZ2h0MTE7XG5cblx0XHRjb25zdCBjb2x1bW4zUm93MCA9IGxlZnQwICogcmlnaHQxMiArIGxlZnQ0ICogcmlnaHQxMyArIGxlZnQ4ICogcmlnaHQxNCArIGxlZnQxMiAqIHJpZ2h0MTU7XG5cdFx0Y29uc3QgY29sdW1uM1JvdzEgPSBsZWZ0MSAqIHJpZ2h0MTIgKyBsZWZ0NSAqIHJpZ2h0MTMgKyBsZWZ0OSAqIHJpZ2h0MTQgKyBsZWZ0MTMgKiByaWdodDE1O1xuXHRcdGNvbnN0IGNvbHVtbjNSb3cyID0gbGVmdDIgKiByaWdodDEyICsgbGVmdDYgKiByaWdodDEzICsgbGVmdDEwICogcmlnaHQxNCArIGxlZnQxNCAqIHJpZ2h0MTU7XG5cdFx0Y29uc3QgY29sdW1uM1JvdzMgPSBsZWZ0MyAqIHJpZ2h0MTIgKyBsZWZ0NyAqIHJpZ2h0MTMgKyBsZWZ0MTEgKiByaWdodDE0ICsgbGVmdDE1ICogcmlnaHQxNTtcblxuXHRcdHJlc3VsdFswXSA9IGNvbHVtbjBSb3cwO1xuXHRcdHJlc3VsdFsxXSA9IGNvbHVtbjBSb3cxO1xuXHRcdHJlc3VsdFsyXSA9IGNvbHVtbjBSb3cyO1xuXHRcdHJlc3VsdFszXSA9IGNvbHVtbjBSb3czO1xuXHRcdHJlc3VsdFs0XSA9IGNvbHVtbjFSb3cwO1xuXHRcdHJlc3VsdFs1XSA9IGNvbHVtbjFSb3cxO1xuXHRcdHJlc3VsdFs2XSA9IGNvbHVtbjFSb3cyO1xuXHRcdHJlc3VsdFs3XSA9IGNvbHVtbjFSb3czO1xuXHRcdHJlc3VsdFs4XSA9IGNvbHVtbjJSb3cwO1xuXHRcdHJlc3VsdFs5XSA9IGNvbHVtbjJSb3cxO1xuXHRcdHJlc3VsdFsxMF0gPSBjb2x1bW4yUm93Mjtcblx0XHRyZXN1bHRbMTFdID0gY29sdW1uMlJvdzM7XG5cdFx0cmVzdWx0WzEyXSA9IGNvbHVtbjNSb3cwO1xuXHRcdHJlc3VsdFsxM10gPSBjb2x1bW4zUm93MTtcblx0XHRyZXN1bHRbMTRdID0gY29sdW1uM1JvdzI7XG5cdFx0cmVzdWx0WzE1XSA9IGNvbHVtbjNSb3czO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRzdGF0aWMgYWRkKGxlZnQ6IE1hdHJpeDQsIHJpZ2h0OiBNYXRyaXg0LCByZXN1bHQ6IE1hdHJpeDQpOiBNYXRyaXg0IHtcblx0XHRyZXN1bHRbMF0gPSBsZWZ0WzBdICsgcmlnaHRbMF07XG5cdFx0cmVzdWx0WzFdID0gbGVmdFsxXSArIHJpZ2h0WzFdO1xuXHRcdHJlc3VsdFsyXSA9IGxlZnRbMl0gKyByaWdodFsyXTtcblx0XHRyZXN1bHRbM10gPSBsZWZ0WzNdICsgcmlnaHRbM107XG5cdFx0cmVzdWx0WzRdID0gbGVmdFs0XSArIHJpZ2h0WzRdO1xuXHRcdHJlc3VsdFs1XSA9IGxlZnRbNV0gKyByaWdodFs1XTtcblx0XHRyZXN1bHRbNl0gPSBsZWZ0WzZdICsgcmlnaHRbNl07XG5cdFx0cmVzdWx0WzddID0gbGVmdFs3XSArIHJpZ2h0WzddO1xuXHRcdHJlc3VsdFs4XSA9IGxlZnRbOF0gKyByaWdodFs4XTtcblx0XHRyZXN1bHRbOV0gPSBsZWZ0WzldICsgcmlnaHRbOV07XG5cdFx0cmVzdWx0WzEwXSA9IGxlZnRbMTBdICsgcmlnaHRbMTBdO1xuXHRcdHJlc3VsdFsxMV0gPSBsZWZ0WzExXSArIHJpZ2h0WzExXTtcblx0XHRyZXN1bHRbMTJdID0gbGVmdFsxMl0gKyByaWdodFsxMl07XG5cdFx0cmVzdWx0WzEzXSA9IGxlZnRbMTNdICsgcmlnaHRbMTNdO1xuXHRcdHJlc3VsdFsxNF0gPSBsZWZ0WzE0XSArIHJpZ2h0WzE0XTtcblx0XHRyZXN1bHRbMTVdID0gbGVmdFsxNV0gKyByaWdodFsxNV07XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyBzdWJ0cmFjdChsZWZ0OiBNYXRyaXg0LCByaWdodDogTWF0cml4NCwgcmVzdWx0OiBNYXRyaXg0KSB7XG5cdFx0cmVzdWx0WzBdID0gbGVmdFswXSAtIHJpZ2h0WzBdO1xuXHRcdHJlc3VsdFsxXSA9IGxlZnRbMV0gLSByaWdodFsxXTtcblx0XHRyZXN1bHRbMl0gPSBsZWZ0WzJdIC0gcmlnaHRbMl07XG5cdFx0cmVzdWx0WzNdID0gbGVmdFszXSAtIHJpZ2h0WzNdO1xuXHRcdHJlc3VsdFs0XSA9IGxlZnRbNF0gLSByaWdodFs0XTtcblx0XHRyZXN1bHRbNV0gPSBsZWZ0WzVdIC0gcmlnaHRbNV07XG5cdFx0cmVzdWx0WzZdID0gbGVmdFs2XSAtIHJpZ2h0WzZdO1xuXHRcdHJlc3VsdFs3XSA9IGxlZnRbN10gLSByaWdodFs3XTtcblx0XHRyZXN1bHRbOF0gPSBsZWZ0WzhdIC0gcmlnaHRbOF07XG5cdFx0cmVzdWx0WzldID0gbGVmdFs5XSAtIHJpZ2h0WzldO1xuXHRcdHJlc3VsdFsxMF0gPSBsZWZ0WzEwXSAtIHJpZ2h0WzEwXTtcblx0XHRyZXN1bHRbMTFdID0gbGVmdFsxMV0gLSByaWdodFsxMV07XG5cdFx0cmVzdWx0WzEyXSA9IGxlZnRbMTJdIC0gcmlnaHRbMTJdO1xuXHRcdHJlc3VsdFsxM10gPSBsZWZ0WzEzXSAtIHJpZ2h0WzEzXTtcblx0XHRyZXN1bHRbMTRdID0gbGVmdFsxNF0gLSByaWdodFsxNF07XG5cdFx0cmVzdWx0WzE1XSA9IGxlZnRbMTVdIC0gcmlnaHRbMTVdO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRzdGF0aWMgbXVsdGlwbHlUcmFuc2Zvcm1hdGlvbihsZWZ0OiBNYXRyaXg0LCByaWdodDogTWF0cml4NCwgcmVzdWx0OiBNYXRyaXg0KTogTWF0cml4NCB7XG5cdFx0Y29uc3QgbGVmdDAgPSBsZWZ0WzBdO1xuXHRcdGNvbnN0IGxlZnQxID0gbGVmdFsxXTtcblx0XHRjb25zdCBsZWZ0MiA9IGxlZnRbMl07XG5cdFx0Y29uc3QgbGVmdDQgPSBsZWZ0WzRdO1xuXHRcdGNvbnN0IGxlZnQ1ID0gbGVmdFs1XTtcblx0XHRjb25zdCBsZWZ0NiA9IGxlZnRbNl07XG5cdFx0Y29uc3QgbGVmdDggPSBsZWZ0WzhdO1xuXHRcdGNvbnN0IGxlZnQ5ID0gbGVmdFs5XTtcblx0XHRjb25zdCBsZWZ0MTAgPSBsZWZ0WzEwXTtcblx0XHRjb25zdCBsZWZ0MTIgPSBsZWZ0WzEyXTtcblx0XHRjb25zdCBsZWZ0MTMgPSBsZWZ0WzEzXTtcblx0XHRjb25zdCBsZWZ0MTQgPSBsZWZ0WzE0XTtcblxuXHRcdGNvbnN0IHJpZ2h0MCA9IHJpZ2h0WzBdO1xuXHRcdGNvbnN0IHJpZ2h0MSA9IHJpZ2h0WzFdO1xuXHRcdGNvbnN0IHJpZ2h0MiA9IHJpZ2h0WzJdO1xuXHRcdGNvbnN0IHJpZ2h0NCA9IHJpZ2h0WzRdO1xuXHRcdGNvbnN0IHJpZ2h0NSA9IHJpZ2h0WzVdO1xuXHRcdGNvbnN0IHJpZ2h0NiA9IHJpZ2h0WzZdO1xuXHRcdGNvbnN0IHJpZ2h0OCA9IHJpZ2h0WzhdO1xuXHRcdGNvbnN0IHJpZ2h0OSA9IHJpZ2h0WzldO1xuXHRcdGNvbnN0IHJpZ2h0MTAgPSByaWdodFsxMF07XG5cdFx0Y29uc3QgcmlnaHQxMiA9IHJpZ2h0WzEyXTtcblx0XHRjb25zdCByaWdodDEzID0gcmlnaHRbMTNdO1xuXHRcdGNvbnN0IHJpZ2h0MTQgPSByaWdodFsxNF07XG5cblx0XHRjb25zdCBjb2x1bW4wUm93MCA9IGxlZnQwICogcmlnaHQwICsgbGVmdDQgKiByaWdodDEgKyBsZWZ0OCAqIHJpZ2h0Mjtcblx0XHRjb25zdCBjb2x1bW4wUm93MSA9IGxlZnQxICogcmlnaHQwICsgbGVmdDUgKiByaWdodDEgKyBsZWZ0OSAqIHJpZ2h0Mjtcblx0XHRjb25zdCBjb2x1bW4wUm93MiA9IGxlZnQyICogcmlnaHQwICsgbGVmdDYgKiByaWdodDEgKyBsZWZ0MTAgKiByaWdodDI7XG5cblx0XHRjb25zdCBjb2x1bW4xUm93MCA9IGxlZnQwICogcmlnaHQ0ICsgbGVmdDQgKiByaWdodDUgKyBsZWZ0OCAqIHJpZ2h0Njtcblx0XHRjb25zdCBjb2x1bW4xUm93MSA9IGxlZnQxICogcmlnaHQ0ICsgbGVmdDUgKiByaWdodDUgKyBsZWZ0OSAqIHJpZ2h0Njtcblx0XHRjb25zdCBjb2x1bW4xUm93MiA9IGxlZnQyICogcmlnaHQ0ICsgbGVmdDYgKiByaWdodDUgKyBsZWZ0MTAgKiByaWdodDY7XG5cblx0XHRjb25zdCBjb2x1bW4yUm93MCA9IGxlZnQwICogcmlnaHQ4ICsgbGVmdDQgKiByaWdodDkgKyBsZWZ0OCAqIHJpZ2h0MTA7XG5cdFx0Y29uc3QgY29sdW1uMlJvdzEgPSBsZWZ0MSAqIHJpZ2h0OCArIGxlZnQ1ICogcmlnaHQ5ICsgbGVmdDkgKiByaWdodDEwO1xuXHRcdGNvbnN0IGNvbHVtbjJSb3cyID0gbGVmdDIgKiByaWdodDggKyBsZWZ0NiAqIHJpZ2h0OSArIGxlZnQxMCAqIHJpZ2h0MTA7XG5cblx0XHRjb25zdCBjb2x1bW4zUm93MCA9IGxlZnQwICogcmlnaHQxMiArIGxlZnQ0ICogcmlnaHQxMyArIGxlZnQ4ICogcmlnaHQxNCArIGxlZnQxMjtcblx0XHRjb25zdCBjb2x1bW4zUm93MSA9IGxlZnQxICogcmlnaHQxMiArIGxlZnQ1ICogcmlnaHQxMyArIGxlZnQ5ICogcmlnaHQxNCArIGxlZnQxMztcblx0XHRjb25zdCBjb2x1bW4zUm93MiA9IGxlZnQyICogcmlnaHQxMiArIGxlZnQ2ICogcmlnaHQxMyArIGxlZnQxMCAqIHJpZ2h0MTQgKyBsZWZ0MTQ7XG5cblx0XHRyZXN1bHRbMF0gPSBjb2x1bW4wUm93MDtcblx0XHRyZXN1bHRbMV0gPSBjb2x1bW4wUm93MTtcblx0XHRyZXN1bHRbMl0gPSBjb2x1bW4wUm93Mjtcblx0XHRyZXN1bHRbM10gPSAwLjA7XG5cdFx0cmVzdWx0WzRdID0gY29sdW1uMVJvdzA7XG5cdFx0cmVzdWx0WzVdID0gY29sdW1uMVJvdzE7XG5cdFx0cmVzdWx0WzZdID0gY29sdW1uMVJvdzI7XG5cdFx0cmVzdWx0WzddID0gMC4wO1xuXHRcdHJlc3VsdFs4XSA9IGNvbHVtbjJSb3cwO1xuXHRcdHJlc3VsdFs5XSA9IGNvbHVtbjJSb3cxO1xuXHRcdHJlc3VsdFsxMF0gPSBjb2x1bW4yUm93Mjtcblx0XHRyZXN1bHRbMTFdID0gMC4wO1xuXHRcdHJlc3VsdFsxMl0gPSBjb2x1bW4zUm93MDtcblx0XHRyZXN1bHRbMTNdID0gY29sdW1uM1JvdzE7XG5cdFx0cmVzdWx0WzE0XSA9IGNvbHVtbjNSb3cyO1xuXHRcdHJlc3VsdFsxNV0gPSAxLjA7XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyBtdWx0aXBseUJ5TWF0cml4MyhtYXRyaXg6IE1hdHJpeDQsIHJvdGF0aW9uOiBNYXRyaXgzLCByZXN1bHQ6IE1hdHJpeDQpOiBNYXRyaXg0IHtcblx0XHRjb25zdCBsZWZ0MCA9IG1hdHJpeFswXTtcblx0XHRjb25zdCBsZWZ0MSA9IG1hdHJpeFsxXTtcblx0XHRjb25zdCBsZWZ0MiA9IG1hdHJpeFsyXTtcblx0XHRjb25zdCBsZWZ0NCA9IG1hdHJpeFs0XTtcblx0XHRjb25zdCBsZWZ0NSA9IG1hdHJpeFs1XTtcblx0XHRjb25zdCBsZWZ0NiA9IG1hdHJpeFs2XTtcblx0XHRjb25zdCBsZWZ0OCA9IG1hdHJpeFs4XTtcblx0XHRjb25zdCBsZWZ0OSA9IG1hdHJpeFs5XTtcblx0XHRjb25zdCBsZWZ0MTAgPSBtYXRyaXhbMTBdO1xuXG5cdFx0Y29uc3QgcmlnaHQwID0gcm90YXRpb25bMF07XG5cdFx0Y29uc3QgcmlnaHQxID0gcm90YXRpb25bMV07XG5cdFx0Y29uc3QgcmlnaHQyID0gcm90YXRpb25bMl07XG5cdFx0Y29uc3QgcmlnaHQ0ID0gcm90YXRpb25bM107XG5cdFx0Y29uc3QgcmlnaHQ1ID0gcm90YXRpb25bNF07XG5cdFx0Y29uc3QgcmlnaHQ2ID0gcm90YXRpb25bNV07XG5cdFx0Y29uc3QgcmlnaHQ4ID0gcm90YXRpb25bNl07XG5cdFx0Y29uc3QgcmlnaHQ5ID0gcm90YXRpb25bN107XG5cdFx0Y29uc3QgcmlnaHQxMCA9IHJvdGF0aW9uWzhdO1xuXG5cdFx0Y29uc3QgY29sdW1uMFJvdzAgPSBsZWZ0MCAqIHJpZ2h0MCArIGxlZnQ0ICogcmlnaHQxICsgbGVmdDggKiByaWdodDI7XG5cdFx0Y29uc3QgY29sdW1uMFJvdzEgPSBsZWZ0MSAqIHJpZ2h0MCArIGxlZnQ1ICogcmlnaHQxICsgbGVmdDkgKiByaWdodDI7XG5cdFx0Y29uc3QgY29sdW1uMFJvdzIgPSBsZWZ0MiAqIHJpZ2h0MCArIGxlZnQ2ICogcmlnaHQxICsgbGVmdDEwICogcmlnaHQyO1xuXG5cdFx0Y29uc3QgY29sdW1uMVJvdzAgPSBsZWZ0MCAqIHJpZ2h0NCArIGxlZnQ0ICogcmlnaHQ1ICsgbGVmdDggKiByaWdodDY7XG5cdFx0Y29uc3QgY29sdW1uMVJvdzEgPSBsZWZ0MSAqIHJpZ2h0NCArIGxlZnQ1ICogcmlnaHQ1ICsgbGVmdDkgKiByaWdodDY7XG5cdFx0Y29uc3QgY29sdW1uMVJvdzIgPSBsZWZ0MiAqIHJpZ2h0NCArIGxlZnQ2ICogcmlnaHQ1ICsgbGVmdDEwICogcmlnaHQ2O1xuXG5cdFx0Y29uc3QgY29sdW1uMlJvdzAgPSBsZWZ0MCAqIHJpZ2h0OCArIGxlZnQ0ICogcmlnaHQ5ICsgbGVmdDggKiByaWdodDEwO1xuXHRcdGNvbnN0IGNvbHVtbjJSb3cxID0gbGVmdDEgKiByaWdodDggKyBsZWZ0NSAqIHJpZ2h0OSArIGxlZnQ5ICogcmlnaHQxMDtcblx0XHRjb25zdCBjb2x1bW4yUm93MiA9IGxlZnQyICogcmlnaHQ4ICsgbGVmdDYgKiByaWdodDkgKyBsZWZ0MTAgKiByaWdodDEwO1xuXG5cdFx0cmVzdWx0WzBdID0gY29sdW1uMFJvdzA7XG5cdFx0cmVzdWx0WzFdID0gY29sdW1uMFJvdzE7XG5cdFx0cmVzdWx0WzJdID0gY29sdW1uMFJvdzI7XG5cdFx0cmVzdWx0WzNdID0gMC4wO1xuXHRcdHJlc3VsdFs0XSA9IGNvbHVtbjFSb3cwO1xuXHRcdHJlc3VsdFs1XSA9IGNvbHVtbjFSb3cxO1xuXHRcdHJlc3VsdFs2XSA9IGNvbHVtbjFSb3cyO1xuXHRcdHJlc3VsdFs3XSA9IDAuMDtcblx0XHRyZXN1bHRbOF0gPSBjb2x1bW4yUm93MDtcblx0XHRyZXN1bHRbOV0gPSBjb2x1bW4yUm93MTtcblx0XHRyZXN1bHRbMTBdID0gY29sdW1uMlJvdzI7XG5cdFx0cmVzdWx0WzExXSA9IDAuMDtcblx0XHRyZXN1bHRbMTJdID0gbWF0cml4WzEyXTtcblx0XHRyZXN1bHRbMTNdID0gbWF0cml4WzEzXTtcblx0XHRyZXN1bHRbMTRdID0gbWF0cml4WzE0XTtcblx0XHRyZXN1bHRbMTVdID0gbWF0cml4WzE1XTtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0c3RhdGljIG11bHRpcGx5QnlUcmFuc2xhdGlvbihtYXRyaXg6IE1hdHJpeDQsIHRyYW5zbGF0aW9uOiBWZWN0b3IzLCByZXN1bHQ6IE1hdHJpeDQpOiBNYXRyaXg0IHtcblx0XHRjb25zdCB4ID0gdHJhbnNsYXRpb24ueDtcblx0XHRjb25zdCB5ID0gdHJhbnNsYXRpb24ueTtcblx0XHRjb25zdCB6ID0gdHJhbnNsYXRpb24uejtcblxuXHRcdGNvbnN0IHR4ID0geCAqIG1hdHJpeFswXSArIHkgKiBtYXRyaXhbNF0gKyB6ICogbWF0cml4WzhdICsgbWF0cml4WzEyXTtcblx0XHRjb25zdCB0eSA9IHggKiBtYXRyaXhbMV0gKyB5ICogbWF0cml4WzVdICsgeiAqIG1hdHJpeFs5XSArIG1hdHJpeFsxM107XG5cdFx0Y29uc3QgdHogPSB4ICogbWF0cml4WzJdICsgeSAqIG1hdHJpeFs2XSArIHogKiBtYXRyaXhbMTBdICsgbWF0cml4WzE0XTtcblxuXHRcdHJlc3VsdFswXSA9IG1hdHJpeFswXTtcblx0XHRyZXN1bHRbMV0gPSBtYXRyaXhbMV07XG5cdFx0cmVzdWx0WzJdID0gbWF0cml4WzJdO1xuXHRcdHJlc3VsdFszXSA9IG1hdHJpeFszXTtcblx0XHRyZXN1bHRbNF0gPSBtYXRyaXhbNF07XG5cdFx0cmVzdWx0WzVdID0gbWF0cml4WzVdO1xuXHRcdHJlc3VsdFs2XSA9IG1hdHJpeFs2XTtcblx0XHRyZXN1bHRbN10gPSBtYXRyaXhbN107XG5cdFx0cmVzdWx0WzhdID0gbWF0cml4WzhdO1xuXHRcdHJlc3VsdFs5XSA9IG1hdHJpeFs5XTtcblx0XHRyZXN1bHRbMTBdID0gbWF0cml4WzEwXTtcblx0XHRyZXN1bHRbMTFdID0gbWF0cml4WzExXTtcblx0XHRyZXN1bHRbMTJdID0gdHg7XG5cdFx0cmVzdWx0WzEzXSA9IHR5O1xuXHRcdHJlc3VsdFsxNF0gPSB0ejtcblx0XHRyZXN1bHRbMTVdID0gbWF0cml4WzE1XTtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0c3RhdGljIG11bHRpcGx5QnlTY2FsZShtYXRyaXg6IE1hdHJpeDQsIHNjYWxlOiBWZWN0b3IzLCByZXN1bHQ6IE1hdHJpeDQpOiBNYXRyaXg0IHtcblx0XHRjb25zdCBzY2FsZVggPSBzY2FsZS54O1xuXHRcdGNvbnN0IHNjYWxlWSA9IHNjYWxlLnk7XG5cdFx0Y29uc3Qgc2NhbGVaID0gc2NhbGUuejtcblxuXHRcdC8vIEZhc3RlciB0aGFuIFZlY3RvcjMuZXF1YWxzXG5cdFx0aWYgKHNjYWxlWCA9PT0gMS4wICYmIHNjYWxlWSA9PT0gMS4wICYmIHNjYWxlWiA9PT0gMS4wKSB7XG5cdFx0XHRyZXR1cm4gTWF0cml4NC5jbG9uZShtYXRyaXgsIHJlc3VsdCk7XG5cdFx0fVxuXG5cdFx0cmVzdWx0WzBdID0gc2NhbGVYICogbWF0cml4WzBdO1xuXHRcdHJlc3VsdFsxXSA9IHNjYWxlWCAqIG1hdHJpeFsxXTtcblx0XHRyZXN1bHRbMl0gPSBzY2FsZVggKiBtYXRyaXhbMl07XG5cdFx0cmVzdWx0WzNdID0gbWF0cml4WzNdO1xuXG5cdFx0cmVzdWx0WzRdID0gc2NhbGVZICogbWF0cml4WzRdO1xuXHRcdHJlc3VsdFs1XSA9IHNjYWxlWSAqIG1hdHJpeFs1XTtcblx0XHRyZXN1bHRbNl0gPSBzY2FsZVkgKiBtYXRyaXhbNl07XG5cdFx0cmVzdWx0WzddID0gbWF0cml4WzddO1xuXG5cdFx0cmVzdWx0WzhdID0gc2NhbGVaICogbWF0cml4WzhdO1xuXHRcdHJlc3VsdFs5XSA9IHNjYWxlWiAqIG1hdHJpeFs5XTtcblx0XHRyZXN1bHRbMTBdID0gc2NhbGVaICogbWF0cml4WzEwXTtcblx0XHRyZXN1bHRbMTFdID0gbWF0cml4WzExXTtcblxuXHRcdHJlc3VsdFsxMl0gPSBtYXRyaXhbMTJdO1xuXHRcdHJlc3VsdFsxM10gPSBtYXRyaXhbMTNdO1xuXHRcdHJlc3VsdFsxNF0gPSBtYXRyaXhbMTRdO1xuXHRcdHJlc3VsdFsxNV0gPSBtYXRyaXhbMTVdO1xuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyBtdWx0aXBseUJ5VW5pZm9ybVNjYWxlKG1hdHJpeDogTWF0cml4NCwgc2NhbGU6IG51bWJlciwgcmVzdWx0OiBNYXRyaXg0KTogTWF0cml4NCB7XG5cdFx0cmVzdWx0WzBdID0gbWF0cml4WzBdICogc2NhbGU7XG5cdFx0cmVzdWx0WzFdID0gbWF0cml4WzFdICogc2NhbGU7XG5cdFx0cmVzdWx0WzJdID0gbWF0cml4WzJdICogc2NhbGU7XG5cdFx0cmVzdWx0WzNdID0gbWF0cml4WzNdO1xuXG5cdFx0cmVzdWx0WzRdID0gbWF0cml4WzRdICogc2NhbGU7XG5cdFx0cmVzdWx0WzVdID0gbWF0cml4WzVdICogc2NhbGU7XG5cdFx0cmVzdWx0WzZdID0gbWF0cml4WzZdICogc2NhbGU7XG5cdFx0cmVzdWx0WzddID0gbWF0cml4WzddO1xuXG5cdFx0cmVzdWx0WzhdID0gbWF0cml4WzhdICogc2NhbGU7XG5cdFx0cmVzdWx0WzldID0gbWF0cml4WzldICogc2NhbGU7XG5cdFx0cmVzdWx0WzEwXSA9IG1hdHJpeFsxMF0gKiBzY2FsZTtcblx0XHRyZXN1bHRbMTFdID0gbWF0cml4WzExXTtcblxuXHRcdHJlc3VsdFsxMl0gPSBtYXRyaXhbMTJdO1xuXHRcdHJlc3VsdFsxM10gPSBtYXRyaXhbMTNdO1xuXHRcdHJlc3VsdFsxNF0gPSBtYXRyaXhbMTRdO1xuXHRcdHJlc3VsdFsxNV0gPSBtYXRyaXhbMTVdO1xuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyBtdWx0aXBseUJ5VmVjdG9yKG1hdHJpeDogTWF0cml4NCwgY2FydGVzaWFuOiBWZWN0b3I0LCByZXN1bHQ6IFZlY3RvcjQpOiBWZWN0b3I0IHtcblx0XHRjb25zdCB2WCA9IGNhcnRlc2lhbi54O1xuXHRcdGNvbnN0IHZZID0gY2FydGVzaWFuLnk7XG5cdFx0Y29uc3QgdlogPSBjYXJ0ZXNpYW4uejtcblx0XHRjb25zdCB2VyA9IGNhcnRlc2lhbi53O1xuXG5cdFx0Y29uc3QgeCA9IG1hdHJpeFswXSAqIHZYICsgbWF0cml4WzRdICogdlkgKyBtYXRyaXhbOF0gKiB2WiArIG1hdHJpeFsxMl0gKiB2Vztcblx0XHRjb25zdCB5ID0gbWF0cml4WzFdICogdlggKyBtYXRyaXhbNV0gKiB2WSArIG1hdHJpeFs5XSAqIHZaICsgbWF0cml4WzEzXSAqIHZXO1xuXHRcdGNvbnN0IHogPSBtYXRyaXhbMl0gKiB2WCArIG1hdHJpeFs2XSAqIHZZICsgbWF0cml4WzEwXSAqIHZaICsgbWF0cml4WzE0XSAqIHZXO1xuXHRcdGNvbnN0IHcgPSBtYXRyaXhbM10gKiB2WCArIG1hdHJpeFs3XSAqIHZZICsgbWF0cml4WzExXSAqIHZaICsgbWF0cml4WzE1XSAqIHZXO1xuXG5cdFx0cmVzdWx0LnggPSB4O1xuXHRcdHJlc3VsdC55ID0geTtcblx0XHRyZXN1bHQueiA9IHo7XG5cdFx0cmVzdWx0LncgPSB3O1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRzdGF0aWMgbXVsdGlwbHlCeVBvaW50QXNWZWN0b3IobWF0cml4OiBNYXRyaXg0LCBjYXJ0ZXNpYW46IFZlY3RvcjMsIHJlc3VsdDogVmVjdG9yMyk6IFZlY3RvcjMge1xuXHRcdGNvbnN0IHZYID0gY2FydGVzaWFuLng7XG5cdFx0Y29uc3QgdlkgPSBjYXJ0ZXNpYW4ueTtcblx0XHRjb25zdCB2WiA9IGNhcnRlc2lhbi56O1xuXG5cdFx0Y29uc3QgeCA9IG1hdHJpeFswXSAqIHZYICsgbWF0cml4WzRdICogdlkgKyBtYXRyaXhbOF0gKiB2Wjtcblx0XHRjb25zdCB5ID0gbWF0cml4WzFdICogdlggKyBtYXRyaXhbNV0gKiB2WSArIG1hdHJpeFs5XSAqIHZaO1xuXHRcdGNvbnN0IHogPSBtYXRyaXhbMl0gKiB2WCArIG1hdHJpeFs2XSAqIHZZICsgbWF0cml4WzEwXSAqIHZaO1xuXG5cdFx0cmVzdWx0LnggPSB4O1xuXHRcdHJlc3VsdC55ID0geTtcblx0XHRyZXN1bHQueiA9IHo7XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyBtdWx0aXBseUJ5UG9pbnQobWF0cml4OiBNYXRyaXg0LCBjYXJ0ZXNpYW46IFZlY3RvcjMsIHJlc3VsdDogVmVjdG9yMyk6IFZlY3RvcjMge1xuXHRcdGNvbnN0IHZYID0gY2FydGVzaWFuLng7XG5cdFx0Y29uc3QgdlkgPSBjYXJ0ZXNpYW4ueTtcblx0XHRjb25zdCB2WiA9IGNhcnRlc2lhbi56O1xuXG5cdFx0Y29uc3QgeCA9IG1hdHJpeFswXSAqIHZYICsgbWF0cml4WzRdICogdlkgKyBtYXRyaXhbOF0gKiB2WiArIG1hdHJpeFsxMl07XG5cdFx0Y29uc3QgeSA9IG1hdHJpeFsxXSAqIHZYICsgbWF0cml4WzVdICogdlkgKyBtYXRyaXhbOV0gKiB2WiArIG1hdHJpeFsxM107XG5cdFx0Y29uc3QgeiA9IG1hdHJpeFsyXSAqIHZYICsgbWF0cml4WzZdICogdlkgKyBtYXRyaXhbMTBdICogdlogKyBtYXRyaXhbMTRdO1xuXG5cdFx0cmVzdWx0LnggPSB4O1xuXHRcdHJlc3VsdC55ID0geTtcblx0XHRyZXN1bHQueiA9IHo7XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyBtdWx0aXBseUJ5U2NhbGFyKG1hdHJpeDogTWF0cml4NCwgc2NhbGFyOiBudW1iZXIsIHJlc3VsdDogTWF0cml4NCk6IE1hdHJpeDQge1xuXHRcdHJlc3VsdFswXSA9IG1hdHJpeFswXSAqIHNjYWxhcjtcblx0XHRyZXN1bHRbMV0gPSBtYXRyaXhbMV0gKiBzY2FsYXI7XG5cdFx0cmVzdWx0WzJdID0gbWF0cml4WzJdICogc2NhbGFyO1xuXHRcdHJlc3VsdFszXSA9IG1hdHJpeFszXSAqIHNjYWxhcjtcblx0XHRyZXN1bHRbNF0gPSBtYXRyaXhbNF0gKiBzY2FsYXI7XG5cdFx0cmVzdWx0WzVdID0gbWF0cml4WzVdICogc2NhbGFyO1xuXHRcdHJlc3VsdFs2XSA9IG1hdHJpeFs2XSAqIHNjYWxhcjtcblx0XHRyZXN1bHRbN10gPSBtYXRyaXhbN10gKiBzY2FsYXI7XG5cdFx0cmVzdWx0WzhdID0gbWF0cml4WzhdICogc2NhbGFyO1xuXHRcdHJlc3VsdFs5XSA9IG1hdHJpeFs5XSAqIHNjYWxhcjtcblx0XHRyZXN1bHRbMTBdID0gbWF0cml4WzEwXSAqIHNjYWxhcjtcblx0XHRyZXN1bHRbMTFdID0gbWF0cml4WzExXSAqIHNjYWxhcjtcblx0XHRyZXN1bHRbMTJdID0gbWF0cml4WzEyXSAqIHNjYWxhcjtcblx0XHRyZXN1bHRbMTNdID0gbWF0cml4WzEzXSAqIHNjYWxhcjtcblx0XHRyZXN1bHRbMTRdID0gbWF0cml4WzE0XSAqIHNjYWxhcjtcblx0XHRyZXN1bHRbMTVdID0gbWF0cml4WzE1XSAqIHNjYWxhcjtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0c3RhdGljIG5lZ2F0ZShtYXRyaXg6IE1hdHJpeDQsIHJlc3VsdDogTWF0cml4NCk6IE1hdHJpeDQge1xuXHRcdHJlc3VsdFswXSA9IC1tYXRyaXhbMF07XG5cdFx0cmVzdWx0WzFdID0gLW1hdHJpeFsxXTtcblx0XHRyZXN1bHRbMl0gPSAtbWF0cml4WzJdO1xuXHRcdHJlc3VsdFszXSA9IC1tYXRyaXhbM107XG5cdFx0cmVzdWx0WzRdID0gLW1hdHJpeFs0XTtcblx0XHRyZXN1bHRbNV0gPSAtbWF0cml4WzVdO1xuXHRcdHJlc3VsdFs2XSA9IC1tYXRyaXhbNl07XG5cdFx0cmVzdWx0WzddID0gLW1hdHJpeFs3XTtcblx0XHRyZXN1bHRbOF0gPSAtbWF0cml4WzhdO1xuXHRcdHJlc3VsdFs5XSA9IC1tYXRyaXhbOV07XG5cdFx0cmVzdWx0WzEwXSA9IC1tYXRyaXhbMTBdO1xuXHRcdHJlc3VsdFsxMV0gPSAtbWF0cml4WzExXTtcblx0XHRyZXN1bHRbMTJdID0gLW1hdHJpeFsxMl07XG5cdFx0cmVzdWx0WzEzXSA9IC1tYXRyaXhbMTNdO1xuXHRcdHJlc3VsdFsxNF0gPSAtbWF0cml4WzE0XTtcblx0XHRyZXN1bHRbMTVdID0gLW1hdHJpeFsxNV07XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyB0cmFuc3Bvc2UobWF0cml4OiBNYXRyaXg0LCByZXN1bHQ6IE1hdHJpeDQpOiBNYXRyaXg0IHtcblx0XHRjb25zdCBtYXRyaXgxID0gbWF0cml4WzFdO1xuXHRcdGNvbnN0IG1hdHJpeDIgPSBtYXRyaXhbMl07XG5cdFx0Y29uc3QgbWF0cml4MyA9IG1hdHJpeFszXTtcblx0XHRjb25zdCBtYXRyaXg2ID0gbWF0cml4WzZdO1xuXHRcdGNvbnN0IG1hdHJpeDcgPSBtYXRyaXhbN107XG5cdFx0Y29uc3QgbWF0cml4MTEgPSBtYXRyaXhbMTFdO1xuXG5cdFx0cmVzdWx0WzBdID0gbWF0cml4WzBdO1xuXHRcdHJlc3VsdFsxXSA9IG1hdHJpeFs0XTtcblx0XHRyZXN1bHRbMl0gPSBtYXRyaXhbOF07XG5cdFx0cmVzdWx0WzNdID0gbWF0cml4WzEyXTtcblx0XHRyZXN1bHRbNF0gPSBtYXRyaXgxO1xuXHRcdHJlc3VsdFs1XSA9IG1hdHJpeFs1XTtcblx0XHRyZXN1bHRbNl0gPSBtYXRyaXhbOV07XG5cdFx0cmVzdWx0WzddID0gbWF0cml4WzEzXTtcblx0XHRyZXN1bHRbOF0gPSBtYXRyaXgyO1xuXHRcdHJlc3VsdFs5XSA9IG1hdHJpeDY7XG5cdFx0cmVzdWx0WzEwXSA9IG1hdHJpeFsxMF07XG5cdFx0cmVzdWx0WzExXSA9IG1hdHJpeFsxNF07XG5cdFx0cmVzdWx0WzEyXSA9IG1hdHJpeDM7XG5cdFx0cmVzdWx0WzEzXSA9IG1hdHJpeDc7XG5cdFx0cmVzdWx0WzE0XSA9IG1hdHJpeDExO1xuXHRcdHJlc3VsdFsxNV0gPSBtYXRyaXhbMTVdO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRzdGF0aWMgYWJzKG1hdHJpeDogTWF0cml4NCwgcmVzdWx0OiBNYXRyaXg0KSB7XG5cdFx0cmVzdWx0WzBdID0gTWF0aC5hYnMobWF0cml4WzBdKTtcblx0XHRyZXN1bHRbMV0gPSBNYXRoLmFicyhtYXRyaXhbMV0pO1xuXHRcdHJlc3VsdFsyXSA9IE1hdGguYWJzKG1hdHJpeFsyXSk7XG5cdFx0cmVzdWx0WzNdID0gTWF0aC5hYnMobWF0cml4WzNdKTtcblx0XHRyZXN1bHRbNF0gPSBNYXRoLmFicyhtYXRyaXhbNF0pO1xuXHRcdHJlc3VsdFs1XSA9IE1hdGguYWJzKG1hdHJpeFs1XSk7XG5cdFx0cmVzdWx0WzZdID0gTWF0aC5hYnMobWF0cml4WzZdKTtcblx0XHRyZXN1bHRbN10gPSBNYXRoLmFicyhtYXRyaXhbN10pO1xuXHRcdHJlc3VsdFs4XSA9IE1hdGguYWJzKG1hdHJpeFs4XSk7XG5cdFx0cmVzdWx0WzldID0gTWF0aC5hYnMobWF0cml4WzldKTtcblx0XHRyZXN1bHRbMTBdID0gTWF0aC5hYnMobWF0cml4WzEwXSk7XG5cdFx0cmVzdWx0WzExXSA9IE1hdGguYWJzKG1hdHJpeFsxMV0pO1xuXHRcdHJlc3VsdFsxMl0gPSBNYXRoLmFicyhtYXRyaXhbMTJdKTtcblx0XHRyZXN1bHRbMTNdID0gTWF0aC5hYnMobWF0cml4WzEzXSk7XG5cdFx0cmVzdWx0WzE0XSA9IE1hdGguYWJzKG1hdHJpeFsxNF0pO1xuXHRcdHJlc3VsdFsxNV0gPSBNYXRoLmFicyhtYXRyaXhbMTVdKTtcblxuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRzdGF0aWMgZXF1YWxzKGxlZnQ6IE1hdHJpeDQsIHJpZ2h0OiBNYXRyaXg0KTogYm9vbGVhbiB7XG5cdFx0Ly8gR2l2ZW4gdGhhdCBtb3N0IG1hdHJpY2VzIHdpbGwgYmUgdHJhbnNmb3JtYXRpb24gbWF0cmljZXMsIHRoZSBlbGVtZW50c1xuXHRcdC8vIGFyZSB0ZXN0ZWQgaW4gb3JkZXIgc3VjaCB0aGF0IHRoZSB0ZXN0IGlzIGxpa2VseSB0byBmYWlsIGFzIGVhcmx5XG5cdFx0Ly8gYXMgcG9zc2libGUuICBJIF90aGlua18gdGhpcyBpcyBqdXN0IGFzIGZyaWVuZGx5IHRvIHRoZSBMMSBjYWNoZVxuXHRcdC8vIGFzIHRlc3RpbmcgaW4gaW5kZXggb3JkZXIuICBJdCBpcyBjZXJ0YWludHkgZmFzdGVyIGluIHByYWN0aWNlLlxuXHRcdHJldHVybiAoXG5cdFx0XHRsZWZ0ID09PSByaWdodCB8fFxuXHRcdFx0KGRlZmluZWQobGVmdCkgJiZcblx0XHRcdFx0ZGVmaW5lZChyaWdodCkgJiZcblx0XHRcdFx0Ly8gVHJhbnNsYXRpb25cblx0XHRcdFx0bGVmdFsxMl0gPT09IHJpZ2h0WzEyXSAmJlxuXHRcdFx0XHRsZWZ0WzEzXSA9PT0gcmlnaHRbMTNdICYmXG5cdFx0XHRcdGxlZnRbMTRdID09PSByaWdodFsxNF0gJiZcblx0XHRcdFx0Ly8gUm90YXRpb24vc2NhbGVcblx0XHRcdFx0bGVmdFswXSA9PT0gcmlnaHRbMF0gJiZcblx0XHRcdFx0bGVmdFsxXSA9PT0gcmlnaHRbMV0gJiZcblx0XHRcdFx0bGVmdFsyXSA9PT0gcmlnaHRbMl0gJiZcblx0XHRcdFx0bGVmdFs0XSA9PT0gcmlnaHRbNF0gJiZcblx0XHRcdFx0bGVmdFs1XSA9PT0gcmlnaHRbNV0gJiZcblx0XHRcdFx0bGVmdFs2XSA9PT0gcmlnaHRbNl0gJiZcblx0XHRcdFx0bGVmdFs4XSA9PT0gcmlnaHRbOF0gJiZcblx0XHRcdFx0bGVmdFs5XSA9PT0gcmlnaHRbOV0gJiZcblx0XHRcdFx0bGVmdFsxMF0gPT09IHJpZ2h0WzEwXSAmJlxuXHRcdFx0XHQvLyBCb3R0b20gcm93XG5cdFx0XHRcdGxlZnRbM10gPT09IHJpZ2h0WzNdICYmXG5cdFx0XHRcdGxlZnRbN10gPT09IHJpZ2h0WzddICYmXG5cdFx0XHRcdGxlZnRbMTFdID09PSByaWdodFsxMV0gJiZcblx0XHRcdFx0bGVmdFsxNV0gPT09IHJpZ2h0WzE1XSlcblx0XHQpO1xuXHR9XG5cblx0c3RhdGljIGVxdWFsc0Vwc2lsb24obGVmdDogTWF0cml4NCwgcmlnaHQ6IE1hdHJpeDQsIGVwc2lsb246IG51bWJlcik6IGJvb2xlYW4ge1xuXHRcdGVwc2lsb24gPSBkZWZhdWx0VmFsdWUoZXBzaWxvbiwgMCk7XG5cblx0XHRyZXR1cm4gKFxuXHRcdFx0bGVmdCA9PT0gcmlnaHQgfHxcblx0XHRcdChkZWZpbmVkKGxlZnQpICYmXG5cdFx0XHRcdGRlZmluZWQocmlnaHQpICYmXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbMF0gLSByaWdodFswXSkgPD0gZXBzaWxvbiAmJlxuXHRcdFx0XHRNYXRoLmFicyhsZWZ0WzFdIC0gcmlnaHRbMV0pIDw9IGVwc2lsb24gJiZcblx0XHRcdFx0TWF0aC5hYnMobGVmdFsyXSAtIHJpZ2h0WzJdKSA8PSBlcHNpbG9uICYmXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbM10gLSByaWdodFszXSkgPD0gZXBzaWxvbiAmJlxuXHRcdFx0XHRNYXRoLmFicyhsZWZ0WzRdIC0gcmlnaHRbNF0pIDw9IGVwc2lsb24gJiZcblx0XHRcdFx0TWF0aC5hYnMobGVmdFs1XSAtIHJpZ2h0WzVdKSA8PSBlcHNpbG9uICYmXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbNl0gLSByaWdodFs2XSkgPD0gZXBzaWxvbiAmJlxuXHRcdFx0XHRNYXRoLmFicyhsZWZ0WzddIC0gcmlnaHRbN10pIDw9IGVwc2lsb24gJiZcblx0XHRcdFx0TWF0aC5hYnMobGVmdFs4XSAtIHJpZ2h0WzhdKSA8PSBlcHNpbG9uICYmXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbOV0gLSByaWdodFs5XSkgPD0gZXBzaWxvbiAmJlxuXHRcdFx0XHRNYXRoLmFicyhsZWZ0WzEwXSAtIHJpZ2h0WzEwXSkgPD0gZXBzaWxvbiAmJlxuXHRcdFx0XHRNYXRoLmFicyhsZWZ0WzExXSAtIHJpZ2h0WzExXSkgPD0gZXBzaWxvbiAmJlxuXHRcdFx0XHRNYXRoLmFicyhsZWZ0WzEyXSAtIHJpZ2h0WzEyXSkgPD0gZXBzaWxvbiAmJlxuXHRcdFx0XHRNYXRoLmFicyhsZWZ0WzEzXSAtIHJpZ2h0WzEzXSkgPD0gZXBzaWxvbiAmJlxuXHRcdFx0XHRNYXRoLmFicyhsZWZ0WzE0XSAtIHJpZ2h0WzE0XSkgPD0gZXBzaWxvbiAmJlxuXHRcdFx0XHRNYXRoLmFicyhsZWZ0WzE1XSAtIHJpZ2h0WzE1XSkgPD0gZXBzaWxvbilcblx0XHQpO1xuXHR9XG5cblx0c3RhdGljIGdldFRyYW5zbGF0aW9uKG1hdHJpeDogTWF0cml4NCwgcmVzdWx0OiBWZWN0b3IzKTogVmVjdG9yMyB7XG5cdFx0cmVzdWx0LnggPSBtYXRyaXhbMTJdO1xuXHRcdHJlc3VsdC55ID0gbWF0cml4WzEzXTtcblx0XHRyZXN1bHQueiA9IG1hdHJpeFsxNF07XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHN0YXRpYyBnZXRNYXRyaXgzKG1hdHJpeDogTWF0cml4NCwgcmVzdWx0OiBNYXRyaXgzKTogTWF0cml4MyB7XG5cdFx0cmVzdWx0WzBdID0gbWF0cml4WzBdO1xuXHRcdHJlc3VsdFsxXSA9IG1hdHJpeFsxXTtcblx0XHRyZXN1bHRbMl0gPSBtYXRyaXhbMl07XG5cdFx0cmVzdWx0WzNdID0gbWF0cml4WzRdO1xuXHRcdHJlc3VsdFs0XSA9IG1hdHJpeFs1XTtcblx0XHRyZXN1bHRbNV0gPSBtYXRyaXhbNl07XG5cdFx0cmVzdWx0WzZdID0gbWF0cml4WzhdO1xuXHRcdHJlc3VsdFs3XSA9IG1hdHJpeFs5XTtcblx0XHRyZXN1bHRbOF0gPSBtYXRyaXhbMTBdO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRzdGF0aWMgaW52ZXJzZShtYXRyaXg6IE1hdHJpeDQsIHJlc3VsdDogTWF0cml4NCkge1xuXHRcdC8vXG5cdFx0Ly8gUG9ydGVkIGZyb206XG5cdFx0Ly8gICBmdHA6Ly9kb3dubG9hZC5pbnRlbC5jb20vZGVzaWduL1BlbnRpdW1JSUkvc21sLzI0NTA0MzAxLnBkZlxuXHRcdC8vXG5cdFx0Y29uc3Qgc3JjMCA9IG1hdHJpeFswXTtcblx0XHRjb25zdCBzcmMxID0gbWF0cml4WzRdO1xuXHRcdGNvbnN0IHNyYzIgPSBtYXRyaXhbOF07XG5cdFx0Y29uc3Qgc3JjMyA9IG1hdHJpeFsxMl07XG5cdFx0Y29uc3Qgc3JjNCA9IG1hdHJpeFsxXTtcblx0XHRjb25zdCBzcmM1ID0gbWF0cml4WzVdO1xuXHRcdGNvbnN0IHNyYzYgPSBtYXRyaXhbOV07XG5cdFx0Y29uc3Qgc3JjNyA9IG1hdHJpeFsxM107XG5cdFx0Y29uc3Qgc3JjOCA9IG1hdHJpeFsyXTtcblx0XHRjb25zdCBzcmM5ID0gbWF0cml4WzZdO1xuXHRcdGNvbnN0IHNyYzEwID0gbWF0cml4WzEwXTtcblx0XHRjb25zdCBzcmMxMSA9IG1hdHJpeFsxNF07XG5cdFx0Y29uc3Qgc3JjMTIgPSBtYXRyaXhbM107XG5cdFx0Y29uc3Qgc3JjMTMgPSBtYXRyaXhbN107XG5cdFx0Y29uc3Qgc3JjMTQgPSBtYXRyaXhbMTFdO1xuXHRcdGNvbnN0IHNyYzE1ID0gbWF0cml4WzE1XTtcblxuXHRcdC8vIGNhbGN1bGF0ZSBwYWlycyBmb3IgZmlyc3QgOCBlbGVtZW50cyAoY29mYWN0b3JzKVxuXHRcdGxldCB0bXAwID0gc3JjMTAgKiBzcmMxNTtcblx0XHRsZXQgdG1wMSA9IHNyYzExICogc3JjMTQ7XG5cdFx0bGV0IHRtcDIgPSBzcmM5ICogc3JjMTU7XG5cdFx0bGV0IHRtcDMgPSBzcmMxMSAqIHNyYzEzO1xuXHRcdGxldCB0bXA0ID0gc3JjOSAqIHNyYzE0O1xuXHRcdGxldCB0bXA1ID0gc3JjMTAgKiBzcmMxMztcblx0XHRsZXQgdG1wNiA9IHNyYzggKiBzcmMxNTtcblx0XHRsZXQgdG1wNyA9IHNyYzExICogc3JjMTI7XG5cdFx0bGV0IHRtcDggPSBzcmM4ICogc3JjMTQ7XG5cdFx0bGV0IHRtcDkgPSBzcmMxMCAqIHNyYzEyO1xuXHRcdGxldCB0bXAxMCA9IHNyYzggKiBzcmMxMztcblx0XHRsZXQgdG1wMTEgPSBzcmM5ICogc3JjMTI7XG5cblx0XHQvLyBjYWxjdWxhdGUgZmlyc3QgOCBlbGVtZW50cyAoY29mYWN0b3JzKVxuXHRcdGNvbnN0IGRzdDAgPSB0bXAwICogc3JjNSArIHRtcDMgKiBzcmM2ICsgdG1wNCAqIHNyYzcgLSAodG1wMSAqIHNyYzUgKyB0bXAyICogc3JjNiArIHRtcDUgKiBzcmM3KTtcblx0XHRjb25zdCBkc3QxID0gdG1wMSAqIHNyYzQgKyB0bXA2ICogc3JjNiArIHRtcDkgKiBzcmM3IC0gKHRtcDAgKiBzcmM0ICsgdG1wNyAqIHNyYzYgKyB0bXA4ICogc3JjNyk7XG5cdFx0Y29uc3QgZHN0MiA9IHRtcDIgKiBzcmM0ICsgdG1wNyAqIHNyYzUgKyB0bXAxMCAqIHNyYzcgLSAodG1wMyAqIHNyYzQgKyB0bXA2ICogc3JjNSArIHRtcDExICogc3JjNyk7XG5cdFx0Y29uc3QgZHN0MyA9IHRtcDUgKiBzcmM0ICsgdG1wOCAqIHNyYzUgKyB0bXAxMSAqIHNyYzYgLSAodG1wNCAqIHNyYzQgKyB0bXA5ICogc3JjNSArIHRtcDEwICogc3JjNik7XG5cdFx0Y29uc3QgZHN0NCA9IHRtcDEgKiBzcmMxICsgdG1wMiAqIHNyYzIgKyB0bXA1ICogc3JjMyAtICh0bXAwICogc3JjMSArIHRtcDMgKiBzcmMyICsgdG1wNCAqIHNyYzMpO1xuXHRcdGNvbnN0IGRzdDUgPSB0bXAwICogc3JjMCArIHRtcDcgKiBzcmMyICsgdG1wOCAqIHNyYzMgLSAodG1wMSAqIHNyYzAgKyB0bXA2ICogc3JjMiArIHRtcDkgKiBzcmMzKTtcblx0XHRjb25zdCBkc3Q2ID0gdG1wMyAqIHNyYzAgKyB0bXA2ICogc3JjMSArIHRtcDExICogc3JjMyAtICh0bXAyICogc3JjMCArIHRtcDcgKiBzcmMxICsgdG1wMTAgKiBzcmMzKTtcblx0XHRjb25zdCBkc3Q3ID0gdG1wNCAqIHNyYzAgKyB0bXA5ICogc3JjMSArIHRtcDEwICogc3JjMiAtICh0bXA1ICogc3JjMCArIHRtcDggKiBzcmMxICsgdG1wMTEgKiBzcmMyKTtcblxuXHRcdC8vIGNhbGN1bGF0ZSBwYWlycyBmb3Igc2Vjb25kIDggZWxlbWVudHMgKGNvZmFjdG9ycylcblx0XHR0bXAwID0gc3JjMiAqIHNyYzc7XG5cdFx0dG1wMSA9IHNyYzMgKiBzcmM2O1xuXHRcdHRtcDIgPSBzcmMxICogc3JjNztcblx0XHR0bXAzID0gc3JjMyAqIHNyYzU7XG5cdFx0dG1wNCA9IHNyYzEgKiBzcmM2O1xuXHRcdHRtcDUgPSBzcmMyICogc3JjNTtcblx0XHR0bXA2ID0gc3JjMCAqIHNyYzc7XG5cdFx0dG1wNyA9IHNyYzMgKiBzcmM0O1xuXHRcdHRtcDggPSBzcmMwICogc3JjNjtcblx0XHR0bXA5ID0gc3JjMiAqIHNyYzQ7XG5cdFx0dG1wMTAgPSBzcmMwICogc3JjNTtcblx0XHR0bXAxMSA9IHNyYzEgKiBzcmM0O1xuXG5cdFx0Ly8gY2FsY3VsYXRlIHNlY29uZCA4IGVsZW1lbnRzIChjb2ZhY3RvcnMpXG5cdFx0Y29uc3QgZHN0OCA9IHRtcDAgKiBzcmMxMyArIHRtcDMgKiBzcmMxNCArIHRtcDQgKiBzcmMxNSAtICh0bXAxICogc3JjMTMgKyB0bXAyICogc3JjMTQgKyB0bXA1ICogc3JjMTUpO1xuXHRcdGNvbnN0IGRzdDkgPSB0bXAxICogc3JjMTIgKyB0bXA2ICogc3JjMTQgKyB0bXA5ICogc3JjMTUgLSAodG1wMCAqIHNyYzEyICsgdG1wNyAqIHNyYzE0ICsgdG1wOCAqIHNyYzE1KTtcblx0XHRjb25zdCBkc3QxMCA9IHRtcDIgKiBzcmMxMiArIHRtcDcgKiBzcmMxMyArIHRtcDEwICogc3JjMTUgLSAodG1wMyAqIHNyYzEyICsgdG1wNiAqIHNyYzEzICsgdG1wMTEgKiBzcmMxNSk7XG5cdFx0Y29uc3QgZHN0MTEgPSB0bXA1ICogc3JjMTIgKyB0bXA4ICogc3JjMTMgKyB0bXAxMSAqIHNyYzE0IC0gKHRtcDQgKiBzcmMxMiArIHRtcDkgKiBzcmMxMyArIHRtcDEwICogc3JjMTQpO1xuXHRcdGNvbnN0IGRzdDEyID0gdG1wMiAqIHNyYzEwICsgdG1wNSAqIHNyYzExICsgdG1wMSAqIHNyYzkgLSAodG1wNCAqIHNyYzExICsgdG1wMCAqIHNyYzkgKyB0bXAzICogc3JjMTApO1xuXHRcdGNvbnN0IGRzdDEzID0gdG1wOCAqIHNyYzExICsgdG1wMCAqIHNyYzggKyB0bXA3ICogc3JjMTAgLSAodG1wNiAqIHNyYzEwICsgdG1wOSAqIHNyYzExICsgdG1wMSAqIHNyYzgpO1xuXHRcdGNvbnN0IGRzdDE0ID0gdG1wNiAqIHNyYzkgKyB0bXAxMSAqIHNyYzExICsgdG1wMyAqIHNyYzggLSAodG1wMTAgKiBzcmMxMSArIHRtcDIgKiBzcmM4ICsgdG1wNyAqIHNyYzkpO1xuXHRcdGNvbnN0IGRzdDE1ID0gdG1wMTAgKiBzcmMxMCArIHRtcDQgKiBzcmM4ICsgdG1wOSAqIHNyYzkgLSAodG1wOCAqIHNyYzkgKyB0bXAxMSAqIHNyYzEwICsgdG1wNSAqIHNyYzgpO1xuXG5cdFx0Ly8gY2FsY3VsYXRlIGRldGVybWluYW50XG5cdFx0bGV0IGRldCA9IHNyYzAgKiBkc3QwICsgc3JjMSAqIGRzdDEgKyBzcmMyICogZHN0MiArIHNyYzMgKiBkc3QzO1xuXG5cdFx0aWYgKE1hdGguYWJzKGRldCkgPCBHTWF0aC5FUFNJTE9OMjEpIHtcblx0XHRcdC8vIFNwZWNpYWwgY2FzZSBmb3IgYSB6ZXJvIHNjYWxlIG1hdHJpeCB0aGF0IGNhbiBvY2N1ciwgZm9yIGV4YW1wbGUsXG5cdFx0XHQvLyB3aGVuIGEgbW9kZWwncyBub2RlIGhhcyBhIFswLCAwLCAwXSBzY2FsZS5cblx0XHRcdGlmIChcblx0XHRcdFx0TWF0cml4My5lcXVhbHNFcHNpbG9uKFxuXHRcdFx0XHRcdE1hdHJpeDQuZ2V0TWF0cml4MyhtYXRyaXgsIHNjcmF0Y2hJbnZlcnNlUm90YXRpb24pLFxuXHRcdFx0XHRcdHNjcmF0Y2hNYXRyaXgzWmVybyxcblx0XHRcdFx0XHRHTWF0aC5FUFNJTE9ON1xuXHRcdFx0XHQpICYmXG5cdFx0XHRcdFZlY3RvcjQuZXF1YWxzKE1hdHJpeDQuZ2V0Um93KG1hdHJpeCwgMywgc2NyYXRjaEJvdHRvbVJvdyksIHNjcmF0Y2hFeHBlY3RlZEJvdHRvbVJvdylcblx0XHRcdCkge1xuXHRcdFx0XHRyZXN1bHRbMF0gPSAwLjA7XG5cdFx0XHRcdHJlc3VsdFsxXSA9IDAuMDtcblx0XHRcdFx0cmVzdWx0WzJdID0gMC4wO1xuXHRcdFx0XHRyZXN1bHRbM10gPSAwLjA7XG5cdFx0XHRcdHJlc3VsdFs0XSA9IDAuMDtcblx0XHRcdFx0cmVzdWx0WzVdID0gMC4wO1xuXHRcdFx0XHRyZXN1bHRbNl0gPSAwLjA7XG5cdFx0XHRcdHJlc3VsdFs3XSA9IDAuMDtcblx0XHRcdFx0cmVzdWx0WzhdID0gMC4wO1xuXHRcdFx0XHRyZXN1bHRbOV0gPSAwLjA7XG5cdFx0XHRcdHJlc3VsdFsxMF0gPSAwLjA7XG5cdFx0XHRcdHJlc3VsdFsxMV0gPSAwLjA7XG5cdFx0XHRcdHJlc3VsdFsxMl0gPSAtbWF0cml4WzEyXTtcblx0XHRcdFx0cmVzdWx0WzEzXSA9IC1tYXRyaXhbMTNdO1xuXHRcdFx0XHRyZXN1bHRbMTRdID0gLW1hdHJpeFsxNF07XG5cdFx0XHRcdHJlc3VsdFsxNV0gPSAxLjA7XG5cdFx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0XHR9XG5cblx0XHRcdHRocm93IG5ldyBFcnJvcihcIm1hdHJpeCBpcyBub3QgaW52ZXJ0aWJsZSBiZWNhdXNlIGl0cyBkZXRlcm1pbmF0ZSBpcyB6ZXJvLlwiKTtcblx0XHR9XG5cblx0XHQvLyBjYWxjdWxhdGUgbWF0cml4IGludmVyc2Vcblx0XHRkZXQgPSAxLjAgLyBkZXQ7XG5cblx0XHRyZXN1bHRbMF0gPSBkc3QwICogZGV0O1xuXHRcdHJlc3VsdFsxXSA9IGRzdDEgKiBkZXQ7XG5cdFx0cmVzdWx0WzJdID0gZHN0MiAqIGRldDtcblx0XHRyZXN1bHRbM10gPSBkc3QzICogZGV0O1xuXHRcdHJlc3VsdFs0XSA9IGRzdDQgKiBkZXQ7XG5cdFx0cmVzdWx0WzVdID0gZHN0NSAqIGRldDtcblx0XHRyZXN1bHRbNl0gPSBkc3Q2ICogZGV0O1xuXHRcdHJlc3VsdFs3XSA9IGRzdDcgKiBkZXQ7XG5cdFx0cmVzdWx0WzhdID0gZHN0OCAqIGRldDtcblx0XHRyZXN1bHRbOV0gPSBkc3Q5ICogZGV0O1xuXHRcdHJlc3VsdFsxMF0gPSBkc3QxMCAqIGRldDtcblx0XHRyZXN1bHRbMTFdID0gZHN0MTEgKiBkZXQ7XG5cdFx0cmVzdWx0WzEyXSA9IGRzdDEyICogZGV0O1xuXHRcdHJlc3VsdFsxM10gPSBkc3QxMyAqIGRldDtcblx0XHRyZXN1bHRbMTRdID0gZHN0MTQgKiBkZXQ7XG5cdFx0cmVzdWx0WzE1XSA9IGRzdDE1ICogZGV0O1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRzdGF0aWMgaW52ZXJzZVRyYW5zZm9ybWF0aW9uKG1hdHJpeDogTWF0cml4NCwgcmVzdWx0OiBNYXRyaXg0KTogTWF0cml4NCB7XG5cdFx0Ly8gVGhpcyBmdW5jdGlvbiBpcyBhbiBvcHRpbWl6ZWQgdmVyc2lvbiBvZiB0aGUgYmVsb3cgNCBsaW5lcy5cblx0XHQvLyBjb25zdCByVCA9IE1hdHJpeDMudHJhbnNwb3NlKE1hdHJpeDQuZ2V0TWF0cml4MyhtYXRyaXgpKTtcblx0XHQvLyBjb25zdCByVE4gPSBNYXRyaXgzLm5lZ2F0ZShyVCk7XG5cdFx0Ly8gY29uc3QgclRUID0gTWF0cml4My5tdWx0aXBseUJ5VmVjdG9yKHJUTiwgTWF0cml4NC5nZXRUcmFuc2xhdGlvbihtYXRyaXgpKTtcblx0XHQvLyByZXR1cm4gTWF0cml4NC5mcm9tUm90YXRpb25UcmFuc2xhdGlvbihyVCwgclRULCByZXN1bHQpO1xuXG5cdFx0Y29uc3QgbWF0cml4MCA9IG1hdHJpeFswXTtcblx0XHRjb25zdCBtYXRyaXgxID0gbWF0cml4WzFdO1xuXHRcdGNvbnN0IG1hdHJpeDIgPSBtYXRyaXhbMl07XG5cdFx0Y29uc3QgbWF0cml4NCA9IG1hdHJpeFs0XTtcblx0XHRjb25zdCBtYXRyaXg1ID0gbWF0cml4WzVdO1xuXHRcdGNvbnN0IG1hdHJpeDYgPSBtYXRyaXhbNl07XG5cdFx0Y29uc3QgbWF0cml4OCA9IG1hdHJpeFs4XTtcblx0XHRjb25zdCBtYXRyaXg5ID0gbWF0cml4WzldO1xuXHRcdGNvbnN0IG1hdHJpeDEwID0gbWF0cml4WzEwXTtcblxuXHRcdGNvbnN0IHZYID0gbWF0cml4WzEyXTtcblx0XHRjb25zdCB2WSA9IG1hdHJpeFsxM107XG5cdFx0Y29uc3QgdlogPSBtYXRyaXhbMTRdO1xuXG5cdFx0Y29uc3QgeCA9IC1tYXRyaXgwICogdlggLSBtYXRyaXgxICogdlkgLSBtYXRyaXgyICogdlo7XG5cdFx0Y29uc3QgeSA9IC1tYXRyaXg0ICogdlggLSBtYXRyaXg1ICogdlkgLSBtYXRyaXg2ICogdlo7XG5cdFx0Y29uc3QgeiA9IC1tYXRyaXg4ICogdlggLSBtYXRyaXg5ICogdlkgLSBtYXRyaXgxMCAqIHZaO1xuXG5cdFx0cmVzdWx0WzBdID0gbWF0cml4MDtcblx0XHRyZXN1bHRbMV0gPSBtYXRyaXg0O1xuXHRcdHJlc3VsdFsyXSA9IG1hdHJpeDg7XG5cdFx0cmVzdWx0WzNdID0gMC4wO1xuXHRcdHJlc3VsdFs0XSA9IG1hdHJpeDE7XG5cdFx0cmVzdWx0WzVdID0gbWF0cml4NTtcblx0XHRyZXN1bHRbNl0gPSBtYXRyaXg5O1xuXHRcdHJlc3VsdFs3XSA9IDAuMDtcblx0XHRyZXN1bHRbOF0gPSBtYXRyaXgyO1xuXHRcdHJlc3VsdFs5XSA9IG1hdHJpeDY7XG5cdFx0cmVzdWx0WzEwXSA9IG1hdHJpeDEwO1xuXHRcdHJlc3VsdFsxMV0gPSAwLjA7XG5cdFx0cmVzdWx0WzEyXSA9IHg7XG5cdFx0cmVzdWx0WzEzXSA9IHk7XG5cdFx0cmVzdWx0WzE0XSA9IHo7XG5cdFx0cmVzdWx0WzE1XSA9IDEuMDtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0c3RhdGljIGludmVyc2VUcmFuc3Bvc2UobWF0cml4OiBNYXRyaXg0LCByZXN1bHQ6IE1hdHJpeDQpOiBNYXRyaXg0IHtcblx0XHRyZXR1cm4gTWF0cml4NC5pbnZlcnNlKE1hdHJpeDQudHJhbnNwb3NlKG1hdHJpeCwgc2NyYXRjaFRyYW5zcG9zZU1hdHJpeCksIHJlc3VsdCk7XG5cdH1cblx0LyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRzdGF0aWMgZXF1YWxzQXJyYXkobWF0cml4OiBNYXRyaXg0LCBhcnJheTogQXJyYXk8bnVtYmVyPiwgb2Zmc2V0OiBudW1iZXIpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0bWF0cml4WzBdID09PSBhcnJheVtvZmZzZXRdICYmXG5cdFx0XHRtYXRyaXhbMV0gPT09IGFycmF5W29mZnNldCArIDFdICYmXG5cdFx0XHRtYXRyaXhbMl0gPT09IGFycmF5W29mZnNldCArIDJdICYmXG5cdFx0XHRtYXRyaXhbM10gPT09IGFycmF5W29mZnNldCArIDNdICYmXG5cdFx0XHRtYXRyaXhbNF0gPT09IGFycmF5W29mZnNldCArIDRdICYmXG5cdFx0XHRtYXRyaXhbNV0gPT09IGFycmF5W29mZnNldCArIDVdICYmXG5cdFx0XHRtYXRyaXhbNl0gPT09IGFycmF5W29mZnNldCArIDZdICYmXG5cdFx0XHRtYXRyaXhbN10gPT09IGFycmF5W29mZnNldCArIDddICYmXG5cdFx0XHRtYXRyaXhbOF0gPT09IGFycmF5W29mZnNldCArIDhdICYmXG5cdFx0XHRtYXRyaXhbOV0gPT09IGFycmF5W29mZnNldCArIDldICYmXG5cdFx0XHRtYXRyaXhbMTBdID09PSBhcnJheVtvZmZzZXQgKyAxMF0gJiZcblx0XHRcdG1hdHJpeFsxMV0gPT09IGFycmF5W29mZnNldCArIDExXSAmJlxuXHRcdFx0bWF0cml4WzEyXSA9PT0gYXJyYXlbb2Zmc2V0ICsgMTJdICYmXG5cdFx0XHRtYXRyaXhbMTNdID09PSBhcnJheVtvZmZzZXQgKyAxM10gJiZcblx0XHRcdG1hdHJpeFsxNF0gPT09IGFycmF5W29mZnNldCArIDE0XSAmJlxuXHRcdFx0bWF0cml4WzE1XSA9PT0gYXJyYXlbb2Zmc2V0ICsgMTVdXG5cdFx0KTtcblx0fVxufVxuXG5jb25zdCBzY3JhdGNoVHJhbnNwb3NlTWF0cml4ID0gbmV3IE1hdHJpeDQoKTtcblxuY29uc3QgZnJvbUNhbWVyYUYgPSBuZXcgVmVjdG9yMygpO1xuY29uc3QgZnJvbUNhbWVyYVIgPSBuZXcgVmVjdG9yMygpO1xuY29uc3QgZnJvbUNhbWVyYVUgPSBuZXcgVmVjdG9yMygpO1xuXG5jb25zdCBzY2FsZVNjcmF0Y2gxID0gbmV3IFZlY3RvcjMoKTtcbmNvbnN0IHNjYWxlU2NyYXRjaDIgPSBuZXcgVmVjdG9yMygpO1xuY29uc3Qgc2NyYXRjaENvbHVtbiA9IG5ldyBWZWN0b3IzKCk7XG5jb25zdCBzY2FsZVNjcmF0Y2gzID0gbmV3IFZlY3RvcjMoKTtcbmNvbnN0IHNjYWxlU2NyYXRjaDQgPSBuZXcgVmVjdG9yMygpO1xuY29uc3Qgc2NhbGVTY3JhdGNoNSA9IG5ldyBWZWN0b3IzKCk7XG5jb25zdCBzY3JhdGNoSW52ZXJzZVJvdGF0aW9uID0gbmV3IE1hdHJpeDMoKTtcbmNvbnN0IHNjcmF0Y2hNYXRyaXgzWmVybyA9IG5ldyBNYXRyaXgzKCk7XG5jb25zdCBzY3JhdGNoQm90dG9tUm93ID0gbmV3IFZlY3RvcjQoKTtcbmNvbnN0IHNjcmF0Y2hFeHBlY3RlZEJvdHRvbVJvdyA9IG5ldyBWZWN0b3I0KDAuMCwgMC4wLCAwLjAsIDEuMCk7XG5jb25zdCB4ID0gbmV3IFZlY3RvcjMoKTtcbmNvbnN0IHkgPSBuZXcgVmVjdG9yMygpO1xuY29uc3QgeiA9IG5ldyBWZWN0b3IzKCk7XG5leHBvcnQgZGVmYXVsdCBNYXRyaXg0O1xuIiwiaW1wb3J0IENhbWVyYSBmcm9tIFwiLi4vY2FtZXJhL0NhbWVyYVwiO1xuaW1wb3J0IE1hdHJpeDQgZnJvbSBcIi4uL21hdGgvTWF0cml4NFwiO1xuaW1wb3J0IFBsYW5lIGZyb20gXCIuLi9tYXRoL1BsYW5lXCI7XG5pbXBvcnQgVmVjdG9yMyBmcm9tIFwiLi4vbWF0aC9WZWN0b3IzXCI7XG5pbXBvcnQgZGVmYXVsdFZhbHVlIGZyb20gXCIuLi91dGlscy9kZWZhdWx0VmFsdWVcIjtcbmltcG9ydCBkZWZpbmVkIGZyb20gXCIuLi91dGlscy9kZWZpbmVkXCI7XG5pbXBvcnQgeyBJbnRlcnNlY3QgfSBmcm9tIFwiLi9XZWJHUFVDb25zdGFudFwiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCb3VuZGluZ1NwaGVyZSB7XG5cdHJhZGl1czogbnVtYmVyO1xuXHRjZW50ZXI6IFZlY3RvcjM7XG5cdG9yaWdpblJhZGl1czogbnVtYmVyO1xuXHRvcmlnaW5DZW50ZXI6IFZlY3RvcjM7XG5cdGNvbnN0cnVjdG9yKGNlbnRlcjogVmVjdG9yMyA9IG5ldyBWZWN0b3IzKDAsIDAsIDApLCByYWRpdXMgPSAwKSB7XG5cdFx0dGhpcy5jZW50ZXIgPSBjZW50ZXI7XG5cdFx0dGhpcy5yYWRpdXMgPSByYWRpdXM7XG5cdFx0dGhpcy5vcmlnaW5DZW50ZXIgPSB0aGlzLmNlbnRlci5jbG9uZSgpO1xuXHRcdHRoaXMub3JpZ2luUmFkaXVzID0gcmFkaXVzO1xuXHR9XG5cdC8qKlxuXHQgKiBAcGFyYW0ge1ZlY3RvcjNbXX0gW3Bvc2l0aW9uc10gQW4gYXJyYXkgb2YgcG9pbnRzIHRoYXQgdGhlIGJvdW5kaW5nIHNwaGVyZSB3aWxsIGVuY2xvc2UuICBFYWNoIHBvaW50IG11c3QgaGF2ZSA8Y29kZT54PC9jb2RlPiwgPGNvZGU+eTwvY29kZT4sIGFuZCA8Y29kZT56PC9jb2RlPiBwcm9wZXJ0aWVzLlxuXHQgKiBAcmV0dXJucyB7Qm91bmRpbmdTcGhlcmV9IFRoZSBtb2RpZmllZCByZXN1bHQgcGFyYW1ldGVyIG9yIGEgbmV3IEJvdW5kaW5nU3BoZXJlIGluc3RhbmNlIGlmIG9uZSB3YXMgbm90IHByb3ZpZGVkLlxuXHQgKi9cblx0c3RhdGljIGZyb21Qb2ludHMocG9zaXRpb25zOiBWZWN0b3IzW10pIHtcblx0XHRjb25zdCByZXN1bHQgPSBuZXcgQm91bmRpbmdTcGhlcmUoKTtcblxuXHRcdGlmICghZGVmaW5lZChwb3NpdGlvbnMpIHx8IHBvc2l0aW9ucy5sZW5ndGggPT09IDApIHtcblx0XHRcdHJlc3VsdC5jZW50ZXIgPSBWZWN0b3IzLmNsb25lKFZlY3RvcjMuWkVSTywgcmVzdWx0LmNlbnRlcik7XG5cdFx0XHRyZXN1bHQucmFkaXVzID0gMC4wO1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cblx0XHRjb25zdCBjdXJyZW50UG9zID0gVmVjdG9yMy5jbG9uZShwb3NpdGlvbnNbMF0sIGZyb21Qb2ludHNDdXJyZW50UG9zKTtcblxuXHRcdGNvbnN0IHhNaW4gPSBWZWN0b3IzLmNsb25lKGN1cnJlbnRQb3MsIGZyb21Qb2ludHNYTWluKTtcblx0XHRjb25zdCB5TWluID0gVmVjdG9yMy5jbG9uZShjdXJyZW50UG9zLCBmcm9tUG9pbnRzWU1pbik7XG5cdFx0Y29uc3Qgek1pbiA9IFZlY3RvcjMuY2xvbmUoY3VycmVudFBvcywgZnJvbVBvaW50c1pNaW4pO1xuXG5cdFx0Y29uc3QgeE1heCA9IFZlY3RvcjMuY2xvbmUoY3VycmVudFBvcywgZnJvbVBvaW50c1hNYXgpO1xuXHRcdGNvbnN0IHlNYXggPSBWZWN0b3IzLmNsb25lKGN1cnJlbnRQb3MsIGZyb21Qb2ludHNZTWF4KTtcblx0XHRjb25zdCB6TWF4ID0gVmVjdG9yMy5jbG9uZShjdXJyZW50UG9zLCBmcm9tUG9pbnRzWk1heCk7XG5cblx0XHRjb25zdCBudW1Qb3NpdGlvbnMgPSBwb3NpdGlvbnMubGVuZ3RoO1xuXHRcdGxldCBpO1xuXHRcdGZvciAoaSA9IDE7IGkgPCBudW1Qb3NpdGlvbnM7IGkrKykge1xuXHRcdFx0VmVjdG9yMy5jbG9uZShwb3NpdGlvbnNbaV0sIGN1cnJlbnRQb3MpO1xuXG5cdFx0XHRjb25zdCB4ID0gY3VycmVudFBvcy54O1xuXHRcdFx0Y29uc3QgeSA9IGN1cnJlbnRQb3MueTtcblx0XHRcdGNvbnN0IHogPSBjdXJyZW50UG9zLno7XG5cblx0XHRcdC8vIFN0b3JlIHBvaW50cyBjb250YWluaW5nIHRoZSB0aGUgc21hbGxlc3QgYW5kIGxhcmdlc3QgY29tcG9uZW50c1xuXHRcdFx0aWYgKHggPCB4TWluLngpIHtcblx0XHRcdFx0VmVjdG9yMy5jbG9uZShjdXJyZW50UG9zLCB4TWluKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHggPiB4TWF4LngpIHtcblx0XHRcdFx0VmVjdG9yMy5jbG9uZShjdXJyZW50UG9zLCB4TWF4KTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHkgPCB5TWluLnkpIHtcblx0XHRcdFx0VmVjdG9yMy5jbG9uZShjdXJyZW50UG9zLCB5TWluKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHkgPiB5TWF4LnkpIHtcblx0XHRcdFx0VmVjdG9yMy5jbG9uZShjdXJyZW50UG9zLCB5TWF4KTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHogPCB6TWluLnopIHtcblx0XHRcdFx0VmVjdG9yMy5jbG9uZShjdXJyZW50UG9zLCB6TWluKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHogPiB6TWF4LnopIHtcblx0XHRcdFx0VmVjdG9yMy5jbG9uZShjdXJyZW50UG9zLCB6TWF4KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDb21wdXRlIHgtLCB5LSwgYW5kIHotc3BhbnMgKFNxdWFyZWQgZGlzdGFuY2VzIGIvbiBlYWNoIGNvbXBvbmVudCdzIG1pbi4gYW5kIG1heC4pLlxuXHRcdGNvbnN0IHhTcGFuID0gVmVjdG9yMy5tYWduaXR1ZGVTcXVhcmVkKFZlY3RvcjMuc3VidHJhY3QoeE1heCwgeE1pbiwgZnJvbVBvaW50c1NjcmF0Y2gpKTtcblx0XHRjb25zdCB5U3BhbiA9IFZlY3RvcjMubWFnbml0dWRlU3F1YXJlZChWZWN0b3IzLnN1YnRyYWN0KHlNYXgsIHlNaW4sIGZyb21Qb2ludHNTY3JhdGNoKSk7XG5cdFx0Y29uc3QgelNwYW4gPSBWZWN0b3IzLm1hZ25pdHVkZVNxdWFyZWQoVmVjdG9yMy5zdWJ0cmFjdCh6TWF4LCB6TWluLCBmcm9tUG9pbnRzU2NyYXRjaCkpO1xuXG5cdFx0Ly8gU2V0IHRoZSBkaWFtZXRlciBlbmRwb2ludHMgdG8gdGhlIGxhcmdlc3Qgc3Bhbi5cblx0XHRsZXQgZGlhbWV0ZXIxID0geE1pbjtcblx0XHRsZXQgZGlhbWV0ZXIyID0geE1heDtcblx0XHRsZXQgbWF4U3BhbiA9IHhTcGFuO1xuXHRcdGlmICh5U3BhbiA+IG1heFNwYW4pIHtcblx0XHRcdG1heFNwYW4gPSB5U3Bhbjtcblx0XHRcdGRpYW1ldGVyMSA9IHlNaW47XG5cdFx0XHRkaWFtZXRlcjIgPSB5TWF4O1xuXHRcdH1cblx0XHRpZiAoelNwYW4gPiBtYXhTcGFuKSB7XG5cdFx0XHRtYXhTcGFuID0gelNwYW47XG5cdFx0XHRkaWFtZXRlcjEgPSB6TWluO1xuXHRcdFx0ZGlhbWV0ZXIyID0gek1heDtcblx0XHR9XG5cblx0XHQvLyBDYWxjdWxhdGUgdGhlIGNlbnRlciBvZiB0aGUgaW5pdGlhbCBzcGhlcmUgZm91bmQgYnkgUml0dGVyJ3MgYWxnb3JpdGhtXG5cdFx0Y29uc3Qgcml0dGVyQ2VudGVyID0gZnJvbVBvaW50c1JpdHRlckNlbnRlcjtcblx0XHRyaXR0ZXJDZW50ZXIueCA9IChkaWFtZXRlcjEueCArIGRpYW1ldGVyMi54KSAqIDAuNTtcblx0XHRyaXR0ZXJDZW50ZXIueSA9IChkaWFtZXRlcjEueSArIGRpYW1ldGVyMi55KSAqIDAuNTtcblx0XHRyaXR0ZXJDZW50ZXIueiA9IChkaWFtZXRlcjEueiArIGRpYW1ldGVyMi56KSAqIDAuNTtcblxuXHRcdC8vIENhbGN1bGF0ZSB0aGUgcmFkaXVzIG9mIHRoZSBpbml0aWFsIHNwaGVyZSBmb3VuZCBieSBSaXR0ZXIncyBhbGdvcml0aG1cblx0XHRsZXQgcmFkaXVzU3F1YXJlZCA9IFZlY3RvcjMubWFnbml0dWRlU3F1YXJlZChWZWN0b3IzLnN1YnRyYWN0KGRpYW1ldGVyMiwgcml0dGVyQ2VudGVyLCBmcm9tUG9pbnRzU2NyYXRjaCkpO1xuXHRcdGxldCByaXR0ZXJSYWRpdXMgPSBNYXRoLnNxcnQocmFkaXVzU3F1YXJlZCk7XG5cblx0XHQvLyBGaW5kIHRoZSBjZW50ZXIgb2YgdGhlIHNwaGVyZSBmb3VuZCB1c2luZyB0aGUgTmFpdmUgbWV0aG9kLlxuXHRcdGNvbnN0IG1pbkJveFB0ID0gZnJvbVBvaW50c01pbkJveFB0O1xuXHRcdG1pbkJveFB0LnggPSB4TWluLng7XG5cdFx0bWluQm94UHQueSA9IHlNaW4ueTtcblx0XHRtaW5Cb3hQdC56ID0gek1pbi56O1xuXG5cdFx0Y29uc3QgbWF4Qm94UHQgPSBmcm9tUG9pbnRzTWF4Qm94UHQ7XG5cdFx0bWF4Qm94UHQueCA9IHhNYXgueDtcblx0XHRtYXhCb3hQdC55ID0geU1heC55O1xuXHRcdG1heEJveFB0LnogPSB6TWF4Lno7XG5cblx0XHRjb25zdCBuYWl2ZUNlbnRlciA9IFZlY3RvcjMubWlkcG9pbnQobWluQm94UHQsIG1heEJveFB0LCBmcm9tUG9pbnRzTmFpdmVDZW50ZXJTY3JhdGNoKTtcblxuXHRcdC8vIEJlZ2luIDJuZCBwYXNzIHRvIGZpbmQgbmFpdmUgcmFkaXVzIGFuZCBtb2RpZnkgdGhlIHJpdHRlciBzcGhlcmUuXG5cdFx0bGV0IG5haXZlUmFkaXVzID0gMDtcblx0XHRmb3IgKGkgPSAwOyBpIDwgbnVtUG9zaXRpb25zOyBpKyspIHtcblx0XHRcdFZlY3RvcjMuY2xvbmUocG9zaXRpb25zW2ldLCBjdXJyZW50UG9zKTtcblxuXHRcdFx0Ly8gRmluZCB0aGUgZnVydGhlc3QgcG9pbnQgZnJvbSB0aGUgbmFpdmUgY2VudGVyIHRvIGNhbGN1bGF0ZSB0aGUgbmFpdmUgcmFkaXVzLlxuXHRcdFx0Y29uc3QgciA9IFZlY3RvcjMubWFnbml0dWRlKFZlY3RvcjMuc3VidHJhY3QoY3VycmVudFBvcywgbmFpdmVDZW50ZXIsIGZyb21Qb2ludHNTY3JhdGNoKSk7XG5cdFx0XHRpZiAociA+IG5haXZlUmFkaXVzKSB7XG5cdFx0XHRcdG5haXZlUmFkaXVzID0gcjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWFrZSBhZGp1c3RtZW50cyB0byB0aGUgUml0dGVyIFNwaGVyZSB0byBpbmNsdWRlIGFsbCBwb2ludHMuXG5cdFx0XHRjb25zdCBvbGRDZW50ZXJUb1BvaW50U3F1YXJlZCA9IFZlY3RvcjMubWFnbml0dWRlU3F1YXJlZChcblx0XHRcdFx0VmVjdG9yMy5zdWJ0cmFjdChjdXJyZW50UG9zLCByaXR0ZXJDZW50ZXIsIGZyb21Qb2ludHNTY3JhdGNoKVxuXHRcdFx0KTtcblx0XHRcdGlmIChvbGRDZW50ZXJUb1BvaW50U3F1YXJlZCA+IHJhZGl1c1NxdWFyZWQpIHtcblx0XHRcdFx0Y29uc3Qgb2xkQ2VudGVyVG9Qb2ludCA9IE1hdGguc3FydChvbGRDZW50ZXJUb1BvaW50U3F1YXJlZCk7XG5cdFx0XHRcdC8vIENhbGN1bGF0ZSBuZXcgcmFkaXVzIHRvIGluY2x1ZGUgdGhlIHBvaW50IHRoYXQgbGllcyBvdXRzaWRlXG5cdFx0XHRcdHJpdHRlclJhZGl1cyA9IChyaXR0ZXJSYWRpdXMgKyBvbGRDZW50ZXJUb1BvaW50KSAqIDAuNTtcblx0XHRcdFx0cmFkaXVzU3F1YXJlZCA9IHJpdHRlclJhZGl1cyAqIHJpdHRlclJhZGl1cztcblx0XHRcdFx0Ly8gQ2FsY3VsYXRlIGNlbnRlciBvZiBuZXcgUml0dGVyIHNwaGVyZVxuXHRcdFx0XHRjb25zdCBvbGRUb05ldyA9IG9sZENlbnRlclRvUG9pbnQgLSByaXR0ZXJSYWRpdXM7XG5cdFx0XHRcdHJpdHRlckNlbnRlci54ID0gKHJpdHRlclJhZGl1cyAqIHJpdHRlckNlbnRlci54ICsgb2xkVG9OZXcgKiBjdXJyZW50UG9zLngpIC8gb2xkQ2VudGVyVG9Qb2ludDtcblx0XHRcdFx0cml0dGVyQ2VudGVyLnkgPSAocml0dGVyUmFkaXVzICogcml0dGVyQ2VudGVyLnkgKyBvbGRUb05ldyAqIGN1cnJlbnRQb3MueSkgLyBvbGRDZW50ZXJUb1BvaW50O1xuXHRcdFx0XHRyaXR0ZXJDZW50ZXIueiA9IChyaXR0ZXJSYWRpdXMgKiByaXR0ZXJDZW50ZXIueiArIG9sZFRvTmV3ICogY3VycmVudFBvcy56KSAvIG9sZENlbnRlclRvUG9pbnQ7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKHJpdHRlclJhZGl1cyA8IG5haXZlUmFkaXVzKSB7XG5cdFx0XHRWZWN0b3IzLmNsb25lKHJpdHRlckNlbnRlciwgcmVzdWx0LmNlbnRlcik7XG5cdFx0XHRyZXN1bHQucmFkaXVzID0gcml0dGVyUmFkaXVzO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRWZWN0b3IzLmNsb25lKG5haXZlQ2VudGVyLCByZXN1bHQuY2VudGVyKTtcblx0XHRcdHJlc3VsdC5yYWRpdXMgPSBuYWl2ZVJhZGl1cztcblx0XHR9XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cdC8qKlxuXHQgKiBDb21wdXRlcyBhIHRpZ2h0LWZpdHRpbmcgYm91bmRpbmcgc3BoZXJlIGVuY2xvc2luZyBhIGxpc3Qgb2YgM0QgcG9pbnRzLCB3aGVyZSB0aGUgcG9pbnRzIGFyZVxuXHQgKiBzdG9yZWQgaW4gYSBmbGF0IGFycmF5IGluIFgsIFksIFosIG9yZGVyLiAgVGhlIGJvdW5kaW5nIHNwaGVyZSBpcyBjb21wdXRlZCBieSBydW5uaW5nIHR3b1xuXHQgKiBhbGdvcml0aG1zLCBhIG5haXZlIGFsZ29yaXRobSBhbmQgUml0dGVyJ3MgYWxnb3JpdGhtLiBUaGUgc21hbGxlciBvZiB0aGUgdHdvIHNwaGVyZXMgaXMgdXNlZCB0b1xuXHQgKiBlbnN1cmUgYSB0aWdodCBmaXQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7TnVtYmVyW119IFtwb3NpdGlvbnNdIEFuIGFycmF5IG9mIHBvaW50cyB0aGF0IHRoZSBib3VuZGluZyBzcGhlcmUgd2lsbCBlbmNsb3NlLiAgRWFjaCBwb2ludFxuXHQgKiAgICAgICAgaXMgZm9ybWVkIGZyb20gdGhyZWUgZWxlbWVudHMgaW4gdGhlIGFycmF5IGluIHRoZSBvcmRlciBYLCBZLCBaLlxuXHQgKiBAcGFyYW0ge1ZlY3RvcjN9IFtjZW50ZXI9VmVjdG9yMy5aRVJPXSBUaGUgcG9zaXRpb24gdG8gd2hpY2ggdGhlIHBvc2l0aW9ucyBhcmUgcmVsYXRpdmUsIHdoaWNoIG5lZWQgbm90IGJlIHRoZVxuXHQgKiAgICAgICAgb3JpZ2luIG9mIHRoZSBjb29yZGluYXRlIHN5c3RlbS4gIFRoaXMgaXMgdXNlZnVsIHdoZW4gdGhlIHBvc2l0aW9ucyBhcmUgdG8gYmUgdXNlZCBmb3Jcblx0ICogICAgICAgIHJlbGF0aXZlLXRvLWNlbnRlciAoUlRDKSByZW5kZXJpbmcuXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBbc3RyaWRlPTNdIFRoZSBudW1iZXIgb2YgYXJyYXkgZWxlbWVudHMgcGVyIHZlcnRleC4gIEl0IG11c3QgYmUgYXQgbGVhc3QgMywgYnV0IGl0IG1heVxuXHQgKiAgICAgICAgYmUgaGlnaGVyLiAgUmVnYXJkbGVzcyBvZiB0aGUgdmFsdWUgb2YgdGhpcyBwYXJhbWV0ZXIsIHRoZSBYIGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IHBvc2l0aW9uXG5cdCAqICAgICAgICBpcyBhdCBhcnJheSBpbmRleCAwLCB0aGUgWSBjb29yZGluYXRlIGlzIGF0IGFycmF5IGluZGV4IDEsIGFuZCB0aGUgWiBjb29yZGluYXRlIGlzIGF0IGFycmF5IGluZGV4XG5cdCAqICAgICAgICAyLiAgV2hlbiBzdHJpZGUgaXMgMywgdGhlIFggY29vcmRpbmF0ZSBvZiB0aGUgbmV4dCBwb3NpdGlvbiB0aGVuIGJlZ2lucyBhdCBhcnJheSBpbmRleCAzLiAgSWZcblx0ICogICAgICAgIHRoZSBzdHJpZGUgaXMgNSwgaG93ZXZlciwgdHdvIGFycmF5IGVsZW1lbnRzIGFyZSBza2lwcGVkIGFuZCB0aGUgbmV4dCBwb3NpdGlvbiBiZWdpbnMgYXQgYXJyYXlcblx0ICogICAgICAgIGluZGV4IDUuXG5cdCAqIEBwYXJhbSB7Qm91bmRpbmdTcGhlcmV9IFtyZXN1bHRdIFRoZSBvYmplY3Qgb250byB3aGljaCB0byBzdG9yZSB0aGUgcmVzdWx0LlxuXHQgKiBAcmV0dXJucyB7Qm91bmRpbmdTcGhlcmV9IFRoZSBtb2RpZmllZCByZXN1bHQgcGFyYW1ldGVyIG9yIGEgbmV3IEJvdW5kaW5nU3BoZXJlIGluc3RhbmNlIGlmIG9uZSB3YXMgbm90IHByb3ZpZGVkLlxuXHQgKlxuXHQgKiBAZXhhbXBsZVxuXHQgKiAvLyBDb21wdXRlIHRoZSBib3VuZGluZyBzcGhlcmUgZnJvbSAzIHBvc2l0aW9ucywgZWFjaCBzcGVjaWZpZWQgcmVsYXRpdmUgdG8gYSBjZW50ZXIuXG5cdCAqIC8vIEluIGFkZGl0aW9uIHRvIHRoZSBYLCBZLCBhbmQgWiBjb29yZGluYXRlcywgdGhlIHBvaW50cyBhcnJheSBjb250YWlucyB0d28gYWRkaXRpb25hbFxuXHQgKiAvLyBlbGVtZW50cyBwZXIgcG9pbnQgd2hpY2ggYXJlIGlnbm9yZWQgZm9yIHRoZSBwdXJwb3NlIG9mIGNvbXB1dGluZyB0aGUgYm91bmRpbmcgc3BoZXJlLlxuXHQgKiBjb25zdCBjZW50ZXIgPSBuZXcgVmVjdG9yMygxLjAsIDIuMCwgMy4wKTtcblx0ICogY29uc3QgcG9pbnRzID0gWzEuMCwgMi4wLCAzLjAsIDAuMSwgMC4yLFxuXHQgKiAgICAgICAgICAgICAgIDQuMCwgNS4wLCA2LjAsIDAuMSwgMC4yLFxuXHQgKiAgICAgICAgICAgICAgIDcuMCwgOC4wLCA5LjAsIDAuMSwgMC4yXTtcblx0ICogY29uc3Qgc3BoZXJlID0gQm91bmRpbmdTcGhlcmUuZnJvbVZlcnRpY2VzKHBvaW50cywgY2VudGVyLCA1KTtcblx0ICpcblx0ICovXG5cdHN0YXRpYyBmcm9tVmVydGljZXMocG9zaXRpb25zOiBudW1iZXJbXSwgY2VudGVyOiBWZWN0b3IzID0gVmVjdG9yMy5aRVJPLCBzdHJpZGUgPSAzKSB7XG5cdFx0Y29uc3QgcmVzdWx0ID0gbmV3IEJvdW5kaW5nU3BoZXJlKCk7XG5cblx0XHRpZiAoIWRlZmluZWQocG9zaXRpb25zKSB8fCBwb3NpdGlvbnMubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRyZXN1bHQuY2VudGVyID0gVmVjdG9yMy5jbG9uZShWZWN0b3IzLlpFUk8sIHJlc3VsdC5jZW50ZXIpO1xuXHRcdFx0cmVzdWx0LnJhZGl1cyA9IDAuMDtcblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fVxuXG5cdFx0Y2VudGVyID0gZGVmYXVsdFZhbHVlKGNlbnRlciwgVmVjdG9yMy5aRVJPKTtcblxuXHRcdHN0cmlkZSA9IGRlZmF1bHRWYWx1ZShzdHJpZGUsIDMpO1xuXG5cdFx0Y29uc3QgY3VycmVudFBvcyA9IGZyb21Qb2ludHNDdXJyZW50UG9zO1xuXHRcdGN1cnJlbnRQb3MueCA9IHBvc2l0aW9uc1swXSArIGNlbnRlci54O1xuXHRcdGN1cnJlbnRQb3MueSA9IHBvc2l0aW9uc1sxXSArIGNlbnRlci55O1xuXHRcdGN1cnJlbnRQb3MueiA9IHBvc2l0aW9uc1syXSArIGNlbnRlci56O1xuXG5cdFx0Y29uc3QgeE1pbiA9IFZlY3RvcjMuY2xvbmUoY3VycmVudFBvcywgZnJvbVBvaW50c1hNaW4pO1xuXHRcdGNvbnN0IHlNaW4gPSBWZWN0b3IzLmNsb25lKGN1cnJlbnRQb3MsIGZyb21Qb2ludHNZTWluKTtcblx0XHRjb25zdCB6TWluID0gVmVjdG9yMy5jbG9uZShjdXJyZW50UG9zLCBmcm9tUG9pbnRzWk1pbik7XG5cblx0XHRjb25zdCB4TWF4ID0gVmVjdG9yMy5jbG9uZShjdXJyZW50UG9zLCBmcm9tUG9pbnRzWE1heCk7XG5cdFx0Y29uc3QgeU1heCA9IFZlY3RvcjMuY2xvbmUoY3VycmVudFBvcywgZnJvbVBvaW50c1lNYXgpO1xuXHRcdGNvbnN0IHpNYXggPSBWZWN0b3IzLmNsb25lKGN1cnJlbnRQb3MsIGZyb21Qb2ludHNaTWF4KTtcblxuXHRcdGNvbnN0IG51bUVsZW1lbnRzID0gcG9zaXRpb25zLmxlbmd0aDtcblx0XHRsZXQgaTtcblx0XHRmb3IgKGkgPSAwOyBpIDwgbnVtRWxlbWVudHM7IGkgKz0gc3RyaWRlKSB7XG5cdFx0XHRjb25zdCB4ID0gcG9zaXRpb25zW2ldICsgY2VudGVyLng7XG5cdFx0XHRjb25zdCB5ID0gcG9zaXRpb25zW2kgKyAxXSArIGNlbnRlci55O1xuXHRcdFx0Y29uc3QgeiA9IHBvc2l0aW9uc1tpICsgMl0gKyBjZW50ZXIuejtcblxuXHRcdFx0Y3VycmVudFBvcy54ID0geDtcblx0XHRcdGN1cnJlbnRQb3MueSA9IHk7XG5cdFx0XHRjdXJyZW50UG9zLnogPSB6O1xuXG5cdFx0XHQvLyBTdG9yZSBwb2ludHMgY29udGFpbmluZyB0aGUgdGhlIHNtYWxsZXN0IGFuZCBsYXJnZXN0IGNvbXBvbmVudHNcblx0XHRcdGlmICh4IDwgeE1pbi54KSB7XG5cdFx0XHRcdFZlY3RvcjMuY2xvbmUoY3VycmVudFBvcywgeE1pbik7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh4ID4geE1heC54KSB7XG5cdFx0XHRcdFZlY3RvcjMuY2xvbmUoY3VycmVudFBvcywgeE1heCk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh5IDwgeU1pbi55KSB7XG5cdFx0XHRcdFZlY3RvcjMuY2xvbmUoY3VycmVudFBvcywgeU1pbik7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh5ID4geU1heC55KSB7XG5cdFx0XHRcdFZlY3RvcjMuY2xvbmUoY3VycmVudFBvcywgeU1heCk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh6IDwgek1pbi56KSB7XG5cdFx0XHRcdFZlY3RvcjMuY2xvbmUoY3VycmVudFBvcywgek1pbik7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh6ID4gek1heC56KSB7XG5cdFx0XHRcdFZlY3RvcjMuY2xvbmUoY3VycmVudFBvcywgek1heCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ29tcHV0ZSB4LSwgeS0sIGFuZCB6LXNwYW5zIChTcXVhcmVkIGRpc3RhbmNlcyBiL24gZWFjaCBjb21wb25lbnQncyBtaW4uIGFuZCBtYXguKS5cblx0XHRjb25zdCB4U3BhbiA9IFZlY3RvcjMubWFnbml0dWRlU3F1YXJlZChWZWN0b3IzLnN1YnRyYWN0KHhNYXgsIHhNaW4sIGZyb21Qb2ludHNTY3JhdGNoKSk7XG5cdFx0Y29uc3QgeVNwYW4gPSBWZWN0b3IzLm1hZ25pdHVkZVNxdWFyZWQoVmVjdG9yMy5zdWJ0cmFjdCh5TWF4LCB5TWluLCBmcm9tUG9pbnRzU2NyYXRjaCkpO1xuXHRcdGNvbnN0IHpTcGFuID0gVmVjdG9yMy5tYWduaXR1ZGVTcXVhcmVkKFZlY3RvcjMuc3VidHJhY3Qoek1heCwgek1pbiwgZnJvbVBvaW50c1NjcmF0Y2gpKTtcblxuXHRcdC8vIFNldCB0aGUgZGlhbWV0ZXIgZW5kcG9pbnRzIHRvIHRoZSBsYXJnZXN0IHNwYW4uXG5cdFx0bGV0IGRpYW1ldGVyMSA9IHhNaW47XG5cdFx0bGV0IGRpYW1ldGVyMiA9IHhNYXg7XG5cdFx0bGV0IG1heFNwYW4gPSB4U3Bhbjtcblx0XHRpZiAoeVNwYW4gPiBtYXhTcGFuKSB7XG5cdFx0XHRtYXhTcGFuID0geVNwYW47XG5cdFx0XHRkaWFtZXRlcjEgPSB5TWluO1xuXHRcdFx0ZGlhbWV0ZXIyID0geU1heDtcblx0XHR9XG5cdFx0aWYgKHpTcGFuID4gbWF4U3Bhbikge1xuXHRcdFx0bWF4U3BhbiA9IHpTcGFuO1xuXHRcdFx0ZGlhbWV0ZXIxID0gek1pbjtcblx0XHRcdGRpYW1ldGVyMiA9IHpNYXg7XG5cdFx0fVxuXG5cdFx0Ly8gQ2FsY3VsYXRlIHRoZSBjZW50ZXIgb2YgdGhlIGluaXRpYWwgc3BoZXJlIGZvdW5kIGJ5IFJpdHRlcidzIGFsZ29yaXRobVxuXHRcdGNvbnN0IHJpdHRlckNlbnRlciA9IGZyb21Qb2ludHNSaXR0ZXJDZW50ZXI7XG5cdFx0cml0dGVyQ2VudGVyLnggPSAoZGlhbWV0ZXIxLnggKyBkaWFtZXRlcjIueCkgKiAwLjU7XG5cdFx0cml0dGVyQ2VudGVyLnkgPSAoZGlhbWV0ZXIxLnkgKyBkaWFtZXRlcjIueSkgKiAwLjU7XG5cdFx0cml0dGVyQ2VudGVyLnogPSAoZGlhbWV0ZXIxLnogKyBkaWFtZXRlcjIueikgKiAwLjU7XG5cblx0XHQvLyBDYWxjdWxhdGUgdGhlIHJhZGl1cyBvZiB0aGUgaW5pdGlhbCBzcGhlcmUgZm91bmQgYnkgUml0dGVyJ3MgYWxnb3JpdGhtXG5cdFx0bGV0IHJhZGl1c1NxdWFyZWQgPSBWZWN0b3IzLm1hZ25pdHVkZVNxdWFyZWQoVmVjdG9yMy5zdWJ0cmFjdChkaWFtZXRlcjIsIHJpdHRlckNlbnRlciwgZnJvbVBvaW50c1NjcmF0Y2gpKTtcblx0XHRsZXQgcml0dGVyUmFkaXVzID0gTWF0aC5zcXJ0KHJhZGl1c1NxdWFyZWQpO1xuXG5cdFx0Ly8gRmluZCB0aGUgY2VudGVyIG9mIHRoZSBzcGhlcmUgZm91bmQgdXNpbmcgdGhlIE5haXZlIG1ldGhvZC5cblx0XHRjb25zdCBtaW5Cb3hQdCA9IGZyb21Qb2ludHNNaW5Cb3hQdDtcblx0XHRtaW5Cb3hQdC54ID0geE1pbi54O1xuXHRcdG1pbkJveFB0LnkgPSB5TWluLnk7XG5cdFx0bWluQm94UHQueiA9IHpNaW4uejtcblxuXHRcdGNvbnN0IG1heEJveFB0ID0gZnJvbVBvaW50c01heEJveFB0O1xuXHRcdG1heEJveFB0LnggPSB4TWF4Lng7XG5cdFx0bWF4Qm94UHQueSA9IHlNYXgueTtcblx0XHRtYXhCb3hQdC56ID0gek1heC56O1xuXG5cdFx0Y29uc3QgbmFpdmVDZW50ZXIgPSBWZWN0b3IzLm1pZHBvaW50KG1pbkJveFB0LCBtYXhCb3hQdCwgZnJvbVBvaW50c05haXZlQ2VudGVyU2NyYXRjaCk7XG5cblx0XHQvLyBCZWdpbiAybmQgcGFzcyB0byBmaW5kIG5haXZlIHJhZGl1cyBhbmQgbW9kaWZ5IHRoZSByaXR0ZXIgc3BoZXJlLlxuXHRcdGxldCBuYWl2ZVJhZGl1cyA9IDA7XG5cdFx0Zm9yIChpID0gMDsgaSA8IG51bUVsZW1lbnRzOyBpICs9IHN0cmlkZSkge1xuXHRcdFx0Y3VycmVudFBvcy54ID0gcG9zaXRpb25zW2ldICsgY2VudGVyLng7XG5cdFx0XHRjdXJyZW50UG9zLnkgPSBwb3NpdGlvbnNbaSArIDFdICsgY2VudGVyLnk7XG5cdFx0XHRjdXJyZW50UG9zLnogPSBwb3NpdGlvbnNbaSArIDJdICsgY2VudGVyLno7XG5cblx0XHRcdC8vIEZpbmQgdGhlIGZ1cnRoZXN0IHBvaW50IGZyb20gdGhlIG5haXZlIGNlbnRlciB0byBjYWxjdWxhdGUgdGhlIG5haXZlIHJhZGl1cy5cblx0XHRcdGNvbnN0IHIgPSBWZWN0b3IzLm1hZ25pdHVkZShWZWN0b3IzLnN1YnRyYWN0KGN1cnJlbnRQb3MsIG5haXZlQ2VudGVyLCBmcm9tUG9pbnRzU2NyYXRjaCkpO1xuXHRcdFx0aWYgKHIgPiBuYWl2ZVJhZGl1cykge1xuXHRcdFx0XHRuYWl2ZVJhZGl1cyA9IHI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE1ha2UgYWRqdXN0bWVudHMgdG8gdGhlIFJpdHRlciBTcGhlcmUgdG8gaW5jbHVkZSBhbGwgcG9pbnRzLlxuXHRcdFx0Y29uc3Qgb2xkQ2VudGVyVG9Qb2ludFNxdWFyZWQgPSBWZWN0b3IzLm1hZ25pdHVkZVNxdWFyZWQoXG5cdFx0XHRcdFZlY3RvcjMuc3VidHJhY3QoY3VycmVudFBvcywgcml0dGVyQ2VudGVyLCBmcm9tUG9pbnRzU2NyYXRjaClcblx0XHRcdCk7XG5cdFx0XHRpZiAob2xkQ2VudGVyVG9Qb2ludFNxdWFyZWQgPiByYWRpdXNTcXVhcmVkKSB7XG5cdFx0XHRcdGNvbnN0IG9sZENlbnRlclRvUG9pbnQgPSBNYXRoLnNxcnQob2xkQ2VudGVyVG9Qb2ludFNxdWFyZWQpO1xuXHRcdFx0XHQvLyBDYWxjdWxhdGUgbmV3IHJhZGl1cyB0byBpbmNsdWRlIHRoZSBwb2ludCB0aGF0IGxpZXMgb3V0c2lkZVxuXHRcdFx0XHRyaXR0ZXJSYWRpdXMgPSAocml0dGVyUmFkaXVzICsgb2xkQ2VudGVyVG9Qb2ludCkgKiAwLjU7XG5cdFx0XHRcdHJhZGl1c1NxdWFyZWQgPSByaXR0ZXJSYWRpdXMgKiByaXR0ZXJSYWRpdXM7XG5cdFx0XHRcdC8vIENhbGN1bGF0ZSBjZW50ZXIgb2YgbmV3IFJpdHRlciBzcGhlcmVcblx0XHRcdFx0Y29uc3Qgb2xkVG9OZXcgPSBvbGRDZW50ZXJUb1BvaW50IC0gcml0dGVyUmFkaXVzO1xuXHRcdFx0XHRyaXR0ZXJDZW50ZXIueCA9IChyaXR0ZXJSYWRpdXMgKiByaXR0ZXJDZW50ZXIueCArIG9sZFRvTmV3ICogY3VycmVudFBvcy54KSAvIG9sZENlbnRlclRvUG9pbnQ7XG5cdFx0XHRcdHJpdHRlckNlbnRlci55ID0gKHJpdHRlclJhZGl1cyAqIHJpdHRlckNlbnRlci55ICsgb2xkVG9OZXcgKiBjdXJyZW50UG9zLnkpIC8gb2xkQ2VudGVyVG9Qb2ludDtcblx0XHRcdFx0cml0dGVyQ2VudGVyLnogPSAocml0dGVyUmFkaXVzICogcml0dGVyQ2VudGVyLnogKyBvbGRUb05ldyAqIGN1cnJlbnRQb3MueikgLyBvbGRDZW50ZXJUb1BvaW50O1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChyaXR0ZXJSYWRpdXMgPCBuYWl2ZVJhZGl1cykge1xuXHRcdFx0VmVjdG9yMy5jbG9uZShyaXR0ZXJDZW50ZXIsIHJlc3VsdC5jZW50ZXIpO1xuXHRcdFx0cmVzdWx0LnJhZGl1cyA9IHJpdHRlclJhZGl1cztcblx0XHR9IGVsc2Uge1xuXHRcdFx0VmVjdG9yMy5jbG9uZShuYWl2ZUNlbnRlciwgcmVzdWx0LmNlbnRlcik7XG5cdFx0XHRyZXN1bHQucmFkaXVzID0gbmFpdmVSYWRpdXM7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdGludGVyc2VjdFBsYW5lKHBsYW5lOiBQbGFuZSkge1xuXHRcdGNvbnN0IGNlbnRlciA9IHRoaXMuY2VudGVyO1xuXHRcdGNvbnN0IHJhZGl1cyA9IHRoaXMucmFkaXVzO1xuXHRcdGNvbnN0IG5vcm1hbCA9IHBsYW5lLm5vcm1hbDtcblx0XHRjb25zdCBkaXN0YW5jZVRvUGxhbmUgPSBWZWN0b3IzLmRvdChub3JtYWwsIGNlbnRlcikgKyBwbGFuZS5kaXN0YW5jZTtcblxuXHRcdGlmIChkaXN0YW5jZVRvUGxhbmUgPCAtcmFkaXVzKSB7XG5cdFx0XHQvLyBUaGUgY2VudGVyIHBvaW50IGlzIG5lZ2F0aXZlIHNpZGUgb2YgdGhlIHBsYW5lIG5vcm1hbFxuXHRcdFx0cmV0dXJuIEludGVyc2VjdC5PVVRTSURFO1xuXHRcdH0gZWxzZSBpZiAoZGlzdGFuY2VUb1BsYW5lIDwgcmFkaXVzKSB7XG5cdFx0XHQvLyBUaGUgY2VudGVyIHBvaW50IGlzIHBvc2l0aXZlIHNpZGUgb2YgdGhlIHBsYW5lLCBidXQgcmFkaXVzIGV4dGVuZHMgYmV5b25kIGl0OyBwYXJ0aWFsIG92ZXJsYXBcblx0XHRcdHJldHVybiBJbnRlcnNlY3QuSU5URVJTRUNUSU5HO1xuXHRcdH1cblx0XHRyZXR1cm4gSW50ZXJzZWN0LklOU0lERTtcblx0fVxuXHR1cGRhdGUodHJhbnNmb3JtOiBNYXRyaXg0KSB7XG5cdFx0TWF0cml4NC5tdWx0aXBseUJ5UG9pbnQodHJhbnNmb3JtLCB0aGlzLm9yaWdpbkNlbnRlciwgdGhpcy5jZW50ZXIpO1xuXHRcdHRoaXMucmFkaXVzID0gTWF0cml4NC5nZXRNYXhpbXVtU2NhbGUodHJhbnNmb3JtKSAqIHRoaXMub3JpZ2luUmFkaXVzO1xuXHR9XG5cdGRpc3RhbmNlVG9DYW1lcmEoY2FtZXJhOiBDYW1lcmEpIHtcblx0XHRyZXR1cm4gTWF0aC5tYXgoMC4wLCBWZWN0b3IzLmRpc3RhbmNlKHRoaXMuY2VudGVyLCBjYW1lcmEucG9zaXRpb24pIC0gdGhpcy5yYWRpdXMpO1xuXHR9XG59XG5jb25zdCBmcm9tUG9pbnRzWE1pbiA9IG5ldyBWZWN0b3IzKCk7XG5jb25zdCBmcm9tUG9pbnRzWU1pbiA9IG5ldyBWZWN0b3IzKCk7XG5jb25zdCBmcm9tUG9pbnRzWk1pbiA9IG5ldyBWZWN0b3IzKCk7XG5jb25zdCBmcm9tUG9pbnRzWE1heCA9IG5ldyBWZWN0b3IzKCk7XG5jb25zdCBmcm9tUG9pbnRzWU1heCA9IG5ldyBWZWN0b3IzKCk7XG5jb25zdCBmcm9tUG9pbnRzWk1heCA9IG5ldyBWZWN0b3IzKCk7XG5jb25zdCBmcm9tUG9pbnRzQ3VycmVudFBvcyA9IG5ldyBWZWN0b3IzKCk7XG5jb25zdCBmcm9tUG9pbnRzU2NyYXRjaCA9IG5ldyBWZWN0b3IzKCk7XG5jb25zdCBmcm9tUG9pbnRzUml0dGVyQ2VudGVyID0gbmV3IFZlY3RvcjMoKTtcbmNvbnN0IGZyb21Qb2ludHNNaW5Cb3hQdCA9IG5ldyBWZWN0b3IzKCk7XG5jb25zdCBmcm9tUG9pbnRzTWF4Qm94UHQgPSBuZXcgVmVjdG9yMygpO1xuY29uc3QgZnJvbVBvaW50c05haXZlQ2VudGVyU2NyYXRjaCA9IG5ldyBWZWN0b3IzKCk7XG4iLCJpbXBvcnQgeyBJbmRleEZvcm1hdCB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVUNvbnN0YW50XCI7XHJcbmltcG9ydCBCdWZmZXIgZnJvbSBcIi4vQnVmZmVyXCI7XHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEluZGV4QnVmZmVyIHtcclxuXHRidWZmZXI6IEJ1ZmZlcjtcclxuXHRpbmRpY2VzOiBBcnJheTxudW1iZXI+O1xyXG5cdGluZGV4Rm9ybWF0OiBHUFVJbmRleEZvcm1hdDtcclxuXHRkaXJ0eTogYm9vbGVhbjtcclxuXHRwcml2YXRlIGxhYmVsOiBzdHJpbmc7XHJcblx0Y29uc3RydWN0b3IobGFiZWw6IHN0cmluZywgaW5kaWNlcz86IEFycmF5PG51bWJlcj4pIHtcclxuXHRcdHRoaXMubGFiZWwgPSBsYWJlbDtcclxuXHRcdHRoaXMuaW5kaWNlcyA9IGluZGljZXM7XHJcblx0XHR0aGlzLmluZGV4Rm9ybWF0ID0gSW5kZXhGb3JtYXQuVWludDE2O1xyXG5cdFx0dGhpcy5kaXJ0eSA9IHRydWU7XHJcblx0fVxyXG5cdHNldEluZGljZXMoaW5kaWNlcykge1xyXG5cdFx0dGhpcy5pbmRpY2VzID0gaW5kaWNlcztcclxuXHRcdHRoaXMuZGlydHkgPSB0cnVlO1xyXG5cdH1cclxuXHRiaW5kKGRldmljZTogR1BVRGV2aWNlLCBwYXNzRW5jb2RlcjogR1BVUmVuZGVyUGFzc0VuY29kZXIpIHtcclxuXHRcdGlmICh0aGlzLmRpcnR5KSB7XHJcblx0XHRcdHRoaXMuZGlydHkgPSBmYWxzZTtcclxuXHRcdFx0dGhpcy5idWZmZXIgPSBCdWZmZXIuY3JlYXRlSW5kZXhCdWZmZXIoXHJcblx0XHRcdFx0dGhpcy5sYWJlbCxcclxuXHRcdFx0XHRkZXZpY2UsXHJcblx0XHRcdFx0dGhpcy5pbmRleEZvcm1hdCA9PSBJbmRleEZvcm1hdC5VaW50MTYgPyBuZXcgVWludDE2QXJyYXkodGhpcy5pbmRpY2VzKSA6IG5ldyBVaW50MzJBcnJheSh0aGlzLmluZGljZXMpXHJcblx0XHRcdCk7XHJcblx0XHR9XHJcblx0XHRwYXNzRW5jb2Rlci5zZXRJbmRleEJ1ZmZlcih0aGlzLmJ1ZmZlci5ncHVCdWZmZXIsIHRoaXMuaW5kZXhGb3JtYXQpO1xyXG5cdH1cclxuXHRkZXN0cm95KCkge1xyXG5cdFx0dGhpcy5idWZmZXIuZGVzdHJveSgpO1xyXG5cdH1cclxufVxyXG4iLCJpbXBvcnQgeyBBdHRyaWJ1dGUsIEF0dHJpYnV0ZVR5cGUsIEJ1ZmZlckZsb2F0MzJBdHRyaWJ1dGUsIEludGVybGVhdmVkQXR0cmlidXRlIH0gZnJvbSBcIi4vQXR0cmlidXRlXCI7XG5pbXBvcnQgQnVmZmVyIGZyb20gXCIuL0J1ZmZlclwiO1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQXR0cmlidXRlcyB7XG5cdHB1YmxpYyBpbnRlcmxlYXZlOiBib29sZWFuO1xuXHRwcml2YXRlIF9hdHRyaWJ1dGVzOiBNYXA8c3RyaW5nLCBBdHRyaWJ1dGUgfCBJbnRlcmxlYXZlZEF0dHJpYnV0ZT47XG5cdHByaXZhdGUgc2hhZGVyTG9jYXRpb246IG51bWJlcjtcblx0cHJpdmF0ZSBvZmZzZXQ6IG51bWJlcjtcblx0Y29uc3RydWN0b3Ioc2hhZGVyTG9jYXRpb24gPSAwKSB7XG5cdFx0dGhpcy5fYXR0cmlidXRlcyA9IG5ldyBNYXAoKTtcblx0XHR0aGlzLnNoYWRlckxvY2F0aW9uID0gc2hhZGVyTG9jYXRpb247XG5cdFx0dGhpcy5vZmZzZXQgPSAwO1xuXHRcdHRoaXMuaW50ZXJsZWF2ZSA9IGZhbHNlO1xuXHR9XG5cdGdldCBkaXJ0eSgpOiBib29sZWFuIHtcblx0XHRsZXQgcmVzdWx0ID0gZmFsc2U7XG5cdFx0dGhpcy5fYXR0cmlidXRlcy5mb3JFYWNoKChhdHRyaWJ1dGUpID0+ICghcmVzdWx0ID8gKHJlc3VsdCA9IGF0dHJpYnV0ZS5kaXJ0eSkgOiBmYWxzZSkpO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblx0c2V0IGRpcnR5KHZhbHVlOiBib29sZWFuKSB7XG5cdFx0dGhpcy5fYXR0cmlidXRlcy5mb3JFYWNoKChhdHRyaWJ1dGUpID0+IChhdHRyaWJ1dGUuZGlydHkgPSB2YWx1ZSkpO1xuXHR9XG5cdGdldCB2YWx1ZXMoKTogTWFwPHN0cmluZywgQXR0cmlidXRlIHwgSW50ZXJsZWF2ZWRBdHRyaWJ1dGU+IHtcblx0XHRyZXR1cm4gdGhpcy5fYXR0cmlidXRlcztcblx0fVxuXHRnZXRBdHRyaWJ1dGUobmFtZSk6IEF0dHJpYnV0ZSB8IEludGVybGVhdmVkQXR0cmlidXRlIHtcblx0XHRyZXR1cm4gdGhpcy5fYXR0cmlidXRlcy5nZXQobmFtZSk7XG5cdH1cblx0c2V0QXR0cmlidXRlKGF0dHJpYnV0ZTogQXR0cmlidXRlIHwgSW50ZXJsZWF2ZWRBdHRyaWJ1dGUpIHtcblx0XHRpZiAoYXR0cmlidXRlLmF0dHJpYnV0ZVR5cGUgPT09IEF0dHJpYnV0ZVR5cGUuYXR0cmlidXRlKSB7XG5cdFx0XHR0aGlzLnNldE5vdEludGVybGVhdmVkQXR0cmlidXRlKGF0dHJpYnV0ZSBhcyBBdHRyaWJ1dGUpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLnNldEludGVybGVhdmVkQXR0cmlidXRlKGF0dHJpYnV0ZSBhcyBJbnRlcmxlYXZlZEF0dHJpYnV0ZSk7XG5cdFx0fVxuXHR9XG5cdHByaXZhdGUgc2V0Tm90SW50ZXJsZWF2ZWRBdHRyaWJ1dGUoYXR0cmlidXRlOiBBdHRyaWJ1dGUpIHtcblx0XHRpZiAodGhpcy5fYXR0cmlidXRlcy5oYXMoYXR0cmlidXRlLm5hbWUpKSByZXR1cm47XG5cdFx0YXR0cmlidXRlLnNoYWRlckxvY2F0aW9uID0gdGhpcy5zaGFkZXJMb2NhdGlvbjtcblx0XHR0aGlzLnNoYWRlckxvY2F0aW9uICs9IDE7XG5cdFx0YXR0cmlidXRlLm9mZnNldCA9IHRoaXMub2Zmc2V0O1xuXHRcdHRoaXMub2Zmc2V0ICs9IGF0dHJpYnV0ZS5hdHRyaWJ1dGVCeXRlU2l6ZTtcblx0XHR0aGlzLl9hdHRyaWJ1dGVzLnNldChhdHRyaWJ1dGUubmFtZSwgYXR0cmlidXRlKTtcblx0fVxuXHRwcml2YXRlIHNldEludGVybGVhdmVkQXR0cmlidXRlKGF0dHJpYnV0ZTogSW50ZXJsZWF2ZWRBdHRyaWJ1dGUpIHtcblx0XHRpZiAodGhpcy5fYXR0cmlidXRlcy5oYXMoYXR0cmlidXRlLm5hbWVzLnRvU3RyaW5nKCkpKSByZXR1cm47XG5cdFx0dGhpcy5fYXR0cmlidXRlcy5zZXQoYXR0cmlidXRlLm5hbWVzLnRvU3RyaW5nKCksIGF0dHJpYnV0ZSk7XG5cdH1cblx0Z2V0R1BVQXR0cmlidXRlc0RlcygpIHtcblx0XHRjb25zdCByZXN1bHQgPSBbXTtcblx0XHR0aGlzLl9hdHRyaWJ1dGVzLmZvckVhY2goKGF0dHJpYnV0ZSkgPT4ge1xuXHRcdFx0cmVzdWx0LnB1c2goLi4uYXR0cmlidXRlLmdldEdQVUF0dHJpYnV0ZSgpKTtcblx0XHR9KTtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cdGdldEF0cnJpYnV0ZVZhbHVlcygpOiB7XG5cdFx0YXJyYXlTdHJpZGU6IG51bWJlcjtcblx0XHR0eXBlQXJyYXk6IEZsb2F0MzJBcnJheTtcblx0XHRidWZmZXI/OiBCdWZmZXI7XG5cdH0ge1xuXHRcdGNvbnN0IGFycmF5U3RyaWRlcyA9IFtdO1xuXHRcdGxldCBhcnJheVN0cmlkZSA9IDA7XG5cdFx0bGV0IGJ1ZmZlciA9IHVuZGVmaW5lZDtcblx0XHRsZXQgdmFsdWVzID0gbnVsbDtcblx0XHRjb25zdCBhcnJheXMgPSBbXTtcblx0XHR0aGlzLl9hdHRyaWJ1dGVzLmZvckVhY2goKGF0dHJpYnV0ZTogQXR0cmlidXRlIHwgSW50ZXJsZWF2ZWRBdHRyaWJ1dGUpID0+IHtcblx0XHRcdGlmIChhdHRyaWJ1dGUuYXR0cmlidXRlVHlwZSA9PT0gQXR0cmlidXRlVHlwZS5hdHRyaWJ1dGUpIHtcblx0XHRcdFx0YXJyYXlTdHJpZGVzLnB1c2goKGF0dHJpYnV0ZSBhcyBBdHRyaWJ1dGUpLml0ZW1TaXplKTtcblx0XHRcdFx0YXJyYXlzLnB1c2goYXR0cmlidXRlLnZhbHVlKTtcblx0XHRcdFx0YXJyYXlTdHJpZGUgKz0gKGF0dHJpYnV0ZSBhcyBBdHRyaWJ1dGUpLml0ZW1TaXplO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKCF0aGlzLmludGVybGVhdmUpIHRoaXMuaW50ZXJsZWF2ZSA9IHRydWU7XG5cdFx0XHRcdHZhbHVlcyA9IHZhbHVlcyA/PyBhdHRyaWJ1dGUudmFsdWU7XG5cdFx0XHRcdGJ1ZmZlciA9IChhdHRyaWJ1dGUgYXMgQnVmZmVyRmxvYXQzMkF0dHJpYnV0ZSk/LmJ1ZmZlcjtcblx0XHRcdFx0YXJyYXlTdHJpZGUgPSAoYXR0cmlidXRlIGFzIEludGVybGVhdmVkQXR0cmlidXRlKS5pdGVtU2l6ZXMucmVkdWNlKFxuXHRcdFx0XHRcdCh0b3RhbCwgY3VycmVudCkgPT4gKHRvdGFsICs9IGN1cnJlbnQpLFxuXHRcdFx0XHRcdDBcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdGNvbnN0IHR5cGVBcnJheSA9IHRoaXMuaW50ZXJsZWF2ZVxuXHRcdFx0PyBuZXcgRmxvYXQzMkFycmF5KHZhbHVlcylcblx0XHRcdDogdGhpcy5pbnRlcmxlYXZlVHlwZWRBcnJheShGbG9hdDMyQXJyYXksIGFycmF5U3RyaWRlcywgLi4uYXJyYXlzKTtcblx0XHRyZXR1cm4ge1xuXHRcdFx0YXJyYXlTdHJpZGU6IGFycmF5U3RyaWRlICogdHlwZUFycmF5LkJZVEVTX1BFUl9FTEVNRU5ULFxuXHRcdFx0dHlwZUFycmF5LFxuXHRcdFx0YnVmZmVyXG5cdFx0fTtcblx0fVxuXHRkZXN0cm95KCkge1xuXHRcdHRoaXMuX2F0dHJpYnV0ZXMuZm9yRWFjaCgoYXR0cmlidXRlKSA9PiB7XG5cdFx0XHRhdHRyaWJ1dGUuZGVzdHJveSgpO1xuXHRcdH0pO1xuXHR9XG5cdC8qKlxuXHQgKiBJbnRlcmxlYXZlIG4gdHlwZWQgYXJyYXlzXG5cdCAqIEBhbGlhcyBtb2R1bGU6aW50ZXJsZWF2ZVR5cGVkQXJyYXlcblx0ICogQHBhcmFtIHtUeXBlZEFycmF5fSBSZXN1bHRDb25zdHJ1Y3RvciBSZXR1cm5lZCB0eXBlZCBhcnJheSBjb25zdHJ1Y3RvclxuXHQgKiBAcGFyYW0ge0FycmF5fSBlbGVtZW50cyBOdW1iZXIgb2YgZWxlbWVudHMgdG8gZ3JvdXAgZm9yIGVhY2ggdHlwZWQgYXJyYXlcblx0ICogQHBhcmFtIHsuLi5UeXBlZEFycmF5fSBhcnJheXMgQXJyYXlzIHRvIGludGVybGVhdmVcblx0ICogQHJldHVybnMge1R5cGVkQXJyYXl9XG5cdCAqL1xuXHRpbnRlcmxlYXZlVHlwZWRBcnJheShSZXN1bHRDb25zdHJ1Y3RvciwgZWxlbWVudHMsIC4uLmFycmF5cykge1xuXHRcdGNvbnN0IHRvdGFsTGVuZ3RoID0gYXJyYXlzLnJlZHVjZSgodG90YWwsIGFycikgPT4gdG90YWwgKyBhcnIubGVuZ3RoLCAwKTtcblx0XHRjb25zdCByZXN1bHQgPSBuZXcgUmVzdWx0Q29uc3RydWN0b3IodG90YWxMZW5ndGgpO1xuXHRcdGNvbnN0IHN0cmlkZSA9IGVsZW1lbnRzLnJlZHVjZSgoYSwgYikgPT4gYSArIGIpO1xuXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0b3RhbExlbmd0aDsgaSsrKSB7XG5cdFx0XHRsZXQgb2Zmc2V0ID0gMDtcblx0XHRcdGZvciAobGV0IGogPSAwOyBqIDwgZWxlbWVudHMubGVuZ3RoOyBqKyspIHtcblx0XHRcdFx0Zm9yIChsZXQgayA9IDA7IGsgPCBlbGVtZW50c1tqXTsgaysrKSB7XG5cdFx0XHRcdFx0cmVzdWx0W2kgKiBzdHJpZGUgKyBvZmZzZXRdID0gYXJyYXlzW2pdW2VsZW1lbnRzW2pdICogaSArIGtdO1xuXHRcdFx0XHRcdG9mZnNldCsrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cbn1cbiIsImltcG9ydCB7IElucHV0U3RlcE1vZGUgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVDb25zdGFudFwiO1xuaW1wb3J0IHsgVmVydGV4QnVmZmVyUGFyYW1zIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcbmltcG9ydCB7IEF0dHJpYnV0ZSwgQXR0cmlidXRlVHlwZSwgSW50ZXJsZWF2ZWRBdHRyaWJ1dGUsIEludGVybGVhdmVkRmxvYXQzMkF0dHJpYnV0ZSB9IGZyb20gXCIuL0F0dHJpYnV0ZVwiO1xuaW1wb3J0IEF0dHJpYnV0ZXMgZnJvbSBcIi4vQXR0cmlidXRlc1wiO1xuaW1wb3J0IEJ1ZmZlciBmcm9tIFwiLi9CdWZmZXJcIjtcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZlcnRleEJ1ZmZlciB7XG5cdHB1YmxpYyBpbmRleDogbnVtYmVyO1xuXHRwdWJsaWMgYXJyYXlTdHJpZGU6IG51bWJlcjtcblx0cHVibGljIHN0ZXBNb2RlOiBzdHJpbmc7XG5cdHB1YmxpYyBidWZmZXI6IEJ1ZmZlcjtcblx0cHVibGljIGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZXM7XG5cdHB1YmxpYyBkaXJ0eTogYm9vbGVhbjtcblx0cHVibGljIGRlZmluZXM6IHsgW3Byb3A6IHN0cmluZ106IGJvb2xlYW4gfCBudW1iZXIgfTtcblx0cHVibGljIGxvY2F0aW9uSW5kZXg6IG51bWJlcjtcblx0cHJpdmF0ZSBsYWJlbDogc3RyaW5nO1xuXHQvL1xuXHRjb25zdHJ1Y3RvcihwYXJhbXM6IFZlcnRleEJ1ZmZlclBhcmFtcykge1xuXHRcdGNvbnN0IHsgbGFiZWwsIGluZGV4LCBsb2NhdGlvbkluZGV4ID0gMCwgc3RlcE1vZGUgPSBJbnB1dFN0ZXBNb2RlLlZlcnRleCwgYXJyYXlTdHJpZGUgfSA9IHBhcmFtcztcblx0XHR0aGlzLmluZGV4ID0gaW5kZXggfHwgMDtcblx0XHR0aGlzLmF0dHJpYnV0ZXMgPSBuZXcgQXR0cmlidXRlcyhsb2NhdGlvbkluZGV4KTtcblx0XHR0aGlzLnN0ZXBNb2RlID0gc3RlcE1vZGU7XG5cdFx0dGhpcy5kaXJ0eSA9IHRydWU7XG5cdFx0dGhpcy5sYWJlbCA9IGxhYmVsPy5jb25jYXQoYF8ke2luZGV4fV9WZXJ0ZXhCdWZmZXJgKTtcblx0XHR0aGlzLmFycmF5U3RyaWRlID0gYXJyYXlTdHJpZGU7XG5cdFx0dGhpcy5kZWZpbmVzID0ge307XG5cdFx0dGhpcy5sb2NhdGlvbkluZGV4ID0gbG9jYXRpb25JbmRleDtcblx0fVxuXHRwdWJsaWMgZ2V0QnVmZmVyRGVzKCkge1xuXHRcdGNvbnN0IHJlc3VsdCA9IHtcblx0XHRcdGFycmF5U3RyaWRlOiB0aGlzLmFycmF5U3RyaWRlLFxuXHRcdFx0c3RlcE1vZGU6IHRoaXMuc3RlcE1vZGUsXG5cdFx0XHRhdHRyaWJ1dGVzOiB0aGlzLmF0dHJpYnV0ZXMuZ2V0R1BVQXR0cmlidXRlc0RlcygpXG5cdFx0fTtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cdHB1YmxpYyBzZXRBdHRyaWJ1dGUoYXR0cmlidXRlOiBBdHRyaWJ1dGUgfCBJbnRlcmxlYXZlZEF0dHJpYnV0ZSkge1xuXHRcdGlmIChhdHRyaWJ1dGUuYXR0cmlidXRlVHlwZSA9PT0gQXR0cmlidXRlVHlwZS5hdHRyaWJ1dGUpIHtcblx0XHRcdHRoaXMuc2V0TG9jYXRpb25JbmRleCgoYXR0cmlidXRlIGFzIEF0dHJpYnV0ZSkubmFtZSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdChhdHRyaWJ1dGUgYXMgSW50ZXJsZWF2ZWRGbG9hdDMyQXR0cmlidXRlKT8ubmFtZXMuZm9yRWFjaCgobmFtZTogc3RyaW5nKSA9PiB0aGlzLnNldExvY2F0aW9uSW5kZXgobmFtZSkpO1xuXHRcdH1cblx0XHR0aGlzLmF0dHJpYnV0ZXMuc2V0QXR0cmlidXRlKGF0dHJpYnV0ZSk7XG5cdFx0dGhpcy5kaXJ0eSA9IHRydWU7XG5cdH1cblx0cHVibGljIGdldEF0dHJpYnV0ZShuYW1lOiBzdHJpbmcpOiBBdHRyaWJ1dGUgfCBJbnRlcmxlYXZlZEF0dHJpYnV0ZSB7XG5cdFx0cmV0dXJuIHRoaXMuYXR0cmlidXRlcy5nZXRBdHRyaWJ1dGUobmFtZSk7XG5cdH1cblx0cHVibGljIGNvbnRhaW5BdHRyaWJ1dGUobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuZGVmaW5lc1tuYW1lPy5jb25jYXQoXCJMb2NhdGlvblwiKV0gIT0gdW5kZWZpbmVkID8gdHJ1ZSA6IGZhbHNlO1xuXHR9XG5cdHB1YmxpYyBiaW5kKGRldmljZTogR1BVRGV2aWNlLCBwYXNzRW5jb2RlcjogR1BVUmVuZGVyUGFzc0VuY29kZXIpIHtcblx0XHRpZiAodGhpcy5hdHRyaWJ1dGVzLmRpcnR5KSB7XG5cdFx0XHR0aGlzLmF0dHJpYnV0ZXMuZGlydHkgPSBmYWxzZTtcblx0XHRcdGNvbnN0IHsgYXJyYXlTdHJpZGUsIHR5cGVBcnJheSwgYnVmZmVyIH0gPSB0aGlzLmF0dHJpYnV0ZXMuZ2V0QXRycmlidXRlVmFsdWVzKCk7XG5cdFx0XHRpZiAodGhpcy5hcnJheVN0cmlkZSA9PT0gdW5kZWZpbmVkKSB0aGlzLmFycmF5U3RyaWRlID0gYXJyYXlTdHJpZGU7XG5cdFx0XHRpZiAoIXRoaXMuYnVmZmVyKSB7XG5cdFx0XHRcdHRoaXMuYnVmZmVyID0gYnVmZmVyID8/IEJ1ZmZlci5jcmVhdGVWZXJ0ZXhCdWZmZXIodGhpcy5sYWJlbCwgZGV2aWNlLCB0eXBlQXJyYXkpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gdXBkYXRlIEJ1ZmZlclxuXHRcdFx0XHRpZiAodHlwZUFycmF5KSB0aGlzLmJ1ZmZlci5zZXRTdWJEYXRhKDAsIHR5cGVBcnJheSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHBhc3NFbmNvZGVyLnNldFZlcnRleEJ1ZmZlcih0aGlzLmluZGV4LCB0aGlzLmJ1ZmZlci5ncHVCdWZmZXIpO1xuXHR9XG5cdHByaXZhdGUgc2V0TG9jYXRpb25JbmRleChuYW1lOiBzdHJpbmcpIHtcblx0XHRpZiAodGhpcy5kZWZpbmVzW25hbWU/LmNvbmNhdChcIkxvY2F0aW9uXCIpXSB8fCAhbmFtZSkgcmV0dXJuO1xuXHRcdHRoaXMuZGVmaW5lc1tuYW1lPy5jb25jYXQoXCJMb2NhdGlvblwiKV0gPSB0aGlzLmxvY2F0aW9uSW5kZXg7XG5cdFx0dGhpcy5sb2NhdGlvbkluZGV4ICs9IDE7XG5cdH1cblx0ZGVzdHJveSgpIHtcblx0XHR0aGlzLmJ1ZmZlci5kZXN0cm95KCk7XG5cdFx0dGhpcy5hdHRyaWJ1dGVzLmRlc3Ryb3koKTtcblx0fVxufVxuIiwiaW1wb3J0IGRlZmF1bHRWYWx1ZSBmcm9tIFwiLi9kZWZhdWx0VmFsdWVcIjtcbmltcG9ydCBkZWZpbmVkIGZyb20gXCIuL2RlZmluZWRcIjtcblxuLyoqXG4gKiBNZXJnZXMgdHdvIG9iamVjdHMsIGNvcHlpbmcgdGhlaXIgcHJvcGVydGllcyBvbnRvIGEgbmV3IGNvbWJpbmVkIG9iamVjdC4gV2hlbiB0d28gb2JqZWN0cyBoYXZlIHRoZSBzYW1lXG4gKiBwcm9wZXJ0eSwgdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSBvbiB0aGUgZmlyc3Qgb2JqZWN0IGlzIHVzZWQuICBJZiBlaXRoZXIgb2JqZWN0IGlzIHVuZGVmaW5lZCxcbiAqIGl0IHdpbGwgYmUgdHJlYXRlZCBhcyBhbiBlbXB0eSBvYmplY3QuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG9iamVjdDEgPSB7XG4gKiAgICAgcHJvcE9uZSA6IDEsXG4gKiAgICAgcHJvcFR3byA6IHtcbiAqICAgICAgICAgdmFsdWUxIDogMTBcbiAqICAgICB9XG4gKiB9XG4gKiBjb25zdCBvYmplY3QyID0ge1xuICogICAgIHByb3BUd28gOiAyXG4gKiB9XG4gKiBjb25zdCBmaW5hbCA9IGNvbWJpbmUob2JqZWN0MSwgb2JqZWN0Mik7XG4gKlxuICogLy8gZmluYWwgPT09IHtcbiAqIC8vICAgICBwcm9wT25lIDogMSxcbiAqIC8vICAgICBwcm9wVHdvIDoge1xuICogLy8gICAgICAgICB2YWx1ZTEgOiAxMFxuICogLy8gICAgIH1cbiAqIC8vIH1cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gW29iamVjdDFdIFRoZSBmaXJzdCBvYmplY3QgdG8gbWVyZ2UuXG4gKiBAcGFyYW0ge09iamVjdH0gW29iamVjdDJdIFRoZSBzZWNvbmQgb2JqZWN0IHRvIG1lcmdlLlxuICogQHBhcmFtIHtCb29sZWFufSBbZGVlcD1mYWxzZV0gUGVyZm9ybSBhIHJlY3Vyc2l2ZSBtZXJnZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBjb21iaW5lZCBvYmplY3QgY29udGFpbmluZyBhbGwgcHJvcGVydGllcyBmcm9tIGJvdGggb2JqZWN0cy5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gY29tYmluZShvYmplY3QxLCBvYmplY3QyLCBkZWVwKSB7XG5cdGRlZXAgPSBkZWZhdWx0VmFsdWUoZGVlcCwgZmFsc2UpO1xuXG5cdGNvbnN0IHJlc3VsdCA9IHt9O1xuXG5cdGNvbnN0IG9iamVjdDFEZWZpbmVkID0gZGVmaW5lZChvYmplY3QxKTtcblx0Y29uc3Qgb2JqZWN0MkRlZmluZWQgPSBkZWZpbmVkKG9iamVjdDIpO1xuXHRsZXQgcHJvcGVydHk7XG5cdGxldCBvYmplY3QxVmFsdWU7XG5cdGxldCBvYmplY3QyVmFsdWU7XG5cdGlmIChvYmplY3QxRGVmaW5lZCkge1xuXHRcdGZvciAocHJvcGVydHkgaW4gb2JqZWN0MSkge1xuXHRcdFx0aWYgKG9iamVjdDEuaGFzT3duUHJvcGVydHkocHJvcGVydHkpKSB7XG5cdFx0XHRcdG9iamVjdDFWYWx1ZSA9IG9iamVjdDFbcHJvcGVydHldO1xuXHRcdFx0XHRpZiAob2JqZWN0MkRlZmluZWQgJiYgZGVlcCAmJiB0eXBlb2Ygb2JqZWN0MVZhbHVlID09PSBcIm9iamVjdFwiICYmIG9iamVjdDIuaGFzT3duUHJvcGVydHkocHJvcGVydHkpKSB7XG5cdFx0XHRcdFx0b2JqZWN0MlZhbHVlID0gb2JqZWN0Mltwcm9wZXJ0eV07XG5cdFx0XHRcdFx0aWYgKHR5cGVvZiBvYmplY3QyVmFsdWUgPT09IFwib2JqZWN0XCIpIHtcblx0XHRcdFx0XHRcdHJlc3VsdFtwcm9wZXJ0eV0gPSBjb21iaW5lKG9iamVjdDFWYWx1ZSwgb2JqZWN0MlZhbHVlLCBkZWVwKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0cmVzdWx0W3Byb3BlcnR5XSA9IG9iamVjdDFWYWx1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmVzdWx0W3Byb3BlcnR5XSA9IG9iamVjdDFWYWx1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRpZiAob2JqZWN0MkRlZmluZWQpIHtcblx0XHRmb3IgKHByb3BlcnR5IGluIG9iamVjdDIpIHtcblx0XHRcdGlmIChvYmplY3QyLmhhc093blByb3BlcnR5KHByb3BlcnR5KSAmJiAhcmVzdWx0Lmhhc093blByb3BlcnR5KHByb3BlcnR5KSkge1xuXHRcdFx0XHRvYmplY3QyVmFsdWUgPSBvYmplY3QyW3Byb3BlcnR5XTtcblx0XHRcdFx0cmVzdWx0W3Byb3BlcnR5XSA9IG9iamVjdDJWYWx1ZTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblx0cmV0dXJuIHJlc3VsdDtcbn1cbmV4cG9ydCBkZWZhdWx0IGNvbWJpbmU7XG4iLCJpbXBvcnQgQm91bmRpbmdCb3ggZnJvbSBcIi4uL2NvcmUvQm91bmRpbmdCb3hcIjtcbmltcG9ydCBCb3VuZGluZ1NwaGVyZSBmcm9tIFwiLi4vY29yZS9Cb3VuZGluZ1NwaGVyZVwiO1xuaW1wb3J0IHsgRnJhbWVTdGF0ZSB9IGZyb20gXCIuLi9jb3JlL0ZyYW1lU3RhdGVcIjtcbmltcG9ydCBWZWN0b3IyIGZyb20gXCIuLi9tYXRoL1ZlY3RvcjJcIjtcbmltcG9ydCBWZWN0b3IzIGZyb20gXCIuLi9tYXRoL1ZlY3RvcjNcIjtcbmltcG9ydCBWZWN0b3I0IGZyb20gXCIuLi9tYXRoL1ZlY3RvcjRcIjtcbmltcG9ydCB7IEF0dHJpYnV0ZSwgSW50ZXJsZWF2ZWRGbG9hdDMyQXR0cmlidXRlIH0gZnJvbSBcIi4uL3JlbmRlci9BdHRyaWJ1dGVcIjtcbmltcG9ydCBJbmRleEJ1ZmZlciBmcm9tIFwiLi4vcmVuZGVyL0luZGV4QnVmZmVyXCI7XG5pbXBvcnQgVmVydGV4QnVmZmVyIGZyb20gXCIuLi9yZW5kZXIvVmVydGV4QnVmZmVyXCI7XG5pbXBvcnQgY29tYmluZSBmcm9tIFwiLi4vdXRpbHMvY29tYmluZVwiO1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgR2VvbWV0cnkge1xuXHRub3JtYWxzOiBudW1iZXJbXTtcblx0dXZzOiBudW1iZXJbXTtcblx0cG9zaXRpb25zOiBudW1iZXJbXTtcblx0aW5kaWNlczogbnVtYmVyW107XG5cdHRhbmdlbnRzOiBudW1iZXJbXTtcblx0dHlwZTogc3RyaW5nO1xuXHRkaXJ0eTogYm9vbGVhbjtcblx0aW5kZXhCdWZmZXI/OiBJbmRleEJ1ZmZlcjtcblx0ZGVmYXVsdFZlcnRleEJ1ZmZlcjogVmVydGV4QnVmZmVyO1xuXHRjb3VudDogbnVtYmVyO1xuXHRib3VuZGluZ1NwaGVyZT86IEJvdW5kaW5nU3BoZXJlO1xuXHRib3VuZGluZ0JveD86IEJvdW5kaW5nQm94O1xuXHRwcml2YXRlIF9kZWZpbmVzOiB7IFtwcm9wOiBzdHJpbmddOiBib29sZWFuIHwgbnVtYmVyIH07XG5cdHB1YmxpYyB2ZXJ0ZXhCdWZmZXJzOiBBcnJheTxWZXJ0ZXhCdWZmZXI+O1xuXHRkZWZpbmVzRGlydHk6IGJvb2xlYW47XG5cdGdldCBkZWZpbmVzKCkge1xuXHRcdHJldHVybiBPYmplY3QuYXNzaWduKHt9LCB0aGlzLl9kZWZpbmVzLCAuLi50aGlzLnZlcnRleEJ1ZmZlcnMubWFwKCh2ZXJ0ZXhCdWZmZXIpID0+IHZlcnRleEJ1ZmZlci5kZWZpbmVzKSk7XG5cdH1cblx0c2V0IGRlZmluZXModmFsdWUpIHtcblx0XHR0aGlzLmRlZmluZXNEaXJ0eSA9IHRydWU7XG5cdFx0dGhpcy5fZGVmaW5lcyA9IGNvbWJpbmUodmFsdWUsIHRoaXMuX2RlZmluZXMsIGZhbHNlKTtcblx0fVxuXHRnZXQgY3VycmVudExvY2F0aW9uSW5kZXgoKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gdGhpcz8udmVydGV4QnVmZmVycz8ucmVkdWNlKFxuXHRcdFx0KG1heCwgY3VycmVudCkgPT4gKGN1cnJlbnQubG9jYXRpb25JbmRleCA+IG1heCA/IChtYXggPSBjdXJyZW50LmxvY2F0aW9uSW5kZXgpIDogbWF4KSxcblx0XHRcdDBcblx0XHQpO1xuXHR9XG5cdGdldCB2ZXJ0ZXhCdWZmZXJDb3VudCgpOiBudW1iZXIge1xuXHRcdHJldHVybiB0aGlzLnZlcnRleEJ1ZmZlcnMubGVuZ3RoO1xuXHR9XG5cdGNvbnN0cnVjdG9yKG9wdGlvbnM/OiB7IHR5cGU/OiBzdHJpbmcgfSkge1xuXHRcdHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZSB8fCB1bmRlZmluZWQ7XG5cdFx0dGhpcy5ib3VuZGluZ1NwaGVyZSA9IHVuZGVmaW5lZDtcblx0XHR0aGlzLmRpcnR5ID0gZmFsc2U7XG5cdFx0dGhpcy5kZWZpbmVzRGlydHkgPSB0cnVlO1xuXHRcdHRoaXMuZGVmYXVsdFZlcnRleEJ1ZmZlciA9IG5ldyBWZXJ0ZXhCdWZmZXIoe1xuXHRcdFx0bGFiZWw6IHRoaXMudHlwZSxcblx0XHRcdGluZGV4OiAwXG5cdFx0fSk7XG5cdFx0dGhpcy52ZXJ0ZXhCdWZmZXJzID0gW3RoaXMuZGVmYXVsdFZlcnRleEJ1ZmZlcl07XG5cdFx0dGhpcy5fZGVmaW5lcyA9IHt9O1xuXHRcdHRoaXMubm9ybWFscyA9IFtdO1xuXHRcdHRoaXMudXZzID0gW107XG5cdFx0dGhpcy5wb3NpdGlvbnMgPSBbXTtcblx0XHR0aGlzLmluZGljZXMgPSBbXTtcblx0XHR0aGlzLnRhbmdlbnRzID0gW107XG5cdH1cblx0Z2V0QXR0cmlidXRlKG5hbWU6IHN0cmluZykge1xuXHRcdHJldHVybiB0aGlzLmRlZmF1bHRWZXJ0ZXhCdWZmZXIuZ2V0QXR0cmlidXRlKG5hbWUpO1xuXHR9XG5cdHNldEF0dHJpYnV0ZShhdHRyaWJ1dGU6IEF0dHJpYnV0ZSB8IEludGVybGVhdmVkRmxvYXQzMkF0dHJpYnV0ZSkge1xuXHRcdHRoaXMuZGVmYXVsdFZlcnRleEJ1ZmZlci5zZXRBdHRyaWJ1dGUoYXR0cmlidXRlKTtcblx0fVxuXHRzZXRJbmRpY2UoaW5kaWNlczogQXJyYXk8bnVtYmVyPikge1xuXHRcdHRoaXMuaW5kaWNlcyA9IGluZGljZXM7XG5cdFx0aWYgKCF0aGlzLmluZGV4QnVmZmVyKSB0aGlzLmluZGV4QnVmZmVyID0gbmV3IEluZGV4QnVmZmVyKHRoaXMudHlwZSArIFwiSW5kZXhCdWZmZXJcIik7XG5cdFx0dGhpcy5pbmRleEJ1ZmZlci5zZXRJbmRpY2VzKGluZGljZXMpO1xuXHR9XG5cdHVwZGF0ZShmcmFtZVN0YXRlOiBGcmFtZVN0YXRlKSB7XG5cdFx0Ly8gdG9kb1xuXHR9XG5cdGNvbXB1dGVCb3VuZGluZ1NwaGVyZShwb3NpdGlvbnM6IG51bWJlcltdLCBzdHJpZGUgPSAzKSB7XG5cdFx0dGhpcy5ib3VuZGluZ1NwaGVyZSA9IEJvdW5kaW5nU3BoZXJlLmZyb21WZXJ0aWNlcyhwb3NpdGlvbnMsIG5ldyBWZWN0b3IzKDAsIDAsIDApLCBzdHJpZGUpO1xuXHR9XG5cdC8qKlxuXHQgKiBDYWxjdWxhdGUgbWVzaCB0YW5nZW50LlxuXHQgKiBAcmVtYXJrIG5lZWQgdG8gc2V0IHBvc2l0aW9ucyh3aXRoIG9yIG5vdCB3aXRoIGluZGljZXMpLCBub3JtYWxzLCB1diBiZWZvcmUgY2FsY3VsYXRpb24uXG5cdCAqIEByZW1hcmsgYmFzZWQgb24gaHR0cDovL2ZvdW5kYXRpb25zb2ZnYW1lZW5naW5lZGV2LmNvbS9GR0VEMi1zYW1wbGUucGRmXG5cdCAqL1xuXHRjYWxjdWxhdGVUYW5nZW50cygpOiB2b2lkIHtcblx0XHRpZiAoIXRoaXMubm9ybWFscyB8fCAhdGhpcy51dnMpIHtcblx0XHRcdHRocm93IFwiU2V0IG5vcm1hbCBhbmQgdXYgYmVmb3JlIGNhbGN1bGF0aW9uLlwiO1xuXHRcdH1cblx0XHRjb25zdCB7IGluZGljZXMsIHBvc2l0aW9ucywgbm9ybWFscywgdXZzIH0gPSB0aGlzO1xuXHRcdGNvbnN0IHRlbXBQb3MwID0gbmV3IFZlY3RvcjMoKSxcblx0XHRcdHRlbXBQb3MxID0gbmV3IFZlY3RvcjMoKSxcblx0XHRcdHRlbXBQb3MyID0gbmV3IFZlY3RvcjMoKSxcblx0XHRcdHRlbXBVVjAgPSBuZXcgVmVjdG9yMigpLFxuXHRcdFx0dGVtcFVWMSA9IG5ldyBWZWN0b3IyKCksXG5cdFx0XHR0ZW1wVVYyID0gbmV3IFZlY3RvcjIoKTtcblx0XHRjb25zdCBlMSA9IG5ldyBWZWN0b3IzKCksXG5cdFx0XHRlMiA9IG5ldyBWZWN0b3IzKCksXG5cdFx0XHR0ID0gbmV3IFZlY3RvcjMoKSxcblx0XHRcdGIgPSBuZXcgVmVjdG9yMygpLFxuXHRcdFx0dGVtcCA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0Y29uc3QgdmVydGV4Q291bnQgPSB0aGlzLmluZGljZXMubGVuZ3RoO1xuXHRcdGNvbnN0IHRyaWFuZ2xlQ291bnQgPSBpbmRpY2VzID8gaW5kaWNlcy5sZW5ndGggLyAzIDogcG9zaXRpb25zLmxlbmd0aCAvIDM7XG5cdFx0Y29uc3QgdGFuZ2VudHMgPSBuZXcgQXJyYXk8VmVjdG9yND4odmVydGV4Q291bnQpO1xuXHRcdGNvbnN0IGJpVGFuZ2VudHMgPSBuZXcgQXJyYXk8VmVjdG9yMz4odmVydGV4Q291bnQpO1xuXHRcdHRoaXMudGFuZ2VudHMgPSBbXTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHZlcnRleENvdW50OyBpKyspIHtcblx0XHRcdHRhbmdlbnRzW2ldID0gbmV3IFZlY3RvcjQoKTtcblx0XHRcdGJpVGFuZ2VudHNbaV0gPSBuZXcgVmVjdG9yMygpO1xuXHRcdH1cblxuXHRcdC8vIENhbGN1bGF0ZSB0YW5nZW50IGFuZCBiaS10YW5nZW50IGZvciBlYWNoIHRyaWFuZ2xlIGFuZCBhZGQgdG8gYWxsIHRocmVlIHZlcnRpY2VzLlxuXHRcdGZvciAobGV0IGsgPSAwOyBrIDwgdHJpYW5nbGVDb3VudDsgaysrKSB7XG5cdFx0XHRsZXQgaTAgPSAzICogaztcblx0XHRcdGxldCBpMSA9IDMgKiBrICsgMTtcblx0XHRcdGxldCBpMiA9IDMgKiBrICsgMjtcblx0XHRcdGlmIChpbmRpY2VzKSB7XG5cdFx0XHRcdGkwID0gaW5kaWNlc1tpMF07XG5cdFx0XHRcdGkxID0gaW5kaWNlc1tpMV07XG5cdFx0XHRcdGkyID0gaW5kaWNlc1tpMl07XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IHAwID0gdGVtcFBvczAuc2V0KHBvc2l0aW9uc1tpMF0sIHBvc2l0aW9uc1tpMCArIDFdLCBwb3NpdGlvbnNbaTAgKyAyXSk7XG5cdFx0XHRjb25zdCBwMSA9IHRlbXBQb3MxLnNldChwb3NpdGlvbnNbaTFdLCBwb3NpdGlvbnNbaTEgKyAxXSwgcG9zaXRpb25zW2kxICsgMl0pO1xuXHRcdFx0Y29uc3QgcDIgPSB0ZW1wUG9zMi5zZXQocG9zaXRpb25zW2kyXSwgcG9zaXRpb25zW2kyICsgMV0sIHBvc2l0aW9uc1tpMiArIDJdKTtcblx0XHRcdGNvbnN0IHcwID0gdGVtcFVWMC5zZXQodXZzW2kwXSwgdXZzW2kwICsgMV0pO1xuXHRcdFx0Y29uc3QgdzEgPSB0ZW1wVVYxLnNldCh1dnNbaTFdLCB1dnNbaTEgKyAxXSk7XG5cdFx0XHRjb25zdCB3MiA9IHRlbXBVVjIuc2V0KHV2c1tpMl0sIHV2c1tpMiArIDFdKTtcblxuXHRcdFx0VmVjdG9yMy5zdWJ0cmFjdChwMSwgcDAsIGUxKTtcblx0XHRcdFZlY3RvcjMuc3VidHJhY3QocDIsIHAwLCBlMik7XG5cdFx0XHRjb25zdCB4MSA9IHcxLnggLSB3MC54O1xuXHRcdFx0Y29uc3QgeDIgPSB3Mi54IC0gdzAueDtcblx0XHRcdGNvbnN0IHkxID0gdzEueSAtIHcwLnk7XG5cdFx0XHRjb25zdCB5MiA9IHcyLnkgLSB3MC55O1xuXHRcdFx0Y29uc3QgciA9IDEuMCAvICh4MSAqIHkyIC0geDIgKiB5MSk7XG5cblx0XHRcdFZlY3RvcjMubXVsdGlwbHlCeVNjYWxhcihlMSwgeTIgKiByLCB0KTtcblx0XHRcdFZlY3RvcjMubXVsdGlwbHlCeVNjYWxhcihlMiwgeTEgKiByLCB0ZW1wKTtcblx0XHRcdFZlY3RvcjMuc3VidHJhY3QodCwgdGVtcCwgdCk7XG5cdFx0XHRWZWN0b3IzLm11bHRpcGx5QnlTY2FsYXIoZTIsIHgxICogciwgYik7XG5cdFx0XHRWZWN0b3IzLm11bHRpcGx5QnlTY2FsYXIoZTEsIHgyICogciwgdGVtcCk7XG5cdFx0XHRWZWN0b3IzLnN1YnRyYWN0KGIsIHRlbXAsIGIpO1xuXG5cdFx0XHRsZXQgdGFuZ2VudCA9IHRhbmdlbnRzW2kwXTtcblx0XHRcdHRhbmdlbnQuc2V0KHRhbmdlbnQueCArIHQueCwgdGFuZ2VudC55ICsgdC55LCB0YW5nZW50LnogKyB0LnosIDEuMCk7XG5cblx0XHRcdHRhbmdlbnQgPSB0YW5nZW50c1tpMV07XG5cdFx0XHR0YW5nZW50LnNldCh0YW5nZW50LnggKyB0LngsIHRhbmdlbnQueSArIHQueSwgdGFuZ2VudC56ICsgdC56LCAxLjApO1xuXG5cdFx0XHR0YW5nZW50ID0gdGFuZ2VudHNbaTJdO1xuXHRcdFx0dGFuZ2VudC5zZXQodGFuZ2VudC54ICsgdC54LCB0YW5nZW50LnkgKyB0LnksIHRhbmdlbnQueiArIHQueiwgMS4wKTtcblx0XHRcdGJpVGFuZ2VudHNbaTBdLmFkZChiKTtcblx0XHRcdGJpVGFuZ2VudHNbaTFdLmFkZChiKTtcblx0XHRcdGJpVGFuZ2VudHNbaTJdLmFkZChiKTtcblx0XHR9XG5cblx0XHQvLyBPcnRob25vcm1hbGl6ZSBlYWNoIHRhbmdlbnQgYW5kIGNhbGN1bGF0ZSB0aGUgaGFuZGVkbmVzcy5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHZlcnRleENvdW50OyBpKyspIHtcblx0XHRcdGNvbnN0IG4gPSBuZXcgVmVjdG9yMyhub3JtYWxzWzMgKiBpXSwgbm9ybWFsc1szICogaSArIDFdLCBub3JtYWxzWzMgKiBpICsgMl0pO1xuXHRcdFx0Y29uc3QgYiA9IGJpVGFuZ2VudHNbaV07XG5cdFx0XHRjb25zdCB0YW5nZW50ID0gdGFuZ2VudHNbaV07XG5cdFx0XHR0LnNldCh0YW5nZW50LngsIHRhbmdlbnQueSwgdGFuZ2VudC56KTtcblxuXHRcdFx0VmVjdG9yMy5jcm9zcyh0LCBiLCB0ZW1wKTtcblx0XHRcdGNvbnN0IHcgPSBWZWN0b3IzLmRvdCh0ZW1wLCBuKSA+IDAuMCA/IDEgOiAtMTtcblx0XHRcdFZlY3RvcjMubXVsdGlwbHlCeVNjYWxhcihuLCBWZWN0b3IzLmRvdCh0LCBuKSwgdGVtcCk7XG5cdFx0XHRWZWN0b3IzLnN1YnRyYWN0KHQsIHRlbXAsIHQpO1xuXHRcdFx0VmVjdG9yMy5ub3JtYWxpemUodCwgdCk7XG5cdFx0XHQvLyB0Lm5vcm1hbGl6ZSgpO1xuXHRcdFx0dGFuZ2VudC5zZXQodC54LCB0LnksIHQueiwgdyk7XG5cdFx0XHR0aGlzLnRhbmdlbnRzLnB1c2godC54LCB0LnksIHQueiwgdyk7XG5cdFx0fVxuXHRcdC8vIHRoaXMuc2V0VGFuZ2VudHModGFuZ2VudHMpO1xuXHR9XG5cdGRlc3Ryb3koKSB7XG5cdFx0dGhpcz8uaW5kZXhCdWZmZXIuZGVzdHJveSgpO1xuXHRcdHRoaXMuZGVmYXVsdFZlcnRleEJ1ZmZlci5kZXN0cm95KCk7XG5cdFx0dGhpcy5ub3JtYWxzID0gbnVsbDtcblx0XHR0aGlzLnV2cyA9IG51bGw7XG5cdFx0dGhpcy5wb3NpdGlvbnMgPSBudWxsO1xuXHRcdHRoaXMuaW5kaWNlcyA9IG51bGw7XG5cdFx0dGhpcy50YW5nZW50cyA9IG51bGw7XG5cdFx0dGhpcy5ib3VuZGluZ1NwaGVyZSA9IHVuZGVmaW5lZDtcblx0fVxufVxuIiwiaW1wb3J0IHsgRmxvYXQzMkF0dHJpYnV0ZSB9IGZyb20gXCIuLi9yZW5kZXIvQXR0cmlidXRlXCI7XG5pbXBvcnQgR2VvbWV0cnkgZnJvbSBcIi4vR2VvbWV0cnlcIjtcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBsYW5lR2VvbWV0cnkgZXh0ZW5kcyBHZW9tZXRyeSB7XG5cdGNvbnN0cnVjdG9yKHB1YmxpYyB3aWR0aDogbnVtYmVyID0gMTAsIHB1YmxpYyBoZWlnaHQ6IG51bWJlciA9IDEwKSB7XG5cdFx0c3VwZXIoe1xuXHRcdFx0dHlwZTogXCJwbGFuZUdlb21ldHJ5XCJcblx0XHR9KTtcblx0XHR0aGlzLmRlZmluZXMgPSB7XG5cdFx0XHRIQVNfTk9STUFMOiB0cnVlXG5cdFx0fTtcblx0XHR0aGlzLmluaXQoKTtcblx0fVxuXHRwcml2YXRlIGluaXQoKSB7XG5cdFx0Ly8gZ2VuZXJhdGUgcG9zIHV2IG5vcm1hbCBzbyBvblxuXHRcdGNvbnN0IHsgaW5kaWNlcywgbm9ybWFscywgdXZzLCB2ZXJ0aWNlcyB9ID0gdGhpcy5jcmVhdGVHcmlkKHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KTtcblx0XHR0aGlzLmNvbXB1dGVCb3VuZGluZ1NwaGVyZSh2ZXJ0aWNlcyk7XG5cdFx0dGhpcy5zZXRBdHRyaWJ1dGUobmV3IEZsb2F0MzJBdHRyaWJ1dGUoXCJwb3NpdGlvblwiLCB2ZXJ0aWNlcywgMykpO1xuXHRcdHRoaXMuc2V0QXR0cmlidXRlKG5ldyBGbG9hdDMyQXR0cmlidXRlKFwibm9ybWFsXCIsIG5vcm1hbHMsIDMpKTtcblx0XHR0aGlzLnNldEF0dHJpYnV0ZShuZXcgRmxvYXQzMkF0dHJpYnV0ZShcInV2XCIsIHV2cywgMikpO1xuXHRcdHRoaXMuc2V0SW5kaWNlKGluZGljZXMpO1xuXHRcdHRoaXMuY291bnQgPSBpbmRpY2VzLmxlbmd0aDtcblx0fVxuXHRwcml2YXRlIGNyZWF0ZUdyaWQod2lkdGggPSAxLCBoZWlnaHQgPSAxLCB3aWR0aFNlZ21lbnRzID0gMSwgaGVpZ2h0U2VnbWVudHMgPSAxKSB7XG5cdFx0Y29uc3Qgd2lkdGhfaGFsZiA9IHdpZHRoIC8gMjtcblx0XHRjb25zdCBoZWlnaHRfaGFsZiA9IGhlaWdodCAvIDI7XG5cblx0XHRjb25zdCBncmlkWCA9IE1hdGguZmxvb3Iod2lkdGhTZWdtZW50cyk7XG5cdFx0Y29uc3QgZ3JpZFkgPSBNYXRoLmZsb29yKGhlaWdodFNlZ21lbnRzKTtcblxuXHRcdGNvbnN0IGdyaWRYMSA9IGdyaWRYICsgMTtcblx0XHRjb25zdCBncmlkWTEgPSBncmlkWSArIDE7XG5cblx0XHRjb25zdCBzZWdtZW50X3dpZHRoID0gd2lkdGggLyBncmlkWDtcblx0XHRjb25zdCBzZWdtZW50X2hlaWdodCA9IGhlaWdodCAvIGdyaWRZO1xuXG5cdFx0Ly9cblxuXHRcdGNvbnN0IGluZGljZXMgPSBbXTtcblx0XHRjb25zdCB2ZXJ0aWNlcyA9IFtdO1xuXHRcdGNvbnN0IG5vcm1hbHMgPSBbXTtcblx0XHRjb25zdCB1dnMgPSBbXTtcblxuXHRcdGZvciAobGV0IGl5ID0gMDsgaXkgPCBncmlkWTE7IGl5KyspIHtcblx0XHRcdGNvbnN0IHkgPSBpeSAqIHNlZ21lbnRfaGVpZ2h0IC0gaGVpZ2h0X2hhbGY7XG5cblx0XHRcdGZvciAobGV0IGl4ID0gMDsgaXggPCBncmlkWDE7IGl4KyspIHtcblx0XHRcdFx0Y29uc3QgeCA9IGl4ICogc2VnbWVudF93aWR0aCAtIHdpZHRoX2hhbGY7XG5cblx0XHRcdFx0dmVydGljZXMucHVzaCh4LCAteSwgMCk7XG5cblx0XHRcdFx0bm9ybWFscy5wdXNoKDAsIDAsIDEpO1xuXG5cdFx0XHRcdHV2cy5wdXNoKGl4IC8gZ3JpZFgpO1xuXHRcdFx0XHR1dnMucHVzaCgxIC0gaXkgLyBncmlkWSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Zm9yIChsZXQgaXkgPSAwOyBpeSA8IGdyaWRZOyBpeSsrKSB7XG5cdFx0XHRmb3IgKGxldCBpeCA9IDA7IGl4IDwgZ3JpZFg7IGl4KyspIHtcblx0XHRcdFx0Y29uc3QgYSA9IGl4ICsgZ3JpZFgxICogaXk7XG5cdFx0XHRcdGNvbnN0IGIgPSBpeCArIGdyaWRYMSAqIChpeSArIDEpO1xuXHRcdFx0XHRjb25zdCBjID0gaXggKyAxICsgZ3JpZFgxICogKGl5ICsgMSk7XG5cdFx0XHRcdGNvbnN0IGQgPSBpeCArIDEgKyBncmlkWDEgKiBpeTtcblxuXHRcdFx0XHRpbmRpY2VzLnB1c2goYSwgYiwgZCk7XG5cdFx0XHRcdGluZGljZXMucHVzaChiLCBjLCBkKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHsgaW5kaWNlcywgbm9ybWFscywgdXZzLCB2ZXJ0aWNlcyB9O1xuXHR9XG59XG4iLCJpbXBvcnQgZGVmYXVsdFZhbHVlIGZyb20gXCIuLi91dGlscy9kZWZhdWx0VmFsdWVcIjtcclxuaW1wb3J0IGRlZmluZWQgZnJvbSBcIi4uL3V0aWxzL2RlZmluZWRcIjtcclxuaW1wb3J0IEdNYXRoIGZyb20gXCIuL01hdGhcIjtcclxuaW1wb3J0IE1hdHJpeDQgZnJvbSBcIi4vTWF0cml4NFwiO1xyXG5pbXBvcnQgVmVjdG9yMyBmcm9tIFwiLi9WZWN0b3IzXCI7XHJcbi8qKlxyXG4gKiBBIHNldCBvZiA0LWRpbWVuc2lvbmFsIGNvb3JkaW5hdGVzIHVzZWQgdG8gcmVwcmVzZW50IHJvdGF0aW9uIGluIDMtZGltZW5zaW9uYWwgc3BhY2UuXHJcbiAqIEBhbGlhcyBRdWF0ZXJuaW9uXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKlxyXG4gKiBAcGFyYW0ge051bWJlcn0gW3g9MC4wXSBUaGUgWCBjb21wb25lbnQuXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBbeT0wLjBdIFRoZSBZIGNvbXBvbmVudC5cclxuICogQHBhcmFtIHtOdW1iZXJ9IFt6PTAuMF0gVGhlIFogY29tcG9uZW50LlxyXG4gKiBAcGFyYW0ge051bWJlcn0gW3c9MC4wXSBUaGUgVyBjb21wb25lbnQuXHJcbiAqXHJcbiAqIEBzZWUgUGFja2FibGVGb3JJbnRlcnBvbGF0aW9uXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgUXVhdGVybmlvbiB7XHJcblx0cHVibGljIHN0YXRpYyBaRVJPID0gT2JqZWN0LmZyZWV6ZShuZXcgUXVhdGVybmlvbigwLjAsIDAuMCwgMC4wLCAwLjApKTtcclxuXHJcblx0cHVibGljIHN0YXRpYyBJREVOVElUWSA9IE9iamVjdC5mcmVlemUobmV3IFF1YXRlcm5pb24oMC4wLCAwLjAsIDAuMCwgMS4wKSk7XHJcblxyXG5cdGNvbnN0cnVjdG9yKHB1YmxpYyB4OiBudW1iZXIgPSAwLCBwdWJsaWMgeTogbnVtYmVyID0gMCwgcHVibGljIHo6IG51bWJlciA9IDAsIHB1YmxpYyB3OiBudW1iZXIgPSAxKSB7fVxyXG5cdHNldCh4LCB5LCB6LCB3KSB7XHJcblx0XHR0aGlzLnggPSB4O1xyXG5cdFx0dGhpcy55ID0geTtcclxuXHRcdHRoaXMueiA9IHo7XHJcblx0XHR0aGlzLncgPSB3O1xyXG5cdH1cclxuXHRub3JtYWxpemUoKSB7XHJcblx0XHRjb25zdCBpbnZlcnNlTWFnbml0dWRlID0gMS4wIC8gUXVhdGVybmlvbi5tYWduaXR1ZGUodGhpcyk7XHJcblx0XHRjb25zdCB4ID0gdGhpcy54ICogaW52ZXJzZU1hZ25pdHVkZTtcclxuXHRcdGNvbnN0IHkgPSB0aGlzLnkgKiBpbnZlcnNlTWFnbml0dWRlO1xyXG5cdFx0Y29uc3QgeiA9IHRoaXMueiAqIGludmVyc2VNYWduaXR1ZGU7XHJcblx0XHRjb25zdCB3ID0gdGhpcy53ICogaW52ZXJzZU1hZ25pdHVkZTtcclxuXHJcblx0XHR0aGlzLnggPSB4O1xyXG5cdFx0dGhpcy55ID0geTtcclxuXHRcdHRoaXMueiA9IHo7XHJcblx0XHR0aGlzLncgPSB3O1xyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG5cdGludmVydCgpIHtcclxuXHRcdHRoaXMueCAqPSAtMTtcclxuXHRcdHRoaXMueSAqPSAtMTtcclxuXHRcdHRoaXMueiAqPSAtMTtcclxuXHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0ZG90KHY6IFF1YXRlcm5pb24pOiBudW1iZXIge1xyXG5cdFx0cmV0dXJuIHRoaXMueCAqIHYueCArIHRoaXMueSAqIHYueSArIHRoaXMueiAqIHYueiArIHRoaXMudyAqIHYudztcclxuXHR9XHJcblx0c2V0RnJvbVVuaXRWZWN0b3JzKHZGcm9tOiBWZWN0b3IzLCB2VG86IFZlY3RvcjMpOiBRdWF0ZXJuaW9uIHtcclxuXHRcdC8vIGFzc3VtZXMgZGlyZWN0aW9uIHZlY3RvcnMgdkZyb20gYW5kIHZUbyBhcmUgbm9ybWFsaXplZFxyXG5cdFx0bGV0IHIgPSBWZWN0b3IzLmRvdCh2RnJvbSwgdlRvKSArIDE7XHJcblx0XHRpZiAociA8IE51bWJlci5FUFNJTE9OKSB7XHJcblx0XHRcdC8vIHZGcm9tIGFuZCB2VG8gcG9pbnQgaW4gb3Bwb3NpdGUgZGlyZWN0aW9uc1xyXG5cclxuXHRcdFx0ciA9IDA7XHJcblxyXG5cdFx0XHRpZiAoTWF0aC5hYnModkZyb20ueCkgPiBNYXRoLmFicyh2RnJvbS56KSkge1xyXG5cdFx0XHRcdHRoaXMueCA9IC12RnJvbS55O1xyXG5cdFx0XHRcdHRoaXMueSA9IHZGcm9tLng7XHJcblx0XHRcdFx0dGhpcy56ID0gMDtcclxuXHRcdFx0XHR0aGlzLncgPSByO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHRoaXMueCA9IDA7XHJcblx0XHRcdFx0dGhpcy55ID0gLXZGcm9tLno7XHJcblx0XHRcdFx0dGhpcy56ID0gdkZyb20ueTtcclxuXHRcdFx0XHR0aGlzLncgPSByO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHQvLyBjcm9zc1ZlY3RvcnMoIHZGcm9tLCB2VG8gKTsgLy8gaW5saW5lZCB0byBhdm9pZCBjeWNsaWMgZGVwZW5kZW5jeSBvbiBWZWN0b3IzXHJcblxyXG5cdFx0XHR0aGlzLnggPSB2RnJvbS55ICogdlRvLnogLSB2RnJvbS56ICogdlRvLnk7XHJcblx0XHRcdHRoaXMueSA9IHZGcm9tLnogKiB2VG8ueCAtIHZGcm9tLnggKiB2VG8uejtcclxuXHRcdFx0dGhpcy56ID0gdkZyb20ueCAqIHZUby55IC0gdkZyb20ueSAqIHZUby54O1xyXG5cdFx0XHR0aGlzLncgPSByO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzLm5vcm1hbGl6ZSgpO1xyXG5cdH1cclxuXHRzZXRGcm9tUm90YXRpb25NYXRyaXgobWF0cml4OiBNYXRyaXg0KTogUXVhdGVybmlvbiB7XHJcblx0XHRjb25zdCB0ZSA9IG1hdHJpeCxcclxuXHRcdFx0bTExID0gdGVbMF0sXHJcblx0XHRcdG0xMiA9IHRlWzRdLFxyXG5cdFx0XHRtMTMgPSB0ZVs4XSxcclxuXHRcdFx0bTIxID0gdGVbMV0sXHJcblx0XHRcdG0yMiA9IHRlWzVdLFxyXG5cdFx0XHRtMjMgPSB0ZVs5XSxcclxuXHRcdFx0bTMxID0gdGVbMl0sXHJcblx0XHRcdG0zMiA9IHRlWzZdLFxyXG5cdFx0XHRtMzMgPSB0ZVsxMF0sXHJcblx0XHRcdHRyYWNlID0gbTExICsgbTIyICsgbTMzO1xyXG5cclxuXHRcdGlmICh0cmFjZSA+IDApIHtcclxuXHRcdFx0Y29uc3QgcyA9IDAuNSAvIE1hdGguc3FydCh0cmFjZSArIDEuMCk7XHJcblxyXG5cdFx0XHR0aGlzLncgPSAwLjI1IC8gcztcclxuXHRcdFx0dGhpcy54ID0gKG0zMiAtIG0yMykgKiBzO1xyXG5cdFx0XHR0aGlzLnkgPSAobTEzIC0gbTMxKSAqIHM7XHJcblx0XHRcdHRoaXMueiA9IChtMjEgLSBtMTIpICogcztcclxuXHRcdH0gZWxzZSBpZiAobTExID4gbTIyICYmIG0xMSA+IG0zMykge1xyXG5cdFx0XHRjb25zdCBzID0gMi4wICogTWF0aC5zcXJ0KDEuMCArIG0xMSAtIG0yMiAtIG0zMyk7XHJcblxyXG5cdFx0XHR0aGlzLncgPSAobTMyIC0gbTIzKSAvIHM7XHJcblx0XHRcdHRoaXMueCA9IDAuMjUgKiBzO1xyXG5cdFx0XHR0aGlzLnkgPSAobTEyICsgbTIxKSAvIHM7XHJcblx0XHRcdHRoaXMueiA9IChtMTMgKyBtMzEpIC8gcztcclxuXHRcdH0gZWxzZSBpZiAobTIyID4gbTMzKSB7XHJcblx0XHRcdGNvbnN0IHMgPSAyLjAgKiBNYXRoLnNxcnQoMS4wICsgbTIyIC0gbTExIC0gbTMzKTtcclxuXHJcblx0XHRcdHRoaXMudyA9IChtMTMgLSBtMzEpIC8gcztcclxuXHRcdFx0dGhpcy54ID0gKG0xMiArIG0yMSkgLyBzO1xyXG5cdFx0XHR0aGlzLnkgPSAwLjI1ICogcztcclxuXHRcdFx0dGhpcy56ID0gKG0yMyArIG0zMikgLyBzO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0Y29uc3QgcyA9IDIuMCAqIE1hdGguc3FydCgxLjAgKyBtMzMgLSBtMTEgLSBtMjIpO1xyXG5cclxuXHRcdFx0dGhpcy53ID0gKG0yMSAtIG0xMikgLyBzO1xyXG5cdFx0XHR0aGlzLnggPSAobTEzICsgbTMxKSAvIHM7XHJcblx0XHRcdHRoaXMueSA9IChtMjMgKyBtMzIpIC8gcztcclxuXHRcdFx0dGhpcy56ID0gMC4yNSAqIHM7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0Y2xvbmUoKSB7XHJcblx0XHRyZXR1cm4gUXVhdGVybmlvbi5jbG9uZSh0aGlzLCB0aGlzKTtcclxuXHR9XHJcblxyXG5cdGVxdWFscyhyaWdodDogUXVhdGVybmlvbik6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIFF1YXRlcm5pb24uZXF1YWxzKHRoaXMsIHJpZ2h0KTtcclxuXHR9XHJcblxyXG5cdGVxdWFsc0Vwc2lsb24ocmlnaHQ6IFF1YXRlcm5pb24sIGVwc2lsb24gPSAwKTogYm9vbGVhbiB7XHJcblx0XHRyZXR1cm4gUXVhdGVybmlvbi5lcXVhbHNFcHNpbG9uKHRoaXMsIHJpZ2h0LCBlcHNpbG9uKTtcclxuXHR9XHJcblx0dG9BcnJheSgpOiBudW1iZXJbXSB7XHJcblx0XHRjb25zdCB7IHgsIHksIHosIHcgfSA9IHRoaXM7XHJcblx0XHRyZXR1cm4gW3gsIHksIHosIHddO1xyXG5cdH1cclxuXHRzdGF0aWMgZnJvbUF4aXNBbmdsZShheGlzOiBWZWN0b3IzLCBhbmdsZTogbnVtYmVyKTogUXVhdGVybmlvbiB7XHJcblx0XHRjb25zdCBoYWxmQW5nbGUgPSBhbmdsZSAvIDIuMDtcclxuXHRcdGNvbnN0IHMgPSBNYXRoLnNpbihoYWxmQW5nbGUpO1xyXG5cdFx0ZnJvbUF4aXNBbmdsZVNjcmF0Y2ggPSBWZWN0b3IzLm5vcm1hbGl6ZShheGlzLCBmcm9tQXhpc0FuZ2xlU2NyYXRjaCk7XHJcblxyXG5cdFx0Y29uc3QgeCA9IGZyb21BeGlzQW5nbGVTY3JhdGNoLnggKiBzO1xyXG5cdFx0Y29uc3QgeSA9IGZyb21BeGlzQW5nbGVTY3JhdGNoLnkgKiBzO1xyXG5cdFx0Y29uc3QgeiA9IGZyb21BeGlzQW5nbGVTY3JhdGNoLnogKiBzO1xyXG5cdFx0Y29uc3QgdyA9IE1hdGguY29zKGhhbGZBbmdsZSk7XHJcblx0XHQvLyBpZiAoIWRlZmluZWQocmVzdWx0KSkge1xyXG5cdFx0Ly8gICByZXR1cm5cclxuXHRcdC8vIH1cclxuXHRcdGNvbnN0IHJlc3VsdCA9IG5ldyBRdWF0ZXJuaW9uKHgsIHksIHosIHcpO1xyXG5cdFx0cmVzdWx0LnggPSB4O1xyXG5cdFx0cmVzdWx0LnkgPSB5O1xyXG5cdFx0cmVzdWx0LnogPSB6O1xyXG5cdFx0cmVzdWx0LncgPSB3O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdC8vIHN0YXRpYyBmcm9tUm90YXRpb25NYXRyaXgobWF0cml4OiBNYXRyaXgzLCByZXN1bHQ6IFF1YXRlcm5pb24pOiBRdWF0ZXJuaW9uIHtcclxuXHQvLyBcdGxldCByb290O1xyXG5cdC8vIFx0bGV0IHg7XHJcblx0Ly8gXHRsZXQgeTtcclxuXHQvLyBcdGxldCB6O1xyXG5cdC8vIFx0bGV0IHc7XHJcblxyXG5cdC8vIFx0Y29uc3QgbTAwID0gbWF0cml4W01hdHJpeDMuQ09MVU1OMFJPVzBdO1xyXG5cdC8vIFx0Y29uc3QgbTExID0gbWF0cml4W01hdHJpeDMuQ09MVU1OMVJPVzFdO1xyXG5cdC8vIFx0Y29uc3QgbTIyID0gbWF0cml4W01hdHJpeDMuQ09MVU1OMlJPVzJdO1xyXG5cdC8vIFx0Y29uc3QgdHJhY2UgPSBtMDAgKyBtMTEgKyBtMjI7XHJcblxyXG5cdC8vIFx0aWYgKHRyYWNlID4gMC4wKSB7XHJcblx0Ly8gXHRcdC8vIHx3fCA+IDEvMiwgbWF5IGFzIHdlbGwgY2hvb3NlIHcgPiAxLzJcclxuXHQvLyBcdFx0cm9vdCA9IE1hdGguc3FydCh0cmFjZSArIDEuMCk7IC8vIDJ3XHJcblx0Ly8gXHRcdHcgPSAwLjUgKiByb290O1xyXG5cdC8vIFx0XHRyb290ID0gMC41IC8gcm9vdDsgLy8gMS8oNHcpXHJcblxyXG5cdC8vIFx0XHR4ID0gKG1hdHJpeFtNYXRyaXgzLkNPTFVNTjFST1cyXSAtIG1hdHJpeFtNYXRyaXgzLkNPTFVNTjJST1cxXSkgKiByb290O1xyXG5cdC8vIFx0XHR5ID0gKG1hdHJpeFtNYXRyaXgzLkNPTFVNTjJST1cwXSAtIG1hdHJpeFtNYXRyaXgzLkNPTFVNTjBST1cyXSkgKiByb290O1xyXG5cdC8vIFx0XHR6ID0gKG1hdHJpeFtNYXRyaXgzLkNPTFVNTjBST1cxXSAtIG1hdHJpeFtNYXRyaXgzLkNPTFVNTjFST1cwXSkgKiByb290O1xyXG5cdC8vIFx0fSBlbHNlIHtcclxuXHQvLyBcdFx0Ly8gfHd8IDw9IDEvMlxyXG5cdC8vIFx0XHRjb25zdCBuZXh0ID0gZnJvbVJvdGF0aW9uTWF0cml4TmV4dDtcclxuXHJcblx0Ly8gXHRcdGxldCBpID0gMDtcclxuXHQvLyBcdFx0aWYgKG0xMSA+IG0wMCkge1xyXG5cdC8vIFx0XHRcdGkgPSAxO1xyXG5cdC8vIFx0XHR9XHJcblx0Ly8gXHRcdGlmIChtMjIgPiBtMDAgJiYgbTIyID4gbTExKSB7XHJcblx0Ly8gXHRcdFx0aSA9IDI7XHJcblx0Ly8gXHRcdH1cclxuXHQvLyBcdFx0Y29uc3QgaiA9IG5leHRbaV07XHJcblx0Ly8gXHRcdGNvbnN0IGsgPSBuZXh0W2pdO1xyXG5cclxuXHQvLyBcdFx0cm9vdCA9IE1hdGguc3FydChcclxuXHQvLyBcdFx0XHRtYXRyaXhbTWF0cml4My5nZXRFbGVtZW50SW5kZXgoaSwgaSldIC1cclxuXHQvLyBcdFx0XHRcdG1hdHJpeFtNYXRyaXgzLmdldEVsZW1lbnRJbmRleChqLCBqKV0gLVxyXG5cdC8vIFx0XHRcdFx0bWF0cml4W01hdHJpeDMuZ2V0RWxlbWVudEluZGV4KGssIGspXSArXHJcblx0Ly8gXHRcdFx0XHQxLjBcclxuXHQvLyBcdFx0KTtcclxuXHJcblx0Ly8gXHRcdGNvbnN0IHF1YXQgPSBmcm9tUm90YXRpb25NYXRyaXhRdWF0O1xyXG5cdC8vIFx0XHRxdWF0W2ldID0gMC41ICogcm9vdDtcclxuXHQvLyBcdFx0cm9vdCA9IDAuNSAvIHJvb3Q7XHJcblx0Ly8gXHRcdHcgPSAobWF0cml4W01hdHJpeDMuZ2V0RWxlbWVudEluZGV4KGssIGopXSAtIG1hdHJpeFtNYXRyaXgzLmdldEVsZW1lbnRJbmRleChqLCBrKV0pICogcm9vdDtcclxuXHQvLyBcdFx0cXVhdFtqXSA9IChtYXRyaXhbTWF0cml4My5nZXRFbGVtZW50SW5kZXgoaiwgaSldICsgbWF0cml4W01hdHJpeDMuZ2V0RWxlbWVudEluZGV4KGksIGopXSkgKiByb290O1xyXG5cdC8vIFx0XHRxdWF0W2tdID0gKG1hdHJpeFtNYXRyaXgzLmdldEVsZW1lbnRJbmRleChrLCBpKV0gKyBtYXRyaXhbTWF0cml4My5nZXRFbGVtZW50SW5kZXgoaSwgayldKSAqIHJvb3Q7XHJcblxyXG5cdC8vIFx0XHR4ID0gLXF1YXRbMF07XHJcblx0Ly8gXHRcdHkgPSAtcXVhdFsxXTtcclxuXHQvLyBcdFx0eiA9IC1xdWF0WzJdO1xyXG5cdC8vIFx0fVxyXG5cclxuXHQvLyBcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0Ly8gXHRcdHJldHVybiBuZXcgUXVhdGVybmlvbih4LCB5LCB6LCB3KTtcclxuXHQvLyBcdH1cclxuXHQvLyBcdHJlc3VsdC54ID0geDtcclxuXHQvLyBcdHJlc3VsdC55ID0geTtcclxuXHQvLyBcdHJlc3VsdC56ID0gejtcclxuXHQvLyBcdHJlc3VsdC53ID0gdztcclxuXHQvLyBcdHJldHVybiByZXN1bHQ7XHJcblx0Ly8gfVxyXG5cclxuXHRzdGF0aWMgY2xvbmUocXVhdGVybmlvbjogUXVhdGVybmlvbiwgcmVzdWx0OiBRdWF0ZXJuaW9uKTogUXVhdGVybmlvbiB7XHJcblx0XHRpZiAoIWRlZmluZWQocXVhdGVybmlvbikpIHtcclxuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIWRlZmluZWQocmVzdWx0KSkge1xyXG5cdFx0XHRyZXR1cm4gbmV3IFF1YXRlcm5pb24ocXVhdGVybmlvbi54LCBxdWF0ZXJuaW9uLnksIHF1YXRlcm5pb24ueiwgcXVhdGVybmlvbi53KTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXN1bHQueCA9IHF1YXRlcm5pb24ueDtcclxuXHRcdHJlc3VsdC55ID0gcXVhdGVybmlvbi55O1xyXG5cdFx0cmVzdWx0LnogPSBxdWF0ZXJuaW9uLno7XHJcblx0XHRyZXN1bHQudyA9IHF1YXRlcm5pb24udztcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgY29uanVnYXRlKHF1YXRlcm5pb246IFF1YXRlcm5pb24sIHJlc3VsdDogUXVhdGVybmlvbik6IFF1YXRlcm5pb24ge1xyXG5cdFx0cmVzdWx0LnggPSAtcXVhdGVybmlvbi54O1xyXG5cdFx0cmVzdWx0LnkgPSAtcXVhdGVybmlvbi55O1xyXG5cdFx0cmVzdWx0LnogPSAtcXVhdGVybmlvbi56O1xyXG5cdFx0cmVzdWx0LncgPSBxdWF0ZXJuaW9uLnc7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG1hZ25pdHVkZVNxdWFyZWQocXVhdGVybmlvbjogUXVhdGVybmlvbik6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHRxdWF0ZXJuaW9uLnggKiBxdWF0ZXJuaW9uLnggK1xyXG5cdFx0XHRxdWF0ZXJuaW9uLnkgKiBxdWF0ZXJuaW9uLnkgK1xyXG5cdFx0XHRxdWF0ZXJuaW9uLnogKiBxdWF0ZXJuaW9uLnogK1xyXG5cdFx0XHRxdWF0ZXJuaW9uLncgKiBxdWF0ZXJuaW9uLndcclxuXHRcdCk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbWFnbml0dWRlKHF1YXRlcm5pb246IFF1YXRlcm5pb24pOiBudW1iZXIge1xyXG5cdFx0cmV0dXJuIE1hdGguc3FydChRdWF0ZXJuaW9uLm1hZ25pdHVkZVNxdWFyZWQocXVhdGVybmlvbikpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG5vcm1hbGl6ZShxdWF0ZXJuaW9uOiBRdWF0ZXJuaW9uLCByZXN1bHQ6IFF1YXRlcm5pb24pOiBRdWF0ZXJuaW9uIHtcclxuXHRcdGNvbnN0IGludmVyc2VNYWduaXR1ZGUgPSAxLjAgLyBRdWF0ZXJuaW9uLm1hZ25pdHVkZShxdWF0ZXJuaW9uKTtcclxuXHRcdGNvbnN0IHggPSBxdWF0ZXJuaW9uLnggKiBpbnZlcnNlTWFnbml0dWRlO1xyXG5cdFx0Y29uc3QgeSA9IHF1YXRlcm5pb24ueSAqIGludmVyc2VNYWduaXR1ZGU7XHJcblx0XHRjb25zdCB6ID0gcXVhdGVybmlvbi56ICogaW52ZXJzZU1hZ25pdHVkZTtcclxuXHRcdGNvbnN0IHcgPSBxdWF0ZXJuaW9uLncgKiBpbnZlcnNlTWFnbml0dWRlO1xyXG5cclxuXHRcdHJlc3VsdC54ID0geDtcclxuXHRcdHJlc3VsdC55ID0geTtcclxuXHRcdHJlc3VsdC56ID0gejtcclxuXHRcdHJlc3VsdC53ID0gdztcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgaW52ZXJzZShxdWF0ZXJuaW9uOiBRdWF0ZXJuaW9uLCByZXN1bHQ6IFF1YXRlcm5pb24pOiBRdWF0ZXJuaW9uIHtcclxuXHRcdGNvbnN0IG1hZ25pdHVkZVNxdWFyZWQgPSBRdWF0ZXJuaW9uLm1hZ25pdHVkZVNxdWFyZWQocXVhdGVybmlvbik7XHJcblx0XHRyZXN1bHQgPSBRdWF0ZXJuaW9uLmNvbmp1Z2F0ZShxdWF0ZXJuaW9uLCByZXN1bHQpO1xyXG5cdFx0cmV0dXJuIFF1YXRlcm5pb24ubXVsdGlwbHlCeVNjYWxhcihyZXN1bHQsIDEuMCAvIG1hZ25pdHVkZVNxdWFyZWQsIHJlc3VsdCk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgYWRkKGxlZnQ6IFF1YXRlcm5pb24sIHJpZ2h0OiBRdWF0ZXJuaW9uLCByZXN1bHQ6IFF1YXRlcm5pb24pOiBRdWF0ZXJuaW9uIHtcclxuXHRcdHJlc3VsdC54ID0gbGVmdC54ICsgcmlnaHQueDtcclxuXHRcdHJlc3VsdC55ID0gbGVmdC55ICsgcmlnaHQueTtcclxuXHRcdHJlc3VsdC56ID0gbGVmdC56ICsgcmlnaHQuejtcclxuXHRcdHJlc3VsdC53ID0gbGVmdC53ICsgcmlnaHQudztcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgc3VidHJhY3QobGVmdDogUXVhdGVybmlvbiwgcmlnaHQ6IFF1YXRlcm5pb24sIHJlc3VsdDogUXVhdGVybmlvbik6IFF1YXRlcm5pb24ge1xyXG5cdFx0cmVzdWx0LnggPSBsZWZ0LnggLSByaWdodC54O1xyXG5cdFx0cmVzdWx0LnkgPSBsZWZ0LnkgLSByaWdodC55O1xyXG5cdFx0cmVzdWx0LnogPSBsZWZ0LnogLSByaWdodC56O1xyXG5cdFx0cmVzdWx0LncgPSBsZWZ0LncgLSByaWdodC53O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBuZWdhdGUocXVhdGVybmlvbjogUXVhdGVybmlvbiwgcmVzdWx0OiBRdWF0ZXJuaW9uKTogUXVhdGVybmlvbiB7XHJcblx0XHRyZXN1bHQueCA9IC1xdWF0ZXJuaW9uLng7XHJcblx0XHRyZXN1bHQueSA9IC1xdWF0ZXJuaW9uLnk7XHJcblx0XHRyZXN1bHQueiA9IC1xdWF0ZXJuaW9uLno7XHJcblx0XHRyZXN1bHQudyA9IC1xdWF0ZXJuaW9uLnc7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGRvdChsZWZ0OiBRdWF0ZXJuaW9uLCByaWdodDogUXVhdGVybmlvbik6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gbGVmdC54ICogcmlnaHQueCArIGxlZnQueSAqIHJpZ2h0LnkgKyBsZWZ0LnogKiByaWdodC56ICsgbGVmdC53ICogcmlnaHQudztcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBtdWx0aXBseShsZWZ0OiBRdWF0ZXJuaW9uLCByaWdodDogUXVhdGVybmlvbiwgcmVzdWx0OiBRdWF0ZXJuaW9uKTogUXVhdGVybmlvbiB7XHJcblx0XHRjb25zdCBsZWZ0WCA9IGxlZnQueDtcclxuXHRcdGNvbnN0IGxlZnRZID0gbGVmdC55O1xyXG5cdFx0Y29uc3QgbGVmdFogPSBsZWZ0Lno7XHJcblx0XHRjb25zdCBsZWZ0VyA9IGxlZnQudztcclxuXHJcblx0XHRjb25zdCByaWdodFggPSByaWdodC54O1xyXG5cdFx0Y29uc3QgcmlnaHRZID0gcmlnaHQueTtcclxuXHRcdGNvbnN0IHJpZ2h0WiA9IHJpZ2h0Lno7XHJcblx0XHRjb25zdCByaWdodFcgPSByaWdodC53O1xyXG5cclxuXHRcdGNvbnN0IHggPSBsZWZ0VyAqIHJpZ2h0WCArIGxlZnRYICogcmlnaHRXICsgbGVmdFkgKiByaWdodFogLSBsZWZ0WiAqIHJpZ2h0WTtcclxuXHRcdGNvbnN0IHkgPSBsZWZ0VyAqIHJpZ2h0WSAtIGxlZnRYICogcmlnaHRaICsgbGVmdFkgKiByaWdodFcgKyBsZWZ0WiAqIHJpZ2h0WDtcclxuXHRcdGNvbnN0IHogPSBsZWZ0VyAqIHJpZ2h0WiArIGxlZnRYICogcmlnaHRZIC0gbGVmdFkgKiByaWdodFggKyBsZWZ0WiAqIHJpZ2h0VztcclxuXHRcdGNvbnN0IHcgPSBsZWZ0VyAqIHJpZ2h0VyAtIGxlZnRYICogcmlnaHRYIC0gbGVmdFkgKiByaWdodFkgLSBsZWZ0WiAqIHJpZ2h0WjtcclxuXHJcblx0XHRyZXN1bHQueCA9IHg7XHJcblx0XHRyZXN1bHQueSA9IHk7XHJcblx0XHRyZXN1bHQueiA9IHo7XHJcblx0XHRyZXN1bHQudyA9IHc7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG11bHRpcGx5QnlTY2FsYXIocXVhdGVybmlvbjogUXVhdGVybmlvbiwgc2NhbGFyOiBudW1iZXIsIHJlc3VsdDogUXVhdGVybmlvbik6IFF1YXRlcm5pb24ge1xyXG5cdFx0cmVzdWx0LnggPSBxdWF0ZXJuaW9uLnggKiBzY2FsYXI7XHJcblx0XHRyZXN1bHQueSA9IHF1YXRlcm5pb24ueSAqIHNjYWxhcjtcclxuXHRcdHJlc3VsdC56ID0gcXVhdGVybmlvbi56ICogc2NhbGFyO1xyXG5cdFx0cmVzdWx0LncgPSBxdWF0ZXJuaW9uLncgKiBzY2FsYXI7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGRpdmlkZUJ5U2NhbGFyKHF1YXRlcm5pb246IFF1YXRlcm5pb24sIHNjYWxhcjogbnVtYmVyLCByZXN1bHQ6IFF1YXRlcm5pb24pOiBRdWF0ZXJuaW9uIHtcclxuXHRcdHJlc3VsdC54ID0gcXVhdGVybmlvbi54IC8gc2NhbGFyO1xyXG5cdFx0cmVzdWx0LnkgPSBxdWF0ZXJuaW9uLnkgLyBzY2FsYXI7XHJcblx0XHRyZXN1bHQueiA9IHF1YXRlcm5pb24ueiAvIHNjYWxhcjtcclxuXHRcdHJlc3VsdC53ID0gcXVhdGVybmlvbi53IC8gc2NhbGFyO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBjb21wdXRlQXhpcyhxdWF0ZXJuaW9uOiBRdWF0ZXJuaW9uLCByZXN1bHQ6IFZlY3RvcjMpOiBWZWN0b3IzIHtcclxuXHRcdGNvbnN0IHcgPSBxdWF0ZXJuaW9uLnc7XHJcblx0XHRpZiAoTWF0aC5hYnModyAtIDEuMCkgPCBHTWF0aC5FUFNJTE9ONikge1xyXG5cdFx0XHRyZXN1bHQueCA9IHJlc3VsdC55ID0gcmVzdWx0LnogPSAwO1xyXG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IHNjYWxhciA9IDEuMCAvIE1hdGguc3FydCgxLjAgLSB3ICogdyk7XHJcblxyXG5cdFx0cmVzdWx0LnggPSBxdWF0ZXJuaW9uLnggKiBzY2FsYXI7XHJcblx0XHRyZXN1bHQueSA9IHF1YXRlcm5pb24ueSAqIHNjYWxhcjtcclxuXHRcdHJlc3VsdC56ID0gcXVhdGVybmlvbi56ICogc2NhbGFyO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBjb21wdXRlQW5nbGUocXVhdGVybmlvbjogUXVhdGVybmlvbik6IG51bWJlciB7XHJcblx0XHRpZiAoTWF0aC5hYnMocXVhdGVybmlvbi53IC0gMS4wKSA8IEdNYXRoLkVQU0lMT042KSB7XHJcblx0XHRcdHJldHVybiAwLjA7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gMi4wICogTWF0aC5hY29zKHF1YXRlcm5pb24udyk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgbGVycChzdGFydDogUXVhdGVybmlvbiwgZW5kOiBRdWF0ZXJuaW9uLCB0OiBudW1iZXIsIHJlc3VsdDogUXVhdGVybmlvbik6IFF1YXRlcm5pb24ge1xyXG5cdFx0bGVycFNjcmF0Y2ggPSBRdWF0ZXJuaW9uLm11bHRpcGx5QnlTY2FsYXIoZW5kLCB0LCBsZXJwU2NyYXRjaCk7XHJcblx0XHRyZXN1bHQgPSBRdWF0ZXJuaW9uLm11bHRpcGx5QnlTY2FsYXIoc3RhcnQsIDEuMCAtIHQsIHJlc3VsdCk7XHJcblx0XHRyZXR1cm4gUXVhdGVybmlvbi5hZGQobGVycFNjcmF0Y2gsIHJlc3VsdCwgcmVzdWx0KTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBzbGVycChzdGFydDogUXVhdGVybmlvbiwgZW5kOiBRdWF0ZXJuaW9uLCB0OiBudW1iZXIsIHJlc3VsdDogUXVhdGVybmlvbik6IFF1YXRlcm5pb24ge1xyXG5cdFx0bGV0IGRvdCA9IFF1YXRlcm5pb24uZG90KHN0YXJ0LCBlbmQpO1xyXG5cclxuXHRcdC8vIFRoZSBhbmdsZSBiZXR3ZWVuIHN0YXJ0IG11c3QgYmUgYWN1dGUuIFNpbmNlIHEgYW5kIC1xIHJlcHJlc2VudFxyXG5cdFx0Ly8gdGhlIHNhbWUgcm90YXRpb24sIG5lZ2F0ZSBxIHRvIGdldCB0aGUgYWN1dGUgYW5nbGUuXHJcblx0XHRsZXQgciA9IGVuZDtcclxuXHRcdGlmIChkb3QgPCAwLjApIHtcclxuXHRcdFx0ZG90ID0gLWRvdDtcclxuXHRcdFx0ciA9IHNsZXJwRW5kTmVnYXRlZCA9IFF1YXRlcm5pb24ubmVnYXRlKGVuZCwgc2xlcnBFbmROZWdhdGVkKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBkb3QgPiAwLCBhcyB0aGUgZG90IHByb2R1Y3QgYXBwcm9hY2hlcyAxLCB0aGUgYW5nbGUgYmV0d2VlbiB0aGVcclxuXHRcdC8vIHF1YXRlcm5pb25zIHZhbmlzaGVzLiB1c2UgbGluZWFyIGludGVycG9sYXRpb24uXHJcblx0XHRpZiAoMS4wIC0gZG90IDwgR01hdGguRVBTSUxPTjYpIHtcclxuXHRcdFx0cmV0dXJuIFF1YXRlcm5pb24ubGVycChzdGFydCwgciwgdCwgcmVzdWx0KTtcclxuXHRcdH1cclxuXHJcblx0XHRjb25zdCB0aGV0YSA9IE1hdGguYWNvcyhkb3QpO1xyXG5cdFx0c2xlcnBTY2FsZWRQID0gUXVhdGVybmlvbi5tdWx0aXBseUJ5U2NhbGFyKHN0YXJ0LCBNYXRoLnNpbigoMSAtIHQpICogdGhldGEpLCBzbGVycFNjYWxlZFApO1xyXG5cdFx0c2xlcnBTY2FsZWRSID0gUXVhdGVybmlvbi5tdWx0aXBseUJ5U2NhbGFyKHIsIE1hdGguc2luKHQgKiB0aGV0YSksIHNsZXJwU2NhbGVkUik7XHJcblx0XHRyZXN1bHQgPSBRdWF0ZXJuaW9uLmFkZChzbGVycFNjYWxlZFAsIHNsZXJwU2NhbGVkUiwgcmVzdWx0KTtcclxuXHRcdHJldHVybiBRdWF0ZXJuaW9uLm11bHRpcGx5QnlTY2FsYXIocmVzdWx0LCAxLjAgLyBNYXRoLnNpbih0aGV0YSksIHJlc3VsdCk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgc3F1YWQoXHJcblx0XHRxMDogUXVhdGVybmlvbixcclxuXHRcdHExOiBRdWF0ZXJuaW9uLFxyXG5cdFx0czA6IFF1YXRlcm5pb24sXHJcblx0XHRzMTogUXVhdGVybmlvbixcclxuXHRcdHQ6IG51bWJlcixcclxuXHRcdHJlc3VsdDogUXVhdGVybmlvblxyXG5cdCk6IFF1YXRlcm5pb24ge1xyXG5cdFx0Y29uc3Qgc2xlcnAwID0gUXVhdGVybmlvbi5zbGVycChxMCwgcTEsIHQsIHNxdWFkU2NyYXRjaFF1YXRlcm5pb24wKTtcclxuXHRcdGNvbnN0IHNsZXJwMSA9IFF1YXRlcm5pb24uc2xlcnAoczAsIHMxLCB0LCBzcXVhZFNjcmF0Y2hRdWF0ZXJuaW9uMSk7XHJcblx0XHRyZXR1cm4gUXVhdGVybmlvbi5zbGVycChzbGVycDAsIHNsZXJwMSwgMi4wICogdCAqICgxLjAgLSB0KSwgcmVzdWx0KTtcclxuXHR9XHJcblx0c3RhdGljIGVxdWFscyhsZWZ0OiBRdWF0ZXJuaW9uLCByaWdodDogUXVhdGVybmlvbik6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0bGVmdCA9PT0gcmlnaHQgfHxcclxuXHRcdFx0KGRlZmluZWQobGVmdCkgJiZcclxuXHRcdFx0XHRkZWZpbmVkKHJpZ2h0KSAmJlxyXG5cdFx0XHRcdGxlZnQueCA9PT0gcmlnaHQueCAmJlxyXG5cdFx0XHRcdGxlZnQueSA9PT0gcmlnaHQueSAmJlxyXG5cdFx0XHRcdGxlZnQueiA9PT0gcmlnaHQueiAmJlxyXG5cdFx0XHRcdGxlZnQudyA9PT0gcmlnaHQudylcclxuXHRcdCk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZXF1YWxzRXBzaWxvbihsZWZ0OiBRdWF0ZXJuaW9uLCByaWdodDogUXVhdGVybmlvbiwgZXBzaWxvbiA9IDApOiBib29sZWFuIHtcclxuXHRcdGVwc2lsb24gPSBkZWZhdWx0VmFsdWUoZXBzaWxvbiwgMCk7XHJcblxyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0bGVmdCA9PT0gcmlnaHQgfHxcclxuXHRcdFx0KGRlZmluZWQobGVmdCkgJiZcclxuXHRcdFx0XHRkZWZpbmVkKHJpZ2h0KSAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnQueCAtIHJpZ2h0LngpIDw9IGVwc2lsb24gJiZcclxuXHRcdFx0XHRNYXRoLmFicyhsZWZ0LnkgLSByaWdodC55KSA8PSBlcHNpbG9uICYmXHJcblx0XHRcdFx0TWF0aC5hYnMobGVmdC56IC0gcmlnaHQueikgPD0gZXBzaWxvbiAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnQudyAtIHJpZ2h0LncpIDw9IGVwc2lsb24pXHJcblx0XHQpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGV4cChjYXJ0ZXNpYW46IFZlY3RvcjMsIHJlc3VsdDogUXVhdGVybmlvbik6IFF1YXRlcm5pb24ge1xyXG5cdFx0Y29uc3QgdGhldGEgPSBWZWN0b3IzLm1hZ25pdHVkZShjYXJ0ZXNpYW4pO1xyXG5cdFx0bGV0IHNpblRoZXRhT3ZlclRoZXRhID0gMC4wO1xyXG5cclxuXHRcdGlmICh0aGV0YSAhPT0gMC4wKSB7XHJcblx0XHRcdHNpblRoZXRhT3ZlclRoZXRhID0gTWF0aC5zaW4odGhldGEpIC8gdGhldGE7XHJcblx0XHR9XHJcblxyXG5cdFx0cmVzdWx0LnggPSBjYXJ0ZXNpYW4ueCAqIHNpblRoZXRhT3ZlclRoZXRhO1xyXG5cdFx0cmVzdWx0LnkgPSBjYXJ0ZXNpYW4ueSAqIHNpblRoZXRhT3ZlclRoZXRhO1xyXG5cdFx0cmVzdWx0LnogPSBjYXJ0ZXNpYW4ueiAqIHNpblRoZXRhT3ZlclRoZXRhO1xyXG5cdFx0cmVzdWx0LncgPSBNYXRoLmNvcyh0aGV0YSk7XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcbn1cclxuXHJcbmxldCBmcm9tQXhpc0FuZ2xlU2NyYXRjaCA9IG5ldyBWZWN0b3IzKCk7XHJcblxyXG5jb25zdCBmcm9tUm90YXRpb25NYXRyaXhOZXh0ID0gWzEsIDIsIDBdO1xyXG5jb25zdCBmcm9tUm90YXRpb25NYXRyaXhRdWF0ID0gbmV3IEFycmF5KDMpO1xyXG5cclxubGV0IGxlcnBTY3JhdGNoID0gbmV3IFF1YXRlcm5pb24oKTtcclxuXHJcbmxldCBzbGVycEVuZE5lZ2F0ZWQgPSBuZXcgUXVhdGVybmlvbigpO1xyXG5sZXQgc2xlcnBTY2FsZWRQID0gbmV3IFF1YXRlcm5pb24oKTtcclxubGV0IHNsZXJwU2NhbGVkUiA9IG5ldyBRdWF0ZXJuaW9uKCk7XHJcblxyXG5jb25zdCBzcXVhZFNjcmF0Y2hDYXJ0ZXNpYW4wID0gbmV3IFZlY3RvcjMoKTtcclxuY29uc3Qgc3F1YWRTY3JhdGNoQ2FydGVzaWFuMSA9IG5ldyBWZWN0b3IzKCk7XHJcbmNvbnN0IHNxdWFkU2NyYXRjaFF1YXRlcm5pb24wID0gbmV3IFF1YXRlcm5pb24oKTtcclxuY29uc3Qgc3F1YWRTY3JhdGNoUXVhdGVybmlvbjEgPSBuZXcgUXVhdGVybmlvbigpO1xyXG4iLCJpbXBvcnQgTWF0cml4NCBmcm9tIFwiLi4vbWF0aC9NYXRyaXg0XCI7XG5pbXBvcnQgeyBRdWF0ZXJuaW9uIH0gZnJvbSBcIi4uL21hdGgvUXVhdGVybmlvblwiO1xuaW1wb3J0IFZlY3RvcjMgZnJvbSBcIi4uL21hdGgvVmVjdG9yM1wiO1xuaW1wb3J0IElDbG9uZSBmcm9tIFwiLi9JQ2xvbmVcIjtcbmltcG9ydCB7IFJlbmRlck9iamVjdFR5cGUgfSBmcm9tIFwiLi9XZWJHUFVUeXBlc1wiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZW5kZXJPYmplY3QgaW1wbGVtZW50cyBJQ2xvbmUge1xuXHRwdWJsaWMgdXA6IFZlY3RvcjM7XG5cdHByb3RlY3RlZCBfcG9zaXRpb246IFZlY3RvcjM7XG5cdHByb3RlY3RlZCBfc2NhbGU6IFZlY3RvcjM7XG5cdHByb3RlY3RlZCBfcXVhdGVybmlvbjogUXVhdGVybmlvbjtcblx0cHJvdGVjdGVkIF90YXJnZXQ6IFZlY3RvcjM7XG5cdHByaXZhdGUgX25vcm1hbE1hdHJpeDogTWF0cml4NDtcblx0bW9kZWxNYXRyaXg6IE1hdHJpeDQ7XG5cdHBhcmVudDogUmVuZGVyT2JqZWN0O1xuXHR0eXBlOiBSZW5kZXJPYmplY3RUeXBlO1xuXHRuYW1lOiBzdHJpbmc7XG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHRoaXMuX3Bvc2l0aW9uID0gbmV3IFZlY3RvcjMoKTtcblx0XHR0aGlzLl9zY2FsZSA9IG5ldyBWZWN0b3IzKDEsIDEsIDEpO1xuXHRcdHRoaXMuX3F1YXRlcm5pb24gPSBuZXcgUXVhdGVybmlvbigpO1xuXHRcdHRoaXMubW9kZWxNYXRyaXggPSBNYXRyaXg0LmNsb25lKE1hdHJpeDQuSURFTlRJVFksIG5ldyBNYXRyaXg0KCkpO1xuXHRcdHRoaXMuX25vcm1hbE1hdHJpeCA9IE1hdHJpeDQuY2xvbmUoTWF0cml4NC5JREVOVElUWSwgbmV3IE1hdHJpeDQoKSk7XG5cdFx0dGhpcy51cCA9IG5ldyBWZWN0b3IzKDAsIDEsIDApO1xuXHRcdHRoaXMuX3RhcmdldCA9IG5ldyBWZWN0b3IzKDAsIDAsIDApO1xuXHR9XG5cdHB1YmxpYyBnZXQgbm9ybWFsTWF0cml4KCk6IE1hdHJpeDQge1xuXHRcdHJldHVybiB0aGlzLl9ub3JtYWxNYXRyaXg7XG5cdH1cblxuXHRwdWJsaWMgZ2V0IHBvc2l0aW9uKCk6IFZlY3RvcjMge1xuXHRcdHJldHVybiB0aGlzLl9wb3NpdGlvbjtcblx0fVxuXHRwdWJsaWMgZ2V0IHNjYWxlKCk6IFZlY3RvcjMge1xuXHRcdHJldHVybiB0aGlzLl9zY2FsZTtcblx0fVxuXHRwdWJsaWMgZ2V0IHF1YXRlcm5pb24oKTogUXVhdGVybmlvbiB7XG5cdFx0cmV0dXJuIHRoaXMuX3F1YXRlcm5pb247XG5cdH1cblx0cHJpdmF0ZSB1cGRhdGVOb3JtYWxNYXRyaXgoKSB7XG5cdFx0TWF0cml4NC5pbnZlcnNlKHRoaXMubW9kZWxNYXRyaXgsIHRoaXMuX25vcm1hbE1hdHJpeCk7XG5cdFx0TWF0cml4NC50cmFuc3Bvc2UodGhpcy5fbm9ybWFsTWF0cml4LCB0aGlzLl9ub3JtYWxNYXRyaXgpO1xuXHR9XG5cdHVwZGF0ZU1hdHJpeChtYXRyaXg/OiBNYXRyaXg0KSB7XG5cdFx0dGhpcy5tb2RlbE1hdHJpeC5jb21wb3NlKHRoaXMucG9zaXRpb24sIHRoaXMucXVhdGVybmlvbiwgdGhpcy5zY2FsZSk7XG5cdFx0aWYgKG1hdHJpeCkgTWF0cml4NC5tdWx0aXBseShtYXRyaXgsIHRoaXMubW9kZWxNYXRyaXgsIHRoaXMubW9kZWxNYXRyaXgpO1xuXHRcdHRoaXMudXBkYXRlTm9ybWFsTWF0cml4KCk7XG5cdH1cblx0bG9va0F0KHgsIHksIHopIHtcblx0XHR0aGlzLl90YXJnZXQuc2V0KHgsIHksIHopO1xuXHRcdGlmICh0aGlzLnR5cGUgPT0gUmVuZGVyT2JqZWN0VHlwZS5DYW1lcmEgfHwgdGhpcy50eXBlID09IFJlbmRlck9iamVjdFR5cGUuTGlnaHQpIHtcblx0XHRcdF9tMS5sb29rQXQodGhpcy5wb3NpdGlvbiwgdGhpcy5fdGFyZ2V0LCB0aGlzLnVwKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0X20xLmxvb2tBdCh0aGlzLl90YXJnZXQsIHRoaXMucG9zaXRpb24sIHRoaXMudXApO1xuXHRcdH1cblx0XHR0aGlzLnF1YXRlcm5pb24uc2V0RnJvbVJvdGF0aW9uTWF0cml4KF9tMSk7XG5cdH1cblx0cm90YXRlT25BeGlzKGF4aXMsIGFuZ2xlKSB7XG5cdFx0Y29uc3QgcXVhdCA9IFF1YXRlcm5pb24uZnJvbUF4aXNBbmdsZShheGlzLCBhbmdsZSk7XG5cdFx0UXVhdGVybmlvbi5tdWx0aXBseSh0aGlzLnF1YXRlcm5pb24sIHF1YXQsIHRoaXMucXVhdGVybmlvbik7XG5cdH1cblx0cm90YXRlWChhbmdsZSkge1xuXHRcdHJldHVybiB0aGlzLnJvdGF0ZU9uQXhpcyhfeEF4aXMsIGFuZ2xlKTtcblx0fVxuXHRyb3RhdGVZKGFuZ2xlKSB7XG5cdFx0cmV0dXJuIHRoaXMucm90YXRlT25BeGlzKF95QXhpcywgYW5nbGUpO1xuXHR9XG5cdHJvdGF0ZVooYW5nbGUpIHtcblx0XHRyZXR1cm4gdGhpcy5yb3RhdGVPbkF4aXMoX3pBeGlzLCBhbmdsZSk7XG5cdH1cbn1cbmNvbnN0IF94QXhpcyA9IG5ldyBWZWN0b3IzKDEsIDAsIDApO1xuY29uc3QgX3lBeGlzID0gbmV3IFZlY3RvcjMoMCwgMSwgMCk7XG5jb25zdCBfekF4aXMgPSBuZXcgVmVjdG9yMygwLCAwLCAxKTtcbmNvbnN0IF9tMSA9IG5ldyBNYXRyaXg0KCk7XG4iLCJpbXBvcnQgUmVuZGVyT2JqZWN0IGZyb20gXCIuLi9jb3JlL1JlbmRlck9iamVjdFwiO1xyXG5pbXBvcnQgeyBMaWdodFR5cGUsIFJlbmRlck9iamVjdFR5cGUgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVUeXBlc1wiO1xyXG5pbXBvcnQgVmVjdG9yMyBmcm9tIFwiLi4vbWF0aC9WZWN0b3IzXCI7XHJcbmltcG9ydCB7IEJhc2VTaGFkb3cgfSBmcm9tIFwiLi9zaGFkb3dzL0Jhc2VTaGFkb3dcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBMaWdodCBleHRlbmRzIFJlbmRlck9iamVjdCB7XHJcblx0cHJpdmF0ZSBfY29sb3I6IFZlY3RvcjM7XHJcblx0dHlwZTogUmVuZGVyT2JqZWN0VHlwZTtcclxuXHRwcml2YXRlIF9pbnRlbnNpdHk6IG51bWJlcjtcclxuXHRkaXJ0eTogYm9vbGVhbjtcclxuXHRjb2xvckRpcnR5OiBib29sZWFuO1xyXG5cdHNoYWRvd0RpcnR5OiBib29sZWFuO1xyXG5cdGludGVuc2l0eURpcnR5OiBib29sZWFuO1xyXG5cdHBvc2l0aW9uRGlydHk6IGJvb2xlYW47XHJcblx0cHVibGljIF9zaGFkb3c6IEJhc2VTaGFkb3c7XHJcblx0cHVibGljIHRhcmdldERpcnR5OiBib29sZWFuO1xyXG5cdHB1YmxpYyBsaWdodFR5cGU6IExpZ2h0VHlwZTtcclxuXHJcblx0Y29uc3RydWN0b3IoY29sb3I6IFZlY3RvcjMsIGludGVuc2l0eTogbnVtYmVyKSB7XHJcblx0XHRzdXBlcigpO1xyXG5cdFx0dGhpcy50eXBlID0gUmVuZGVyT2JqZWN0VHlwZS5MaWdodDtcclxuXHRcdHRoaXMuX2NvbG9yID0gVmVjdG9yMy5tdWx0aXBseUJ5U2NhbGFyKGNvbG9yLCBpbnRlbnNpdHksIG5ldyBWZWN0b3IzKCkpO1xyXG5cdFx0dGhpcy5faW50ZW5zaXR5ID0gaW50ZW5zaXR5O1xyXG5cdFx0dGhpcy5fcG9zaXRpb24gPSBuZXcgVmVjdG9yMygwLCAxLCAwKTtcclxuXHRcdHRoaXMuX3RhcmdldCA9IG5ldyBWZWN0b3IzKCk7XHJcblx0XHR0aGlzLnBvc2l0aW9uRGlydHkgPSB0cnVlO1xyXG5cdFx0dGhpcy50YXJnZXREaXJ0eSA9IHRydWU7XHJcblx0XHR0aGlzLmNvbG9yRGlydHkgPSB0cnVlO1xyXG5cdFx0dGhpcy5zaGFkb3dEaXJ0eSA9IHRydWU7XHJcblx0XHR0aGlzLmludGVuc2l0eURpcnR5ID0gdHJ1ZTtcclxuXHRcdHRoaXMuX3NoYWRvdyA9IG51bGw7XHJcblx0fVxyXG5cclxuXHRnZXQgcG9zaXRpb24oKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5fcG9zaXRpb247XHJcblx0fVxyXG5cclxuXHRzZXQgcG9zaXRpb24odmFsdWUpIHtcclxuXHRcdHRoaXMucG9zaXRpb25EaXJ0eSA9IHRydWU7XHJcblx0XHR0aGlzLl9wb3NpdGlvbiA9IHZhbHVlO1xyXG5cdH1cclxuXHJcblx0Z2V0IHRhcmdldCgpIHtcclxuXHRcdHJldHVybiB0aGlzLl90YXJnZXQ7XHJcblx0fVxyXG5cclxuXHRzZXQgdGFyZ2V0KHZhbHVlKSB7XHJcblx0XHR0aGlzLnRhcmdldERpcnR5ID0gdHJ1ZTtcclxuXHRcdHRoaXMuX3RhcmdldCA9IHZhbHVlO1xyXG5cdH1cclxuXHJcblx0Z2V0IGNvbG9yKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuX2NvbG9yO1xyXG5cdH1cclxuXHJcblx0c2V0IGNvbG9yKHZhbHVlKSB7XHJcblx0XHR0aGlzLmNvbG9yRGlydHkgPSB0cnVlO1xyXG5cdFx0dGhpcy5fY29sb3IgPSB2YWx1ZTtcclxuXHR9XHJcblxyXG5cdHNldCBpbnRlbnNpdHkodmFsdWUpIHtcclxuXHRcdHRoaXMuY29sb3IgPSBWZWN0b3IzLm11bHRpcGx5QnlTY2FsYXIodGhpcy5jb2xvciwgdmFsdWUsIG5ldyBWZWN0b3IzKCkpO1xyXG5cdFx0dGhpcy5pbnRlbnNpdHlEaXJ0eSA9IHRydWU7XHJcblx0XHR0aGlzLl9pbnRlbnNpdHkgPSB2YWx1ZTtcclxuXHR9XHJcblxyXG5cdGdldCBpbnRlbnNpdHkoKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5faW50ZW5zaXR5O1xyXG5cdH1cclxuXHJcblx0Z2V0IHNoYWRvdygpIHtcclxuXHRcdHJldHVybiB0aGlzLl9zaGFkb3c7XHJcblx0fVxyXG5cclxuXHRzZXQgc2hhZG93KHZhbHVlKSB7XHJcblx0XHR0aGlzLnNoYWRvd0RpcnR5ID0gdHJ1ZTtcclxuXHRcdHRoaXMuX3NoYWRvdyA9IHZhbHVlO1xyXG5cdH1cclxufVxyXG4iLCJpbXBvcnQgZGVmYXVsdFZhbHVlIGZyb20gXCIuLi91dGlscy9kZWZhdWx0VmFsdWVcIjtcclxuaW1wb3J0IGRlZmluZWQgZnJvbSBcIi4uL3V0aWxzL2RlZmluZWRcIjtcclxuaW1wb3J0IEdNYXRoIGZyb20gXCIuL01hdGhcIjtcclxuLy8gI3JnYmFcclxuY29uc3QgcmdiYU1hdGNoZXIgPSAvXiMoWzAtOWEtZl0pKFswLTlhLWZdKShbMC05YS1mXSkoWzAtOWEtZl0pPyQvaTtcclxuLy8gI3JyZ2diYmFhXHJcbmNvbnN0IHJyZ2diYmFhTWF0Y2hlciA9IC9eIyhbMC05YS1mXXsyfSkoWzAtOWEtZl17Mn0pKFswLTlhLWZdezJ9KShbMC05YS1mXXsyfSk/JC9pO1xyXG4vLyByZ2IoKSwgcmdiYSgpLCBvciByZ2IlKClcclxuY29uc3QgcmdiUGFyZW50aGVzZXNNYXRjaGVyID0gL15yZ2JhP1xcKFxccyooWzAtOS5dKyU/KVxccyosXFxzKihbMC05Ll0rJT8pXFxzKixcXHMqKFswLTkuXSslPykoPzpcXHMqLFxccyooWzAtOS5dKykpP1xccypcXCkkL2k7XHJcbi8vIGhzbCgpIG9yIGhzbGEoKVxyXG5jb25zdCBoc2xQYXJlbnRoZXNlc01hdGNoZXIgPSAvXmhzbGE/XFwoXFxzKihbMC05Ll0rKVxccyosXFxzKihbMC05Ll0rJSlcXHMqLFxccyooWzAtOS5dKyUpKD86XFxzKixcXHMqKFswLTkuXSspKT9cXHMqXFwpJC9pO1xyXG5mdW5jdGlvbiBodWUycmdiKG0xLCBtMiwgaCkge1xyXG5cdGlmIChoIDwgMCkge1xyXG5cdFx0aCArPSAxO1xyXG5cdH1cclxuXHRpZiAoaCA+IDEpIHtcclxuXHRcdGggLT0gMTtcclxuXHR9XHJcblx0aWYgKGggKiA2IDwgMSkge1xyXG5cdFx0cmV0dXJuIG0xICsgKG0yIC0gbTEpICogNiAqIGg7XHJcblx0fVxyXG5cdGlmIChoICogMiA8IDEpIHtcclxuXHRcdHJldHVybiBtMjtcclxuXHR9XHJcblx0aWYgKGggKiAzIDwgMikge1xyXG5cdFx0cmV0dXJuIG0xICsgKG0yIC0gbTEpICogKDIgLyAzIC0gaCkgKiA2O1xyXG5cdH1cclxuXHRyZXR1cm4gbTE7XHJcbn1cclxuXHJcbmNsYXNzIENvbG9yIHtcclxuXHRncmVlbjogbnVtYmVyO1xyXG5cdHJlZDogbnVtYmVyO1xyXG5cdGJsdWU6IG51bWJlcjtcclxuXHRjb25zdHJ1Y3RvcihyZWQgPSAxLjAsIGdyZWVuID0gMS4wLCBibHVlID0gMS4wKSB7XHJcblx0XHQvKipcclxuXHRcdCAqIFRoZSByZWQgY29tcG9uZW50LlxyXG5cdFx0ICogQHR5cGUge051bWJlcn1cclxuXHRcdCAqIEBkZWZhdWx0IDEuMFxyXG5cdFx0ICovXHJcblx0XHR0aGlzLnJlZCA9IHJlZDtcclxuXHRcdC8qKlxyXG5cdFx0ICogVGhlIGdyZWVuIGNvbXBvbmVudC5cclxuXHRcdCAqIEB0eXBlIHtOdW1iZXJ9XHJcblx0XHQgKiBAZGVmYXVsdCAxLjBcclxuXHRcdCAqL1xyXG5cdFx0dGhpcy5ncmVlbiA9IGdyZWVuO1xyXG5cdFx0LyoqXHJcblx0XHQgKiBUaGUgYmx1ZSBjb21wb25lbnQuXHJcblx0XHQgKiBAdHlwZSB7TnVtYmVyfVxyXG5cdFx0ICogQGRlZmF1bHQgMS4wXHJcblx0XHQgKi9cclxuXHRcdHRoaXMuYmx1ZSA9IGJsdWU7XHJcblx0fVxyXG5cdHNldCh2YWx1ZTogc3RyaW5nKTogQ29sb3Ige1xyXG5cdFx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIikge1xyXG5cdFx0XHRDb2xvci5mcm9tQ3NzQ29sb3JTdHJpbmcodmFsdWUsIHRoaXMpO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG5cdHRvQXJyYXkoKTogbnVtYmVyW10ge1xyXG5cdFx0cmV0dXJuIFt0aGlzLnJlZCwgdGhpcy5ncmVlbiwgdGhpcy5ibHVlXTtcclxuXHR9XHJcblxyXG5cdGNsb25lKHJlc3VsdDogQ29sb3IpOiBDb2xvciB7XHJcblx0XHRyZXR1cm4gQ29sb3IuY2xvbmUodGhpcywgcmVzdWx0KTtcclxuXHR9XHJcblxyXG5cdGVxdWFscyhvdGhlcjogQ29sb3IpOiBib29sZWFuIHtcclxuXHRcdHJldHVybiBDb2xvci5lcXVhbHModGhpcywgb3RoZXIpO1xyXG5cdH1cclxuXHJcblx0dG9Dc3NIZXhTdHJpbmcoKTogc3RyaW5nIHtcclxuXHRcdGxldCByID0gQ29sb3IuZmxvYXRUb0J5dGUodGhpcy5yZWQpLnRvU3RyaW5nKDE2KTtcclxuXHRcdGlmIChyLmxlbmd0aCA8IDIpIHtcclxuXHRcdFx0ciA9IGAwJHtyfWA7XHJcblx0XHR9XHJcblx0XHRsZXQgZyA9IENvbG9yLmZsb2F0VG9CeXRlKHRoaXMuZ3JlZW4pLnRvU3RyaW5nKDE2KTtcclxuXHRcdGlmIChnLmxlbmd0aCA8IDIpIHtcclxuXHRcdFx0ZyA9IGAwJHtnfWA7XHJcblx0XHR9XHJcblx0XHRsZXQgYiA9IENvbG9yLmZsb2F0VG9CeXRlKHRoaXMuYmx1ZSkudG9TdHJpbmcoMTYpO1xyXG5cdFx0aWYgKGIubGVuZ3RoIDwgMikge1xyXG5cdFx0XHRiID0gYDAke2J9YDtcclxuXHRcdH1cclxuXHRcdHJldHVybiBgIyR7cn0ke2d9JHtifWA7XHJcblx0fVxyXG5cclxuXHR0b0J5dGVzKHJlc3VsdDogbnVtYmVyW10pOiBudW1iZXJbXSB7XHJcblx0XHRjb25zdCByZWQgPSBDb2xvci5mbG9hdFRvQnl0ZSh0aGlzLnJlZCk7XHJcblx0XHRjb25zdCBncmVlbiA9IENvbG9yLmZsb2F0VG9CeXRlKHRoaXMuZ3JlZW4pO1xyXG5cdFx0Y29uc3QgYmx1ZSA9IENvbG9yLmZsb2F0VG9CeXRlKHRoaXMuYmx1ZSk7XHJcblxyXG5cdFx0aWYgKCFkZWZpbmVkKHJlc3VsdCkpIHtcclxuXHRcdFx0cmV0dXJuIFtyZWQsIGdyZWVuLCBibHVlXTtcclxuXHRcdH1cclxuXHRcdHJlc3VsdFswXSA9IHJlZDtcclxuXHRcdHJlc3VsdFsxXSA9IGdyZWVuO1xyXG5cdFx0cmVzdWx0WzJdID0gYmx1ZTtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZnJvbUJ5dGVzKHJlZDogbnVtYmVyLCBncmVlbjogbnVtYmVyLCBibHVlOiBudW1iZXIsIHJlc3VsdDogQ29sb3IpOiBDb2xvciB7XHJcblx0XHRyZWQgPSBDb2xvci5ieXRlVG9GbG9hdChkZWZhdWx0VmFsdWUocmVkLCAyNTUuMCkpO1xyXG5cdFx0Z3JlZW4gPSBDb2xvci5ieXRlVG9GbG9hdChkZWZhdWx0VmFsdWUoZ3JlZW4sIDI1NS4wKSk7XHJcblx0XHRibHVlID0gQ29sb3IuYnl0ZVRvRmxvYXQoZGVmYXVsdFZhbHVlKGJsdWUsIDI1NS4wKSk7XHJcblxyXG5cdFx0aWYgKCFkZWZpbmVkKHJlc3VsdCkpIHtcclxuXHRcdFx0cmV0dXJuIG5ldyBDb2xvcihyZWQsIGdyZWVuLCBibHVlKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXN1bHQucmVkID0gcmVkO1xyXG5cdFx0cmVzdWx0LmdyZWVuID0gZ3JlZW47XHJcblx0XHRyZXN1bHQuYmx1ZSA9IGJsdWU7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGZyb21Ic2woaHVlOiBudW1iZXIsIHNhdHVyYXRpb246IG51bWJlciwgbGlnaHRuZXNzOiBudW1iZXIsIHJlc3VsdDogQ29sb3IpOiBDb2xvciB7XHJcblx0XHRodWUgPSBkZWZhdWx0VmFsdWUoaHVlLCAwLjApICUgMS4wO1xyXG5cdFx0c2F0dXJhdGlvbiA9IGRlZmF1bHRWYWx1ZShzYXR1cmF0aW9uLCAwLjApO1xyXG5cdFx0bGlnaHRuZXNzID0gZGVmYXVsdFZhbHVlKGxpZ2h0bmVzcywgMC4wKTtcclxuXHRcdGxldCByZWQgPSBsaWdodG5lc3M7XHJcblx0XHRsZXQgZ3JlZW4gPSBsaWdodG5lc3M7XHJcblx0XHRsZXQgYmx1ZSA9IGxpZ2h0bmVzcztcclxuXHJcblx0XHRpZiAoc2F0dXJhdGlvbiAhPT0gMCkge1xyXG5cdFx0XHRsZXQgbTI7XHJcblx0XHRcdGlmIChsaWdodG5lc3MgPCAwLjUpIHtcclxuXHRcdFx0XHRtMiA9IGxpZ2h0bmVzcyAqICgxICsgc2F0dXJhdGlvbik7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0bTIgPSBsaWdodG5lc3MgKyBzYXR1cmF0aW9uIC0gbGlnaHRuZXNzICogc2F0dXJhdGlvbjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Y29uc3QgbTEgPSAyLjAgKiBsaWdodG5lc3MgLSBtMjtcclxuXHRcdFx0cmVkID0gaHVlMnJnYihtMSwgbTIsIGh1ZSArIDEgLyAzKTtcclxuXHRcdFx0Z3JlZW4gPSBodWUycmdiKG0xLCBtMiwgaHVlKTtcclxuXHRcdFx0Ymx1ZSA9IGh1ZTJyZ2IobTEsIG0yLCBodWUgLSAxIC8gMyk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCFkZWZpbmVkKHJlc3VsdCkpIHtcclxuXHRcdFx0cmV0dXJuIG5ldyBDb2xvcihyZWQsIGdyZWVuLCBibHVlKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXN1bHQucmVkID0gcmVkO1xyXG5cdFx0cmVzdWx0LmdyZWVuID0gZ3JlZW47XHJcblx0XHRyZXN1bHQuYmx1ZSA9IGJsdWU7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogQ3JlYXRlcyBhIHJhbmRvbSBjb2xvciB1c2luZyB0aGUgcHJvdmlkZWQgb3B0aW9ucy4gRm9yIHJlcHJvZHVjaWJsZSByYW5kb20gY29sb3JzLCB5b3Ugc2hvdWxkXHJcblx0ICogY2FsbCB7QGxpbmsgR01hdGgjc2V0UmFuZG9tTnVtYmVyU2VlZH0gb25jZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHlvdXIgYXBwbGljYXRpb24uXHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIE9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcclxuXHQgKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMucmVkXSBJZiBzcGVjaWZpZWQsIHRoZSByZWQgY29tcG9uZW50IHRvIHVzZSBpbnN0ZWFkIG9mIGEgcmFuZG9taXplZCB2YWx1ZS5cclxuXHQgKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMubWluaW11bVJlZD0wLjBdIFRoZSBtYXhpbXVtIHJlZCB2YWx1ZSB0byBnZW5lcmF0ZSBpZiBub25lIHdhcyBzcGVjaWZpZWQuXHJcblx0ICogQHBhcmFtIHtOdW1iZXJ9IFtvcHRpb25zLm1heGltdW1SZWQ9MS4wXSBUaGUgbWluaW11bSByZWQgdmFsdWUgdG8gZ2VuZXJhdGUgaWYgbm9uZSB3YXMgc3BlY2lmaWVkLlxyXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0aW9ucy5ncmVlbl0gSWYgc3BlY2lmaWVkLCB0aGUgZ3JlZW4gY29tcG9uZW50IHRvIHVzZSBpbnN0ZWFkIG9mIGEgcmFuZG9taXplZCB2YWx1ZS5cclxuXHQgKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMubWluaW11bUdyZWVuPTAuMF0gVGhlIG1heGltdW0gZ3JlZW4gdmFsdWUgdG8gZ2VuZXJhdGUgaWYgbm9uZSB3YXMgc3BlY2lmaWVkLlxyXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0aW9ucy5tYXhpbXVtR3JlZW49MS4wXSBUaGUgbWluaW11bSBncmVlbiB2YWx1ZSB0byBnZW5lcmF0ZSBpZiBub25lIHdhcyBzcGVjaWZpZWQuXHJcblx0ICogQHBhcmFtIHtOdW1iZXJ9IFtvcHRpb25zLmJsdWVdIElmIHNwZWNpZmllZCwgdGhlIGJsdWUgY29tcG9uZW50IHRvIHVzZSBpbnN0ZWFkIG9mIGEgcmFuZG9taXplZCB2YWx1ZS5cclxuXHQgKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMubWluaW11bUJsdWU9MC4wXSBUaGUgbWF4aW11bSBibHVlIHZhbHVlIHRvIGdlbmVyYXRlIGlmIG5vbmUgd2FzIHNwZWNpZmllZC5cclxuXHQgKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMubWF4aW11bUJsdWU9MS4wXSBUaGUgbWluaW11bSBibHVlIHZhbHVlIHRvIGdlbmVyYXRlIGlmIG5vbmUgd2FzIHNwZWNpZmllZC5cclxuXHQgKiBAcGFyYW0ge0NvbG9yfSBbcmVzdWx0XSBUaGUgb2JqZWN0IHRvIHN0b3JlIHRoZSByZXN1bHQgaW4sIGlmIHVuZGVmaW5lZCBhIG5ldyBpbnN0YW5jZSB3aWxsIGJlIGNyZWF0ZWQuXHJcblx0ICogQHJldHVybnMge0NvbG9yfSBUaGUgbW9kaWZpZWQgcmVzdWx0IHBhcmFtZXRlciBvciBhIG5ldyBpbnN0YW5jZSBpZiByZXN1bHQgd2FzIHVuZGVmaW5lZC5cclxuXHQgKlxyXG5cdCAqIEBleGFtcGxlXHJcblx0ICogLy9DcmVhdGUgYSBjb21wbGV0ZWx5IHJhbmRvbSBjb2xvclxyXG5cdCAqIGNvbnN0IGNvbG9yID0gQ29sb3IuZnJvbVJhbmRvbSgpO1xyXG5cdCAqXHJcblx0ICogLy9DcmVhdGUgYSByYW5kb20gc2hhZGUgb2YgeWVsbG93LlxyXG5cdCAqIGNvbnN0IGNvbG9yMSA9IENvbG9yLmZyb21SYW5kb20oe1xyXG5cdCAqICAgICByZWQgOiAxLjAsXHJcblx0ICogICAgIGdyZWVuIDogMS4wLFxyXG5cdCAqIH0pO1xyXG5cdCAqXHJcblx0ICogLy9DcmVhdGUgYSByYW5kb20gYnJpZ2h0IGNvbG9yLlxyXG5cdCAqIGNvbnN0IGNvbG9yMiA9IENvbG9yLmZyb21SYW5kb20oe1xyXG5cdCAqICAgICBtaW5pbXVtUmVkIDogMC43NSxcclxuXHQgKiAgICAgbWluaW11bUdyZWVuIDogMC43NSxcclxuXHQgKiAgICAgbWluaW11bUJsdWUgOiAwLjc1LFxyXG5cdCAqIH0pO1xyXG5cdCAqL1xyXG5cdHN0YXRpYyBmcm9tUmFuZG9tKG9wdGlvbnMsIHJlc3VsdDogQ29sb3IpOiBDb2xvciB7XHJcblx0XHRvcHRpb25zID0gZGVmYXVsdFZhbHVlKG9wdGlvbnMsIGRlZmF1bHRWYWx1ZS5FTVBUWV9PQkpFQ1QpO1xyXG5cclxuXHRcdGxldCByZWQgPSBvcHRpb25zLnJlZDtcclxuXHRcdGlmICghZGVmaW5lZChyZWQpKSB7XHJcblx0XHRcdGNvbnN0IG1pbmltdW1SZWQgPSBkZWZhdWx0VmFsdWUob3B0aW9ucy5taW5pbXVtUmVkLCAwKTtcclxuXHRcdFx0Y29uc3QgbWF4aW11bVJlZCA9IGRlZmF1bHRWYWx1ZShvcHRpb25zLm1heGltdW1SZWQsIDEuMCk7XHJcblxyXG5cdFx0XHRyZWQgPSBtaW5pbXVtUmVkICsgR01hdGgubmV4dFJhbmRvbU51bWJlcigpICogKG1heGltdW1SZWQgLSBtaW5pbXVtUmVkKTtcclxuXHRcdH1cclxuXHJcblx0XHRsZXQgZ3JlZW4gPSBvcHRpb25zLmdyZWVuO1xyXG5cdFx0aWYgKCFkZWZpbmVkKGdyZWVuKSkge1xyXG5cdFx0XHRjb25zdCBtaW5pbXVtR3JlZW4gPSBkZWZhdWx0VmFsdWUob3B0aW9ucy5taW5pbXVtR3JlZW4sIDApO1xyXG5cdFx0XHRjb25zdCBtYXhpbXVtR3JlZW4gPSBkZWZhdWx0VmFsdWUob3B0aW9ucy5tYXhpbXVtR3JlZW4sIDEuMCk7XHJcblxyXG5cdFx0XHRncmVlbiA9IG1pbmltdW1HcmVlbiArIEdNYXRoLm5leHRSYW5kb21OdW1iZXIoKSAqIChtYXhpbXVtR3JlZW4gLSBtaW5pbXVtR3JlZW4pO1xyXG5cdFx0fVxyXG5cclxuXHRcdGxldCBibHVlID0gb3B0aW9ucy5ibHVlO1xyXG5cdFx0aWYgKCFkZWZpbmVkKGJsdWUpKSB7XHJcblx0XHRcdGNvbnN0IG1pbmltdW1CbHVlID0gZGVmYXVsdFZhbHVlKG9wdGlvbnMubWluaW11bUJsdWUsIDApO1xyXG5cdFx0XHRjb25zdCBtYXhpbXVtQmx1ZSA9IGRlZmF1bHRWYWx1ZShvcHRpb25zLm1heGltdW1CbHVlLCAxLjApO1xyXG5cclxuXHRcdFx0Ymx1ZSA9IG1pbmltdW1CbHVlICsgR01hdGgubmV4dFJhbmRvbU51bWJlcigpICogKG1heGltdW1CbHVlIC0gbWluaW11bUJsdWUpO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCFkZWZpbmVkKHJlc3VsdCkpIHtcclxuXHRcdFx0cmV0dXJuIG5ldyBDb2xvcihyZWQsIGdyZWVuLCBibHVlKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXN1bHQucmVkID0gcmVkO1xyXG5cdFx0cmVzdWx0LmdyZWVuID0gZ3JlZW47XHJcblx0XHRyZXN1bHQuYmx1ZSA9IGJsdWU7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGZyb21Dc3NDb2xvclN0cmluZyhjb2xvcjogc3RyaW5nLCByZXN1bHQ6IENvbG9yID0gbmV3IENvbG9yKCkpOiBDb2xvciB7XHJcblx0XHQvLyBSZW1vdmUgYWxsIHdoaXRlc3BhY2VzIGZyb20gdGhlIGNvbG9yIHN0cmluZ1xyXG5cdFx0Y29sb3IgPSBjb2xvci5yZXBsYWNlKC9cXHMvZywgXCJcIik7XHJcblxyXG5cdFx0Y29uc3QgbmFtZWRDb2xvciA9IENvbG9yW2NvbG9yLnRvVXBwZXJDYXNlKCldO1xyXG5cdFx0aWYgKGRlZmluZWQobmFtZWRDb2xvcikpIHtcclxuXHRcdFx0Q29sb3IuY2xvbmUobmFtZWRDb2xvciwgcmVzdWx0KTtcclxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcclxuXHRcdH1cclxuXHJcblx0XHRsZXQgbWF0Y2hlcyA9IHJnYmFNYXRjaGVyLmV4ZWMoY29sb3IpO1xyXG5cdFx0aWYgKG1hdGNoZXMgIT09IG51bGwpIHtcclxuXHRcdFx0cmVzdWx0LnJlZCA9IHBhcnNlSW50KG1hdGNoZXNbMV0sIDE2KSAvIDE1O1xyXG5cdFx0XHRyZXN1bHQuZ3JlZW4gPSBwYXJzZUludChtYXRjaGVzWzJdLCAxNikgLyAxNS4wO1xyXG5cdFx0XHRyZXN1bHQuYmx1ZSA9IHBhcnNlSW50KG1hdGNoZXNbM10sIDE2KSAvIDE1LjA7XHJcblx0XHRcdHJldHVybiByZXN1bHQ7XHJcblx0XHR9XHJcblxyXG5cdFx0bWF0Y2hlcyA9IHJyZ2diYmFhTWF0Y2hlci5leGVjKGNvbG9yKTtcclxuXHRcdGlmIChtYXRjaGVzICE9PSBudWxsKSB7XHJcblx0XHRcdHJlc3VsdC5yZWQgPSBwYXJzZUludChtYXRjaGVzWzFdLCAxNikgLyAyNTUuMDtcclxuXHRcdFx0cmVzdWx0LmdyZWVuID0gcGFyc2VJbnQobWF0Y2hlc1syXSwgMTYpIC8gMjU1LjA7XHJcblx0XHRcdHJlc3VsdC5ibHVlID0gcGFyc2VJbnQobWF0Y2hlc1szXSwgMTYpIC8gMjU1LjA7XHJcblx0XHRcdHJldHVybiByZXN1bHQ7XHJcblx0XHR9XHJcblxyXG5cdFx0bWF0Y2hlcyA9IHJnYlBhcmVudGhlc2VzTWF0Y2hlci5leGVjKGNvbG9yKTtcclxuXHRcdGlmIChtYXRjaGVzICE9PSBudWxsKSB7XHJcblx0XHRcdHJlc3VsdC5yZWQgPSBwYXJzZUZsb2F0KG1hdGNoZXNbMV0pIC8gKFwiJVwiID09PSBtYXRjaGVzWzFdLnN1YnN0cigtMSkgPyAxMDAuMCA6IDI1NS4wKTtcclxuXHRcdFx0cmVzdWx0LmdyZWVuID0gcGFyc2VGbG9hdChtYXRjaGVzWzJdKSAvIChcIiVcIiA9PT0gbWF0Y2hlc1syXS5zdWJzdHIoLTEpID8gMTAwLjAgOiAyNTUuMCk7XHJcblx0XHRcdHJlc3VsdC5ibHVlID0gcGFyc2VGbG9hdChtYXRjaGVzWzNdKSAvIChcIiVcIiA9PT0gbWF0Y2hlc1szXS5zdWJzdHIoLTEpID8gMTAwLjAgOiAyNTUuMCk7XHJcblx0XHRcdHJldHVybiByZXN1bHQ7XHJcblx0XHR9XHJcblxyXG5cdFx0bWF0Y2hlcyA9IGhzbFBhcmVudGhlc2VzTWF0Y2hlci5leGVjKGNvbG9yKTtcclxuXHRcdGlmIChtYXRjaGVzICE9PSBudWxsKSB7XHJcblx0XHRcdHJldHVybiBDb2xvci5mcm9tSHNsKFxyXG5cdFx0XHRcdHBhcnNlRmxvYXQobWF0Y2hlc1sxXSkgLyAzNjAuMCxcclxuXHRcdFx0XHRwYXJzZUZsb2F0KG1hdGNoZXNbMl0pIC8gMTAwLjAsXHJcblx0XHRcdFx0cGFyc2VGbG9hdChtYXRjaGVzWzNdKSAvIDEwMC4wLFxyXG5cdFx0XHRcdHJlc3VsdFxyXG5cdFx0XHQpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJlc3VsdCA9IHVuZGVmaW5lZDtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgYnl0ZVRvRmxvYXQodmFsdWU6IG51bWJlcik6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gdmFsdWUgLyAyNTUuMDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBmbG9hdFRvQnl0ZSh2YWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcclxuXHRcdHJldHVybiB2YWx1ZSA9PT0gMS4wID8gMjU1LjAgOiAodmFsdWUgKiAyNTYuMCkgfCAwO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGNsb25lKGNvbG9yOiBDb2xvciwgcmVzdWx0OiBDb2xvcik6IENvbG9yIHtcclxuXHRcdGlmICghZGVmaW5lZChjb2xvcikpIHtcclxuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJldHVybiBuZXcgQ29sb3IoY29sb3IucmVkLCBjb2xvci5ncmVlbiwgY29sb3IuYmx1ZSk7XHJcblx0XHR9XHJcblx0XHRyZXN1bHQucmVkID0gY29sb3IucmVkO1xyXG5cdFx0cmVzdWx0LmdyZWVuID0gY29sb3IuZ3JlZW47XHJcblx0XHRyZXN1bHQuYmx1ZSA9IGNvbG9yLmJsdWU7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGVxdWFscyhsZWZ0OiBDb2xvciwgcmlnaHQ6IENvbG9yKTogYm9vbGVhbiB7XHJcblx0XHRyZXR1cm4gKFxyXG5cdFx0XHRsZWZ0ID09PSByaWdodCB8fCAvL1xyXG5cdFx0XHQoZGVmaW5lZChsZWZ0KSAmJiAvL1xyXG5cdFx0XHRcdGRlZmluZWQocmlnaHQpICYmIC8vXHJcblx0XHRcdFx0bGVmdC5yZWQgPT09IHJpZ2h0LnJlZCAmJiAvL1xyXG5cdFx0XHRcdGxlZnQuZ3JlZW4gPT09IHJpZ2h0LmdyZWVuICYmIC8vXHJcblx0XHRcdFx0bGVmdC5ibHVlID09PSByaWdodC5ibHVlKVxyXG5cdFx0KTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0c3RhdGljIGVxdWFsc0FycmF5KGNvbG9yOiBDb2xvciwgYXJyYXk6IG51bWJlcltdLCBvZmZzZXQ6IG51bWJlcik6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIGNvbG9yLnJlZCA9PT0gYXJyYXlbb2Zmc2V0XSAmJiBjb2xvci5ncmVlbiA9PT0gYXJyYXlbb2Zmc2V0ICsgMV0gJiYgY29sb3IuYmx1ZSA9PT0gYXJyYXlbb2Zmc2V0ICsgMl07XHJcblx0fVxyXG59XHJcbmV4cG9ydCBkZWZhdWx0IENvbG9yO1xyXG4iLCJpbXBvcnQgZGVmYXVsdFZhbHVlIGZyb20gXCIuLi91dGlscy9kZWZhdWx0VmFsdWVcIjtcclxuaW1wb3J0IGRlZmluZWQgZnJvbSBcIi4uL3V0aWxzL2RlZmluZWRcIjtcclxuaW1wb3J0IFZlY3RvcjIgZnJvbSBcIi4vVmVjdG9yMlwiO1xyXG5cclxuLyoqXHJcbiAqIEEgMngyIG1hdHJpeCwgaW5kZXhhYmxlIGFzIGEgY29sdW1uLW1ham9yIG9yZGVyIGFycmF5LlxyXG4gKiBAcGFyYW0ge051bWJlcn0gW2NvbHVtbjBSb3cwPTAuMF0gVGhlIHZhbHVlIGZvciBjb2x1bW4gMCwgcm93IDAuXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBbY29sdW1uMVJvdzA9MC4wXSBUaGUgdmFsdWUgZm9yIGNvbHVtbiAxLCByb3cgMC5cclxuICogQHBhcmFtIHtOdW1iZXJ9IFtjb2x1bW4wUm93MT0wLjBdIFRoZSB2YWx1ZSBmb3IgY29sdW1uIDAsIHJvdyAxLlxyXG4gKiBAcGFyYW0ge051bWJlcn0gW2NvbHVtbjFSb3cxPTAuMF0gVGhlIHZhbHVlIGZvciBjb2x1bW4gMSwgcm93IDEuXHJcbiAqL1xyXG5jbGFzcyBNYXRyaXgyIHtcclxuXHRjb25zdHJ1Y3Rvcihjb2x1bW4wUm93MCA9IDAsIGNvbHVtbjFSb3cwID0gMCwgY29sdW1uMFJvdzEgPSAwLCBjb2x1bW4xUm93MSA9IDApIHtcclxuXHRcdHRoaXNbMF0gPSBjb2x1bW4wUm93MDtcclxuXHRcdHRoaXNbMV0gPSBjb2x1bW4wUm93MTtcclxuXHRcdHRoaXNbMl0gPSBjb2x1bW4xUm93MDtcclxuXHRcdHRoaXNbM10gPSBjb2x1bW4xUm93MTtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBjbG9uZShtYXRyaXg6IE1hdHJpeDIgfCBudW1iZXJbXSwgcmVzdWx0OiBNYXRyaXgyKTogTWF0cml4MiB7XHJcblx0XHRpZiAoIWRlZmluZWQobWF0cml4KSkge1xyXG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCFkZWZpbmVkKHJlc3VsdCkpIHtcclxuXHRcdFx0cmV0dXJuIG5ldyBNYXRyaXgyKG1hdHJpeFswXSwgbWF0cml4WzJdLCBtYXRyaXhbMV0sIG1hdHJpeFszXSk7XHJcblx0XHR9XHJcblx0XHRyZXN1bHRbMF0gPSBtYXRyaXhbMF07XHJcblx0XHRyZXN1bHRbMV0gPSBtYXRyaXhbMV07XHJcblx0XHRyZXN1bHRbMl0gPSBtYXRyaXhbMl07XHJcblx0XHRyZXN1bHRbM10gPSBtYXRyaXhbM107XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGZyb21Db2x1bW5NYWpvckFycmF5KHZhbHVlczogbnVtYmVyW10sIHJlc3VsdDogTWF0cml4Mik6IE1hdHJpeDIge1xyXG5cdFx0cmV0dXJuIE1hdHJpeDIuY2xvbmUodmFsdWVzLCByZXN1bHQpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGZyb21Sb3dNYWpvckFycmF5KHZhbHVlczogbnVtYmVyLCByZXN1bHQ6IE1hdHJpeDIpOiBNYXRyaXgyIHtcclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJldHVybiBuZXcgTWF0cml4Mih2YWx1ZXNbMF0sIHZhbHVlc1sxXSwgdmFsdWVzWzJdLCB2YWx1ZXNbM10pO1xyXG5cdFx0fVxyXG5cdFx0cmVzdWx0WzBdID0gdmFsdWVzWzBdO1xyXG5cdFx0cmVzdWx0WzFdID0gdmFsdWVzWzJdO1xyXG5cdFx0cmVzdWx0WzJdID0gdmFsdWVzWzFdO1xyXG5cdFx0cmVzdWx0WzNdID0gdmFsdWVzWzNdO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBmcm9tU2NhbGUoc2NhbGU6IFZlY3RvcjIsIHJlc3VsdDogTWF0cml4Mik6IE1hdHJpeDIge1xyXG5cdFx0aWYgKCFkZWZpbmVkKHJlc3VsdCkpIHtcclxuXHRcdFx0cmV0dXJuIG5ldyBNYXRyaXgyKHNjYWxlLngsIDAuMCwgMC4wLCBzY2FsZS55KTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXN1bHRbMF0gPSBzY2FsZS54O1xyXG5cdFx0cmVzdWx0WzFdID0gMC4wO1xyXG5cdFx0cmVzdWx0WzJdID0gMC4wO1xyXG5cdFx0cmVzdWx0WzNdID0gc2NhbGUueTtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZnJvbVJvdGF0aW9uKGFuZ2xlOiBudW1iZXIsIHJlc3VsdDogTWF0cml4Mik6IE1hdHJpeDIge1xyXG5cdFx0Y29uc3QgY29zQW5nbGUgPSBNYXRoLmNvcyhhbmdsZSk7XHJcblx0XHRjb25zdCBzaW5BbmdsZSA9IE1hdGguc2luKGFuZ2xlKTtcclxuXHJcblx0XHRpZiAoIWRlZmluZWQocmVzdWx0KSkge1xyXG5cdFx0XHRyZXR1cm4gbmV3IE1hdHJpeDIoY29zQW5nbGUsIC1zaW5BbmdsZSwgc2luQW5nbGUsIGNvc0FuZ2xlKTtcclxuXHRcdH1cclxuXHRcdHJlc3VsdFswXSA9IGNvc0FuZ2xlO1xyXG5cdFx0cmVzdWx0WzFdID0gc2luQW5nbGU7XHJcblx0XHRyZXN1bHRbMl0gPSAtc2luQW5nbGU7XHJcblx0XHRyZXN1bHRbM10gPSBjb3NBbmdsZTtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cdHRvQXJyYXkoKSB7XHJcblx0XHRjb25zdCByZXN1bHQgPSBbXTtcclxuXHRcdE1hdHJpeDIudG9BcnJheSh0aGlzLCByZXN1bHQpO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyB0b0FycmF5KG1hdHJpeDogTWF0cml4MiwgcmVzdWx0OiBudW1iZXJbXSk6IG51bWJlcltdIHtcclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJldHVybiBbbWF0cml4WzBdLCBtYXRyaXhbMV0sIG1hdHJpeFsyXSwgbWF0cml4WzNdXTtcclxuXHRcdH1cclxuXHRcdHJlc3VsdFswXSA9IG1hdHJpeFswXTtcclxuXHRcdHJlc3VsdFsxXSA9IG1hdHJpeFsxXTtcclxuXHRcdHJlc3VsdFsyXSA9IG1hdHJpeFsyXTtcclxuXHRcdHJlc3VsdFszXSA9IG1hdHJpeFszXTtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZ2V0RWxlbWVudEluZGV4KGNvbHVtbjogbnVtYmVyLCByb3c6IG51bWJlcik6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gY29sdW1uICogMiArIHJvdztcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBnZXRDb2x1bW4obWF0cml4OiBNYXRyaXgyLCBpbmRleDogbnVtYmVyLCByZXN1bHQ6IFZlY3RvcjIpOiBWZWN0b3IyIHtcclxuXHRcdGNvbnN0IHN0YXJ0SW5kZXggPSBpbmRleCAqIDI7XHJcblx0XHRjb25zdCB4ID0gbWF0cml4W3N0YXJ0SW5kZXhdO1xyXG5cdFx0Y29uc3QgeSA9IG1hdHJpeFtzdGFydEluZGV4ICsgMV07XHJcblxyXG5cdFx0cmVzdWx0LnggPSB4O1xyXG5cdFx0cmVzdWx0LnkgPSB5O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBzZXRDb2x1bW4obWF0cml4OiBNYXRyaXgyLCBpbmRleDogbnVtYmVyLCBjYXJ0ZXNpYW46IFZlY3RvcjIsIHJlc3VsdDogTWF0cml4Mik6IE1hdHJpeDIge1xyXG5cdFx0cmVzdWx0ID0gTWF0cml4Mi5jbG9uZShtYXRyaXgsIHJlc3VsdCk7XHJcblx0XHRjb25zdCBzdGFydEluZGV4ID0gaW5kZXggKiAyO1xyXG5cdFx0cmVzdWx0W3N0YXJ0SW5kZXhdID0gY2FydGVzaWFuLng7XHJcblx0XHRyZXN1bHRbc3RhcnRJbmRleCArIDFdID0gY2FydGVzaWFuLnk7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGdldFJvdyhtYXRyaXg6IE1hdHJpeDIsIGluZGV4OiBudW1iZXIsIHJlc3VsdDogVmVjdG9yMik6IFZlY3RvcjIge1xyXG5cdFx0Y29uc3QgeCA9IG1hdHJpeFtpbmRleF07XHJcblx0XHRjb25zdCB5ID0gbWF0cml4W2luZGV4ICsgMl07XHJcblxyXG5cdFx0cmVzdWx0LnggPSB4O1xyXG5cdFx0cmVzdWx0LnkgPSB5O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBzZXRSb3cobWF0cml4OiBNYXRyaXgyLCBpbmRleDogbnVtYmVyLCBjYXJ0ZXNpYW46IFZlY3RvcjIsIHJlc3VsdDogTWF0cml4Mik6IE1hdHJpeDIge1xyXG5cdFx0cmVzdWx0ID0gTWF0cml4Mi5jbG9uZShtYXRyaXgsIHJlc3VsdCk7XHJcblx0XHRyZXN1bHRbaW5kZXhdID0gY2FydGVzaWFuLng7XHJcblx0XHRyZXN1bHRbaW5kZXggKyAyXSA9IGNhcnRlc2lhbi55O1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBzZXRTY2FsZShtYXRyaXg6IE1hdHJpeDIsIHNjYWxlOiBWZWN0b3IyLCByZXN1bHQ6IE1hdHJpeDIpOiBNYXRyaXgyIHtcclxuXHRcdGNvbnN0IGV4aXN0aW5nU2NhbGUgPSBNYXRyaXgyLmdldFNjYWxlKG1hdHJpeCwgc2NhbGVTY3JhdGNoMSk7XHJcblx0XHRjb25zdCBzY2FsZVJhdGlvWCA9IHNjYWxlLnggLyBleGlzdGluZ1NjYWxlLng7XHJcblx0XHRjb25zdCBzY2FsZVJhdGlvWSA9IHNjYWxlLnkgLyBleGlzdGluZ1NjYWxlLnk7XHJcblxyXG5cdFx0cmVzdWx0WzBdID0gbWF0cml4WzBdICogc2NhbGVSYXRpb1g7XHJcblx0XHRyZXN1bHRbMV0gPSBtYXRyaXhbMV0gKiBzY2FsZVJhdGlvWDtcclxuXHRcdHJlc3VsdFsyXSA9IG1hdHJpeFsyXSAqIHNjYWxlUmF0aW9ZO1xyXG5cdFx0cmVzdWx0WzNdID0gbWF0cml4WzNdICogc2NhbGVSYXRpb1k7XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBnZXRTY2FsZShtYXRyaXg6IE1hdHJpeDIsIHJlc3VsdDogVmVjdG9yMik6IFZlY3RvcjIge1xyXG5cdFx0cmVzdWx0LnggPSBWZWN0b3IyLm1hZ25pdHVkZShWZWN0b3IyLmZyb21FbGVtZW50cyhtYXRyaXhbMF0sIG1hdHJpeFsxXSwgc2NyYXRjaENvbHVtbikpO1xyXG5cdFx0cmVzdWx0LnkgPSBWZWN0b3IyLm1hZ25pdHVkZShWZWN0b3IyLmZyb21FbGVtZW50cyhtYXRyaXhbMl0sIG1hdHJpeFszXSwgc2NyYXRjaENvbHVtbikpO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBnZXRNYXhpbXVtU2NhbGUobWF0cml4OiBNYXRyaXgyKTogbnVtYmVyIHtcclxuXHRcdE1hdHJpeDIuZ2V0U2NhbGUobWF0cml4LCBzY2FsZVNjcmF0Y2gzKTtcclxuXHRcdHJldHVybiBWZWN0b3IyLm1heGltdW1Db21wb25lbnQoc2NhbGVTY3JhdGNoMyk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgc2V0Um90YXRpb24obWF0cml4OiBNYXRyaXgyLCByb3RhdGlvbjogTWF0cml4MiwgcmVzdWx0OiBNYXRyaXgyKTogTWF0cml4MiB7XHJcblx0XHRjb25zdCBzY2FsZSA9IE1hdHJpeDIuZ2V0U2NhbGUobWF0cml4LCBzY2FsZVNjcmF0Y2g0KTtcclxuXHJcblx0XHRyZXN1bHRbMF0gPSByb3RhdGlvblswXSAqIHNjYWxlLng7XHJcblx0XHRyZXN1bHRbMV0gPSByb3RhdGlvblsxXSAqIHNjYWxlLng7XHJcblx0XHRyZXN1bHRbMl0gPSByb3RhdGlvblsyXSAqIHNjYWxlLnk7XHJcblx0XHRyZXN1bHRbM10gPSByb3RhdGlvblszXSAqIHNjYWxlLnk7XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBnZXRSb3RhdGlvbihtYXRyaXg6IE1hdHJpeDIsIHJlc3VsdDogTWF0cml4Mik6IE1hdHJpeDIge1xyXG5cdFx0Y29uc3Qgc2NhbGUgPSBNYXRyaXgyLmdldFNjYWxlKG1hdHJpeCwgc2NhbGVTY3JhdGNoNSk7XHJcblxyXG5cdFx0cmVzdWx0WzBdID0gbWF0cml4WzBdIC8gc2NhbGUueDtcclxuXHRcdHJlc3VsdFsxXSA9IG1hdHJpeFsxXSAvIHNjYWxlLng7XHJcblx0XHRyZXN1bHRbMl0gPSBtYXRyaXhbMl0gLyBzY2FsZS55O1xyXG5cdFx0cmVzdWx0WzNdID0gbWF0cml4WzNdIC8gc2NhbGUueTtcclxuXHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG11bHRpcGx5KGxlZnQ6IE1hdHJpeDIsIHJpZ2h0OiBNYXRyaXgyLCByZXN1bHQ6IE1hdHJpeDIpOiBNYXRyaXgyIHtcclxuXHRcdGNvbnN0IGNvbHVtbjBSb3cwID0gbGVmdFswXSAqIHJpZ2h0WzBdICsgbGVmdFsyXSAqIHJpZ2h0WzFdO1xyXG5cdFx0Y29uc3QgY29sdW1uMVJvdzAgPSBsZWZ0WzBdICogcmlnaHRbMl0gKyBsZWZ0WzJdICogcmlnaHRbM107XHJcblx0XHRjb25zdCBjb2x1bW4wUm93MSA9IGxlZnRbMV0gKiByaWdodFswXSArIGxlZnRbM10gKiByaWdodFsxXTtcclxuXHRcdGNvbnN0IGNvbHVtbjFSb3cxID0gbGVmdFsxXSAqIHJpZ2h0WzJdICsgbGVmdFszXSAqIHJpZ2h0WzNdO1xyXG5cclxuXHRcdHJlc3VsdFswXSA9IGNvbHVtbjBSb3cwO1xyXG5cdFx0cmVzdWx0WzFdID0gY29sdW1uMFJvdzE7XHJcblx0XHRyZXN1bHRbMl0gPSBjb2x1bW4xUm93MDtcclxuXHRcdHJlc3VsdFszXSA9IGNvbHVtbjFSb3cxO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBhZGQobGVmdDogTWF0cml4MiwgcmlnaHQ6IE1hdHJpeDIsIHJlc3VsdDogTWF0cml4Mikge1xyXG5cdFx0cmVzdWx0WzBdID0gbGVmdFswXSArIHJpZ2h0WzBdO1xyXG5cdFx0cmVzdWx0WzFdID0gbGVmdFsxXSArIHJpZ2h0WzFdO1xyXG5cdFx0cmVzdWx0WzJdID0gbGVmdFsyXSArIHJpZ2h0WzJdO1xyXG5cdFx0cmVzdWx0WzNdID0gbGVmdFszXSArIHJpZ2h0WzNdO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBzdWJ0cmFjdChsZWZ0OiBNYXRyaXgyLCByaWdodDogTWF0cml4MiwgcmVzdWx0OiBNYXRyaXgyKTogTWF0cml4MiB7XHJcblx0XHRyZXN1bHRbMF0gPSBsZWZ0WzBdIC0gcmlnaHRbMF07XHJcblx0XHRyZXN1bHRbMV0gPSBsZWZ0WzFdIC0gcmlnaHRbMV07XHJcblx0XHRyZXN1bHRbMl0gPSBsZWZ0WzJdIC0gcmlnaHRbMl07XHJcblx0XHRyZXN1bHRbM10gPSBsZWZ0WzNdIC0gcmlnaHRbM107XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG11bHRpcGx5QnlWZWN0b3IobWF0cml4OiBNYXRyaXgyLCBjYXJ0ZXNpYW46IFZlY3RvcjIsIHJlc3VsdDogVmVjdG9yMik6IFZlY3RvcjIge1xyXG5cdFx0Y29uc3QgeCA9IG1hdHJpeFswXSAqIGNhcnRlc2lhbi54ICsgbWF0cml4WzJdICogY2FydGVzaWFuLnk7XHJcblx0XHRjb25zdCB5ID0gbWF0cml4WzFdICogY2FydGVzaWFuLnggKyBtYXRyaXhbM10gKiBjYXJ0ZXNpYW4ueTtcclxuXHJcblx0XHRyZXN1bHQueCA9IHg7XHJcblx0XHRyZXN1bHQueSA9IHk7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG11bHRpcGx5QnlTY2FsYXIobWF0cml4OiBNYXRyaXgyLCBzY2FsYXI6IG51bWJlciwgcmVzdWx0OiBNYXRyaXgyKTogTWF0cml4MiB7XHJcblx0XHRyZXN1bHRbMF0gPSBtYXRyaXhbMF0gKiBzY2FsYXI7XHJcblx0XHRyZXN1bHRbMV0gPSBtYXRyaXhbMV0gKiBzY2FsYXI7XHJcblx0XHRyZXN1bHRbMl0gPSBtYXRyaXhbMl0gKiBzY2FsYXI7XHJcblx0XHRyZXN1bHRbM10gPSBtYXRyaXhbM10gKiBzY2FsYXI7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIG11bHRpcGx5QnlTY2FsZShtYXRyaXg6IE1hdHJpeDIsIHNjYWxlOiBWZWN0b3IyLCByZXN1bHQ6IE1hdHJpeDIpOiBNYXRyaXgyIHtcclxuXHRcdHJlc3VsdFswXSA9IG1hdHJpeFswXSAqIHNjYWxlLng7XHJcblx0XHRyZXN1bHRbMV0gPSBtYXRyaXhbMV0gKiBzY2FsZS54O1xyXG5cdFx0cmVzdWx0WzJdID0gbWF0cml4WzJdICogc2NhbGUueTtcclxuXHRcdHJlc3VsdFszXSA9IG1hdHJpeFszXSAqIHNjYWxlLnk7XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBuZWdhdGUobWF0cml4OiBNYXRyaXgyLCByZXN1bHQ6IE1hdHJpeDIpOiBNYXRyaXgyIHtcclxuXHRcdHJlc3VsdFswXSA9IC1tYXRyaXhbMF07XHJcblx0XHRyZXN1bHRbMV0gPSAtbWF0cml4WzFdO1xyXG5cdFx0cmVzdWx0WzJdID0gLW1hdHJpeFsyXTtcclxuXHRcdHJlc3VsdFszXSA9IC1tYXRyaXhbM107XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIHRyYW5zcG9zZShtYXRyaXg6IE1hdHJpeDIsIHJlc3VsdDogTWF0cml4Mik6IE1hdHJpeDIge1xyXG5cdFx0Y29uc3QgY29sdW1uMFJvdzAgPSBtYXRyaXhbMF07XHJcblx0XHRjb25zdCBjb2x1bW4wUm93MSA9IG1hdHJpeFsyXTtcclxuXHRcdGNvbnN0IGNvbHVtbjFSb3cwID0gbWF0cml4WzFdO1xyXG5cdFx0Y29uc3QgY29sdW1uMVJvdzEgPSBtYXRyaXhbM107XHJcblxyXG5cdFx0cmVzdWx0WzBdID0gY29sdW1uMFJvdzA7XHJcblx0XHRyZXN1bHRbMV0gPSBjb2x1bW4wUm93MTtcclxuXHRcdHJlc3VsdFsyXSA9IGNvbHVtbjFSb3cwO1xyXG5cdFx0cmVzdWx0WzNdID0gY29sdW1uMVJvdzE7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGFicyhtYXRyaXg6IE1hdHJpeDIsIHJlc3VsdDogTWF0cml4Mik6IE1hdHJpeDIge1xyXG5cdFx0cmVzdWx0WzBdID0gTWF0aC5hYnMobWF0cml4WzBdKTtcclxuXHRcdHJlc3VsdFsxXSA9IE1hdGguYWJzKG1hdHJpeFsxXSk7XHJcblx0XHRyZXN1bHRbMl0gPSBNYXRoLmFicyhtYXRyaXhbMl0pO1xyXG5cdFx0cmVzdWx0WzNdID0gTWF0aC5hYnMobWF0cml4WzNdKTtcclxuXHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGVxdWFscyhsZWZ0OiBNYXRyaXgyLCByaWdodDogTWF0cml4Mik6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0bGVmdCA9PT0gcmlnaHQgfHxcclxuXHRcdFx0KGRlZmluZWQobGVmdCkgJiZcclxuXHRcdFx0XHRkZWZpbmVkKHJpZ2h0KSAmJlxyXG5cdFx0XHRcdGxlZnRbMF0gPT09IHJpZ2h0WzBdICYmXHJcblx0XHRcdFx0bGVmdFsxXSA9PT0gcmlnaHRbMV0gJiZcclxuXHRcdFx0XHRsZWZ0WzJdID09PSByaWdodFsyXSAmJlxyXG5cdFx0XHRcdGxlZnRbM10gPT09IHJpZ2h0WzNdKVxyXG5cdFx0KTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0c3RhdGljIGVxdWFsc0FycmF5KG1hdHJpeDogTWF0cml4MiwgYXJyYXk6IG51bWJlcltdLCBvZmZzZXQ6IG51bWJlcik6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0bWF0cml4WzBdID09PSBhcnJheVtvZmZzZXRdICYmXHJcblx0XHRcdG1hdHJpeFsxXSA9PT0gYXJyYXlbb2Zmc2V0ICsgMV0gJiZcclxuXHRcdFx0bWF0cml4WzJdID09PSBhcnJheVtvZmZzZXQgKyAyXSAmJlxyXG5cdFx0XHRtYXRyaXhbM10gPT09IGFycmF5W29mZnNldCArIDNdXHJcblx0XHQpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGVxdWFsc0Vwc2lsb24obGVmdDogTWF0cml4MiwgcmlnaHQ6IE1hdHJpeDIsIGVwc2lsb24gPSAwKTogYm9vbGVhbiB7XHJcblx0XHRlcHNpbG9uID0gZGVmYXVsdFZhbHVlKGVwc2lsb24sIDApO1xyXG5cdFx0cmV0dXJuIChcclxuXHRcdFx0bGVmdCA9PT0gcmlnaHQgfHxcclxuXHRcdFx0KGRlZmluZWQobGVmdCkgJiZcclxuXHRcdFx0XHRkZWZpbmVkKHJpZ2h0KSAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbMF0gLSByaWdodFswXSkgPD0gZXBzaWxvbiAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbMV0gLSByaWdodFsxXSkgPD0gZXBzaWxvbiAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbMl0gLSByaWdodFsyXSkgPD0gZXBzaWxvbiAmJlxyXG5cdFx0XHRcdE1hdGguYWJzKGxlZnRbM10gLSByaWdodFszXSkgPD0gZXBzaWxvbilcclxuXHRcdCk7XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgc3RhdGljIElERU5USVRZID0gT2JqZWN0LmZyZWV6ZShuZXcgTWF0cml4MigxLjAsIDAuMCwgMC4wLCAxLjApKTtcclxuXHJcblx0cHVibGljIHN0YXRpYyBaRVJPID0gT2JqZWN0LmZyZWV6ZShuZXcgTWF0cml4MigwLjAsIDAuMCwgMC4wLCAwLjApKTtcclxuXHJcblx0Y2xvbmUocmVzdWx0OiBNYXRyaXgyKTogTWF0cml4MiB7XHJcblx0XHRyZXR1cm4gTWF0cml4Mi5jbG9uZSh0aGlzLCByZXN1bHQpO1xyXG5cdH1cclxuXHJcblx0ZXF1YWxzKHJpZ2h0OiBNYXRyaXgyKTogYm9vbGVhbiB7XHJcblx0XHRyZXR1cm4gTWF0cml4Mi5lcXVhbHModGhpcywgcmlnaHQpO1xyXG5cdH1cclxuXHJcblx0ZXF1YWxzRXBzaWxvbihyaWdodDogTWF0cml4MiwgZXBzaWxvbiA9IDApOiBib29sZWFuIHtcclxuXHRcdHJldHVybiBNYXRyaXgyLmVxdWFsc0Vwc2lsb24odGhpcywgcmlnaHQsIGVwc2lsb24pO1xyXG5cdH1cclxuXHJcblx0dG9TdHJpbmcoKSB7XHJcblx0XHRyZXR1cm4gYCgke3RoaXNbMF19LCAke3RoaXNbMl19KVxcbmAgKyBgKCR7dGhpc1sxXX0sICR7dGhpc1szXX0pYDtcclxuXHR9XHJcbn1cclxuY29uc3Qgc2NhbGVTY3JhdGNoMSA9IG5ldyBWZWN0b3IyKCk7XHJcbmNvbnN0IHNjYWxlU2NyYXRjaDIgPSBuZXcgVmVjdG9yMigpO1xyXG5jb25zdCBzY2FsZVNjcmF0Y2gzID0gbmV3IFZlY3RvcjIoKTtcclxuY29uc3Qgc2NhbGVTY3JhdGNoNCA9IG5ldyBWZWN0b3IyKCk7XHJcbmNvbnN0IHNjcmF0Y2hDb2x1bW4gPSBuZXcgVmVjdG9yMigpO1xyXG5jb25zdCBzY2FsZVNjcmF0Y2g1ID0gbmV3IFZlY3RvcjIoKTtcclxuZXhwb3J0IGRlZmF1bHQgTWF0cml4MjtcclxuIiwiaW1wb3J0IHsgU2hhZGVyU3RhZ2UgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVDb25zdGFudFwiO1xuaW1wb3J0IHsgVW5pZm9ybUZ1bmMsIFVuaWZvcm1FbnVtLCBVbmlmb3JtU3RydWN0IH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcbmltcG9ydCB7IERpcmVjdGlvbmFsTGlnaHQgfSBmcm9tIFwiLi4vbGlnaHQvRGlyZWN0aW9uYWxMaWdodFwiO1xuaW1wb3J0IHsgUG9pbnRMaWdodCB9IGZyb20gXCIuLi9saWdodC9Qb2ludExpZ2h0XCI7XG5pbXBvcnQgeyBTcG90TGlnaHQgfSBmcm9tIFwiLi4vbGlnaHQvU3BvdExpZ2h0XCI7XG5pbXBvcnQgQ29sb3IgZnJvbSBcIi4uL21hdGgvQ29sb3JcIjtcbmltcG9ydCBNYXRyaXgyIGZyb20gXCIuLi9tYXRoL01hdHJpeDJcIjtcbmltcG9ydCBNYXRyaXgzIGZyb20gXCIuLi9tYXRoL01hdHJpeDNcIjtcbmltcG9ydCBNYXRyaXg0IGZyb20gXCIuLi9tYXRoL01hdHJpeDRcIjtcbmltcG9ydCBWZWN0b3IyIGZyb20gXCIuLi9tYXRoL1ZlY3RvcjJcIjtcbmltcG9ydCBWZWN0b3IzIGZyb20gXCIuLi9tYXRoL1ZlY3RvcjNcIjtcbmltcG9ydCBWZWN0b3I0IGZyb20gXCIuLi9tYXRoL1ZlY3RvcjRcIjtcbmltcG9ydCBkZWZhdWx0VmFsdWUgZnJvbSBcIi4uL3V0aWxzL2RlZmF1bHRWYWx1ZVwiO1xuaW1wb3J0IFNhbXBsZXIgZnJvbSBcIi4vU2FtcGxlclwiO1xuaW1wb3J0IFRleHR1cmUgZnJvbSBcIi4vVGV4dHVyZVwiO1xuaW1wb3J0IFVuaWZvcm1CdWZmZXIgZnJvbSBcIi4vVW5pZm9ybUJ1ZmZlclwiO1xuZXhwb3J0IGNsYXNzIFVuaWZvcm08VD4ge1xuXHRfdmFsdWU6IFQ7XG5cdG5hbWU6IHN0cmluZztcblx0dmFsdWU6IFQ7XG5cdG9mZnNldDogbnVtYmVyO1xuXHRidWZmZXI6IEZsb2F0MzJBcnJheSB8IFVpbnQxNkFycmF5IHwgVWludDMyQXJyYXkgfCBVaW50OEFycmF5IHwgRmxvYXQ2NEFycmF5O1xuXHRjYjogVW5pZm9ybUZ1bmMgfCBudW1iZXIgfCBvYmplY3Q7XG5cdGJ5dGVTaXplOiBudW1iZXI7XG5cdHR5cGU/OiBzdHJpbmc7XG5cdGRpcnR5PzogYm9vbGVhbjtcblxuXHRjb25zdHJ1Y3Rvcih1bmlmb3JtTmFtZTogc3RyaW5nLCBjYj86IFVuaWZvcm1GdW5jIHwgbnVtYmVyIHwgb2JqZWN0LCBvZmZzZXQ/OiBudW1iZXIpIHtcblx0XHR0aGlzLm5hbWUgPSB1bmlmb3JtTmFtZTtcblx0XHR0aGlzLmNiID0gY2I7XG5cdFx0dGhpcy5vZmZzZXQgPSBkZWZhdWx0VmFsdWUob2Zmc2V0LCAwKTtcblx0XHR0aGlzLnR5cGUgPSBcIm51bWJlclwiO1xuXHR9XG5cdHNldEJ1ZmZlcihhcnJheTogQXJyYXk8bnVtYmVyPiwgb2Zmc2V0ID0gMCkge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuYnVmZmVyW2kgKyBvZmZzZXRdID0gYXJyYXlbaV07XG5cdFx0fVxuXHR9XG5cdHNldCgpIHtcblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHR9XG5cdGdldFZhbHVlKCkge1xuXHRcdGxldCByZXN1bHQ7XG5cdFx0Y29uc3QgY2JUeXBlID0gdHlwZW9mIHRoaXMuY2I7XG5cdFx0c3dpdGNoIChjYlR5cGUpIHtcblx0XHRcdGNhc2UgXCJvYmplY3RcIjpcblx0XHRcdFx0cmVzdWx0ID0gdGhpcy5jYlt0aGlzLm5hbWVdIHx8IHRoaXMuY2I7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcImZ1bmN0aW9uXCI6XG5cdFx0XHRcdC8vIEB0cy1pZ25vcmVcblx0XHRcdFx0cmVzdWx0ID0gdGhpcy5jYigpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJudW1iZXJcIjpcblx0XHRcdFx0cmVzdWx0ID0gdGhpcy5jYjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJ0eXBlIGlzIGVycm9yXCIpO1xuXHRcdH1cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cdC8vIGNvbXBhcmUgYXJyYXlcblx0ZXF1YWxzKHYpIHtcblx0XHRpZiAoKHRoaXMuX3ZhbHVlIGFzIEFycmF5PG51bWJlcj4pLmxlbmd0aCAhPT0gdi5sZW5ndGgpIHJldHVybiBmYWxzZTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHYubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmICh2W2ldICE9PSB0aGlzLl92YWx1ZVtpXSkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG59XG5cbmV4cG9ydCBjbGFzcyBVbmlmb3JtVWludCBleHRlbmRzIFVuaWZvcm08bnVtYmVyPiB7XG5cdHN0YXRpYyBhbGlnbiA9IDQ7XG5cdGNvbnN0cnVjdG9yKFxuXHRcdHVuaWZvcm1OYW1lOiBzdHJpbmcsXG5cdFx0YnVmZmVyOiBGbG9hdDMyQXJyYXksXG5cdFx0Ynl0ZU9mZnNldDogbnVtYmVyLFxuXHRcdGNiOiBVbmlmb3JtRnVuYyB8IG51bWJlciB8IG9iamVjdCxcblx0XHRvZmZzZXQ/OiBudW1iZXJcblx0KSB7XG5cdFx0c3VwZXIodW5pZm9ybU5hbWUsIGNiLCBvZmZzZXQpO1xuXHRcdHRoaXMudmFsdWUgPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy5fdmFsdWUgPSAwO1xuXHRcdHRoaXMuYnl0ZVNpemUgPSA0O1xuXHRcdHRoaXMuYnVmZmVyID0gbmV3IFVpbnQzMkFycmF5KGJ1ZmZlci5idWZmZXIsIGJ5dGVPZmZzZXQsIDEpO1xuXHRcdHRoaXMudHlwZSA9IFwidWludFwiO1xuXHR9XG5cdHNldCgpIHtcblx0XHRpZiAodGhpcy5jYiAhPSB1bmRlZmluZWQpIHRoaXMudmFsdWUgPSB0aGlzLmdldFZhbHVlKCk7XG5cdFx0aWYgKHRoaXMudmFsdWUgIT09IHRoaXMuX3ZhbHVlKSB7XG5cdFx0XHR0aGlzLl92YWx1ZSA9IHRoaXMudmFsdWU7XG5cdFx0XHR0aGlzLmJ1ZmZlclswXSA9IHRoaXMudmFsdWU7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59XG5cbmV4cG9ydCBjbGFzcyBVbmlmb3JtRmxvYXQgZXh0ZW5kcyBVbmlmb3JtPG51bWJlcj4ge1xuXHRzdGF0aWMgYWxpZ24gPSA0O1xuXHRjb25zdHJ1Y3Rvcihcblx0XHR1bmlmb3JtTmFtZTogc3RyaW5nLFxuXHRcdGJ1ZmZlcjogRmxvYXQzMkFycmF5LFxuXHRcdGJ5dGVPZmZzZXQ6IG51bWJlcixcblx0XHRjYjogVW5pZm9ybUZ1bmMgfCBudW1iZXIgfCBvYmplY3QsXG5cdFx0b2Zmc2V0PzogbnVtYmVyXG5cdCkge1xuXHRcdHN1cGVyKHVuaWZvcm1OYW1lLCBjYiwgb2Zmc2V0KTtcblx0XHR0aGlzLnZhbHVlID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMuX3ZhbHVlID0gMDtcblx0XHR0aGlzLmJ5dGVTaXplID0gNDtcblx0XHR0aGlzLmJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmJ1ZmZlciwgYnl0ZU9mZnNldCwgMSk7XG5cdFx0dGhpcy50eXBlID0gXCJ2ZWMxXCI7XG5cdH1cblx0c2V0KCkge1xuXHRcdGlmICh0aGlzLmNiICE9IHVuZGVmaW5lZCkgdGhpcy52YWx1ZSA9IHRoaXMuZ2V0VmFsdWUoKTtcblx0XHRpZiAodGhpcy52YWx1ZSAhPT0gdGhpcy5fdmFsdWUpIHtcblx0XHRcdHRoaXMuX3ZhbHVlID0gdGhpcy52YWx1ZTtcblx0XHRcdHRoaXMuYnVmZmVyWzBdID0gdGhpcy52YWx1ZTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn1cbmV4cG9ydCBjbGFzcyBVbmlmb3JtRmxvYXRWZWMyIGV4dGVuZHMgVW5pZm9ybTxWZWN0b3IyPiB7XG5cdHN0YXRpYyBhbGlnbiA9IDg7XG5cdGNvbnN0cnVjdG9yKFxuXHRcdHVuaWZvcm1OYW1lOiBzdHJpbmcsXG5cdFx0YnVmZmVyOiBGbG9hdDMyQXJyYXksXG5cdFx0Ynl0ZU9mZnNldDogbnVtYmVyLFxuXHRcdGNiOiBVbmlmb3JtRnVuYyB8IG51bWJlciB8IG9iamVjdCxcblx0XHRvZmZzZXQ/OiBudW1iZXJcblx0KSB7XG5cdFx0c3VwZXIodW5pZm9ybU5hbWUsIGNiLCBvZmZzZXQpO1xuXHRcdHRoaXMudmFsdWUgPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy5fdmFsdWUgPSBuZXcgVmVjdG9yMigpO1xuXHRcdHRoaXMuYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXIuYnVmZmVyLCBieXRlT2Zmc2V0LCAyKTtcblx0XHR0aGlzLmJ5dGVTaXplID0gODtcblx0XHR0aGlzLnR5cGUgPSBcInZlYzJcIjtcblx0fVxuXHRzZXQoKTogYm9vbGVhbiB7XG5cdFx0aWYgKHRoaXMuY2IgIT0gdW5kZWZpbmVkKSB0aGlzLnZhbHVlID0gdGhpcy5nZXRWYWx1ZSgpO1xuXHRcdGNvbnN0IHYgPSB0aGlzLnZhbHVlO1xuXHRcdGlmICh2IGluc3RhbmNlb2YgVmVjdG9yMikge1xuXHRcdFx0aWYgKFZlY3RvcjIuZXF1YWxzKHYsIHRoaXMuX3ZhbHVlKSkgcmV0dXJuIGZhbHNlO1xuXHRcdFx0VmVjdG9yMi5jbG9uZSh2LCB0aGlzLl92YWx1ZSk7XG5cdFx0XHR0aGlzLnNldEJ1ZmZlcih0aGlzLl92YWx1ZS50b0FycmF5KCkpO1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGlmICh0aGlzLmVxdWFscyh2KSkgcmV0dXJuIGZhbHNlO1xuXHRcdFx0dGhpcy5fdmFsdWUgPSB2O1xuXHRcdFx0dGhpcy5zZXRCdWZmZXIodik7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cdH1cbn1cbmV4cG9ydCBjbGFzcyBVbmlmb3JtRmxvYXRWZWMzIGV4dGVuZHMgVW5pZm9ybTxWZWN0b3IzPiB7XG5cdHN0YXRpYyBhbGlnbiA9IDE2O1xuXHRjb25zdHJ1Y3Rvcihcblx0XHR1bmlmb3JtTmFtZTogc3RyaW5nLFxuXHRcdGJ1ZmZlcjogRmxvYXQzMkFycmF5LFxuXHRcdGJ5dGVPZmZzZXQ6IG51bWJlcixcblx0XHRjYjogVW5pZm9ybUZ1bmMgfCBudW1iZXIgfCBvYmplY3QsXG5cdFx0b2Zmc2V0PzogbnVtYmVyXG5cdCkge1xuXHRcdHN1cGVyKHVuaWZvcm1OYW1lLCBjYiwgb2Zmc2V0KTtcblx0XHR0aGlzLnZhbHVlID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMuX3ZhbHVlID0gbmV3IFZlY3RvcjMoKTtcblx0XHR0aGlzLmJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmJ1ZmZlciwgYnl0ZU9mZnNldCwgMyk7XG5cdFx0dGhpcy5ieXRlU2l6ZSA9IDEyO1xuXHRcdHRoaXMudHlwZSA9IFwidmVjM1wiO1xuXHR9XG5cdHNldCgpOiBib29sZWFuIHtcblx0XHRpZiAodGhpcy5jYiAhPSB1bmRlZmluZWQpIHRoaXMudmFsdWUgPSB0aGlzLmdldFZhbHVlKCk7XG5cdFx0Y29uc3QgdiA9IHRoaXMudmFsdWU7XG5cdFx0aWYgKHYgaW5zdGFuY2VvZiBWZWN0b3IzKSB7XG5cdFx0XHRpZiAoVmVjdG9yMy5lcXVhbHModiwgdGhpcy5fdmFsdWUpKSByZXR1cm4gZmFsc2U7XG5cdFx0XHRWZWN0b3IzLmNsb25lKHYsIHRoaXMuX3ZhbHVlKTtcblx0XHRcdHRoaXMuc2V0QnVmZmVyKHRoaXMuX3ZhbHVlLnRvQXJyYXkoKSk7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0aWYgKHRoaXMuZXF1YWxzKHYpKSByZXR1cm4gZmFsc2U7XG5cdFx0XHR0aGlzLl92YWx1ZSA9IHY7XG5cdFx0XHR0aGlzLnNldEJ1ZmZlcih2KTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0fVxufVxuZXhwb3J0IGNsYXNzIFVuaWZvcm1GbG9hdFZlYzQgZXh0ZW5kcyBVbmlmb3JtPFZlY3RvcjQ+IHtcblx0c3RhdGljIGFsaWduID0gMTY7XG5cdGNvbnN0cnVjdG9yKFxuXHRcdHVuaWZvcm1OYW1lOiBzdHJpbmcsXG5cdFx0YnVmZmVyOiBGbG9hdDMyQXJyYXksXG5cdFx0Ynl0ZU9mZnNldDogbnVtYmVyLFxuXHRcdGNiOiBVbmlmb3JtRnVuYyB8IG51bWJlciB8IG9iamVjdCxcblx0XHRvZmZzZXQ/OiBudW1iZXJcblx0KSB7XG5cdFx0c3VwZXIodW5pZm9ybU5hbWUsIGNiLCBvZmZzZXQpO1xuXHRcdHRoaXMudmFsdWUgPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy5fdmFsdWUgPSBuZXcgVmVjdG9yNCgpO1xuXHRcdHRoaXMuYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXIuYnVmZmVyLCBieXRlT2Zmc2V0LCA0KTtcblx0XHR0aGlzLmJ5dGVTaXplID0gMTY7XG5cdFx0dGhpcy50eXBlID0gXCJ2ZWM0XCI7XG5cdH1cblx0c2V0KCk6IGJvb2xlYW4ge1xuXHRcdGlmICh0aGlzLmNiICE9IHVuZGVmaW5lZCkgdGhpcy52YWx1ZSA9IHRoaXMuZ2V0VmFsdWUoKTtcblx0XHRjb25zdCB2ID0gdGhpcy52YWx1ZTtcblx0XHRpZiAodiBpbnN0YW5jZW9mIFZlY3RvcjQpIHtcblx0XHRcdGlmIChWZWN0b3I0LmVxdWFscyh2LCB0aGlzLl92YWx1ZSkpIHJldHVybiBmYWxzZTtcblx0XHRcdFZlY3RvcjQuY2xvbmUodiwgdGhpcy5fdmFsdWUpO1xuXHRcdFx0dGhpcy5zZXRCdWZmZXIodGhpcy5fdmFsdWUudG9BcnJheSgpKTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAodGhpcy5lcXVhbHModikpIHJldHVybiBmYWxzZTtcblx0XHRcdHRoaXMuX3ZhbHVlID0gdjtcblx0XHRcdHRoaXMuc2V0QnVmZmVyKHYpO1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHR9XG59XG5leHBvcnQgY2xhc3MgVW5pZm9ybUNvbG9yIGV4dGVuZHMgVW5pZm9ybTxDb2xvcj4ge1xuXHRzdGF0aWMgYWxpZ24gPSAxNjtcblx0Y29uc3RydWN0b3IoXG5cdFx0dW5pZm9ybU5hbWU6IHN0cmluZyxcblx0XHRidWZmZXI6IEZsb2F0MzJBcnJheSxcblx0XHRieXRlT2Zmc2V0OiBudW1iZXIsXG5cdFx0Y2I6IFVuaWZvcm1GdW5jIHwgbnVtYmVyIHwgb2JqZWN0LFxuXHRcdG9mZnNldD86IG51bWJlclxuXHQpIHtcblx0XHRzdXBlcih1bmlmb3JtTmFtZSwgY2IsIG9mZnNldCk7XG5cdFx0dGhpcy52YWx1ZSA9IHVuZGVmaW5lZDtcblx0XHR0aGlzLl92YWx1ZSA9IG5ldyBDb2xvcigpO1xuXHRcdHRoaXMuYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXIuYnVmZmVyLCBieXRlT2Zmc2V0LCAzKTtcblx0XHR0aGlzLmJ5dGVTaXplID0gMTI7XG5cdFx0dGhpcy50eXBlID0gXCJ2ZWMzXCI7XG5cdH1cblx0c2V0KCk6IGJvb2xlYW4ge1xuXHRcdGlmICh0aGlzLmNiICE9IHVuZGVmaW5lZCkgdGhpcy52YWx1ZSA9IHRoaXMuZ2V0VmFsdWUoKTtcblx0XHRjb25zdCB2ID0gdGhpcy52YWx1ZTtcblx0XHRpZiAodiBpbnN0YW5jZW9mIENvbG9yKSB7XG5cdFx0XHRpZiAoQ29sb3IuZXF1YWxzKHYsIHRoaXMuX3ZhbHVlKSkgcmV0dXJuIGZhbHNlO1xuXHRcdFx0Q29sb3IuY2xvbmUodiwgdGhpcy5fdmFsdWUpO1xuXHRcdFx0dGhpcy5zZXRCdWZmZXIodGhpcy5fdmFsdWUudG9BcnJheSgpKTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAodGhpcy5lcXVhbHModikpIHJldHVybiBmYWxzZTtcblx0XHRcdHRoaXMuX3ZhbHVlID0gdjtcblx0XHRcdHRoaXMuc2V0QnVmZmVyKHYpO1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBjbGFzcyBVbmlmb3JtTWF0MiBleHRlbmRzIFVuaWZvcm08TWF0cml4Mj4ge1xuXHRzdGF0aWMgYWxpZ24gPSA4O1xuXHRjb25zdHJ1Y3Rvcihcblx0XHR1bmlmb3JtTmFtZTogc3RyaW5nLFxuXHRcdGJ1ZmZlcjogRmxvYXQzMkFycmF5LFxuXHRcdGJ5dGVPZmZzZXQ6IG51bWJlcixcblx0XHRjYjogVW5pZm9ybUZ1bmMgfCBudW1iZXIgfCBvYmplY3QsXG5cdFx0b2Zmc2V0PzogbnVtYmVyXG5cdCkge1xuXHRcdHN1cGVyKHVuaWZvcm1OYW1lLCBjYiwgb2Zmc2V0KTtcblx0XHR0aGlzLnZhbHVlID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMuX3ZhbHVlID0gbmV3IE1hdHJpeDIoKTtcblx0XHR0aGlzLmJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmJ1ZmZlciwgYnl0ZU9mZnNldCwgNCk7XG5cdFx0dGhpcy5ieXRlU2l6ZSA9IDE2O1xuXHRcdHRoaXMudHlwZSA9IFwibWF0MlwiO1xuXHR9XG5cdHNldCgpOiBib29sZWFuIHtcblx0XHRpZiAodGhpcy5jYiAhPSB1bmRlZmluZWQpIHRoaXMudmFsdWUgPSB0aGlzLmdldFZhbHVlKCk7XG5cdFx0Y29uc3QgdiA9IHRoaXMudmFsdWU7XG5cdFx0aWYgKHYgaW5zdGFuY2VvZiBNYXRyaXgyKSB7XG5cdFx0XHRpZiAoTWF0cml4Mi5lcXVhbHModiwgdGhpcy5fdmFsdWUpKSByZXR1cm4gZmFsc2U7XG5cdFx0XHRNYXRyaXgyLmNsb25lKHYsIHRoaXMuX3ZhbHVlKTtcblx0XHRcdHRoaXMuc2V0QnVmZmVyKHRoaXMuX3ZhbHVlLnRvQXJyYXkoKSk7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0aWYgKHRoaXMuZXF1YWxzKHYpKSByZXR1cm4gZmFsc2U7XG5cdFx0XHR0aGlzLl92YWx1ZSA9IHY7XG5cdFx0XHR0aGlzLnNldEJ1ZmZlcih2KTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0fVxufVxuZXhwb3J0IGNsYXNzIFVuaWZvcm1NYXQzIGV4dGVuZHMgVW5pZm9ybTxNYXRyaXgzPiB7XG5cdHN0YXRpYyBhbGlnbiA9IDE2O1xuXHRjb25zdHJ1Y3Rvcihcblx0XHR1bmlmb3JtTmFtZTogc3RyaW5nLFxuXHRcdGJ1ZmZlcjogRmxvYXQzMkFycmF5LFxuXHRcdGJ5dGVPZmZzZXQ6IG51bWJlcixcblx0XHRjYjogVW5pZm9ybUZ1bmMgfCBudW1iZXIgfCBvYmplY3QsXG5cdFx0b2Zmc2V0PzogbnVtYmVyXG5cdCkge1xuXHRcdHN1cGVyKHVuaWZvcm1OYW1lLCBjYiwgb2Zmc2V0KTtcblx0XHR0aGlzLnZhbHVlID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMuX3ZhbHVlID0gbmV3IE1hdHJpeDMoKTtcblx0XHR0aGlzLmJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmJ1ZmZlciwgYnl0ZU9mZnNldCwgOSk7XG5cdFx0dGhpcy5ieXRlU2l6ZSA9IDQ4O1xuXHRcdHRoaXMudHlwZSA9IFwibWF0M1wiO1xuXHR9XG5cdHNldCgpOiBib29sZWFuIHtcblx0XHRpZiAodGhpcy5jYiAhPSB1bmRlZmluZWQpIHRoaXMudmFsdWUgPSB0aGlzLmdldFZhbHVlKCk7XG5cdFx0Y29uc3QgdiA9IHRoaXMudmFsdWU7XG5cdFx0aWYgKHYgaW5zdGFuY2VvZiBNYXRyaXgzKSB7XG5cdFx0XHRpZiAoTWF0cml4My5lcXVhbHModiwgdGhpcy5fdmFsdWUpKSByZXR1cm4gZmFsc2U7XG5cdFx0XHRNYXRyaXgzLmNsb25lKHYsIHRoaXMuX3ZhbHVlKTtcblx0XHRcdHRoaXMuc2V0QnVmZmVyKHRoaXMuX3ZhbHVlLnRvQXJyYXkoKSk7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0aWYgKHRoaXMuZXF1YWxzKHYpKSByZXR1cm4gZmFsc2U7XG5cdFx0XHR0aGlzLl92YWx1ZSA9IHY7XG5cdFx0XHR0aGlzLnNldEJ1ZmZlcih2KTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0fVxufVxuZXhwb3J0IGNsYXNzIFVuaWZvcm1NYXQ0IGV4dGVuZHMgVW5pZm9ybTxNYXRyaXg0PiB7XG5cdHN0YXRpYyBhbGlnbiA9IDE2O1xuXHRjb25zdHJ1Y3Rvcihcblx0XHR1bmlmb3JtTmFtZTogc3RyaW5nLFxuXHRcdGJ1ZmZlcjogRmxvYXQzMkFycmF5LFxuXHRcdGJ5dGVPZmZzZXQ6IG51bWJlcixcblx0XHRjYjogVW5pZm9ybUZ1bmMgfCBudW1iZXIgfCBvYmplY3QsXG5cdFx0b2Zmc2V0PzogbnVtYmVyXG5cdCkge1xuXHRcdHN1cGVyKHVuaWZvcm1OYW1lLCBjYiwgb2Zmc2V0KTtcblx0XHR0aGlzLnZhbHVlID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMuX3ZhbHVlID0gbmV3IE1hdHJpeDQoKTtcblx0XHR0aGlzLmJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmJ1ZmZlciwgYnl0ZU9mZnNldCwgMTYpO1xuXHRcdHRoaXMuYnl0ZVNpemUgPSA2NDtcblx0XHR0aGlzLnR5cGUgPSBcIm1hdDRcIjtcblx0fVxuXHRzZXQoKTogYm9vbGVhbiB7XG5cdFx0aWYgKHRoaXMuY2IgIT0gdW5kZWZpbmVkKSB0aGlzLnZhbHVlID0gdGhpcy5nZXRWYWx1ZSgpO1xuXHRcdGNvbnN0IHYgPSB0aGlzLnZhbHVlO1xuXHRcdGlmICh2IGluc3RhbmNlb2YgTWF0cml4NCkge1xuXHRcdFx0aWYgKE1hdHJpeDQuZXF1YWxzKHYsIHRoaXMuX3ZhbHVlKSkgcmV0dXJuIGZhbHNlO1xuXHRcdFx0TWF0cml4NC5jbG9uZSh2LCB0aGlzLl92YWx1ZSk7XG5cdFx0XHR0aGlzLnNldEJ1ZmZlcih0aGlzLl92YWx1ZS50b0FycmF5KCkpO1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIGlmKHRoaXMuZXF1YWxzKHYpKSByZXR1cm4gZmFsc2U7XG5cdFx0XHR0aGlzLl92YWx1ZSA9IHY7XG5cdFx0XHR0aGlzLnNldEJ1ZmZlcih2KTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0fVxufVxuZXhwb3J0IGNsYXNzIFVuaWZvcm1NYXRyaXg0QXJyYXkgZXh0ZW5kcyBVbmlmb3JtPEFycmF5PE1hdHJpeDQ+PiB7XG5cdHN0YXRpYyBhbGlnbiA9IDE2O1xuXHRjb25zdHJ1Y3Rvcihcblx0XHR1bmlmb3JtTmFtZTogc3RyaW5nLFxuXHRcdGJ1ZmZlcjogRmxvYXQzMkFycmF5LFxuXHRcdGJ5dGVPZmZzZXQ6IG51bWJlcixcblx0XHRjYjogVW5pZm9ybUZ1bmMgfCBudW1iZXIgfCBvYmplY3QsXG5cdFx0Y291bnQ/OiBudW1iZXJcblx0KSB7XG5cdFx0c3VwZXIodW5pZm9ybU5hbWUsIGNiLCAwKTtcblx0XHR0aGlzLmJ5dGVTaXplID0gY291bnQgKiA2NDtcblx0XHR0aGlzLmJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmJ1ZmZlciwgYnl0ZU9mZnNldCwgdGhpcy5ieXRlU2l6ZSAvIDQpO1xuXHRcdHRoaXMudHlwZSA9IFwibWF0NC1hcnJheVwiO1xuXHR9XG5cdHNldCgpOiBib29sZWFuIHtcblx0XHR0aGlzLnZhbHVlID0gdGhpcy5nZXRWYWx1ZSgpO1xuXHRcdGlmICghdGhpcy52YWx1ZSkgcmV0dXJuIGZhbHNlO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52YWx1ZS5sZW5ndGg7IGkrKykge1xuXHRcdFx0dGhpcy5zZXRCdWZmZXIodGhpcy52YWx1ZVtpXS50b0FycmF5KCksIGkgKiAxNik7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG59XG5leHBvcnQgY2xhc3MgVW5pZm9ybUZsb2F0QXJyYXkgZXh0ZW5kcyBVbmlmb3JtPEFycmF5PG51bWJlcj4+IHtcblx0c3RhdGljIGFsaWduID0gNDtcblx0Ly8gY2I6IEZ1bmN0aW9uO1xuXHRjb25zdHJ1Y3Rvcihcblx0XHR1bmlmb3JtTmFtZTogc3RyaW5nLFxuXHRcdGJ1ZmZlcjogRmxvYXQzMkFycmF5LFxuXHRcdGJ5dGVPZmZzZXQ6IG51bWJlcixcblx0XHRjYjogVW5pZm9ybUZ1bmMgfCBudW1iZXIgfCBvYmplY3QsXG5cdFx0Y291bnQ/OiBudW1iZXJcblx0KSB7XG5cdFx0c3VwZXIodW5pZm9ybU5hbWUsIGNiLCAwKTtcblx0XHR0aGlzLmJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmJ1ZmZlciwgYnl0ZU9mZnNldCwgY291bnQpO1xuXHRcdHRoaXMuYnl0ZVNpemUgPSA0ICogY291bnQ7XG5cdFx0dGhpcy50eXBlID0gXCJmbG9hdC1hcnJheVwiO1xuXHR9XG5cdHNldCgpOiBib29sZWFuIHtcblx0XHR0aGlzLnZhbHVlID0gdGhpcy5nZXRWYWx1ZSgpO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52YWx1ZS5sZW5ndGg7IGkrKykge1xuXHRcdFx0dGhpcy5idWZmZXJbaV0gPSB0aGlzLnZhbHVlW2ldO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxufVxuZXhwb3J0IGNsYXNzIFVuaWZvcm1WZWMyQXJyYXkgZXh0ZW5kcyBVbmlmb3JtPEFycmF5PFZlY3RvcjI+PiB7XG5cdHN0YXRpYyBhbGlnbiA9IDg7XG5cdGNvbnN0cnVjdG9yKFxuXHRcdHVuaWZvcm1OYW1lOiBzdHJpbmcsXG5cdFx0YnVmZmVyOiBGbG9hdDMyQXJyYXksXG5cdFx0Ynl0ZU9mZnNldDogbnVtYmVyLFxuXHRcdGNiOiBVbmlmb3JtRnVuYyB8IG51bWJlciB8IG9iamVjdCxcblx0XHRjb3VudD86IG51bWJlclxuXHQpIHtcblx0XHRzdXBlcih1bmlmb3JtTmFtZSwgY2IsIDApO1xuXHRcdHRoaXMuYnl0ZVNpemUgPSBjb3VudCAqIDg7XG5cdFx0dGhpcy5idWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlci5idWZmZXIsIGJ5dGVPZmZzZXQsIHRoaXMuYnl0ZVNpemUgLyA0KTtcblx0XHR0aGlzLnR5cGUgPSBcInZlYzItYXJyYXlcIjtcblx0fVxuXHRzZXQoKTogYm9vbGVhbiB7XG5cdFx0Ly8gdGhpcy52YWx1ZSA9IHRoaXMuY2IoKTtcblx0XHR0aGlzLnZhbHVlID0gdGhpcy5nZXRWYWx1ZSgpO1xuXHRcdGxldCBqID0gMDtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmFsdWUubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuYnVmZmVyW2pdID0gdGhpcy52YWx1ZVtpXS54O1xuXHRcdFx0dGhpcy5idWZmZXJbaiArIDFdID0gdGhpcy52YWx1ZVtpXS55O1xuXHRcdFx0aiArPSAyO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxufVxuZXhwb3J0IGNsYXNzIFVuaWZvcm1WZWMzQXJyYXkgZXh0ZW5kcyBVbmlmb3JtPEFycmF5PFZlY3RvcjM+PiB7XG5cdHN0YXRpYyBhbGlnbiA9IDE2O1xuXHQvLyBjYjogRnVuY3Rpb247XG5cdGNvbnN0cnVjdG9yKFxuXHRcdHVuaWZvcm1OYW1lOiBzdHJpbmcsXG5cdFx0YnVmZmVyOiBGbG9hdDMyQXJyYXksXG5cdFx0Ynl0ZU9mZnNldDogbnVtYmVyLFxuXHRcdGNiOiBVbmlmb3JtRnVuYyB8IG51bWJlciB8IG9iamVjdCxcblx0XHRjb3VudD86IG51bWJlclxuXHQpIHtcblx0XHRzdXBlcih1bmlmb3JtTmFtZSwgY2IsIDApO1xuXHRcdHRoaXMuYnl0ZVNpemUgPSBjb3VudCAqIDE2O1xuXHRcdHRoaXMuYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXIuYnVmZmVyLCBieXRlT2Zmc2V0LCB0aGlzLmJ5dGVTaXplIC8gNCk7XG5cdFx0dGhpcy50eXBlID0gXCJ2ZWMzLWFycmF5XCI7XG5cdH1cblx0c2V0KCk6IGJvb2xlYW4ge1xuXHRcdC8vIHRoaXMudmFsdWUgPSB0aGlzLmNiKCk7XG5cdFx0dGhpcy52YWx1ZSA9IHRoaXMuZ2V0VmFsdWUoKTtcblx0XHRsZXQgaiA9IDA7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnZhbHVlLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR0aGlzLmJ1ZmZlcltqXSA9IHRoaXMudmFsdWVbaV0ueDtcblx0XHRcdHRoaXMuYnVmZmVyW2ogKyAxXSA9IHRoaXMudmFsdWVbaV0ueTtcblx0XHRcdHRoaXMuYnVmZmVyW2ogKyAyXSA9IHRoaXMudmFsdWVbaV0uejtcblx0XHRcdHRoaXMuYnVmZmVyW2ogKyAzXSA9IDA7XG5cdFx0XHRqICs9IDQ7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG59XG5leHBvcnQgY2xhc3MgVW5pZm9ybVZlYzRBcnJheSBleHRlbmRzIFVuaWZvcm08QXJyYXk8VmVjdG9yND4+IHtcblx0c3RhdGljIGFsaWduID0gMTY7XG5cdC8vIGNiOiBGdW5jdGlvbjtcblx0Y29uc3RydWN0b3IoXG5cdFx0dW5pZm9ybU5hbWU6IHN0cmluZyxcblx0XHRidWZmZXI6IEZsb2F0MzJBcnJheSxcblx0XHRieXRlT2Zmc2V0OiBudW1iZXIsXG5cdFx0Y2I6IFVuaWZvcm1GdW5jIHwgbnVtYmVyIHwgb2JqZWN0LFxuXHRcdGNvdW50PzogbnVtYmVyXG5cdCkge1xuXHRcdHN1cGVyKHVuaWZvcm1OYW1lLCBjYiwgMCk7XG5cdFx0dGhpcy5ieXRlU2l6ZSA9IGNvdW50ICogMTY7XG5cdFx0dGhpcy5idWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlci5idWZmZXIsIGJ5dGVPZmZzZXQsIHRoaXMuYnl0ZVNpemUgLyA0KTtcblx0XHR0aGlzLnR5cGUgPSBcInZlYzQtYXJyYXlcIjtcblx0fVxuXHRzZXQoKTogYm9vbGVhbiB7XG5cdFx0dGhpcy52YWx1ZSA9IHRoaXMuZ2V0VmFsdWUoKTtcblx0XHRsZXQgaiA9IDA7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnZhbHVlLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR0aGlzLmJ1ZmZlcltqXSA9IHRoaXMudmFsdWVbaV0ueDtcblx0XHRcdHRoaXMuYnVmZmVyW2ogKyAxXSA9IHRoaXMudmFsdWVbaV0ueTtcblx0XHRcdHRoaXMuYnVmZmVyW2ogKyAyXSA9IHRoaXMudmFsdWVbaV0uejtcblx0XHRcdHRoaXMuYnVmZmVyW2ogKyAzXSA9IHRoaXMudmFsdWVbaV0udztcblx0XHRcdGogKz0gNDtcblx0XHR9XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cbn1cbmV4cG9ydCBjbGFzcyBVbmlmb3JtVGV4dHVyZSBleHRlbmRzIFVuaWZvcm08VGV4dHVyZT4ge1xuXHRwdWJsaWMgYmluZGluZzogbnVtYmVyO1xuXHRwdWJsaWMgdHlwZTogc3RyaW5nO1xuXHRwdWJsaWMgdmlzaWJpbGl0eTogU2hhZGVyU3RhZ2U7XG5cdHB1YmxpYyBuYW1lOiBzdHJpbmc7XG5cdHB1YmxpYyB0ZXh0dXJlOiBUZXh0dXJlO1xuXHRwdWJsaWMgaXNUZXh0dXJlOiBib29sZWFuO1xuXHRwdWJsaWMgdGV4dHVyZVZpZXc/OiBHUFVUZXh0dXJlVmlldztcblx0cHJpdmF0ZSBfdGV4dHVyZTogVW5pZm9ybUZ1bmMgfCBUZXh0dXJlO1xuXHRjb25zdHJ1Y3Rvcihcblx0XHR1bmlmb3JtTmFtZTogc3RyaW5nLFxuXHRcdGJpbmRpbmc6IG51bWJlcixcblx0XHR0ZXh0dXJlOiBVbmlmb3JtRnVuYyB8IFRleHR1cmUsXG5cdFx0dHlwZT86IHN0cmluZyxcblx0XHR2aXNpYmlsaXR5PzogU2hhZGVyU3RhZ2UsXG5cdFx0dGV4dHVyZVZpZXc/OiBHUFVUZXh0dXJlVmlld1xuXHQpIHtcblx0XHRzdXBlcih1bmlmb3JtTmFtZSwgdW5kZWZpbmVkLCAwKTtcblx0XHR0aGlzLmJpbmRpbmcgPSBiaW5kaW5nO1xuXHRcdHRoaXMudmlzaWJpbGl0eSA9IGRlZmF1bHRWYWx1ZSh2aXNpYmlsaXR5LCBTaGFkZXJTdGFnZS5WZXJ0ZXggfCBTaGFkZXJTdGFnZS5GcmFnbWVudCk7XG5cdFx0dGhpcy50ZXh0dXJlVmlldyA9IHRleHR1cmVWaWV3O1xuXHRcdHRoaXMudHlwZSA9IHR5cGUgPz8gXCJ0ZXh0dXJlXCI7XG5cdFx0dGhpcy5pc1RleHR1cmUgPSB0cnVlO1xuXHRcdHRoaXMuX3RleHR1cmUgPSB0ZXh0dXJlO1xuXHR9XG5cdGdldCBsYXlvdXRUeXBlKCkge1xuXHRcdHJldHVybiB0aGlzLnRleHR1cmU/LmxheW91dFR5cGUgfHwgXCJub3QgeWV0IGJpbmRcIjtcblx0fVxuXHRnZXQgc3RvcmFnZVRleHR1cmVMYXlvdXRUeXBlKCkge1xuXHRcdHJldHVybiB0aGlzLnRleHR1cmU/LnN0b3JhZ2VUZXh0dXJlTGF5b3V0VHlwZSB8fCBcIm5vdCB5ZXQgYmluZFwiO1xuXHR9XG5cdGJpbmQoZGV2aWNlOiBHUFVEZXZpY2UpIHtcblx0XHRpZiAoIXRoaXMuX3RleHR1cmUpIHJldHVybjtcblx0XHR0aGlzLnRleHR1cmUgPSB0aGlzLl90ZXh0dXJlIGluc3RhbmNlb2YgRnVuY3Rpb24gPyB0aGlzLl90ZXh0dXJlKCkgOiB0aGlzLl90ZXh0dXJlO1xuXHRcdHRoaXMudGV4dHVyZS51cGRhdGUoZGV2aWNlKTtcblx0fVxufVxuZXhwb3J0IGNsYXNzIFVuaWZvcm1TYW1wbGVyIGV4dGVuZHMgVW5pZm9ybTxTYW1wbGVyPiB7XG5cdHB1YmxpYyBiaW5kaW5nOiBudW1iZXI7XG5cdHB1YmxpYyB0eXBlOiBzdHJpbmc7XG5cdHB1YmxpYyB2aXNpYmlsaXR5OiBTaGFkZXJTdGFnZTtcblx0cHVibGljIG5hbWU6IHN0cmluZztcblx0cHVibGljIHNhbXBsZXI6IFNhbXBsZXI7XG5cdHB1YmxpYyBpc1NhbXBsZXI6IGJvb2xlYW47XG5cdHByaXZhdGUgX3NhbXBsZXI6IFVuaWZvcm1GdW5jIHwgU2FtcGxlcjtcblx0Y29uc3RydWN0b3IodW5pZm9ybU5hbWU6IHN0cmluZywgYmluZGluZzogbnVtYmVyLCBzYW1wbGVyOiBVbmlmb3JtRnVuYyB8IFNhbXBsZXIsIHZpc2liaWxpdHk/OiBTaGFkZXJTdGFnZSkge1xuXHRcdHN1cGVyKHVuaWZvcm1OYW1lLCB1bmRlZmluZWQsIDApO1xuXHRcdHRoaXMudmlzaWJpbGl0eSA9IGRlZmF1bHRWYWx1ZSh2aXNpYmlsaXR5LCBTaGFkZXJTdGFnZS5WZXJ0ZXggfCBTaGFkZXJTdGFnZS5GcmFnbWVudCk7XG5cdFx0dGhpcy5uYW1lID0gdW5pZm9ybU5hbWU7XG5cdFx0dGhpcy5iaW5kaW5nID0gYmluZGluZztcblx0XHR0aGlzLnR5cGUgPSBcInNhbXBsZXJcIjtcblx0XHR0aGlzLmlzU2FtcGxlciA9IHRydWU7XG5cdFx0dGhpcy5fc2FtcGxlciA9IHNhbXBsZXI7XG5cdH1cblx0Z2V0IGxheW91dFR5cGUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuc2FtcGxlcj8ubGF5b3V0VHlwZSB8fCBcIm5vdCB5ZXQgYmluZFwiO1xuXHR9XG5cdGJpbmQoZGV2aWNlOiBHUFVEZXZpY2UpIHtcblx0XHR0aGlzLnNhbXBsZXIgPSB0aGlzLl9zYW1wbGVyIGluc3RhbmNlb2YgRnVuY3Rpb24gPyB0aGlzLl9zYW1wbGVyKCkgOiB0aGlzLl9zYW1wbGVyO1xuXHRcdHRoaXMuc2FtcGxlci51cGRhdGUoZGV2aWNlKTtcblx0fVxufVxuZXhwb3J0IGNsYXNzIFVuaWZvcm1TdHJ1Y3RBcnJheSBleHRlbmRzIFVuaWZvcm08VW5pZm9ybVN0cnVjdD4ge1xuXHRzdGF0aWMgYWxpZ24gPSAxNjtcblx0c3RhdGljIGFsaWducyA9IHtcblx0XHRbVW5pZm9ybUVudW0uVW5pZm9ybVVpbnRdOiA0LFxuXHRcdFtVbmlmb3JtRW51bS5GbG9hdF06IDQsXG5cdFx0W1VuaWZvcm1FbnVtLkZsb2F0VmVjMl06IDgsXG5cdFx0W1VuaWZvcm1FbnVtLkZsb2F0VmVjM106IDE2LFxuXHRcdFtVbmlmb3JtRW51bS5GbG9hdFZlYzRdOiAxNixcblx0XHRbVW5pZm9ybUVudW0uTWF0Ml06IDgsXG5cdFx0W1VuaWZvcm1FbnVtLk1hdDNdOiAxNixcblx0XHRbVW5pZm9ybUVudW0uTWF0NF06IDE2LFxuXHRcdFtVbmlmb3JtRW51bS5Db2xvcl06IDE2XG5cdH07XG5cdHN0YXRpYyBieXRlU2l6ZXMgPSB7XG5cdFx0W1VuaWZvcm1FbnVtLlVuaWZvcm1VaW50XTogNCxcblx0XHRbVW5pZm9ybUVudW0uRmxvYXRdOiA0LFxuXHRcdFtVbmlmb3JtRW51bS5GbG9hdFZlYzJdOiA4LFxuXHRcdFtVbmlmb3JtRW51bS5GbG9hdFZlYzNdOiAxMixcblx0XHRbVW5pZm9ybUVudW0uRmxvYXRWZWM0XTogMTYsXG5cdFx0W1VuaWZvcm1FbnVtLk1hdDJdOiAxNixcblx0XHRbVW5pZm9ybUVudW0uTWF0M106IDQ4LFxuXHRcdFtVbmlmb3JtRW51bS5NYXQ0XTogNjQsXG5cdFx0W1VuaWZvcm1FbnVtLkNvbG9yXTogMTJcblx0fTtcblx0Ynl0ZU9mZnNldD86IG51bWJlcjtcblx0c291cmNlQnVmZmVyPzogRmxvYXQzMkFycmF5O1xuXHRzdHJ1Y3RBcnJheT86IEFycmF5PFVuaWZvcm1TdHJ1Y3Q+O1xuXHRjb25zdHJ1Y3Rvcihcblx0XHR1bmlmb3JtTmFtZTogc3RyaW5nLFxuXHRcdGJ1ZmZlcjogRmxvYXQzMkFycmF5LFxuXHRcdGJ5dGVPZmZzZXQ6IG51bWJlcixcblx0XHRjYjogVW5pZm9ybUZ1bmMgfCBudW1iZXIgfCBvYmplY3QsXG5cdFx0b2Zmc2V0PzogbnVtYmVyXG5cdCkge1xuXHRcdHN1cGVyKHVuaWZvcm1OYW1lLCBjYiwgb2Zmc2V0KTtcblx0XHR0aGlzLmNiID0gY2I7XG5cdFx0dGhpcy50eXBlID0gXCJzdHJ1Y3QtYXJyYXlcIjtcblx0XHR0aGlzLmRpcnR5ID0gZmFsc2U7XG5cdFx0dGhpcy5ieXRlT2Zmc2V0ID0gYnl0ZU9mZnNldDtcblx0XHR0aGlzLnNvdXJjZUJ1ZmZlciA9IGJ1ZmZlcjtcblx0fVxuXHRzZXQoKSB7XG5cdFx0Ly9cblx0XHR0aGlzLnN0cnVjdEFycmF5ID0gdGhpcy5nZXRWYWx1ZSgpO1xuXHRcdHRoaXMuYnl0ZVNpemUgPSB0aGlzLmdldFN0cnVjdFNpemUoKTtcblx0XHR0aGlzLmJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5zb3VyY2VCdWZmZXIuYnVmZmVyLCB0aGlzLmJ5dGVPZmZzZXQsIHRoaXMuYnl0ZVNpemUgLyA0KTtcblx0XHR0aGlzLnNldFN1YkRhdGEoKTtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXHRwcml2YXRlIHNldFN1YkRhdGEoKSB7XG5cdFx0dGhpcy5zdHJ1Y3RBcnJheS5mb3JFYWNoKChzdHJ1Y3QpID0+IHtcblx0XHRcdGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhzdHJ1Y3QpO1xuXHRcdFx0a2V5cy5mb3JFYWNoKChrZXkpID0+IHtcblx0XHRcdFx0Y29uc3QgZGF0YSA9IEFycmF5LmlzQXJyYXkoc3RydWN0W2tleV0/LnZhbHVlKVxuXHRcdFx0XHRcdD8gc3RydWN0W2tleV0/LnZhbHVlXG5cdFx0XHRcdFx0OiAoc3RydWN0W2tleV0/LnZhbHVlIGFzIGFueSkudG9BcnJheSgpO1xuXHRcdFx0XHRzZXREYXRhVG9UeXBlQXJyYXkodGhpcy5idWZmZXIsIGRhdGEsIHN0cnVjdFtrZXldLm9mZnNldCk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXHRwcml2YXRlIGdldFN0cnVjdFNpemUoKSB7XG5cdFx0bGV0IGJ5dGVPZmZzZXQgPSAwO1xuXHRcdHRoaXMuc3RydWN0QXJyYXkuZm9yRWFjaCgoc3RydWN0KSA9PiB7XG5cdFx0XHRjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoc3RydWN0KTtcblx0XHRcdGtleXMuZm9yRWFjaCgoa2V5KSA9PiB7XG5cdFx0XHRcdGJ5dGVPZmZzZXQgKz0gVW5pZm9ybUJ1ZmZlci5jaGVja1VuaWZvcm1PZmZzZXQoYnl0ZU9mZnNldCwgVW5pZm9ybVN0cnVjdEFycmF5LmFsaWduc1tzdHJ1Y3Rba2V5XS50eXBlXSk7XG5cdFx0XHRcdHN0cnVjdFtrZXldLm9mZnNldCA9IGJ5dGVPZmZzZXQ7XG5cdFx0XHRcdHRoaXMuYnl0ZU9mZnNldCArPSBVbmlmb3JtU3RydWN0QXJyYXkuYnl0ZVNpemVzW3N0cnVjdFtrZXldLnR5cGVdO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIGJ5dGVPZmZzZXQ7XG5cdH1cbn1cbmV4cG9ydCBjbGFzcyBVbmlmb3JtU3BvdExpZ2h0cyBleHRlbmRzIFVuaWZvcm08U3BvdExpZ2h0PiB7XG5cdHN0YXRpYyBhbGlnbiA9IDE2O1xuXHRsaWdodHM6IEFycmF5PFNwb3RMaWdodD47XG5cdC8vIGNiOiBGdW5jdGlvbjtcblx0Y29uc3RydWN0b3IoXG5cdFx0dW5pZm9ybU5hbWU6IHN0cmluZyxcblx0XHRidWZmZXI6IEZsb2F0MzJBcnJheSxcblx0XHRieXRlT2Zmc2V0OiBudW1iZXIsXG5cdFx0Y2I6IFVuaWZvcm1GdW5jIHwgbnVtYmVyIHwgb2JqZWN0LFxuXHRcdGNvdW50PzogbnVtYmVyXG5cdCkge1xuXHRcdHN1cGVyKHVuaWZvcm1OYW1lLCBjYiwgMCk7XG5cdFx0dGhpcy5jYiA9IGNiO1xuXHRcdHRoaXMuYnl0ZVNpemUgPSBjb3VudCAqIDY0O1xuXHRcdHRoaXMuYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXIuYnVmZmVyLCBieXRlT2Zmc2V0LCB0aGlzLmJ5dGVTaXplIC8gNCk7XG5cdFx0dGhpcy50eXBlID0gXCJzcG90c0xpZ2h0XCI7XG5cdFx0dGhpcy5kaXJ0eSA9IGZhbHNlO1xuXHR9XG5cdHNldCgpIHtcblx0XHR0aGlzLmxpZ2h0cyA9IHRoaXMuZ2V0VmFsdWUoKTtcblx0XHR0aGlzLmxpZ2h0cy5mb3JFYWNoKChzcG90TGlnaHQsIGluZGV4KSA9PiB7XG5cdFx0XHR0aGlzLnNldFN1YkRhdGEoc3BvdExpZ2h0LCBpbmRleCk7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIHRoaXMuZGlydHk7XG5cdH1cblx0cHJpdmF0ZSBzZXRTdWJEYXRhKHNwb3RMaWdodDogU3BvdExpZ2h0LCBpbmRleDogbnVtYmVyKSB7XG5cdFx0Y29uc3Qgb2Zmc2V0ID0gaW5kZXggKiAxNjtcblx0XHRpZiAoc3BvdExpZ2h0LnBvc2l0aW9uRGlydHkpIHtcblx0XHRcdHRoaXMuZGlydHkgPSBzZXREYXRhVG9UeXBlQXJyYXkodGhpcy5idWZmZXIsIHNwb3RMaWdodC5wb3NpdGlvbi50b0FycmF5KCksIG9mZnNldCArIDApOyAvLyBieXRlT2Zmc2V0PTA7XG5cdFx0fVxuXHRcdGlmIChzcG90TGlnaHQuZGlzdGFuY2VEaXJ0eSkge1xuXHRcdFx0dGhpcy5kaXJ0eSA9IHNldERhdGFUb1R5cGVBcnJheSh0aGlzLmJ1ZmZlciwgc3BvdExpZ2h0LmRpc3RhbmNlLCBvZmZzZXQgKyAzKTsgLy8gYnl0ZU9mZnNldD0xMjtcblx0XHR9XG5cdFx0aWYgKHNwb3RMaWdodC5kaXJ0ZWN0RGlydHkpIHtcblx0XHRcdHRoaXMuZGlydHkgPSBzZXREYXRhVG9UeXBlQXJyYXkodGhpcy5idWZmZXIsIHNwb3RMaWdodC5kaXJlY3Rpb25hbC50b0FycmF5KCksIG9mZnNldCArIDQpOyAvLyBieXRlT2Zmc2V0PTE2O1xuXHRcdH1cblx0XHRpZiAoc3BvdExpZ2h0LmNvbmVDb3NEaXJ0eSkge1xuXHRcdFx0dGhpcy5kaXJ0eSA9IHNldERhdGFUb1R5cGVBcnJheSh0aGlzLmJ1ZmZlciwgc3BvdExpZ2h0LmNvbmVDb3MsIG9mZnNldCArIDcpOyAvLyBieXRlT2Zmc2V0PTI4O1xuXHRcdH1cblx0XHRpZiAoc3BvdExpZ2h0LmNvbG9yRGlydHkpIHtcblx0XHRcdHRoaXMuZGlydHkgPSBzZXREYXRhVG9UeXBlQXJyYXkodGhpcy5idWZmZXIsIHNwb3RMaWdodC5jb2xvci50b0FycmF5KCksIG9mZnNldCArIDgpOyAvLyBieXRlT2Zmc2V0PTMyO1xuXHRcdH1cblx0XHRpZiAoc3BvdExpZ2h0LnBlbnVtYnJhQ29zRGlydHkpIHtcblx0XHRcdHRoaXMuZGlydHkgPSBzZXREYXRhVG9UeXBlQXJyYXkodGhpcy5idWZmZXIsIHNwb3RMaWdodC5wZW51bWJyYUNvcywgb2Zmc2V0ICsgMTEpOyAvLyBieXRlT2Zmc2V0PTQ0O1xuXHRcdH1cblx0XHRpZiAoc3BvdExpZ2h0LmRlY2F5RGlydHkpIHtcblx0XHRcdHRoaXMuZGlydHkgPSBzZXREYXRhVG9UeXBlQXJyYXkodGhpcy5idWZmZXIsIHNwb3RMaWdodC5kZWNheSwgb2Zmc2V0ICsgMTIpOyAvLyBieXRlT2Zmc2V0PTQ4O1xuXHRcdH1cblxuXHRcdHNwb3RMaWdodC5wb3NpdGlvbkRpcnR5ID0gZmFsc2U7XG5cdFx0c3BvdExpZ2h0LmRpc3RhbmNlRGlydHkgPSBmYWxzZTtcblx0XHRzcG90TGlnaHQuZGlydGVjdERpcnR5ID0gZmFsc2U7XG5cdFx0c3BvdExpZ2h0LmNvbmVDb3NEaXJ0eSA9IGZhbHNlO1xuXHRcdHNwb3RMaWdodC5jb2xvckRpcnR5ID0gZmFsc2U7XG5cdFx0c3BvdExpZ2h0LnBlbnVtYnJhQ29zRGlydHkgPSBmYWxzZTtcblx0XHRzcG90TGlnaHQuZGVjYXlEaXJ0eSA9IGZhbHNlO1xuXHR9XG59XG5cbmV4cG9ydCBjbGFzcyBVbmlmb3JtU3BvdExpZ2h0U2hhZG93cyBleHRlbmRzIFVuaWZvcm08U3BvdExpZ2h0PiB7XG5cdHN0YXRpYyBhbGlnbiA9IDE2O1xuXHRzdGF0aWMgdW5pZm9ybVNpemUgPSAxODtcblx0bGlnaHRzOiBBcnJheTxTcG90TGlnaHQ+O1xuXHQvLyBjYjogRnVuY3Rpb247XG5cdHByaXZhdGUgX25lYXJWYWx1ZTogbnVtYmVyO1xuXHRwcml2YXRlIF9mYXJWYWx1ZTogbnVtYmVyO1xuXHRwcml2YXRlIF9zdWJEYXRhU2l6ZTogbnVtYmVyO1xuXG5cdGNvbnN0cnVjdG9yKFxuXHRcdHVuaWZvcm1OYW1lOiBzdHJpbmcsXG5cdFx0YnVmZmVyOiBGbG9hdDMyQXJyYXksXG5cdFx0Ynl0ZU9mZnNldDogbnVtYmVyLFxuXHRcdGNiOiBVbmlmb3JtRnVuYyB8IG51bWJlciB8IG9iamVjdCxcblx0XHRjb3VudD86IG51bWJlclxuXHQpIHtcblx0XHRzdXBlcih1bmlmb3JtTmFtZSwgY2IsIDApO1xuXHRcdGNvbnN0IGJ5dGVzUGVyRWxlbWVudCA9IEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVDtcblx0XHR0aGlzLl9zdWJEYXRhU2l6ZSA9IFVuaWZvcm1TcG90TGlnaHRTaGFkb3dzLnVuaWZvcm1TaXplO1xuXHRcdHRoaXMuYnl0ZVNpemUgPSBjb3VudCAqIHRoaXMuX3N1YkRhdGFTaXplICogYnl0ZXNQZXJFbGVtZW50O1xuXHRcdHRoaXMuYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXIuYnVmZmVyLCBieXRlT2Zmc2V0LCB0aGlzLmJ5dGVTaXplIC8gNCk7XG5cdFx0dGhpcy50eXBlID0gXCJzcG90TGlnaHRTaGFkb3dzXCI7XG5cdFx0dGhpcy5fbmVhclZhbHVlID0gbnVsbDtcblx0XHR0aGlzLl9mYXJWYWx1ZSA9IG51bGw7XG5cdH1cblx0c2V0KCkge1xuXHRcdHRoaXMubGlnaHRzID0gdGhpcy5nZXRWYWx1ZSgpO1xuXHRcdHRoaXMubGlnaHRzLmZvckVhY2goKHNwb3RMaWdodCwgaW5kZXgpID0+IHtcblx0XHRcdHRoaXMuc2V0U3ViRGF0YShzcG90TGlnaHQsIGluZGV4KTtcblx0XHR9KTtcblx0XHRyZXR1cm4gdGhpcy5kaXJ0eTtcblx0fVxuXHRwcml2YXRlIHNldFN1YkRhdGEoc3BvdExpZ2h0OiBTcG90TGlnaHQsIGluZGV4OiBudW1iZXIpIHtcblx0XHRjb25zdCBvZmZzZXQgPSBpbmRleCAqIHRoaXMuX3N1YkRhdGFTaXplO1xuXHRcdGlmIChzcG90TGlnaHQuc2hhZG93LnZwTWF0cml4RGlydHkpIHtcblx0XHRcdHNwb3RMaWdodC5zaGFkb3cudnBNYXRyaXhEaXJ0eSA9IGZhbHNlO1xuXHRcdFx0dGhpcy5kaXJ0eSA9IHNldERhdGFUb1R5cGVBcnJheSh0aGlzLmJ1ZmZlciwgc3BvdExpZ2h0LnNoYWRvdy5jYW1lcmEudnBNYXRyaXgudG9BcnJheSgpLCBvZmZzZXQgKyAwKTsgLy8gYnl0ZU9mZnNldD0wO1xuXHRcdH1cblx0XHRjb25zdCBuZWFyVmFsdWUgPSBzcG90TGlnaHQuc2hhZG93LmNhbWVyYS5uZWFyO1xuXHRcdGlmIChuZWFyVmFsdWUgIT0gdGhpcy5fbmVhclZhbHVlKSB7XG5cdFx0XHR0aGlzLl9uZWFyVmFsdWUgPSBuZWFyVmFsdWU7XG5cdFx0XHR0aGlzLmRpcnR5ID0gc2V0RGF0YVRvVHlwZUFycmF5KHRoaXMuYnVmZmVyLCB0aGlzLl9uZWFyVmFsdWUsIG9mZnNldCArIDE2KTsgLy8gYnl0ZU9mZnNldD0wO1xuXHRcdH1cblx0XHRjb25zdCBmYXJWYWx1ZSA9IHNwb3RMaWdodC5zaGFkb3cuY2FtZXJhLmZhcjtcblx0XHRpZiAoZmFyVmFsdWUgIT0gdGhpcy5fZmFyVmFsdWUpIHtcblx0XHRcdHRoaXMuX2ZhclZhbHVlID0gZmFyVmFsdWU7XG5cdFx0XHR0aGlzLmRpcnR5ID0gc2V0RGF0YVRvVHlwZUFycmF5KHRoaXMuYnVmZmVyLCB0aGlzLl9mYXJWYWx1ZSwgb2Zmc2V0ICsgMTcpOyAvLyBieXRlT2Zmc2V0PTA7XG5cdFx0fVxuXHR9XG59XG5leHBvcnQgY2xhc3MgVW5pZm9ybVBvaW50TGlnaHRzIGV4dGVuZHMgVW5pZm9ybTxQb2ludExpZ2h0PiB7XG5cdHN0YXRpYyBhbGlnbiA9IDE2O1xuXHRsaWdodHM6IEFycmF5PFBvaW50TGlnaHQ+O1xuXHQvLyBjYjogRnVuY3Rpb247XG5cdGNvbnN0cnVjdG9yKFxuXHRcdHVuaWZvcm1OYW1lOiBzdHJpbmcsXG5cdFx0YnVmZmVyOiBGbG9hdDMyQXJyYXksXG5cdFx0Ynl0ZU9mZnNldDogbnVtYmVyLFxuXHRcdGNiOiBVbmlmb3JtRnVuYyB8IG51bWJlciB8IG9iamVjdCxcblx0XHRjb3VudD86IG51bWJlclxuXHQpIHtcblx0XHRzdXBlcih1bmlmb3JtTmFtZSwgY2IsIDApO1xuXHRcdHRoaXMuYnl0ZVNpemUgPSBjb3VudCAqIDMyO1xuXHRcdHRoaXMuYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXIuYnVmZmVyLCBieXRlT2Zmc2V0LCB0aGlzLmJ5dGVTaXplIC8gNCk7XG5cdFx0dGhpcy50eXBlID0gXCJwb2ludHNMaWdodFwiO1xuXHR9XG5cdHNldCgpIHtcblx0XHR0aGlzLmxpZ2h0cyA9IHRoaXMuZ2V0VmFsdWUoKTtcblx0XHR0aGlzLmxpZ2h0cy5mb3JFYWNoKChwb2ludExpZ2h0LCBpbmRleCkgPT4ge1xuXHRcdFx0dGhpcy5zZXRTdWJEYXRhKHBvaW50TGlnaHQsIGluZGV4KTtcblx0XHR9KTtcblx0XHRyZXR1cm4gdGhpcy5kaXJ0eTtcblx0fVxuXHRwcml2YXRlIHNldFN1YkRhdGEocG9pbnRMaWdodDogUG9pbnRMaWdodCwgaW5kZXg6IG51bWJlcikge1xuXHRcdGNvbnN0IG9mZnNldCA9IGluZGV4ICogODtcblx0XHRpZiAocG9pbnRMaWdodC5wb3NpdGlvbkRpcnR5KSB7XG5cdFx0XHRwb2ludExpZ2h0LnBvc2l0aW9uRGlydHkgPSBmYWxzZTtcblx0XHRcdHRoaXMuZGlydHkgPSBzZXREYXRhVG9UeXBlQXJyYXkodGhpcy5idWZmZXIsIHBvaW50TGlnaHQucG9zaXRpb24udG9BcnJheSgpLCBvZmZzZXQgKyAwKTsgLy8gYnl0ZU9mZnNldD0wO1xuXHRcdH1cblx0XHRpZiAocG9pbnRMaWdodC5kaXN0YW5jZURpcnR5KSB7XG5cdFx0XHRwb2ludExpZ2h0LmRpc3RhbmNlRGlydHkgPSBmYWxzZTtcblx0XHRcdHRoaXMuZGlydHkgPSBzZXREYXRhVG9UeXBlQXJyYXkodGhpcy5idWZmZXIsIHBvaW50TGlnaHQuZGlzdGFuY2UsIG9mZnNldCArIDMpOyAvLyBieXRlT2Zmc2V0PTEyO1xuXHRcdH1cblx0XHRpZiAocG9pbnRMaWdodC5jb2xvckRpcnR5KSB7XG5cdFx0XHRwb2ludExpZ2h0LmNvbG9yRGlydHkgPSBmYWxzZTtcblx0XHRcdHRoaXMuZGlydHkgPSBzZXREYXRhVG9UeXBlQXJyYXkodGhpcy5idWZmZXIsIHBvaW50TGlnaHQuY29sb3IudG9BcnJheSgpLCBvZmZzZXQgKyA0KTsgLy8gYnl0ZU9mZnNldD0zMjtcblx0XHR9XG5cdFx0aWYgKHBvaW50TGlnaHQuZGVjYXlEaXJ0eSkge1xuXHRcdFx0cG9pbnRMaWdodC5kZWNheURpcnR5ID0gZmFsc2U7XG5cdFx0XHR0aGlzLmRpcnR5ID0gc2V0RGF0YVRvVHlwZUFycmF5KHRoaXMuYnVmZmVyLCBwb2ludExpZ2h0LmRlY2F5LCBvZmZzZXQgKyA3KTsgLy8gYnl0ZU9mZnNldD0xMjtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGNsYXNzIFVuaWZvcm1Qb2ludExpZ2h0U2hhZG93cyBleHRlbmRzIFVuaWZvcm08UG9pbnRMaWdodD4ge1xuXHRzdGF0aWMgYWxpZ24gPSAxNjtcblx0c3RhdGljIHVuaWZvcm1TaXplID0gMTIyO1xuXHRsaWdodHM6IEFycmF5PFBvaW50TGlnaHQ+O1xuXHQvLyBjYjogRnVuY3Rpb247XG5cdHByaXZhdGUgX25lYXJWYWx1ZTogbnVtYmVyO1xuXHRwcml2YXRlIF9mYXJWYWx1ZTogbnVtYmVyO1xuXHRwcml2YXRlIF9zdWJEYXRhU2l6ZTogbnVtYmVyO1xuXG5cdGNvbnN0cnVjdG9yKFxuXHRcdHVuaWZvcm1OYW1lOiBzdHJpbmcsXG5cdFx0YnVmZmVyOiBGbG9hdDMyQXJyYXksXG5cdFx0Ynl0ZU9mZnNldDogbnVtYmVyLFxuXHRcdGNiOiBVbmlmb3JtRnVuYyB8IG51bWJlciB8IG9iamVjdCxcblx0XHRjb3VudD86IG51bWJlclxuXHQpIHtcblx0XHRzdXBlcih1bmlmb3JtTmFtZSwgY2IsIDApO1xuXHRcdGNvbnN0IGJ5dGVzUGVyRWxlbWVudCA9IEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVDtcblx0XHR0aGlzLl9zdWJEYXRhU2l6ZSA9IFVuaWZvcm1Qb2ludExpZ2h0U2hhZG93cy51bmlmb3JtU2l6ZTtcblx0XHR0aGlzLmJ5dGVTaXplID0gY291bnQgKiBieXRlc1BlckVsZW1lbnQgKiB0aGlzLl9zdWJEYXRhU2l6ZTtcblx0XHR0aGlzLmJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmJ1ZmZlciwgYnl0ZU9mZnNldCwgdGhpcy5ieXRlU2l6ZSAvIDQpO1xuXHRcdHRoaXMudHlwZSA9IFwicG9pbnRMaWdodFNoYWRvd3NcIjtcblx0XHR0aGlzLl9uZWFyVmFsdWUgPSBudWxsO1xuXHRcdHRoaXMuX2ZhclZhbHVlID0gbnVsbDtcblx0fVxuXHRzZXQoKSB7XG5cdFx0dGhpcy5saWdodHMgPSB0aGlzLmdldFZhbHVlKCk7XG5cdFx0dGhpcy5saWdodHMuZm9yRWFjaCgocG9pbnRMaWdodCwgaW5kZXgpID0+IHtcblx0XHRcdHRoaXMuc2V0U3ViRGF0YShwb2ludExpZ2h0LCBpbmRleCk7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIHRoaXMuZGlydHk7XG5cdH1cblx0cHJpdmF0ZSBzZXRTdWJEYXRhKHBvaW50TGlnaHQ6IFBvaW50TGlnaHQsIGluZGV4OiBudW1iZXIpIHtcblx0XHRjb25zdCBvZmZzZXQgPSBpbmRleCAqIHRoaXMuX3N1YkRhdGFTaXplO1xuXG5cdFx0aWYgKHBvaW50TGlnaHQuc2hhZG93LnZwTWF0cml4QXJyYXlEaXJ0eSkge1xuXHRcdFx0cG9pbnRMaWdodC5zaGFkb3cudnBNYXRyaXhBcnJheURpcnR5ID0gZmFsc2U7XG5cdFx0XHRjb25zdCB2cE1hdHJpeEFycmF5ID0gcG9pbnRMaWdodC5zaGFkb3cuY2FtZXJhLnZwTWF0cml4QXJyYXk7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHZwTWF0cml4QXJyYXkubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0Y29uc3QgdnBNYXRyaXggPSB2cE1hdHJpeEFycmF5W2ldO1xuXHRcdFx0XHR0aGlzLmRpcnR5ID0gc2V0RGF0YVRvVHlwZUFycmF5KHRoaXMuYnVmZmVyLCB2cE1hdHJpeC50b0FycmF5KCksIG9mZnNldCArIDAgKyAxNiAqIGkpOyAvLyBieXRlT2Zmc2V0PTk4ICogNDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAocG9pbnRMaWdodC5zaGFkb3cudmlld1BvcnREaXJ0eSkge1xuXHRcdFx0cG9pbnRMaWdodC5zaGFkb3cudmlld1BvcnREaXJ0eSA9IGZhbHNlO1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCA2OyBpKyspIHtcblx0XHRcdFx0dGhpcy5kaXJ0eSA9IHNldERhdGFUb1R5cGVBcnJheShcblx0XHRcdFx0XHR0aGlzLmJ1ZmZlcixcblx0XHRcdFx0XHRwb2ludExpZ2h0LnNoYWRvdy52aWV3cG9ydHNbaV0udG9BcnJheSgpLFxuXHRcdFx0XHRcdG9mZnNldCArIDk2ICsgNCAqIGlcblx0XHRcdFx0KTsgLy8gYnl0ZU9mZnNldD0wO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGNvbnN0IG5lYXJWYWx1ZSA9IHBvaW50TGlnaHQuc2hhZG93LmNhbWVyYS5uZWFyO1xuXHRcdGlmIChuZWFyVmFsdWUgIT0gdGhpcy5fbmVhclZhbHVlKSB7XG5cdFx0XHR0aGlzLl9uZWFyVmFsdWUgPSBuZWFyVmFsdWU7XG5cdFx0XHR0aGlzLmRpcnR5ID0gc2V0RGF0YVRvVHlwZUFycmF5KHRoaXMuYnVmZmVyLCB0aGlzLl9uZWFyVmFsdWUsIG9mZnNldCArIDEyMCk7IC8vIGJ5dGVPZmZzZXQ9MDtcblx0XHR9XG5cdFx0Y29uc3QgZmFyVmFsdWUgPSBwb2ludExpZ2h0LnNoYWRvdy5jYW1lcmEuZmFyO1xuXHRcdGlmIChmYXJWYWx1ZSAhPSB0aGlzLl9mYXJWYWx1ZSkge1xuXHRcdFx0dGhpcy5fZmFyVmFsdWUgPSBmYXJWYWx1ZTtcblx0XHRcdHRoaXMuZGlydHkgPSBzZXREYXRhVG9UeXBlQXJyYXkodGhpcy5idWZmZXIsIHRoaXMuX2ZhclZhbHVlLCBvZmZzZXQgKyAxMjEpOyAvLyBieXRlT2Zmc2V0PTE7XG5cdFx0fVxuXHR9XG59XG5leHBvcnQgY2xhc3MgVW5pZm9ybURpcnRlY3RMaWdodHMgZXh0ZW5kcyBVbmlmb3JtPERpcmVjdGlvbmFsTGlnaHQ+IHtcblx0c3RhdGljIGFsaWduID0gMTY7XG5cdGxpZ2h0czogQXJyYXk8RGlyZWN0aW9uYWxMaWdodD47XG5cdGNvbnN0cnVjdG9yKFxuXHRcdHVuaWZvcm1OYW1lOiBzdHJpbmcsXG5cdFx0YnVmZmVyOiBGbG9hdDMyQXJyYXksXG5cdFx0Ynl0ZU9mZnNldDogbnVtYmVyLFxuXHRcdGNiOiBVbmlmb3JtRnVuYyB8IG51bWJlciB8IG9iamVjdCxcblx0XHRjb3VudD86IG51bWJlclxuXHQpIHtcblx0XHRzdXBlcih1bmlmb3JtTmFtZSwgY2IsIDApO1xuXHRcdHRoaXMuY2IgPSBjYjtcblx0XHR0aGlzLmJ5dGVTaXplID0gY291bnQgKiAzMjtcblx0XHR0aGlzLmJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmJ1ZmZlciwgYnl0ZU9mZnNldCwgdGhpcy5ieXRlU2l6ZSAvIDQpO1xuXHRcdHRoaXMudHlwZSA9IFwiZGlydGVjdExpZ2h0c1wiO1xuXHR9XG5cdHNldCgpIHtcblx0XHR0aGlzLmxpZ2h0cyA9IHRoaXMuZ2V0VmFsdWUoKTtcblx0XHR0aGlzLmxpZ2h0cy5mb3JFYWNoKChkaXJlY3Rpb25hbExpZ2h0LCBpbmRleCkgPT4ge1xuXHRcdFx0dGhpcy5zZXRTdWJEYXRhKGRpcmVjdGlvbmFsTGlnaHQsIGluZGV4KTtcblx0XHR9KTtcblx0XHRyZXR1cm4gdGhpcy5kaXJ0eTtcblx0fVxuXHRwcml2YXRlIHNldFN1YkRhdGEoZGlyZWN0aW9uYWxMaWdodDogRGlyZWN0aW9uYWxMaWdodCwgaW5kZXg6IG51bWJlcikge1xuXHRcdGNvbnN0IG9mZnNldCA9IGluZGV4ICogODtcblx0XHRpZiAoZGlyZWN0aW9uYWxMaWdodC5kaXJ0ZWN0RGlydHkpIHtcblx0XHRcdGRpcmVjdGlvbmFsTGlnaHQuZGlydGVjdERpcnR5ID0gZmFsc2U7XG5cdFx0XHR0aGlzLmRpcnR5ID0gc2V0RGF0YVRvVHlwZUFycmF5KHRoaXMuYnVmZmVyLCBkaXJlY3Rpb25hbExpZ2h0LmRpcmVjdGlvbmFsLnRvQXJyYXkoKSwgb2Zmc2V0ICsgMCk7IC8vIGJ5dGVPZmZzZXQ9MTY7XG5cdFx0fVxuXHRcdGlmIChkaXJlY3Rpb25hbExpZ2h0LmNvbG9yRGlydHkpIHtcblx0XHRcdGRpcmVjdGlvbmFsTGlnaHQuY29sb3JEaXJ0eSA9IGZhbHNlO1xuXHRcdFx0dGhpcy5kaXJ0eSA9IHNldERhdGFUb1R5cGVBcnJheSh0aGlzLmJ1ZmZlciwgZGlyZWN0aW9uYWxMaWdodC5jb2xvci50b0FycmF5KCksIG9mZnNldCArIDQpOyAvLyBieXRlT2Zmc2V0PTMyO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgY2xhc3MgVW5pZm9ybURpcnRlY3RMaWdodFNoYWRvd3MgZXh0ZW5kcyBVbmlmb3JtPERpcmVjdGlvbmFsTGlnaHQ+IHtcblx0c3RhdGljIGFsaWduID0gMTY7XG5cdHN0YXRpYyB1bmlmb3JtU2l6ZSA9IDE2O1xuXHRsaWdodHM6IEFycmF5PERpcmVjdGlvbmFsTGlnaHQ+O1xuXHRwcml2YXRlIF9zdWJEYXRhU2l6ZTogbnVtYmVyO1xuXG5cdGNvbnN0cnVjdG9yKFxuXHRcdHVuaWZvcm1OYW1lOiBzdHJpbmcsXG5cdFx0YnVmZmVyOiBGbG9hdDMyQXJyYXksXG5cdFx0Ynl0ZU9mZnNldDogbnVtYmVyLFxuXHRcdGNiOiBVbmlmb3JtRnVuYyB8IG51bWJlciB8IG9iamVjdCxcblx0XHRjb3VudD86IG51bWJlclxuXHQpIHtcblx0XHRzdXBlcih1bmlmb3JtTmFtZSwgY2IsIDApO1xuXHRcdGNvbnN0IGJ5dGVzUGVyRWxlbWVudCA9IEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVDtcblx0XHR0aGlzLl9zdWJEYXRhU2l6ZSA9IFVuaWZvcm1EaXJ0ZWN0TGlnaHRTaGFkb3dzLnVuaWZvcm1TaXplO1xuXHRcdHRoaXMuYnl0ZVNpemUgPSBjb3VudCAqIGJ5dGVzUGVyRWxlbWVudCAqIHRoaXMuX3N1YkRhdGFTaXplO1xuXHRcdHRoaXMuYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXIuYnVmZmVyLCBieXRlT2Zmc2V0LCB0aGlzLmJ5dGVTaXplIC8gNCk7XG5cdFx0dGhpcy50eXBlID0gXCJkaXJ0ZWN0TGlnaHRTaGFkb3dzXCI7XG5cdH1cblx0c2V0KCkge1xuXHRcdHRoaXMubGlnaHRzID0gdGhpcy5nZXRWYWx1ZSgpO1xuXHRcdHRoaXMubGlnaHRzLmZvckVhY2goKGRpcmVjdGlvbmFsTGlnaHQsIGluZGV4KSA9PiB7XG5cdFx0XHR0aGlzLnNldFN1YkRhdGEoZGlyZWN0aW9uYWxMaWdodCwgaW5kZXgpO1xuXHRcdH0pO1xuXHRcdHJldHVybiB0aGlzLmRpcnR5O1xuXHR9XG5cdHByaXZhdGUgc2V0U3ViRGF0YShkaXJlY3Rpb25hbExpZ2h0OiBEaXJlY3Rpb25hbExpZ2h0LCBpbmRleDogbnVtYmVyKSB7XG5cdFx0Y29uc3Qgb2Zmc2V0ID0gaW5kZXggKiB0aGlzLl9zdWJEYXRhU2l6ZTtcblx0XHRpZiAoZGlyZWN0aW9uYWxMaWdodC5zaGFkb3cudnBNYXRyaXhEaXJ0eSkge1xuXHRcdFx0ZGlyZWN0aW9uYWxMaWdodC5zaGFkb3cudnBNYXRyaXhEaXJ0eSA9IGZhbHNlO1xuXHRcdFx0dGhpcy5kaXJ0eSA9IHNldERhdGFUb1R5cGVBcnJheSh0aGlzLmJ1ZmZlciwgZGlyZWN0aW9uYWxMaWdodC5zaGFkb3cuY2FtZXJhLnZwTWF0cml4LnRvQXJyYXkoKSwgb2Zmc2V0ICsgMCk7IC8vIGJ5dGVPZmZzZXQ9MTY7XG5cdFx0fVxuXHR9XG59XG5mdW5jdGlvbiBzZXREYXRhVG9UeXBlQXJyYXkoYnVmZmVyLCBkYXRhLCBvZmZzZXQpIHtcblx0aWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcblx0XHRkYXRhLmZvckVhY2goKHZhbHVlLCBpbmRleCkgPT4ge1xuXHRcdFx0YnVmZmVyW2luZGV4ICsgb2Zmc2V0XSA9IHZhbHVlO1xuXHRcdH0pO1xuXHR9IGVsc2Uge1xuXHRcdGJ1ZmZlcltvZmZzZXRdID0gZGF0YTtcblx0fVxuXHRyZXR1cm4gdHJ1ZTtcbn1cbiIsImltcG9ydCB7IEJ1ZmZlckJpbmRpbmdUeXBlLCBCdWZmZXJVc2FnZSwgU2hhZGVyU3RhZ2UgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVDb25zdGFudFwiO1xuaW1wb3J0IHsgVW5pZm9ybUZ1bmMsIFVuaWZvcm1FbnVtIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcbmltcG9ydCBkZWZhdWx0VmFsdWUgZnJvbSBcIi4uL3V0aWxzL2RlZmF1bHRWYWx1ZVwiO1xuaW1wb3J0IEJ1ZmZlciBmcm9tIFwiLi9CdWZmZXJcIjtcblxuaW1wb3J0IHtcblx0VW5pZm9ybSxcblx0VW5pZm9ybUNvbG9yLFxuXHRVbmlmb3JtRGlydGVjdExpZ2h0cyxcblx0VW5pZm9ybURpcnRlY3RMaWdodFNoYWRvd3MsXG5cdFVuaWZvcm1GbG9hdCxcblx0VW5pZm9ybUZsb2F0QXJyYXksXG5cdFVuaWZvcm1GbG9hdFZlYzIsXG5cdFVuaWZvcm1GbG9hdFZlYzMsXG5cdFVuaWZvcm1GbG9hdFZlYzQsXG5cdFVuaWZvcm1NYXQyLFxuXHRVbmlmb3JtTWF0Myxcblx0VW5pZm9ybU1hdDQsXG5cdFVuaWZvcm1NYXRyaXg0QXJyYXksXG5cdFVuaWZvcm1Qb2ludExpZ2h0cyxcblx0VW5pZm9ybVBvaW50TGlnaHRTaGFkb3dzLFxuXHRVbmlmb3JtU3BvdExpZ2h0cyxcblx0VW5pZm9ybVNwb3RMaWdodFNoYWRvd3MsXG5cdFVuaWZvcm1VaW50LFxuXHRVbmlmb3JtVmVjMkFycmF5LFxuXHRVbmlmb3JtVmVjM0FycmF5LFxuXHRVbmlmb3JtVmVjNEFycmF5LFxuXHRVbmlmb3JtU3RydWN0QXJyYXlcbn0gZnJvbSBcIi4vVW5pZm9ybXNcIjtcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFVuaWZvcm1CdWZmZXIge1xuXHRwdWJsaWMgdHlwZTogc3RyaW5nO1xuXHRwdWJsaWMgaGFzRHluYW1pY09mZnNldDogYm9vbGVhbjtcblx0cHVibGljIG1pbkJpbmRpbmdTaXplOiBudW1iZXI7XG5cdHByaXZhdGUgX3VuaWZvcm1TdHJ1Y3Q6IE1hcDxzdHJpbmcsIFVuaWZvcm08YW55Pj47XG5cdHByaXZhdGUgX2J1ZmZlclNpemU6IG51bWJlcjtcblx0cHJpdmF0ZSBsYWJlbDogc3RyaW5nO1xuXHRwdWJsaWMgYnl0ZU9mZnNldDogbnVtYmVyO1xuXHRwdWJsaWMgdW5pZm9ybURpcnR5OiBib29sZWFuO1xuXHRwdWJsaWMgYmluZGluZzogbnVtYmVyO1xuXHRwdWJsaWMgdmlzaWJpbGl0eTogU2hhZGVyU3RhZ2U7XG5cdHB1YmxpYyB1c2FnZTogQnVmZmVyVXNhZ2U7XG5cdHB1YmxpYyBidWZmZXI6IEJ1ZmZlcjtcblx0cHVibGljIGRhdGFCdWZmZXI6IEZsb2F0MzJBcnJheTtcblx0cHVibGljIG9mZnNldDogbnVtYmVyO1xuXHRwdWJsaWMgbWF4T2Zmc2V0OiBudW1iZXI7XG5cdHB1YmxpYyBpc1VuaWZvcm1CdWZmZXI6IGJvb2xlYW47XG5cdHB1YmxpYyBuYW1lOiBzdHJpbmc7XG5cdHByaXZhdGUgc3RhdGljIFVuaWZvcm1UeXBlID0ge1xuXHRcdFtVbmlmb3JtRW51bS5Vbmlmb3JtVWludF06IFVuaWZvcm1VaW50LFxuXHRcdFtVbmlmb3JtRW51bS5GbG9hdF06IFVuaWZvcm1GbG9hdCxcblx0XHRbVW5pZm9ybUVudW0uRmxvYXRWZWMyXTogVW5pZm9ybUZsb2F0VmVjMixcblx0XHRbVW5pZm9ybUVudW0uRmxvYXRWZWMzXTogVW5pZm9ybUZsb2F0VmVjMyxcblx0XHRbVW5pZm9ybUVudW0uRmxvYXRWZWM0XTogVW5pZm9ybUZsb2F0VmVjNCxcblx0XHRbVW5pZm9ybUVudW0uTWF0Ml06IFVuaWZvcm1NYXQyLFxuXHRcdFtVbmlmb3JtRW51bS5NYXQzXTogVW5pZm9ybU1hdDMsXG5cdFx0W1VuaWZvcm1FbnVtLk1hdDRdOiBVbmlmb3JtTWF0NCxcblx0XHRbVW5pZm9ybUVudW0uQ29sb3JdOiBVbmlmb3JtQ29sb3IsXG5cdFx0W1VuaWZvcm1FbnVtLkZsb2F0QXJyYXldOiBVbmlmb3JtRmxvYXRBcnJheSxcblx0XHRbVW5pZm9ybUVudW0uVmVjMkFycmF5XTogVW5pZm9ybVZlYzJBcnJheSxcblx0XHRbVW5pZm9ybUVudW0uVmVjM0FycmF5XTogVW5pZm9ybVZlYzNBcnJheSxcblx0XHRbVW5pZm9ybUVudW0uVmVjNEFycmF5XTogVW5pZm9ybVZlYzRBcnJheSxcblx0XHRbVW5pZm9ybUVudW0uTWF0NEFycmF5XTogVW5pZm9ybU1hdHJpeDRBcnJheSxcblx0XHRbVW5pZm9ybUVudW0uUG9pbnRMaWdodHNdOiBVbmlmb3JtUG9pbnRMaWdodHMsXG5cdFx0W1VuaWZvcm1FbnVtLlNwb3RMaWdodHNdOiBVbmlmb3JtU3BvdExpZ2h0cyxcblx0XHRbVW5pZm9ybUVudW0uRGlydGVjdExpZ2h0c106IFVuaWZvcm1EaXJ0ZWN0TGlnaHRzLFxuXHRcdFtVbmlmb3JtRW51bS5Qb2ludExpZ2h0U2hhZG93c106IFVuaWZvcm1Qb2ludExpZ2h0U2hhZG93cyxcblx0XHRbVW5pZm9ybUVudW0uU3BvdExpZ2h0U2hhZG93c106IFVuaWZvcm1TcG90TGlnaHRTaGFkb3dzLFxuXHRcdFtVbmlmb3JtRW51bS5EaXJ0ZWN0TGlnaHRTaGFkb3dzXTogVW5pZm9ybURpcnRlY3RMaWdodFNoYWRvd3MsXG5cdFx0W1VuaWZvcm1FbnVtLlVuaWZvcm1TdHJ1Y3RBcnJheV06IFVuaWZvcm1TdHJ1Y3RBcnJheVxuXHR9O1xuXHRjb25zdHJ1Y3RvcihvcHRpb25zOiBVbmlmb3JtQnVmZmVyUGFyYW1zKSB7XG5cdFx0dGhpcy50eXBlID0gZGVmYXVsdFZhbHVlKG9wdGlvbnMudHlwZSwgXCJ1bmlmb3JtXCIpO1xuXHRcdHRoaXMubGFiZWwgPSBkZWZhdWx0VmFsdWUob3B0aW9ucy5sYWJlbCwgXCJcIik7XG5cdFx0dGhpcy5uYW1lID0gZGVmYXVsdFZhbHVlKG9wdGlvbnMubGFiZWwsIFwiXCIpO1xuXHRcdHRoaXMuaGFzRHluYW1pY09mZnNldCA9IG9wdGlvbnMuaGFzRHluYW1pY09mZnNldCA/PyBmYWxzZTtcblx0XHR0aGlzLm1pbkJpbmRpbmdTaXplID0gb3B0aW9ucy5taW5CaW5kaW5nU2l6ZSA/PyAwO1xuXHRcdHRoaXMuYmluZGluZyA9IG9wdGlvbnMuYmluZGluZyA/PyAwO1xuXHRcdHRoaXMudmlzaWJpbGl0eSA9IGRlZmF1bHRWYWx1ZShvcHRpb25zLnZpc2liaWxpdHksIFNoYWRlclN0YWdlLkZyYWdtZW50IHwgU2hhZGVyU3RhZ2UuVmVydGV4KTtcblx0XHR0aGlzLnVzYWdlID0gZGVmYXVsdFZhbHVlKG9wdGlvbnMudXNhZ2UsIEJ1ZmZlclVzYWdlLlVuaWZvcm0gfCBCdWZmZXJVc2FnZS5Db3B5RHN0KTtcblx0XHR0aGlzLl91bmlmb3JtU3RydWN0ID0gbmV3IE1hcCgpO1xuXHRcdHRoaXMudW5pZm9ybURpcnR5ID0gdHJ1ZTtcblx0XHR0aGlzLl9idWZmZXJTaXplID0gb3B0aW9ucy5zaXplO1xuXHRcdHRoaXMuYnVmZmVyID0gb3B0aW9ucy5idWZmZXI7XG5cdFx0dGhpcy5vZmZzZXQgPSAwO1xuXHRcdHRoaXMuZGF0YUJ1ZmZlciA9IGRlZmF1bHRWYWx1ZShvcHRpb25zLmRhdGFCdWZmZXIsIG5ldyBGbG9hdDMyQXJyYXkoZGVmYXVsdFZhbHVlKHRoaXMuX2J1ZmZlclNpemUsIDQwMCkpKTtcblx0XHR0aGlzLmJ5dGVPZmZzZXQgPSAwO1xuXHRcdHRoaXMuaXNVbmlmb3JtQnVmZmVyID0gdHJ1ZTtcblx0XHR0aGlzLm1heE9mZnNldCA9IG9wdGlvbnMubWF4T2Zmc2V0ID8/IDA7XG5cdH1cblx0Z2V0IGxheW91dFR5cGUoKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHR5cGU6IHRoaXMudHlwZSxcblx0XHRcdGhhc0R5bmFtaWNPZmZzZXQ6IHRoaXMuaGFzRHluYW1pY09mZnNldCxcblx0XHRcdG1pbkJpbmRpbmdTaXplOiB0aGlzLm1pbkJpbmRpbmdTaXplXG5cdFx0fTtcblx0fVxuXHRnZXQgYnVmZmVyU2l6ZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5fYnVmZmVyU2l6ZSA/PyB0aGlzLnVuaWZvcm1zU2l6ZSAqIDQ7XG5cdH1cblx0Z2V0IHVuaWZvcm1zU2l6ZSgpIHtcblx0XHQvLyBodHRwczovL2dwdXdlYi5naXRodWIuaW8vZ3B1d2ViL3dnc2wvI2FkZHJlc3Mtc3BhY2UtbGF5b3V0LWNvbnN0cmFpbnRzXG5cdFx0cmV0dXJuIHRoaXMuX2J1ZmZlclNpemUgIT0gdW5kZWZpbmVkID8gdGhpcy5fYnVmZmVyU2l6ZSAvIDQgOiBNYXRoLmNlaWwodGhpcy5ieXRlT2Zmc2V0IC8gMTYpICogMTY7XG5cdH1cblx0YmluZChkZXZpY2U6IEdQVURldmljZSkge1xuXHRcdHRoaXMuX3VuaWZvcm1TdHJ1Y3QuZm9yRWFjaCgodW5pZm9ybSkgPT4ge1xuXHRcdFx0Y29uc3QgcmVzdWx0ID0gdW5pZm9ybS5zZXQoKTtcblx0XHRcdGlmICh1bmlmb3JtPy5kaXJ0eSAhPSB1bmRlZmluZWQpIHVuaWZvcm0uZGlydHkgPSBmYWxzZTtcblx0XHRcdGlmIChyZXN1bHQgIT0gdW5kZWZpbmVkICYmIHRoaXMudW5pZm9ybURpcnR5ID09IGZhbHNlKSB0aGlzLnVuaWZvcm1EaXJ0eSA9IHJlc3VsdDtcblx0XHR9KTtcblx0XHRpZiAodGhpcy51bmlmb3JtRGlydHkpIHtcblx0XHRcdHRoaXMudW5pZm9ybURpcnR5ID0gZmFsc2U7XG5cdFx0XHRpZiAoIXRoaXMuYnVmZmVyKSB0aGlzLmJ1ZmZlciA9IEJ1ZmZlci5jcmVhdGVVbmlmb3JtQnVmZmVyKHRoaXMubGFiZWwsIGRldmljZSwgdGhpcy5idWZmZXJTaXplLCB0aGlzLnVzYWdlKTtcblx0XHRcdGlmICh0aGlzLnR5cGUgIT0gQnVmZmVyQmluZGluZ1R5cGUuU3RvcmFnZSlcblx0XHRcdFx0dGhpcy5idWZmZXIuc2V0U3ViRGF0YShcblx0XHRcdFx0XHQwLFxuXHRcdFx0XHRcdHRoaXMuZGF0YUJ1ZmZlci5zbGljZSgwLCBkZWZhdWx0VmFsdWUodGhpcz8uYnVmZmVyU2l6ZSAvIDQsIHRoaXMudW5pZm9ybXNTaXplKSlcblx0XHRcdFx0KTtcblx0XHR9XG5cdH1cblx0cHVibGljIGdldFVuaWZvcm1CdWZmZXJTdHJ1Y3QoKSB7XG5cdFx0bGV0IHVuaWZvcm1TdHJ1Y3QgPSBgc3RydWN0IE1hdGVyaWFsVW5pZm9ybSB7XFxuIGA7XG5cdFx0dGhpcy5fdW5pZm9ybVN0cnVjdC5mb3JFYWNoKCh1bmlmb3JtKSA9PiB7XG5cdFx0XHR1bmlmb3JtU3RydWN0ICs9IHRoaXMuY3JlYXRlVW5pZm9ybVN0cmluZyh1bmlmb3JtKTtcblx0XHR9KTtcblx0XHR1bmlmb3JtU3RydWN0ICs9IGB9XFxuYDtcblx0XHRyZXR1cm4gdW5pZm9ybVN0cnVjdDtcblx0fVxuXHRwcml2YXRlIGNyZWF0ZVVuaWZvcm1TdHJpbmcodW5pZm9ybSkge1xuXHRcdGxldCByZXN1bHQgPSBgYDtcblx0XHRzd2l0Y2ggKHVuaWZvcm0udHlwZSkge1xuXHRcdFx0Y2FzZSBcInZlYzFcIjpcblx0XHRcdFx0cmVzdWx0ID0gYCR7dW5pZm9ybS5uYW1lfSA6ZjMyLFxcbmA7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcInZlYzJcIjpcblx0XHRcdFx0cmVzdWx0ID0gYCR7dW5pZm9ybS5uYW1lfSA6dmVjMjxmMzI+LFxcbmA7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcInZlYzNcIjpcblx0XHRcdFx0cmVzdWx0ID0gYCR7dW5pZm9ybS5uYW1lfSA6dmVjMzxmMzI+LFxcbmA7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcInZlYzRcIjpcblx0XHRcdFx0cmVzdWx0ID0gYCR7dW5pZm9ybS5uYW1lfSA6dmVjNDxmMzI+LFxcbmA7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcIm1hdDJcIjpcblx0XHRcdFx0cmVzdWx0ID0gYCR7dW5pZm9ybS5uYW1lfSA6bWF0MngyPGYzMj4sXFxuYDtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwibWF0M1wiOlxuXHRcdFx0XHRyZXN1bHQgPSBgJHt1bmlmb3JtLm5hbWV9IDptYXQzeDM8ZjMyPixcXG5gO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJtYXQ0XCI6XG5cdFx0XHRcdHJlc3VsdCA9IGAke3VuaWZvcm0ubmFtZX0gOm1hdDR4NDxmMzI+LFxcbmA7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cdGNvbnRhaW5zKG5hbWU6IHN0cmluZyk6IFVuaWZvcm08YW55PiB7XG5cdFx0cmV0dXJuIHRoaXMuX3VuaWZvcm1TdHJ1Y3QuZ2V0KG5hbWUpO1xuXHR9XG5cdHJlcGxhY2VVbmlmb3JtVmFsdWUobmFtZTogc3RyaW5nLCB2YWx1ZTogVW5pZm9ybUZ1bmMgfCBudW1iZXIgfCBvYmplY3QpIHtcblx0XHRjb25zdCB1bmlmb3JtID0gdGhpcy5fdW5pZm9ybVN0cnVjdC5nZXQobmFtZSk7XG5cdFx0aWYgKCF1bmlmb3JtKSByZXR1cm47XG5cdFx0dW5pZm9ybS5jYiA9IHZhbHVlO1xuXHR9XG5cdC8vIHVuaWZvcm1CdWZmZXIuc2V0VmVjM0FycmF5KCd0ZXN0JywoKT0+e3JldHVybiBbbmV3IFZlY3RvcjMoMSwwLDApLG5ldyBWZWN0b3IzKDEsMC44LDAuNSldfSwyKTtcblx0Ly8gdW5pZm9ybUJ1ZmZlci5zZXRGbG9hdEFycmF5KCd0ZXN0MScsKCk9PntyZXR1cm4gWzAuNSwwLjUsMS4wXX0sMyk7XG5cdC8vIHVuaWZvcm1CdWZmZXIuc2V0VmVjNEFycmF5KCd0ZXN0NCcsKCk9PntyZXR1cm4gW25ldyBWZWN0b3I0KDAuNSwwLjYsMC4yLDEuMCksbmV3IFZlY3RvcjQoMC41LDAuOCwwLjgsMS4wKV19LDIpO1xuXHQvLyB1bmlmb3JtQnVmZmVyLnNldFZlYzJBcnJheSgndGVzdDInLCgpPT57cmV0dXJuIFtuZXcgVmVjdG9yMigwLjUsMC42KSxuZXcgVmVjdG9yMigwLjUsMC44LCldfSwyKTtcblx0c2V0VW5pZm9ybShuYW1lOiBzdHJpbmcsIHZhbHVlOiBVbmlmb3JtRnVuYyB8IG51bWJlciB8IG9iamVjdCwgdW5pZm9ybVR5cGU6IFVuaWZvcm1FbnVtLCBjb3VudD86IG51bWJlcikge1xuXHRcdGlmICh0aGlzLl91bmlmb3JtU3RydWN0LmdldChuYW1lKSkgcmV0dXJuO1xuXHRcdGNvbnN0IFR5cGVVbmlmb3JtID0gVW5pZm9ybUJ1ZmZlci5Vbmlmb3JtVHlwZVt1bmlmb3JtVHlwZV07XG5cdFx0dGhpcy5ieXRlT2Zmc2V0ICs9IFVuaWZvcm1CdWZmZXIuY2hlY2tVbmlmb3JtT2Zmc2V0KHRoaXMuYnl0ZU9mZnNldCwgVHlwZVVuaWZvcm0uYWxpZ24pO1xuXHRcdGNvbnN0IHVuaWZvcm0gPVxuXHRcdFx0Y291bnQgIT0gdW5kZWZpbmVkXG5cdFx0XHRcdD8gbmV3IFR5cGVVbmlmb3JtKG5hbWUsIHRoaXMuZGF0YUJ1ZmZlciwgdGhpcy5ieXRlT2Zmc2V0LCB2YWx1ZSwgY291bnQpXG5cdFx0XHRcdDogbmV3IFR5cGVVbmlmb3JtKG5hbWUsIHRoaXMuZGF0YUJ1ZmZlciwgdGhpcy5ieXRlT2Zmc2V0LCB2YWx1ZSk7XG5cdFx0dGhpcy5fdW5pZm9ybVN0cnVjdC5zZXQobmFtZSwgdW5pZm9ybSk7XG5cdFx0dGhpcy5ieXRlT2Zmc2V0ICs9IHVuaWZvcm0uYnl0ZVNpemU7XG5cdH1cblx0c3RhdGljIGNoZWNrVW5pZm9ybU9mZnNldChieXRlU2l6ZTogbnVtYmVyLCBBbGlnbjogbnVtYmVyKTogbnVtYmVyIHtcblx0XHQvLyBmcm9tIGh0dHBzOi8vZ3B1d2ViLmdpdGh1Yi5pby9ncHV3ZWIvd2dzbC8jYWRkcmVzcy1zcGFjZS1sYXlvdXQtY29uc3RyYWludHNcblx0XHQvLyByZXR1cm4gdGhpcy5oYXNEeW5hbWljT2Zmc2V0XG5cdFx0Ly8gXHQ/IE1hdGguY2VpbChieXRlU2l6ZSAvIDI1NikgKiAyNTYgLSBieXRlU2l6ZVxuXHRcdC8vIFx0OiBNYXRoLmNlaWwoYnl0ZVNpemUgLyBBbGlnbikgKiBBbGlnbiAtIGJ5dGVTaXplO1xuXHRcdHJldHVybiBNYXRoLmNlaWwoYnl0ZVNpemUgLyBBbGlnbikgKiBBbGlnbiAtIGJ5dGVTaXplO1xuXHR9XG5cdGRlc3Ryb3koKSB7XG5cdFx0dGhpcz8uYnVmZmVyPy5kZXN0cm95KCk7XG5cdH1cbn1cbnR5cGUgVW5pZm9ybUJ1ZmZlclBhcmFtcyA9IHtcblx0bGFiZWw6IHN0cmluZztcblx0dHlwZT86IHN0cmluZztcblx0dXNhZ2U/OiBCdWZmZXJVc2FnZTtcblx0c2l6ZT86IG51bWJlcjtcblx0ZGF0YUJ1ZmZlcj86IEZsb2F0MzJBcnJheTtcblx0YmluZGluZz86IG51bWJlcjtcblx0aGFzRHluYW1pY09mZnNldD86IGJvb2xlYW47XG5cdG1pbkJpbmRpbmdTaXplPzogbnVtYmVyO1xuXHRtYXhPZmZzZXQ/OiBudW1iZXI7XG5cdGJ1ZmZlcj86IEJ1ZmZlcjtcblx0dmlzaWJpbGl0eT86IFNoYWRlclN0YWdlO1xufTtcbiIsIi8vIGltcG9ydCBDb2xvciBmcm9tIFwiLi4vLi4vbWF0aC9Db2xvclwiO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY29sb3JGcmFnKGRlZmluZXMpIHtcclxuICByZXR1cm4gYFxyXG4gICAgc3RydWN0IFZlcnRleE91dHB1dCB7XHJcbiAgICAgICAgQGJ1aWx0aW4ocG9zaXRpb24pIHBvc2l0aW9uOiB2ZWM0PGYzMj4sXHJcbiAgICAgICAgQGxvY2F0aW9uKDApIGNvbG9yOiB2ZWM0PGYzMj4sXHJcbiAgICB9O1xyXG4gICAgQGZyYWdtZW50XHJcbiAgICBmbiBtYWluKGlucHV0OlZlcnRleE91dHB1dCkgLT4gQGxvY2F0aW9uKDApIHZlYzQ8ZjMyPiB7XHJcbiAgICAgIHJldHVybiBpbnB1dC5jb2xvcjtcclxuICAgIH1cclxuICAgIGA7XHJcbn1cclxuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY29sb3JWZXJ0KGRlZmluZXMpIHtcblx0cmV0dXJuIGBcbiAgIHN0cnVjdCBWZXJ0ZXhJbnB1dCB7XG4gICAgICAgIEBsb2NhdGlvbigke2RlZmluZXMucG9zaXRpb25Mb2NhdGlvbn0pIHBvc2l0aW9uOiB2ZWMzPGYzMj4sICAgICAgIFxuICAgICAgICBAbG9jYXRpb24oJHtkZWZpbmVzLmNvbG9yTG9jYXRpb259KSBjb2xvcjogdmVjNDxmMzI+LFxuICAgfVxuICAgc3RydWN0IFZlcnRleE91dHB1dCB7XG4gICAgICAgIEBidWlsdGluKHBvc2l0aW9uKSBwb3NpdGlvbjogdmVjNDxmMzI+LFxuICAgICAgICBAbG9jYXRpb24oMCkgY29sb3I6IHZlYzQ8ZjMyPixcbiAgICB9O1xuICAgc3RydWN0IFNlbGZVbmlmb3JtIHtcbiAgICAgIG1vZGVsTWF0cml4OiBtYXQ0eDQ8ZjMyPixcbiAgIH1cbiAgIHN0cnVjdCBTeXN0ZW1Vbmlmb3JtIHtcbiAgICAgIHByb2plY3Rpb25NYXRyaXg6IG1hdDR4NDxmMzI+LFxuICAgICAgdmlld01hdHJpeDogbWF0NHg0PGYzMj4sXG4gICAgICBpbnZlcnNlVmlld01hdHJpeDogbWF0NHg0PGYzMj4sXG4gICAgICBjYW1lcmFQb3NpdGlvbjogdmVjMzxmMzI+LFxuICAgfTsgXG4gICBAYmluZGluZygke2RlZmluZXMuY29sb3JCaW5kaW5nfSkgQGdyb3VwKDApIHZhcjx1bmlmb3JtPiBzZWxmVW5pZm9ybSA6IFNlbGZVbmlmb3JtO1xuICAgQGJpbmRpbmcoJHtkZWZpbmVzLmNhbWVyYUJpbmRpbmd9KSBAZ3JvdXAoMSkgdmFyPHVuaWZvcm0+IHN5c3RlbVVuaWZvcm0gOiBTeXN0ZW1Vbmlmb3JtO1xuICAgQHZlcnRleFxuICAgZm4gbWFpbihpbnB1dDogVmVydGV4SW5wdXQpIC0+IFZlcnRleE91dHB1dCB7XG4gICAgdmFyIG91dHB1dDpWZXJ0ZXhPdXRwdXQ7XG4gICAgb3V0cHV0LmNvbG9yPWlucHV0LmNvbG9yO1xuICAgIG91dHB1dC5wb3NpdGlvbiA9IHN5c3RlbVVuaWZvcm0ucHJvamVjdGlvbk1hdHJpeCAqIHN5c3RlbVVuaWZvcm0udmlld01hdHJpeCAqc2VsZlVuaWZvcm0ubW9kZWxNYXRyaXgqdmVjNDxmMzI+KGlucHV0LnBvc2l0aW9uLDEuMCk7XG4gICAgcmV0dXJuIG91dHB1dDtcbiAgIH1cbiAgIGA7XG59XG4iLCJjb25zdCBwcmVwcm9jZXNzb3JTeW1ib2xzID0gLyMoW15cXHNdKikoXFxzKikvZ207XG4vLyBUZW1wbGF0ZSBsaXRlcmFsIHRhZyB0aGF0IGhhbmRsZXMgc2ltcGxlIHByZXByb2Nlc3NvciBzeW1ib2xzIGZvciBXR1NMXG4vLyBzaGFkZXJzLiBTdXBwb3J0cyAjaWYvZWxpZi9lbHNlL2VuZGlmIHN0YXRlbWVudHMuXG5leHBvcnQgZnVuY3Rpb24gd2dzbFBhcnNlRGVmaW5lcyhzdHJpbmdzLCAuLi52YWx1ZXMpIHtcblx0Y29uc3Qgc3RhdGVTdGFjayA9IFtdO1xuXHRsZXQgc3RhdGUgPSB7IGZyYWc6IFwiXCIsIGVsc2VJc1ZhbGlkOiBmYWxzZSwgZXhwcmVzc2lvbjogdHJ1ZSB9O1xuXHRsZXQgZGVwdGggPSAxO1xuXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgc3RyaW5ncy5sZW5ndGg7ICsraSkge1xuXHRcdGNvbnN0IGZyYWcgPSBzdHJpbmdzW2ldO1xuXHRcdGNvbnN0IG1hdGNoZWRTeW1ib2xzID0gZnJhZy5tYXRjaEFsbChwcmVwcm9jZXNzb3JTeW1ib2xzKTtcblxuXHRcdGxldCBsYXN0SW5kZXggPSAwO1xuXHRcdGxldCB2YWx1ZUNvbnN1bWVkID0gZmFsc2U7XG5cblx0XHRmb3IgKGNvbnN0IG1hdGNoIG9mIG1hdGNoZWRTeW1ib2xzKSB7XG5cdFx0XHRzdGF0ZS5mcmFnICs9IGZyYWcuc3Vic3RyaW5nKGxhc3RJbmRleCwgbWF0Y2guaW5kZXgpO1xuXG5cdFx0XHRzd2l0Y2ggKG1hdGNoWzFdKSB7XG5cdFx0XHRcdGNhc2UgXCJpZlwiOlxuXHRcdFx0XHRcdGlmIChtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aCAhPSBmcmFnLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiI2lmIG11c3QgYmUgaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgYSB0ZW1wbGF0ZSBleHByZXNzaW9uIChpZTogJHt2YWx1ZX0pXCIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR2YWx1ZUNvbnN1bWVkID0gdHJ1ZTtcblx0XHRcdFx0XHRzdGF0ZVN0YWNrLnB1c2goc3RhdGUpO1xuXHRcdFx0XHRcdGRlcHRoKys7XG5cdFx0XHRcdFx0c3RhdGUgPSB7IGZyYWc6IFwiXCIsIGVsc2VJc1ZhbGlkOiB0cnVlLCBleHByZXNzaW9uOiAhIXZhbHVlc1tpXSB9O1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIFwiZWxpZlwiOlxuXHRcdFx0XHRcdGlmIChtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aCAhPSBmcmFnLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiI2VsaWYgbXVzdCBiZSBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSBhIHRlbXBsYXRlIGV4cHJlc3Npb24gKGllOiAke3ZhbHVlfSlcIik7XG5cdFx0XHRcdFx0fSBlbHNlIGlmICghc3RhdGUuZWxzZUlzVmFsaWQpIHtcblx0XHRcdFx0XHRcdHRocm93IG5ldyBFcnJvcihcIiNlbGlmIG5vdCBwcmVjZWVkZWQgYnkgYW4gI2lmIG9yICNlbGlmXCIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR2YWx1ZUNvbnN1bWVkID0gdHJ1ZTtcblx0XHRcdFx0XHRpZiAoc3RhdGUuZXhwcmVzc2lvbiAmJiBzdGF0ZVN0YWNrLmxlbmd0aCAhPSBkZXB0aCkge1xuXHRcdFx0XHRcdFx0c3RhdGVTdGFjay5wdXNoKHN0YXRlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0c3RhdGUgPSB7IGZyYWc6IFwiXCIsIGVsc2VJc1ZhbGlkOiB0cnVlLCBleHByZXNzaW9uOiAhIXZhbHVlc1tpXSB9O1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIFwiZWxzZVwiOlxuXHRcdFx0XHRcdGlmICghc3RhdGUuZWxzZUlzVmFsaWQpIHtcblx0XHRcdFx0XHRcdHRocm93IG5ldyBFcnJvcihcIiNlbHNlIG5vdCBwcmVjZWVkZWQgYnkgYW4gI2lmIG9yICNlbGlmXCIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoc3RhdGUuZXhwcmVzc2lvbiAmJiBzdGF0ZVN0YWNrLmxlbmd0aCAhPSBkZXB0aCkge1xuXHRcdFx0XHRcdFx0c3RhdGVTdGFjay5wdXNoKHN0YXRlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0c3RhdGUgPSB7IGZyYWc6IG1hdGNoWzJdLCBlbHNlSXNWYWxpZDogZmFsc2UsIGV4cHJlc3Npb246IHRydWUgfTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSBcImVuZGlmXCI6XG5cdFx0XHRcdFx0aWYgKCFzdGF0ZVN0YWNrLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiI2VuZGlmIG5vdCBwcmVjZWVkZWQgYnkgYW4gI2lmXCIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjb25zdCBicmFuY2hTdGF0ZSA9IHN0YXRlU3RhY2subGVuZ3RoID09IGRlcHRoID8gc3RhdGVTdGFjay5wb3AoKSA6IHN0YXRlO1xuXHRcdFx0XHRcdHN0YXRlID0gc3RhdGVTdGFjay5wb3AoKTtcblx0XHRcdFx0XHRkZXB0aC0tO1xuXHRcdFx0XHRcdGlmIChicmFuY2hTdGF0ZS5leHByZXNzaW9uKSB7XG5cdFx0XHRcdFx0XHRzdGF0ZS5mcmFnICs9IGJyYW5jaFN0YXRlLmZyYWc7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHN0YXRlLmZyYWcgKz0gbWF0Y2hbMl07XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0Ly8gVW5rbm93biBwcmVwcm9jZXNzb3Igc3ltYm9sLiBFbWl0IGl0IGJhY2sgaW50byB0aGUgb3V0cHV0IGZyYWcgdW5jaGFuZ2VkLlxuXHRcdFx0XHRcdHN0YXRlLmZyYWcgKz0gbWF0Y2hbMF07XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cblx0XHRcdGxhc3RJbmRleCA9IG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoO1xuXHRcdH1cblxuXHRcdC8vIElmIHRoZSBmcmFnIGRpZG4ndCBlbmQgb24gb25lIG9mIHRoZSBwcmVwcm9jZXNzb3Igc3ltYm9scyBhcHBlbmQgdGhlIHJlc3Qgb2YgaXQgaGVyZS5cblx0XHRpZiAobGFzdEluZGV4ICE9IGZyYWcubGVuZ3RoKSB7XG5cdFx0XHRzdGF0ZS5mcmFnICs9IGZyYWcuc3Vic3RyaW5nKGxhc3RJbmRleCwgZnJhZy5sZW5ndGgpO1xuXHRcdH1cblxuXHRcdC8vIElmIHRoZSBuZXh0IHZhbHVlIHdhc24ndCBjb25zdW1lZCBieSB0aGUgcHJlcHJvY2Vzc29yIHN5bWJvbCwgYXBwZW5kIGl0IGhlcmUuXG5cdFx0aWYgKCF2YWx1ZUNvbnN1bWVkICYmIHZhbHVlcy5sZW5ndGggPiBpKSB7XG5cdFx0XHRzdGF0ZS5mcmFnICs9IHZhbHVlc1tpXTtcblx0XHR9XG5cdH1cblxuXHRpZiAoc3RhdGVTdGFjay5sZW5ndGgpIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoXCJNaXNtYXRjaGVkICNpZi8jZW5kaWYgY291bnRcIik7XG5cdH1cblxuXHRyZXR1cm4gc3RhdGUuZnJhZztcbn1cbiIsImltcG9ydCB7IHdnc2xQYXJzZURlZmluZXMgfSBmcm9tIFwiLi4vV2dzbFByZXByb2Nlc3NvclwiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcGJyX2ZzKGRlZmluZXMpIHtcblx0cmV0dXJuIHdnc2xQYXJzZURlZmluZXNgXG4gICAgICAgIC8vIHJlZmVyZW5jZTogaHR0cHM6Ly9naXRodWIuY29tL0tocm9ub3NHcm91cC9nbFRGLVdlYkdMLVBCUi9ibG9iL21hc3Rlci9zaGFkZXJzL3Bici1mcmFnLmdsc2xcbiAgICAgICAgI2luY2x1ZGUgPHBiclV0aWxzPlxuICAgICAgICAjaW5jbHVkZSA8bGlnaHQ+XG4gICAgICAgICNpbmNsdWRlIDxicmRmPlxuICAgICAgICAjaW5jbHVkZSA8UGJyTWF0ZXJpYWxTdHJ1Y3Q+XG4gICAgICAgICNpbmNsdWRlIDxTeXN0ZW1Vbmlmb3JtPiBcbiAgICAgICAgI2luY2x1ZGUgPEZyYWdJbnB1dD4gICBcbiAgICAgICAgc3RydWN0IFBoeXNpY2FsTWF0ZXJpYWwge1xuICAgICAgICAgICAgZGlmZnVzZUNvbG9yOnZlYzM8ZjMyPixcbiAgICAgICAgICAgIHJvdWdobmVzczpmMzIsXG4gICAgICAgICAgICBzcGVjdWxhckNvbG9yOnZlYzM8ZjMyPixcbiAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfQ0xFQVJDT0FUfVxuICAgICAgICAgICAgICAgY2xlYXJjb2F0OmYzMixcbiAgICAgICAgICAgICAgIGNsZWFyY29hdFJvdWdobmVzczpmMzIsXG4gICAgICAgICAgICAgICBjbGVhcmNvYXRGMDp2ZWMzPGYzMj4sXG4gICAgICAgICAgICAgICBjbGVhcmNvYXRGOTA6ZjMyLFxuICAgICAgICAgICAjZW5kaWZcblxuICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9JUklERVNDRU5DRX1cbiAgICAgICAgICAgICAgIGlyaWRlc2NlbmNlOmYzMixcbiAgICAgICAgICAgICAgIGlyaWRlc2NlbmNlSU9SOmYzMixcbiAgICAgICAgICAgICAgIGlyaWRlc2NlbmNlVGhpY2tuZXNzOmYzMixcbiAgICAgICAgICAgICAgIGlyaWRlc2NlbmNlRnJlc25lbDp2ZWMzPGYzMj4sXG4gICAgICAgICAgICAgICBpcmlkZXNjZW5jZUYwOnZlYzM8ZjMyPixcbiAgICAgICAgICAgI2VuZGlmXG5cbiAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfU0hFRU59XG4gICAgICAgICAgICAgICBzaGVlbkNvbG9yOnZlYzM8ZjMyPixcbiAgICAgICAgICAgICAgIHNoZWVuUm91Z2huZXNzOmYzMixcbiAgICAgICAgICAgI2VuZGlmXG5cbiAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5JT1J9XG4gICAgICAgICAgICAgICAgaW9yOmYzMixcbiAgICAgICAgICAgI2VuZGlmXG5cbiAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfVFJBTlNNSVNTSU9OfVxuICAgICAgICAgICAgICAgdHJhbnNtaXNzaW9uOmYzMixcbiAgICAgICAgICAgICAgIHRyYW5zbWlzc2lvbkFscGhhOmYzMixcbiAgICAgICAgICAgICAgIHRoaWNrbmVzczpmMzIsXG4gICAgICAgICAgICAgICBhdHRlbnVhdGlvbkRpc3RhbmNlOmYzMixcbiAgICAgICAgICAgICAgIGF0dGVudWF0aW9uQ29sb3I6dmVjMzxmMzI+LFxuICAgICAgICAgICAjZW5kaWZcbiAgICAgICB9O1xuICAgICAgICBjb25zdCBNX1BJOmYzMiA9IDMuMTQxNTkyNjUzNTg5NzkzO1xuICAgICAgICBjb25zdCBjX01pblJvdWdobmVzczpmMzIgPSAwLjA0O1xuICAgICAgICAjaW5jbHVkZSA8VGV4dHVyZUFuZFNhbXBsZXJEZWZpbmU+XG4gICAgICAgICNpZiAke2RlZmluZXMuVVNFX0lCTH1cbiAgICAgICAgICAgICNpbmNsdWRlIDxpYmw+XG4gICAgICAgICNlbmRpZlxuICAgICAgICBAYmluZGluZygke2RlZmluZXMucGJyQmluZGluZ30pIEBncm91cCgwKSB2YXI8dW5pZm9ybT4gbWF0ZXJpYWxVbmlmb3JtIDogTWF0ZXJpYWxVbmlmb3JtO1xuICAgICAgICBAYmluZGluZygke2RlZmluZXMuY2FtZXJhQmluZGluZ30pIEBncm91cCgxKSB2YXI8dW5pZm9ybT4gc3lzdGVtVW5pZm9ybSA6IFN5c3RlbVVuaWZvcm07XG4gICAgICAgIEBmcmFnbWVudFxuICAgICAgICBmbiBtYWluKGlucHV0OkZyYWdJbnB1dCkgLT4gQGxvY2F0aW9uKDApIHZlYzQ8ZjMyPiBcbiAgICAgICAge1xuICAgICAgICAgICAgdmFyIHBlcmNlcHR1YWxSb3VnaG5lc3M6ZjMyID0gbWF0ZXJpYWxVbmlmb3JtLnJvdWdobmVzcztcbiAgICAgICAgICAgIHZhciBtZXRhbGxpYzpmMzIgPSBtYXRlcmlhbFVuaWZvcm0ubWV0YWxsaWM7XG5cbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX01FVEFMTkVTU1RFWFRVUkV9XG4gICAgICAgICAgICAgICAgbGV0IG1yU2FtcGxlOnZlYzQ8ZjMyPiA9IHRleHR1cmVTYW1wbGUobWV0YWxuZXNzUm91Z2huZXNzVGV4dHVyZSxtZXRhbG5lc3NSb3VnaG5lc3NTYW1wbGVyLCBpbnB1dC51dik7XG4gICAgICAgICAgICAgICAgcGVyY2VwdHVhbFJvdWdobmVzcyA9IG1yU2FtcGxlLmcgKiBwZXJjZXB0dWFsUm91Z2huZXNzO1xuICAgICAgICAgICAgICAgIG1ldGFsbGljID0gbXJTYW1wbGUuYiAqIG1ldGFsbGljO1xuICAgICAgICAgICAgI2VuZGlmXG4gICAgICAgICAgICBwZXJjZXB0dWFsUm91Z2huZXNzID0gY2xhbXAocGVyY2VwdHVhbFJvdWdobmVzcywgY19NaW5Sb3VnaG5lc3MsIDEuMCk7XG4gICAgICAgICAgICBtZXRhbGxpYyA9IGNsYW1wKG1ldGFsbGljLCAwLjAsIDEuMCk7XG4gICAgICAgICAgICBsZXQgYWxwaGFSb3VnaG5lc3M6ZjMyID0gcGVyY2VwdHVhbFJvdWdobmVzcyAqIHBlcmNlcHR1YWxSb3VnaG5lc3M7XG5cblxuICAgICAgICAgICAgLy8gVGhlIGFsYmVkbyBtYXkgYmUgZGVmaW5lZCBmcm9tIGEgYmFzZSB0ZXh0dXJlIG9yIGEgZmxhdCBjb2xvclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfVEVYVFVSRX1cbiAgICAgICAgICAgICAgICBsZXQgYmFzZUNvbG9yOnZlYzQ8ZjMyPiA9IHRleHR1cmVTYW1wbGUoYmFzZUNvbG9yVGV4dHVyZSxiYXNlQ29sb3JTYW1wbGVyLCBpbnB1dC51dikgO1xuICAgICAgICAgICAgI2Vsc2VcbiAgICAgICAgICAgICAgICBsZXQgYmFzZUNvbG9yOnZlYzQ8ZjMyPiA9IHZlYzQ8ZjMyPihtYXRlcmlhbFVuaWZvcm0uY29sb3IsMS4wKTtcbiAgICAgICAgICAgICNlbmRpZlxuXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9OT1JNQUxURVhUVVJFfVxuICAgICAgICAgICAgICAgIGxldCBuOnZlYzM8ZjMyPiA9IGdldE5vcm1hbEJ5Tm9ybWFsVGV4dHVyZShpbnB1dCk7ICBcbiAgICAgICAgICAgICNlbHNlXG4gICAgICAgICAgICAgICAgbGV0IG46dmVjMzxmMzI+ID0gZ2V0Tm9ybWFsKGlucHV0KTtcbiAgICAgICAgICAgICNlbmRpZlxuICAgICAgICAgICAgdmFyIG1hdGVyaWFsOlBoeXNpY2FsTWF0ZXJpYWw7XG4gICAgICAgICAgICBtYXRlcmlhbC5kaWZmdXNlQ29sb3I9YmFzZUNvbG9yLnJnYiooIDEuMCAtIG1ldGFsbGljICk7XG4gICAgICAgICAgICBtYXRlcmlhbC5yb3VnaG5lc3M9cGVyY2VwdHVhbFJvdWdobmVzcztcbiAgICAgICAgICAgIG1hdGVyaWFsLnNwZWN1bGFyQ29sb3I9bWl4KCB2ZWMzPGYzMj4oIDAuMDQpLCBiYXNlQ29sb3IucmdiLCBtZXRhbGxpYyApO1xuICAgICAgICAgICAgdmFyIGdlb21ldHJ5Okdlb21ldHJ5O1xuICAgICAgICAgICAgZ2VvbWV0cnkubm9ybWFsPW47XG4gICAgICAgICAgICBnZW9tZXRyeS52aWV3RGlyPW5vcm1hbGl6ZShzeXN0ZW1Vbmlmb3JtLmNhbWVyYVBvc2l0aW9uIC0gaW5wdXQud29ybGRQb3MpO1xuICAgICAgICAgICAgZ2VvbWV0cnkucG9zaXRpb249aW5wdXQud29ybGRQb3M7XG4gICAgICAgICAgICBnZW9tZXRyeS5kb3ROViA9IHNhdHVyYXRlKGRvdChnZW9tZXRyeS5ub3JtYWwsIGdlb21ldHJ5LnZpZXdEaXIpICk7XG4gICAgICAgICAgICAvL2xpZ2h0IHNoYWRpbmdcbiAgICAgICAgICAgIHZhciByZWZsZWN0ZWRMaWdodD1wYXJzZUxpZ2h0cyhnZW9tZXRyeSxtYXRlcmlhbCk7XG4gICAgICAgICAgICB2YXIgY29sb3I9cmVmbGVjdGVkTGlnaHQuZGlyZWN0RGlmZnVzZStyZWZsZWN0ZWRMaWdodC5kaXJlY3RTcGVjdWxhcjtcbiAgICAgICAgICAgIC8vSUJMXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9JQkwgJiYgZGVmaW5lcy5IQVNfVVZ9XG4gICAgICAgICAgICAgICAgdmFyIHJlZmxlY3RlZExpZ2h0RGlmZnVzZT1pbmRpcmVjdERpZmZ1c2VfUGh5c2ljYWwoZ2VvbWV0cnksbWF0ZXJpYWwpO1xuICAgICAgICAgICAgICAgIHZhciByZWZsZWN0ZWRMaWdodFNwZWN1bGFyPWluZGlyZWN0U3BlY3VsYXJfUGh5c2ljYWwoZ2VvbWV0cnksbWF0ZXJpYWwpO1xuICAgICAgICAgICAgICAgIGNvbG9yKz1yZWZsZWN0ZWRMaWdodERpZmZ1c2UuaW5kaXJlY3REaWZmdXNlO1xuICAgICAgICAgICAgICAgIGNvbG9yKz1yZWZsZWN0ZWRMaWdodFNwZWN1bGFyLmluZGlyZWN0U3BlY3VsYXI7XG4gICAgICAgICAgICAjZW5kaWZcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX0FPVEVYVFVSRX1cbiAgICAgICAgICAgICAgICBsZXQgYW86ZjMyID0gdGV4dHVyZVNhbXBsZShhb1RleHR1cmUsYW9TYW1wbGVyLCBpbnB1dC51dikucjtcbiAgICAgICAgICAgICAgICBjb2xvciA9IG1peChjb2xvciwgY29sb3IgKiBhbywgbWF0ZXJpYWxVbmlmb3JtLm9jY2x1c2lvblN0cmVuZ3RoKTtcbiAgICAgICAgICAgICNlbmRpZlxuXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9FTUlTU0lWRVRFWFRVUkV9XG4gICAgICAgICAgICAgICAgbGV0IGVtaXNzaXZlOnZlYzM8ZjMyPiA9IHRleHR1cmVTYW1wbGUoZW1pc3NpdmVUZXh0dXJlLCBlbWlzc2l2ZVNhbXBsZXIsaW5wdXQudXYpLnJnYiA7XG4gICAgICAgICAgICAgICAgY29sb3IgKz0gZW1pc3NpdmU7XG4gICAgICAgICAgICAjZW5kaWZcbiAgICAgICByZXR1cm4gdmVjNDxmMzI+KGNvbG9yLCBiYXNlQ29sb3IuYSk7XG4gICAgfVxuICAgYDtcbn1cbiIsImltcG9ydCB7IHdnc2xQYXJzZURlZmluZXMgfSBmcm9tIFwiLi4vV2dzbFByZXByb2Nlc3NvclwiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcGJyX3ZzKGRlZmluZXMpIHtcblx0cmV0dXJuIHdnc2xQYXJzZURlZmluZXNgXG4gICAgI2luY2x1ZGUgPFBick1hdGVyaWFsU3RydWN0PlxuICAgICNpbmNsdWRlIDxTeXN0ZW1Vbmlmb3JtPlxuICAgICNpbmNsdWRlIDxWZXJ0ZXhJbnB1dD5cbiAgICAjaW5jbHVkZSA8VmVydGV4T3V0cHV0PiBcbiAgICAjaW5jbHVkZSA8c2tpblZlcnRIZWFkZXI+XG4gICAgI2luY2x1ZGUgPGluc3RhbmNlVmVydEhlYWRlcj5cbiAgICBAYmluZGluZygke2RlZmluZXMucGJyQmluZGluZ30pIEBncm91cCgwKSB2YXI8dW5pZm9ybT4gbWF0ZXJpYWxVbmlmb3JtIDogTWF0ZXJpYWxVbmlmb3JtO1xuICAgIEBiaW5kaW5nKCR7ZGVmaW5lcy5jYW1lcmFCaW5kaW5nfSkgQGdyb3VwKDEpIHZhcjx1bmlmb3JtPiBzeXN0ZW1Vbmlmb3JtIDogU3lzdGVtVW5pZm9ybTtcbiAgICBAdmVydGV4XG4gICAgZm4gbWFpbihpbnB1dDogVmVydGV4SW5wdXQpLT4gVmVydGV4T3V0cHV0XG4gICB7XG4gICAgICAgIHZhciBvdXRwdXQ6IFZlcnRleE91dHB1dDtcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5IQVNfVVZ9XG4gICAgICAgICAgICBvdXRwdXQudXYgPSBpbnB1dC51djtcbiAgICAgICAgI2VuZGlmXG4gICAgICAgIHZhciBtb2RlbE1hdHJpeDptYXQ0eDQ8ZjMyPjtcbiAgICAgICAgdmFyIHZOb3JtYWxWaWV3OnZlYzM8ZjMyPjtcbiAgICAgICAgdk5vcm1hbFZpZXcgPSBub3JtYWxpemUobWF0ZXJpYWxVbmlmb3JtLm5vcm1hbE1hdHJpeCAqIHZlYzQ8ZjMyPihpbnB1dC5ub3JtYWwsMC4wKSkueHl6O1xuICAgICAgICBtb2RlbE1hdHJpeD1tYXRlcmlhbFVuaWZvcm0ubW9kZWxNYXRyaXg7ICAgXG4gICAgICAgICNpbmNsdWRlIDxza2luVmVydE1haW4+XG4gICAgICAgICNpbmNsdWRlIDxpbnN0YW5jZVZlcnRNYWluPiAgXG4gICAgICAgIG91dHB1dC5ub3JtYWwgPSB2Tm9ybWFsVmlldy54eXo7XG4gICAgICAgIG91dHB1dC5wb3NpdGlvbiA9IHN5c3RlbVVuaWZvcm0ucHJvamVjdGlvbk1hdHJpeCAqIHN5c3RlbVVuaWZvcm0udmlld01hdHJpeCAqbW9kZWxNYXRyaXgqIHZlYzQ8ZjMyPihpbnB1dC5wb3NpdGlvbiwgMS4wKTtcbiAgICAgICAgbGV0IG1vZGVsUG9zPW1vZGVsTWF0cml4ICp2ZWM0PGYzMj4oaW5wdXQucG9zaXRpb24sMS4wKTtcbiAgICAgICAgb3V0cHV0LndvcmxkUG9zID0gbW9kZWxQb3MueHl6L21vZGVsUG9zLnc7XG4gICAgICAgIHJldHVybiBvdXRwdXQ7ICAgXG4gICB9XG4gICBgO1xufVxuIiwiaW1wb3J0IHsgd2dzbFBhcnNlRGVmaW5lcyB9IGZyb20gXCIuLi9XZ3NsUHJlcHJvY2Vzc29yXCI7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBwYnJGcmFnKGRlZmluZXMpIHtcclxuXHRyZXR1cm4gd2dzbFBhcnNlRGVmaW5lc2BcclxuICAgICNpbmNsdWRlIDxsaWdodENvbW1vbj5cclxuICAgICNpbmNsdWRlIDxsaWdodD5cclxuICAgICNpbmNsdWRlIDxicmRmPlxyXG4gICAgI2luY2x1ZGUgPHBiclN0cnVjdD5cclxuICAgICNpbmNsdWRlIDxwYnJVdGlscz5cclxuICAgICNpbmNsdWRlIDxwYnJGdW5jdGlvbj5cclxuICAgICNpbmNsdWRlIDxwYnJUZXh0dXJlPlxyXG4gICAgI2luY2x1ZGUgPGVudmlyb25tZW50PlxyXG4gICAgc3RydWN0IFN5c3RlbVVuaWZvcm0ge1xyXG4gICAgICAgIHByb2plY3Rpb25NYXRyaXg6IG1hdDR4NDxmMzI+LFxyXG4gICAgICAgIHZpZXdNYXRyaXg6IG1hdDR4NDxmMzI+LFxyXG4gICAgICAgIGludmVyc2VWaWV3TWF0cml4OiBtYXQ0eDQ8ZjMyPixcclxuICAgICAgICBjYW1lcmFQb3NpdGlvbjogdmVjMzxmMzI+LFxyXG4gICAgfTsgXHJcbiAgICAvLyB1bmlmb3JtIHZlYzMgbGlnaHRQcm9iZVs5XSxcclxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcbnN0cnVjdCBWZXJ0ZXhPdXRwdXQge1xyXG4gICAgQGJ1aWx0aW4ocG9zaXRpb24pIHBvc2l0aW9uOiB2ZWM0PGYzMj4sXHJcbiAgICBAYnVpbHRpbihmcm9udF9mYWNpbmcpIGlzX2Zyb250OiBib29sLFxyXG4gICAgQGxvY2F0aW9uKDApIHZVdjogdmVjMjxmMzI+LFxyXG4gICAgQGxvY2F0aW9uKDEpIHZWaWV3UG9zaXRpb246IHZlYzM8ZjMyPiwgLy8gVmVjdG9yIGZyb20gdmVydGV4IHRvIGNhbWVyYS5cclxuICAgIEBsb2NhdGlvbigyKSB2V29ybGRQb3NpdGlvbjogdmVjMzxmMzI+LFxyXG4gICAgQGxvY2F0aW9uKDMpIHZOb3JtYWw6IHZlYzM8ZjMyPixcclxuICAgIC8vIOWPr+mAiVxyXG4gICAgI2lmICR7ZGVmaW5lcy5VU0VfTElHSFRURVhUVVJFIHx8IGRlZmluZXMuVVNFX0FPVEVYVFVSRX1cclxuICAgICAgICBAbG9jYXRpb24oJHtkZWZpbmVzLnZVdjJPdXRMb2NhdGlvbn0pIHZVdjI6IHZlYzI8ZjMyPixcclxuICAgICNlbmRpZlxyXG5cclxuICAgICNpZiAke2RlZmluZXMuVVNFX0NPTE9SX0FMUEhBfVxyXG4gICAgICAgIEBsb2NhdGlvbigke2RlZmluZXMudkNvbG9yT3V0TG9jYXRpb259KSB2Q29sb3I6IHZlYzQ8ZjMyPixcclxuICAgICNlbGlmICR7ZGVmaW5lcy5VU0VfQ09MT1IgfHwgZGVmaW5lcy5VU0VfSU5TVEFOQ0lOR19DT0xPUn1cclxuICAgICAgICBAbG9jYXRpb24oJHtkZWZpbmVzLnZDb2xvck91dExvY2F0aW9ufSkgdkNvbG9yOiB2ZWMzPGYzMj4sXHJcbiAgICAjZW5kaWZcclxuXHJcbiAgICAjaWYgJHtkZWZpbmVzLlVTRV9UQU5HRU5UfVxyXG4gICAgICAgIEBsb2NhdGlvbigke2RlZmluZXMudlRhbmdlbnRPdXRMb2NhdGlvbn0pIHZUYW5nZW50OiB2ZWMzPGYzMj4sXHJcbiAgICAgICAgQGxvY2F0aW9uKCR7ZGVmaW5lcy52Qml0YW5nZW50T3V0TG9jYXRpb259KSB2Qml0YW5nZW50OiB2ZWMzPGYzMj4sXHJcbiAgICAjZW5kaWZcclxufTtcclxuICAgICAgICBzdHJ1Y3QgUGh5c2ljYWxNYXRlcmlhbCB7XHJcbiAgICAgICAgICAgICBkaWZmdXNlQ29sb3I6dmVjMzxmMzI+LFxyXG4gICAgICAgICAgICAgcm91Z2huZXNzOmYzMixcclxuICAgICAgICAgICAgIHNwZWN1bGFyQ29sb3I6dmVjMzxmMzI+LFxyXG4gICAgICAgICAgICAgc3BlY3VsYXJGOTA6ZjMyLFxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9DTEVBUkNPQVR9XHJcbiAgICAgICAgICAgICAgICBjbGVhcmNvYXQ6ZjMyLFxyXG4gICAgICAgICAgICAgICAgY2xlYXJjb2F0Um91Z2huZXNzOmYzMixcclxuICAgICAgICAgICAgICAgIGNsZWFyY29hdEYwOnZlYzM8ZjMyPixcclxuICAgICAgICAgICAgICAgIGNsZWFyY29hdEY5MDpmMzIsXHJcbiAgICAgICAgICAgICNlbmRpZlxyXG5cclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfSVJJREVTQ0VOQ0V9XHJcbiAgICAgICAgICAgICAgICBpcmlkZXNjZW5jZTpmMzIsXHJcbiAgICAgICAgICAgICAgICBpcmlkZXNjZW5jZUlPUjpmMzIsXHJcbiAgICAgICAgICAgICAgICBpcmlkZXNjZW5jZVRoaWNrbmVzczpmMzIsXHJcbiAgICAgICAgICAgICAgICBpcmlkZXNjZW5jZUZyZXNuZWw6dmVjMzxmMzI+LFxyXG4gICAgICAgICAgICAgICAgaXJpZGVzY2VuY2VGMDp2ZWMzPGYzMj4sXHJcbiAgICAgICAgICAgICNlbmRpZlxyXG5cclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfU0hFRU59XHJcbiAgICAgICAgICAgICAgICBzaGVlbkNvbG9yOnZlYzM8ZjMyPixcclxuICAgICAgICAgICAgICAgIHNoZWVuUm91Z2huZXNzOmYzMixcclxuICAgICAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLklPUn1cclxuICAgICAgICAgICAgICAgICBpb3I6ZjMyLFxyXG4gICAgICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX1RSQU5TTUlTU0lPTn1cclxuICAgICAgICAgICAgICAgIHRyYW5zbWlzc2lvbjpmMzIsXHJcbiAgICAgICAgICAgICAgICB0cmFuc21pc3Npb25BbHBoYTpmMzIsXHJcbiAgICAgICAgICAgICAgICB0aGlja25lc3M6ZjMyLFxyXG4gICAgICAgICAgICAgICAgYXR0ZW51YXRpb25EaXN0YW5jZTpmMzIsXHJcbiAgICAgICAgICAgICAgICBhdHRlbnVhdGlvbkNvbG9yOnZlYzM8ZjMyPixcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgfTtcclxuQGJpbmRpbmcoMCkgQGdyb3VwKDApIHZhcjx1bmlmb3JtPiBtYXRlcmlhbFVuaWZvcm0gOiBNYXRlcmlhbFVuaWZvcm07XHJcbkBiaW5kaW5nKDApIEBncm91cCgxKSB2YXI8dW5pZm9ybT4gc3lzdGVtVW5pZm9ybSA6IFN5c3RlbVVuaWZvcm07XHJcbkBmcmFnbWVudFxyXG5mbiBtYWluKGlucHV0OlZlcnRleE91dHB1dCktPiBAbG9jYXRpb24oMCkgdmVjNDxmMzI+IHtcclxuICAgICAgICB2YXIgZGlmZnVzZUNvbG9yOnZlYzQ8ZjMyPiA9IHZlYzQobWF0ZXJpYWxVbmlmb3JtLmRpZmZ1c2UsIG1hdGVyaWFsVW5pZm9ybS5vcGFjaXR5ICk7XHJcbiAgICAgICAvLyBSZWZsZWN0ZWRMaWdodCByZWZsZWN0ZWRMaWdodCA9IFJlZmxlY3RlZExpZ2h0KCB2ZWMzKCAwLjAgKSwgdmVjMyggMC4wICksIHZlYzMoIDAuMCApLCB2ZWMzKCAwLjAgKSApO1xyXG4gICAgICAgIHZhciByZWZsZWN0ZWRMaWdodDpSZWZsZWN0ZWRMaWdodDtcclxuICAgICAgICB2YXIgdG90YWxFbWlzc2l2ZVJhZGlhbmNlOnZlYzM8ZjMyPiA9IG1hdGVyaWFsVW5pZm9ybS5lbWlzc2l2ZTtcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9URVhUVVJFfVxyXG4gICAgICAgICAgICB2YXIgc2FtcGxlZERpZmZ1c2VDb2xvcjp2ZWM0PGYzMj4gPXRleHR1cmVTYW1wbGUoYmFzZVRleHR1cmUsIGJhc2VTYW1wbGVyLCBpbnB1dC52VXYpO1xyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLkRFQ09ERV9WSURFT19URVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgc2FtcGxlZERpZmZ1c2VDb2xvciA9IHZlYzQ8ZjMyPiggbWl4KCBwb3coIHNhbXBsZWREaWZmdXNlQ29sb3IucmdiICogMC45NDc4NjcyOTg2ICsgdmVjMzxmMzI+KCAwLjA1MjEzMjcwMTQgKSwgdmVjMzxmMzI+KCAyLjQgKSApLCBzYW1wbGVkRGlmZnVzZUNvbG9yLnJnYiAqIDAuMDc3Mzk5MzgwOCwgdmVjMzxmMzI+KCBsZXNzVGhhbkVxdWFsKCBzYW1wbGVkRGlmZnVzZUNvbG9yLnJnYiwgdmVjMzxmMzI+KCAwLjA0MDQ1ICkgKSApICksIHNhbXBsZWREaWZmdXNlQ29sb3IudyApO1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgICAgIGRpZmZ1c2VDb2xvciAqPSBzYW1wbGVkRGlmZnVzZUNvbG9yO1xyXG4gICAgICAgICNlbmRpZlxyXG5cclxuICAgICAgICB2YXIgcm91Z2huZXNzRmFjdG9yOmYzMiA9IG1hdGVyaWFsVW5pZm9ybS5yb3VnaG5lc3M7XHJcbiAgICBcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9ST1VHSE5FU1NURVhUVVJFfVxyXG4gICAgICAgICAgICBsZXQgdGV4ZWxSb3VnaG5lc3M6dmVjNDxmMzI+PXRleHR1cmVTYW1wbGUocm91Z2huZXNzVGV4dHVyZSwgYmFzZVNhbXBsZXIsIGlucHV0LnZVdik7XHJcbiAgICAgICAgICAgIHJvdWdobmVzc0ZhY3RvciAqPSB0ZXhlbFJvdWdobmVzcy5nO1xyXG4gICAgICAgICNlbmRpZlxyXG5cclxuICAgICAgICB2YXIgbWV0YWxuZXNzRmFjdG9yOmYzMiA9IG1hdGVyaWFsVW5pZm9ybS5tZXRhbG5lc3M7XHJcbiAgICBcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9NRVRBTE5FU1NURVhUVVJFfVxyXG4gICAgICAgICAgICBsZXQgdGV4ZWxNZXRhbG5lc3M6dmVjNDxmMzI+ID10ZXh0dXJlU2FtcGxlKG1ldGFsbmVzc1RleHR1cmUsIGJhc2VTYW1wbGVyLCBpbnB1dC52VXYpO1xyXG4gICAgICAgICAgICBtZXRhbG5lc3NGYWN0b3IgKj0gdGV4ZWxNZXRhbG5lc3MuYjtcclxuICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgbGV0IGZhY2VEaXJlY3Rpb246ZjMyID1zZWxlY3QoLTEuMCwxLjAsaW5wdXQuaXNfZnJvbnQpO1xyXG4gICAgICAgICNpZiAke2RlZmluZXMuRkxBVF9TSEFERUR9XHJcbiAgICAgICAgICAgIGxldCBmZHg6dmVjMzxmMzI+ID0gZHBkeCggaW5wdXQudlZpZXdQb3NpdGlvbiApO1xyXG4gICAgICAgICAgICBsZXQgZmR5OnZlYzM8ZjMyPiA9IGRwZHkoIGlucHV0LnZWaWV3UG9zaXRpb24gKTtcclxuICAgICAgICAgICAgbGV0IG5vcm1hbDp2ZWMzPGYzMj4gPSBub3JtYWxpemUoIGNyb3NzKCBmZHksIGZkeCApICk7XHJcbiAgICAgICAgI2Vsc2VcclxuICAgICAgICAgICAgbGV0IG5vcm1hbDp2ZWMzPGYzMj4gPSBub3JtYWxpemUoIGlucHV0LnZOb3JtYWwgKTtcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5ET1VCTEVfU0lERUR9XHJcbiAgICAgICAgICAgICAgICBub3JtYWwgPSBub3JtYWwgKiBmYWNlRGlyZWN0aW9uO1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfVEFOR0VOVH1cclxuICAgICAgICAgICAgICAgIGxldCB0YW5nZW50OnZlYzM8ZjMyPiA9IG5vcm1hbGl6ZSggaW5wdXQudlRhbmdlbnQgKTtcclxuICAgICAgICAgICAgICAgIGxldCBiaXRhbmdlbnQ6dmVjMzxmMzI+ID0gbm9ybWFsaXplKCBpbnB1dC52Qml0YW5nZW50ICk7XHJcbiAgICAgICAgICAgICAgICAjaWYgJHtkZWZpbmVzLkRPVUJMRV9TSURFRH1cclxuICAgICAgICAgICAgICAgICAgICB0YW5nZW50ID0gdGFuZ2VudCAqIGZhY2VEaXJlY3Rpb247XHJcbiAgICAgICAgICAgICAgICAgICAgYml0YW5nZW50ID0gYml0YW5nZW50ICogZmFjZURpcmVjdGlvbjtcclxuICAgICAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5UQU5HRU5UU1BBQ0VfTk9STUFMVEVYVFVSRSB8fCBkZWZpbmVzLlVTRV9DTEVBUkNPQVRfTk9STUFMVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgICAgICBsZXQgdlRCTjptYXQzeDM8ZjMyPiA9IG1hdDN4MzxmMzI+KCB0YW5nZW50LCBiaXRhbmdlbnQsIG5vcm1hbCApO1xyXG4gICAgICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICNlbmRpZlxyXG4gICAgXHJcbiAgICAgICAgbGV0IGdlb21ldHJ5Tm9ybWFsOnZlYzM8ZjMyPiA9IG5vcm1hbDtcclxuXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5PQkpFQ1RTUEFDRV9OT1JNQUxURVhUVVJFfVxyXG4gICAgICAgICAgICBub3JtYWwgPXRleHR1cmVTYW1wbGUobm9ybWFsVGV4dHVyZSwgYmFzZVNhbXBsZXIsIGlucHV0LnZVdikueHl6ICogMi4wIC0gMS4wO1xyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLkZMSVBfU0lERUR9XHJcbiAgICAgICAgICAgICAgICBub3JtYWwgPSAtIG5vcm1hbDtcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuRE9VQkxFX1NJREVEfVxyXG4gICAgICAgICAgICAgICAgbm9ybWFsID0gbm9ybWFsICogZmFjZURpcmVjdGlvbjtcclxuICAgICAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgICAgICBub3JtYWwgPSBub3JtYWxpemUobWF0ZXJpYWxVbmlmb3JtLm5vcm1hbE1hdHJpeCAqIG5vcm1hbCApO1xyXG5cclxuICAgICAgICAgICAgI2VsaWYgJHtkZWZpbmVzLlRBTkdFTlRTUEFDRV9OT1JNQUxURVhUVVJFfVxyXG4gICAgICAgICAgICBsZXQgdGVtcE1hcE46dmVjMzxmMzI+ID10ZXh0dXJlU2FtcGxlKG5vcm1hbFRleHR1cmUsIGJhc2VTYW1wbGVyLCBpbnB1dC52VXYpLnh5eiAqIDIuMCAtIDEuMDtcclxuICAgICAgICAgICAgbGV0IG1hcE46dmVjMzxmMzI+ID10ZW1wTWFwTi54eSAqPSBtYXRlcmlhbFVuaWZvcm0ubm9ybWFsU2NhbGU7XHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX1RBTkdFTlR9XHJcbiAgICAgICAgICAgICAgICBub3JtYWwgPSBub3JtYWxpemUoIHZUQk4gKiBtYXBOICk7XHJcbiAgICAgICAgICAgICNlbHNlXHJcbiAgICAgICAgICAgICAgICBub3JtYWwgPSBwZXJ0dXJiTm9ybWFsMkFyYiggLSBpbnB1dC52Vmlld1Bvc2l0aW9uLCBub3JtYWwsIG1hcE4sIGZhY2VEaXJlY3Rpb24gKTtcclxuICAgICAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgICAgICAjZWxpZiAke2RlZmluZXMuVVNFX0JVTVBURVhUVVJFfVxyXG5cclxuICAgICAgICAgICAgICAgIG5vcm1hbCA9IHBlcnR1cmJOb3JtYWxBcmIoIC0gaW5wdXQudlZpZXdQb3NpdGlvbiwgbm9ybWFsLCBkSGR4eV9md2QoKSwgZmFjZURpcmVjdGlvbiApO1xyXG4gICAgICAgICNlbmRpZlxyXG5cclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9DTEVBUkNPQVR9XHJcbiAgICAgICAgICAgIHZhciBjbGVhcmNvYXROb3JtYWw6dmVjMzxmMzI+ID0gZ2VvbWV0cnlOb3JtYWw7XHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfQ0xFQVJDT0FUX05PUk1BTFRFWFRVUkV9XHJcbiAgICAgICAgICAgIHZhciBjbGVhcmNvYXRNYXBOOnZlYzM8ZjMyPiA9dGV4dHVyZVNhbXBsZShjbGVhcmNvYXROb3JtYWxUZXh0dXJlLCBiYXNlU2FtcGxlciwgaW5wdXQudlV2KS54eXogKiAyLjAgLSAxLjA7XHJcbiAgICAgICAgICAgIGNsZWFyY29hdE1hcE4ueHkgKj0gbWF0ZXJpYWxVbmlmb3JtLmNsZWFyY29hdE5vcm1hbFNjYWxlO1xyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9UQU5HRU5UfVxyXG4gICAgICAgICAgICAgICAgY2xlYXJjb2F0Tm9ybWFsID0gbm9ybWFsaXplKCB2VEJOICogY2xlYXJjb2F0TWFwTiApO1xyXG4gICAgICAgICAgICAjZWxzZVxyXG4gICAgICAgICAgICAgICAgY2xlYXJjb2F0Tm9ybWFsID0gcGVydHVyYk5vcm1hbDJBcmIoIC0gaW5wdXQudlZpZXdQb3NpdGlvbiwgY2xlYXJjb2F0Tm9ybWFsLCBjbGVhcmNvYXRNYXBOLCBmYWNlRGlyZWN0aW9uICk7XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICNlbmRpZlxyXG4gICAgICAgICNpZiAke2RlZmluZXMuVVNFX0VNSVNTSVZFVEVYVFVSRX1cclxuICAgICAgICAgICAgbGV0IGVtaXNzaXZlQ29sb3I6dmVjNDxmMzI+ID10ZXh0dXJlU2FtcGxlKGVtaXNzaXZlVGV4dHVyZSwgYmFzZVNhbXBsZXIsIGlucHV0LnZVdik7XHJcbiAgICAgICAgICAgIHRvdGFsRW1pc3NpdmVSYWRpYW5jZSAqPSBlbWlzc2l2ZUNvbG9yLnJnYjtcclxuICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgdmFyIG1hdGVyaWFsOlBoeXNpY2FsTWF0ZXJpYWw7XHJcbiAgICAgICAgbWF0ZXJpYWwuZGlmZnVzZUNvbG9yID0gZGlmZnVzZUNvbG9yLnJnYiAqICggMS4wIC0gbWV0YWxuZXNzRmFjdG9yICk7XHJcbiAgICAgICAgbGV0IGR4eTp2ZWMzPGYzMj4gPSBtYXgoIGFicyggZHBkeCggZ2VvbWV0cnlOb3JtYWwgKSApLCBhYnMoIGRwZHkoIGdlb21ldHJ5Tm9ybWFsICkgKSApO1xyXG4gICAgICAgIGxldCBnZW9tZXRyeVJvdWdobmVzczpmMzIgPSBtYXgoIG1heCggZHh5LngsIGR4eS55ICksIGR4eS56ICk7XHJcbiAgICAgICAgbWF0ZXJpYWwucm91Z2huZXNzID0gbWF4KCByb3VnaG5lc3NGYWN0b3IsIDAuMDUyNSApO1xyXG4gICAgICAgIG1hdGVyaWFsLnJvdWdobmVzcyArPSBnZW9tZXRyeVJvdWdobmVzcztcclxuICAgICAgICBtYXRlcmlhbC5yb3VnaG5lc3MgPSBtaW4oIG1hdGVyaWFsLnJvdWdobmVzcywgMS4wICk7XHJcblxyXG4gICAgICAgICNpZiAke2RlZmluZXMuSU9SfVxyXG4gICAgICAgICAgICBtYXRlcmlhbC5pb3IgPSBtYXRlcmlhbFVuaWZvcm0uaW9yO1xyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlNQRUNVTEFSfVxyXG4gICAgICAgICAgICAgICAgbGV0IHNwZWN1bGFySW50ZW5zaXR5RmFjdG9yOmYzMiA9IG1hdGVyaWFsVW5pZm9ybS5zcGVjdWxhckludGVuc2l0eTtcclxuICAgICAgICAgICAgICAgIGxldCBzcGVjdWxhckNvbG9yRmFjdG9yOnZlYzM8ZjMyPiA9IG1hdGVyaWFsVW5pZm9ybS5zcGVjdWxhckNvbG9yO1xyXG4gICAgICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfU1BFQ1VMQVJJTlRFTlNJVFlURVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgICAgIHNwZWN1bGFySW50ZW5zaXR5RmFjdG9yICo9dGV4dHVyZVNhbXBsZShzcGVjdWxhckludGVuc2l0eVRleHR1cmUsIGJhc2VTYW1wbGVyLCBpbnB1dC52VXYpLmE7XHJcbiAgICAgICAgICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9TUEVDVUxBUkNPTE9SVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgICAgICBzcGVjdWxhckNvbG9yRmFjdG9yICo9dGV4dHVyZVNhbXBsZShzcGVjdWxhckNvbG9yVGV4dHVyZSwgYmFzZVNhbXBsZXIsIGlucHV0LnZVdikucmdiO1xyXG4gICAgICAgICAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgICAgICAgICAgbWF0ZXJpYWwuc3BlY3VsYXJGOTAgPSBtaXgoIHNwZWN1bGFySW50ZW5zaXR5RmFjdG9yLCAxLjAsIG1ldGFsbmVzc0ZhY3RvciApO1xyXG4gICAgICAgICAgICAjZWxzZVxyXG4gICAgICAgICAgICAgICAgbGV0IHNwZWN1bGFySW50ZW5zaXR5RmFjdG9yOmYzMiA9IDEuMDtcclxuICAgICAgICAgICAgICAgIGxldCBzcGVjdWxhckNvbG9yRmFjdG9yOnZlYzM8ZjMyPiA9IHZlYzM8ZjMyPiggMS4wICk7XHJcbiAgICAgICAgICAgICAgICBtYXRlcmlhbC5zcGVjdWxhckY5MCA9IDEuMDtcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgICAgIG1hdGVyaWFsLnNwZWN1bGFyQ29sb3IgPSBtaXgoIG1pbiggcG93MiggKCBtYXRlcmlhbC5pb3IgLSAxLjAgKSAvICggbWF0ZXJpYWwuaW9yICsgMS4wICkgKSAqIHNwZWN1bGFyQ29sb3JGYWN0b3IsIHZlYzMoIDEuMCApICkgKiBzcGVjdWxhckludGVuc2l0eUZhY3RvciwgZGlmZnVzZUNvbG9yLnJnYiwgbWV0YWxuZXNzRmFjdG9yICk7XHJcbiAgICAgICAgI2Vsc2VcclxuICAgICAgICAgICAgbWF0ZXJpYWwuc3BlY3VsYXJDb2xvciA9IG1peCggdmVjMzxmMzI+KCAwLjA0ICksIGRpZmZ1c2VDb2xvci5yZ2IsIG1ldGFsbmVzc0ZhY3RvciApO1xyXG4gICAgICAgICAgICBtYXRlcmlhbC5zcGVjdWxhckY5MCA9IDEuMDtcclxuICAgICAgICAjZW5kaWZcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9DTEVBUkNPQVR9XHJcbiAgICAgICAgICAgIG1hdGVyaWFsLmNsZWFyY29hdCA9IG1hdGVyaWFsVW5pZm9ybS5jbGVhcmNvYXQ7XHJcbiAgICAgICAgICAgIG1hdGVyaWFsLmNsZWFyY29hdFJvdWdobmVzcyA9IG1hdGVyaWFsVW5pZm9ybS5jbGVhcmNvYXRSb3VnaG5lc3M7XHJcbiAgICAgICAgICAgIG1hdGVyaWFsLmNsZWFyY29hdEYwID0gdmVjMzxmMzI+KCAwLjA0ICk7XHJcbiAgICAgICAgICAgIG1hdGVyaWFsLmNsZWFyY29hdEY5MCA9IDEuMDtcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfQ0xFQVJDT0FUVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgIG1hdGVyaWFsLmNsZWFyY29hdCAqPXRleHR1cmVTYW1wbGUoY2xlYXJjb2F0VGV4dHVyZSwgYmFzZVNhbXBsZXIsIGlucHV0LnZVdikueDtcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX0NMRUFSQ09BVF9ST1VHSE5FU1NURVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgbWF0ZXJpYWwuY2xlYXJjb2F0Um91Z2huZXNzICo9dGV4dHVyZVNhbXBsZShjbGVhcmNvYXRSb3VnaG5lc3NUZXh0dXJlLCBiYXNlU2FtcGxlciwgaW5wdXQudlV2KS55O1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgbWF0ZXJpYWwuY2xlYXJjb2F0ID0gc2F0dXJhdGUoIG1hdGVyaWFsLmNsZWFyY29hdCApO1xyXG4gICAgICAgICAgICBtYXRlcmlhbC5jbGVhcmNvYXRSb3VnaG5lc3MgPSBtYXgoIG1hdGVyaWFsLmNsZWFyY29hdFJvdWdobmVzcywgMC4wNTI1ICk7XHJcbiAgICAgICAgICAgIG1hdGVyaWFsLmNsZWFyY29hdFJvdWdobmVzcyArPSBnZW9tZXRyeVJvdWdobmVzcztcclxuICAgICAgICAgICAgbWF0ZXJpYWwuY2xlYXJjb2F0Um91Z2huZXNzID0gbWluKCBtYXRlcmlhbC5jbGVhcmNvYXRSb3VnaG5lc3MsIDEuMCApO1xyXG4gICAgICAgICNlbmRpZlxyXG4gICAgICAgICNpZiAke2RlZmluZXMuVVNFX0lSSURFU0NFTkNFfVxyXG4gICAgICAgICAgICBtYXRlcmlhbC5pcmlkZXNjZW5jZSA9IG1hdGVyaWFsVW5pZm9ybS5pcmlkZXNjZW5jZTtcclxuICAgICAgICAgICAgbWF0ZXJpYWwuaXJpZGVzY2VuY2VJT1IgPSBtYXRlcmlhbFVuaWZvcm0uaXJpZGVzY2VuY2VJT1I7XHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX0lSSURFU0NFTkNFVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgIG1hdGVyaWFsLmlyaWRlc2NlbmNlICo9dGV4dHVyZVNhbXBsZShpcmlkZXNjZW5jZVRleHR1cmUsIGJhc2VTYW1wbGVyLCBpbnB1dC52VXYpLnI7XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9JUklERVNDRU5DRV9USElDS05FU1NURVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgbWF0ZXJpYWwuaXJpZGVzY2VuY2VUaGlja25lc3MgPSAobWF0ZXJpYWxVbmlmb3JtLmlyaWRlc2NlbmNlVGhpY2tuZXNzTWF4aW11bSAtIG1hdGVyaWFsVW5pZm9ybS5pcmlkZXNjZW5jZVRoaWNrbmVzc01pbmltdW0pICogdGV4dHVyZVNhbXBsZShpcmlkZXNjZW5jZVRoaWNrbmVzc1RleHR1cmUsIGJhc2VTYW1wbGVyLCBpbnB1dC52VXYpLmcgKyBtYXRlcmlhbFVuaWZvcm0uaXJpZGVzY2VuY2VUaGlja25lc3NNaW5pbXVtO1xyXG4gICAgICAgICAgICAjZWxzZVxyXG4gICAgICAgICAgICAgICAgbWF0ZXJpYWwuaXJpZGVzY2VuY2VUaGlja25lc3MgPSBtYXRlcmlhbFVuaWZvcm0uaXJpZGVzY2VuY2VUaGlja25lc3NNYXhpbXVtO1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAjZW5kaWZcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9TSEVFTn1cclxuICAgICAgICAgICAgbWF0ZXJpYWwuc2hlZW5Db2xvciA9IG1hdGVyaWFsVW5pZm9ybS5zaGVlbkNvbG9yO1xyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9TSEVFTkNPTE9SVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgIG1hdGVyaWFsLnNoZWVuQ29sb3IgKj10ZXh0dXJlU2FtcGxlKHNoZWVuQ29sb3JUZXh0dXJlLCBiYXNlU2FtcGxlciwgaW5wdXQudlV2KS5yZ2I7XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICBtYXRlcmlhbC5zaGVlblJvdWdobmVzcyA9IGNsYW1wKCBtYXRlcmlhbFVuaWZvcm0uc2hlZW5Sb3VnaG5lc3MsIDAuMDcsIDEuMCApO1xyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9TSEVFTlJPVUdITkVTU1RFWFRVUkV9XHJcbiAgICAgICAgICAgICAgICBtYXRlcmlhbC5zaGVlblJvdWdobmVzcyAqPXRleHR1cmVTYW1wbGUoc2hlZW5Sb3VnaG5lc3NUZXh0dXJlLCBiYXNlU2FtcGxlciwgaW5wdXQudlV2KS5hO1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAjZW5kaWZcclxuICAgICAgICBcclxuICAgICAgICB2YXIgZ2VvbWV0cnk6R2VvbWV0cmljQ29udGV4dDtcclxuICAgICAgICBnZW9tZXRyeS5wb3NpdGlvbiA9IC0gaW5wdXQudlZpZXdQb3NpdGlvbjtcclxuICAgICAgICBnZW9tZXRyeS5ub3JtYWwgPSBub3JtYWw7XHJcbiAgICAgICAvLyBnZW9tZXRyeS52aWV3RGlyID0gKCBpc09ydGhvZ3JhcGhpYyApID8gdmVjMyggMCwgMCwgMSApIDogbm9ybWFsaXplKCBpbnB1dC52Vmlld1Bvc2l0aW9uICk7XHJcbiAgICAgICAgZ2VvbWV0cnkudmlld0RpciA9IG5vcm1hbGl6ZSggaW5wdXQudlZpZXdQb3NpdGlvbik7IFxyXG5cclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9DTEVBUkNPQVR9XHJcbiAgICAgICAgICAgIGdlb21ldHJ5LmNsZWFyY29hdE5vcm1hbCA9IGNsZWFyY29hdE5vcm1hbDtcclxuICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfSVJJREVTQ0VOQ0V9XHJcbiAgICAgICAgICAgIGxldCBkb3ROVmk6ZjMyID0gc2F0dXJhdGUoIGRvdCggbm9ybWFsLCBnZW9tZXRyeS52aWV3RGlyICkgKTtcclxuICAgICAgICAgICAgaWYgKCBtYXRlcmlhbC5pcmlkZXNjZW5jZVRoaWNrbmVzcyA9PSAwLjAgKSB7XHJcbiAgICAgICAgICAgICAgICBtYXRlcmlhbC5pcmlkZXNjZW5jZSA9IDAuMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIG1hdGVyaWFsLmlyaWRlc2NlbmNlID0gc2F0dXJhdGUoIG1hdGVyaWFsLmlyaWRlc2NlbmNlICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCBtYXRlcmlhbC5pcmlkZXNjZW5jZSA+IDAuMCApIHtcclxuICAgICAgICAgICAgICAgIG1hdGVyaWFsLmlyaWRlc2NlbmNlRnJlc25lbCA9IGV2YWxJcmlkZXNjZW5jZSggMS4wLCBtYXRlcmlhbC5pcmlkZXNjZW5jZUlPUiwgZG90TlZpLCBtYXRlcmlhbC5pcmlkZXNjZW5jZVRoaWNrbmVzcywgbWF0ZXJpYWwuc3BlY3VsYXJDb2xvciApO1xyXG4gICAgICAgICAgICAgICAgbWF0ZXJpYWwuaXJpZGVzY2VuY2VGMCA9IFNjaGxpY2tfdG9fRjAoIG1hdGVyaWFsLmlyaWRlc2NlbmNlRnJlc25lbCwgMS4wLCBkb3ROVmkgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICNlbmRpZlxyXG5cclxuICAgICAgICB2YXIgaWJsSXJyYWRpYW5jZTp2ZWMzPGYzMj4gPSB2ZWMzPGYzMj4oIDAuMCApO1xyXG4gICAgICAgIHZhciBpcnJhZGlhbmNlOnZlYzM8ZjMyPiA9IGdldEFtYmllbnRMaWdodElycmFkaWFuY2UoY29tbW9uTGlnaHRzUGFybXMuYW1iaWVudCk7XHJcbiAgICAgICAgLy9pcnJhZGlhbmNlICs9IGdldExpZ2h0UHJvYmVJcnJhZGlhbmNlKCBsaWdodFByb2JlLCBnZW9tZXRyeS5ub3JtYWwsc3lzdGVtVW5pZm9ybS52aWV3TWF0cml4ICk7XHJcblxyXG4gICAgICAgIHZhciByYWRpYW5jZTp2ZWMzPGYzMj4gPSB2ZWMzPGYzMj4oIDAuMCApO1xyXG4gICAgICAgIHZhciBjbGVhcmNvYXRSYWRpYW5jZTp2ZWMzPGYzMj4gPSB2ZWMzPGYzMj4oIDAuMCApO1xyXG5cclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9MSUdIVFRFWFRVUkV9XHJcbiAgICAgICAgICAgIGxldCBsaWdodE1hcFRleGVsOnZlYzQ8ZjMyPiA9dGV4dHVyZVNhbXBsZShsaWdodFRleHR1cmUsIGJhc2VTYW1wbGVyLCBpbnB1dC52VXYyKTtcclxuICAgICAgICAgICAgbGV0IGxpZ2h0TWFwSXJyYWRpYW5jZTp2ZWMzPGYzMj4gPSBsaWdodE1hcFRleGVsLnJnYiAqIG1hdGVyaWFsVW5pZm9ybS5saWdodFRleHR1cmVJbnRlbnNpdHk7XHJcbiAgICAgICAgICAgIGlycmFkaWFuY2UgKz0gbGlnaHRNYXBJcnJhZGlhbmNlO1xyXG4gICAgICAgICNlbmRpZlxyXG4gICAgICAgIC8vJiYgZGVmaW5lcy5TVEFOREFSRCYmZGVmaW5lcy5FTlZURVhUVVJFX1RZUEVfQ1VCRV9VVlxyXG4gICAgICAgICNpZiAke2RlZmluZXMuVVNFX0VOVlRFWFRVUkV9IFxyXG4gICAgICAgICAgICBpYmxJcnJhZGlhbmNlICs9IGdldElCTElycmFkaWFuY2UoIGdlb21ldHJ5Lm5vcm1hbCxiYXNlU2FtcGxlcixzeXN0ZW1Vbmlmb3JtLnZpZXdNYXRyaXggKTtcclxuICAgICAgICAjZW5kaWZcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9FTlZURVhUVVJFfVxyXG4gICAgICAgICAgICByYWRpYW5jZSArPSBnZXRJQkxSYWRpYW5jZSggZ2VvbWV0cnkudmlld0RpcixiYXNlU2FtcGxlcixzeXN0ZW1Vbmlmb3JtLnZpZXdNYXRyaXgsIGdlb21ldHJ5Lm5vcm1hbCwgbWF0ZXJpYWxVbmlmb3JtLnJvdWdobmVzcyApO1xyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9DTEVBUkNPQVR9XHJcbiAgICAgICAgICAgICAgICBjbGVhcmNvYXRSYWRpYW5jZSArPSBnZXRJQkxSYWRpYW5jZSggZ2VvbWV0cnkudmlld0RpcixiYXNlU2FtcGxlcixzeXN0ZW1Vbmlmb3JtLnZpZXdNYXRyaXgsIGdlb21ldHJ5LmNsZWFyY29hdE5vcm1hbCwgbWF0ZXJpYWwuY2xlYXJjb2F0Um91Z2huZXNzICk7XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICNlbmRpZlxyXG4gICAgICAgIC8v55u05o6l5YWJ54WnXHJcbiAgICAgICAgICAgIGxldCBkaXJSZWZsZWN0ZWRMaWdodDpSZWZsZWN0ZWRMaWdodD0gcGFyc2VMaWdodHMoZ2VvbWV0cnksbWF0ZXJpYWwpO1xyXG4gICAgICAgICAgICByZWZsZWN0ZWRMaWdodC5kaXJlY3REaWZmdXNlICs9ZGlyUmVmbGVjdGVkTGlnaHQuZGlyZWN0RGlmZnVzZTtcclxuICAgICAgICAgICAgcmVmbGVjdGVkTGlnaHQuZGlyZWN0U3BlY3VsYXIgKz1kaXJSZWZsZWN0ZWRMaWdodC5kaXJlY3RTcGVjdWxhcjtcclxuICAgICAgICAvL+mXtOaOpea8q+WPjeWwhFxyXG4gICAgICAgICAgICBsZXQgaW5kaXJlY3REaWZmdXNlTGlnaHQ6UmVmbGVjdGVkTGlnaHQ9IFJFX0luZGlyZWN0RGlmZnVzZV9QaHlzaWNhbCggaXJyYWRpYW5jZSwgZ2VvbWV0cnksIG1hdGVyaWFsKTtcclxuICAgICAgICAgICAgcmVmbGVjdGVkTGlnaHQuZGlyZWN0RGlmZnVzZSArPWluZGlyZWN0RGlmZnVzZUxpZ2h0LmluZGlyZWN0RGlmZnVzZTtcclxuICAgICAgICAgICAgcmVmbGVjdGVkTGlnaHQuZGlyZWN0U3BlY3VsYXIgKz1pbmRpcmVjdERpZmZ1c2VMaWdodC5pbmRpcmVjdFNwZWN1bGFyO1xyXG4gICAgICAgIC8v6Ze05o6l6auY5YWJXHJcbiAgICAgICAgICAgIGxldCBpbmRpcmVjdFNwZWN1bGFyTGlnaHQ6UmVmbGVjdGVkTGlnaHQ9UkVfSW5kaXJlY3RTcGVjdWxhcl9QaHlzaWNhbCggcmFkaWFuY2UsIGlibElycmFkaWFuY2UsIGNsZWFyY29hdFJhZGlhbmNlLCBnZW9tZXRyeSwgbWF0ZXJpYWwpO1xyXG4gICAgICAgICAgICByZWZsZWN0ZWRMaWdodC5kaXJlY3REaWZmdXNlICs9aW5kaXJlY3RTcGVjdWxhckxpZ2h0LmluZGlyZWN0RGlmZnVzZTtcclxuICAgICAgICAgICAgcmVmbGVjdGVkTGlnaHQuZGlyZWN0U3BlY3VsYXIgKz1pbmRpcmVjdFNwZWN1bGFyTGlnaHQuaW5kaXJlY3RTcGVjdWxhcjtcclxuICAgICAgICAvL+eOr+Wig+WFiemBruiUvVxyXG4gICAgICAgICNpZiAke2RlZmluZXMuVVNFX0FPVEVYVFVSRX1cclxuICAgICAgICAgICAgbGV0IGFtYmllbnRPY2NsdXNpb246ZjMyID0gKHRleHR1cmVTYW1wbGUoYW9UZXh0dXJlLCBiYXNlU2FtcGxlciwgaW5wdXQudlV2MikuciAtIDEuMCApICogbWF0ZXJpYWxVbmlmb3JtLmFvVGV4dHVyZUludGVuc2l0eSArIDEuMDtcclxuXHJcbiAgICAgICAgICAgIHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0RGlmZnVzZSAqPSBhbWJpZW50T2NjbHVzaW9uO1xyXG4gICAgICAgICAgICAvLyYmZGVmaW5lcy5TVEFOREFSRFxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9FTlZURVhUVVJFfSBcclxuICAgICAgICAgICAgICAgIGxldCBkb3ROVjpmMzIgPSBzYXR1cmF0ZSggZG90KCBnZW9tZXRyeS5ub3JtYWwsIGdlb21ldHJ5LnZpZXdEaXIgKSApO1xyXG4gICAgICAgICAgICAgICAgcmVmbGVjdGVkTGlnaHQuaW5kaXJlY3RTcGVjdWxhciAqPSBjb21wdXRlU3BlY3VsYXJPY2NsdXNpb24oIGRvdE5WLCBhbWJpZW50T2NjbHVzaW9uLCBtYXRlcmlhbC5yb3VnaG5lc3MgKTtcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgIHZhciB0b3RhbERpZmZ1c2U6dmVjMzxmMzI+ID0gcmVmbGVjdGVkTGlnaHQuZGlyZWN0RGlmZnVzZSArIHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0RGlmZnVzZTtcclxuICAgICAgICB2YXIgdG90YWxTcGVjdWxhcjp2ZWMzPGYzMj4gPSByZWZsZWN0ZWRMaWdodC5kaXJlY3RTcGVjdWxhciArIHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0U3BlY3VsYXI7XHJcbiAgICAgICAgLy/pgI/lsIRcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9UUkFOU01JU1NJT059XHJcbiAgICAgICAgICAgIG1hdGVyaWFsLnRyYW5zbWlzc2lvbiA9IG1hdGVyaWFsVW5pZm9ybS50cmFuc21pc3Npb247XHJcbiAgICAgICAgICAgIG1hdGVyaWFsLnRyYW5zbWlzc2lvbkFscGhhID0gMS4wO1xyXG4gICAgICAgICAgICBtYXRlcmlhbC50aGlja25lc3MgPSBtYXRlcmlhbFVuaWZvcm0udGhpY2tuZXNzO1xyXG4gICAgICAgICAgICBtYXRlcmlhbC5hdHRlbnVhdGlvbkRpc3RhbmNlID0gbWF0ZXJpYWxVbmlmb3JtLmF0dGVudWF0aW9uRGlzdGFuY2U7XHJcbiAgICAgICAgICAgIG1hdGVyaWFsLmF0dGVudWF0aW9uQ29sb3IgPSBtYXRlcmlhbFVuaWZvcm0uYXR0ZW51YXRpb25Db2xvcjtcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfVFJBTlNNSVNTSU9OVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgIG1hdGVyaWFsLnRyYW5zbWlzc2lvbiAqPXRleHR1cmVTYW1wbGUodHJhbnNtaXNzaW9uVGV4dHVyZSwgYmFzZVNhbXBsZXIsIGlucHV0LnZVdikucjtcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX1RISUNLTkVTU1RFWFRVUkV9XHJcbiAgICAgICAgICAgICAgICBtYXRlcmlhbC50aGlja25lc3MgKj10ZXh0dXJlU2FtcGxlKHRoaWNrbmVzc1RleHR1cmUsIGJhc2VTYW1wbGVyLCBpbnB1dC52VXYpLmc7XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICBsZXQgcG9zOnZlYzM8ZjMyPiA9IHZXb3JsZFBvc2l0aW9uO1xyXG4gICAgICAgICAgICBsZXQgdjp2ZWMzPGYzMj4gPSBub3JtYWxpemUoIGNhbWVyYVBvc2l0aW9uIC0gcG9zICk7XHJcbiAgICAgICAgICAgIGxldCBuOnZlYzM8ZjMyPiA9IGludmVyc2VUcmFuc2Zvcm1EaXJlY3Rpb24oIG5vcm1hbCwgc3lzdGVtVW5pZm9ybS52aWV3TWF0cml4ICk7XHJcbiAgICAgICAgICAgIGxldCB0cmFuc21pc3Npb246dmVjNDxmMzI+ID0gZ2V0SUJMVm9sdW1lUmVmcmFjdGlvbihcclxuICAgICAgICAgICAgbiwgdiwgbWF0ZXJpYWwucm91Z2huZXNzLCBtYXRlcmlhbC5kaWZmdXNlQ29sb3IsIG1hdGVyaWFsLnNwZWN1bGFyQ29sb3IsIG1hdGVyaWFsLnNwZWN1bGFyRjkwLCBwb3MsIG1vZGVsTWF0cml4LCBzeXN0ZW1Vbmlmb3JtLnZpZXdNYXRyaXgsIHN5c3RlbVVuaWZvcm0ucHJvamVjdGlvbk1hdHJpeCwgbWF0ZXJpYWwuaW9yLCBtYXRlcmlhbC50aGlja25lc3MsIG1hdGVyaWFsLmF0dGVudWF0aW9uQ29sb3IsIG1hdGVyaWFsLmF0dGVudWF0aW9uRGlzdGFuY2UgKTtcclxuICAgICAgICAgICAgbWF0ZXJpYWwudHJhbnNtaXNzaW9uQWxwaGEgPSBtaXgoIG1hdGVyaWFsLnRyYW5zbWlzc2lvbkFscGhhLCB0cmFuc21pc3Npb24uYSwgbWF0ZXJpYWwudHJhbnNtaXNzaW9uICk7XHJcbiAgICAgICAgICAgIHRvdGFsRGlmZnVzZSA9IG1peCggdG90YWxEaWZmdXNlLCB0cmFuc21pc3Npb24ucmdiLCBtYXRlcmlhbC50cmFuc21pc3Npb24gKTtcclxuICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgbGV0IG91dGdvaW5nTGlnaHQ6dmVjMzxmMzI+ID0gdG90YWxEaWZmdXNlICsgdG90YWxTcGVjdWxhciArIHRvdGFsRW1pc3NpdmVSYWRpYW5jZTtcclxuXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfU0hFRU59XHJcbiAgICAgICAgICAgIGxldCBzaGVlbkVuZXJneUNvbXA6ZjMyID0gMS4wIC0gMC4xNTcgKiBtYXgzKCBtYXRlcmlhbC5zaGVlbkNvbG9yICk7XHJcbiAgICAgICAgICAgIG91dGdvaW5nTGlnaHQgPSBvdXRnb2luZ0xpZ2h0ICogc2hlZW5FbmVyZ3lDb21wICsgc2hlZW5TcGVjdWxhcjtcclxuICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfQ0xFQVJDT0FUfVxyXG4gICAgICAgICAgICBsZXQgZG90TlZjYzpmMzIgPSBzYXR1cmF0ZSggZG90KCBnZW9tZXRyeS5jbGVhcmNvYXROb3JtYWwsIGdlb21ldHJ5LnZpZXdEaXIgKSApO1xyXG4gICAgICAgICAgICBsZXQgRmNjOnZlYzM8ZjMyPiA9IEZfU2NobGljayggbWF0ZXJpYWwuY2xlYXJjb2F0RjAsIG1hdGVyaWFsLmNsZWFyY29hdEY5MCwgZG90TlZjYyApO1xyXG4gICAgICAgICAgICBvdXRnb2luZ0xpZ2h0ID0gb3V0Z29pbmdMaWdodCAqICggMS4wIC0gbWF0ZXJpYWwuY2xlYXJjb2F0ICogRmNjICkgKyBjbGVhcmNvYXRTcGVjdWxhciAqIG1hdGVyaWFsLmNsZWFyY29hdDtcclxuICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfVFJBTlNNSVNTSU9OfVxyXG4gICAgICAgICAgICBkaWZmdXNlQ29sb3IuYSAqPSBtYXRlcmlhbC50cmFuc21pc3Npb25BbHBoYSArIDAuMTtcclxuICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgdmFyIGZpbm5hbENvbG9yOnZlYzQ8ZjMyPjtcclxuICAgICAgICBmaW5uYWxDb2xvciA9IHZlYzQ8ZjMyPiggb3V0Z29pbmdMaWdodCwgZGlmZnVzZUNvbG9yLmEgKTtcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlRPTkVfTUFQUElOR31cclxuICAgICAgICAgICBmaW5uYWxDb2xvci5yZ2IgPSB0b25lTWFwcGluZyggZmlubmFsQ29sb3IucmdiLG1hdGVyaWFsVW5pZm9ybS50b25lTWFwcGluZ0V4cG9zdXJlICk7XHJcbiAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgICAgZmlubmFsQ29sb3IgPSBsaW5lYXJUb091dHB1dFRleGVsKCBmaW5uYWxDb2xvcik7XHJcblxyXG4gICAgICAgICNpZiAke2RlZmluZXMuUFJFTVVMVElQTElFRF9BTFBIQX1cclxuICAgICAgICAgICAgZmlubmFsQ29sb3IucmdiICo9IGZpbm5hbENvbG9yLmE7XHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5ESVRIRVJJTkd9XHJcbiAgICAgICAgICAgIGZpbm5hbENvbG9yLnJnYiA9IGRpdGhlcmluZyggZmlubmFsQ29sb3IucmdiICk7XHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgcmV0dXJuIGZpbm5hbENvbG9yO1xyXG4gICAgfWA7XHJcbn1cclxuIiwiaW1wb3J0IHsgd2dzbFBhcnNlRGVmaW5lcyB9IGZyb20gXCIuLi9XZ3NsUHJlcHJvY2Vzc29yXCI7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBwYnJWZXJ0KGRlZmluZXMpIHtcclxuICByZXR1cm4gd2dzbFBhcnNlRGVmaW5lc2BcclxuICAgICNpbmNsdWRlIDxwYnJTdHJ1Y3Q+XHJcbiAgICBzdHJ1Y3QgVmVydGV4T3V0cHV0IHtcclxuICAgICAgICBAYnVpbHRpbihwb3NpdGlvbikgcG9zaXRpb246IHZlYzQ8ZjMyPixcclxuICAgICAgICBAbG9jYXRpb24oMCkgdlV2OiB2ZWMyPGYzMj4sXHJcbiAgICAgICAgQGxvY2F0aW9uKDEpIHZWaWV3UG9zaXRpb246IHZlYzM8ZjMyPiwgLy8gVmVjdG9yIGZyb20gdmVydGV4IHRvIGNhbWVyYS5cclxuICAgICAgICBAbG9jYXRpb24oMikgdldvcmxkUG9zaXRpb246IHZlYzM8ZjMyPixcclxuICAgICAgICBAbG9jYXRpb24oMykgdk5vcm1hbDogdmVjMzxmMzI+LFxyXG4gICAgICAgIC8vIOWPr+mAiVxyXG4gICAgICAgICNpZiAke2RlZmluZXMuVVNFX0xJR0hUVEVYVFVSRSB8fCBkZWZpbmVzLlVTRV9BT1RFWFRVUkV9XHJcbiAgICAgICAgICAgIEBsb2NhdGlvbigke2RlZmluZXMudlV2Mk91dExvY2F0aW9ufSkgdlV2MjogdmVjMjxmMzI+LFxyXG4gICAgICAgICNlbmRpZlxyXG5cclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9DT0xPUl9BTFBIQX1cclxuICAgICAgICAgICAgQGxvY2F0aW9uKCR7ZGVmaW5lcy52Q29sb3JPdXRMb2NhdGlvbn0pIHZDb2xvcjogdmVjNDxmMzI+LFxyXG4gICAgICAgICNlbGlmICR7ZGVmaW5lcy5VU0VfQ09MT1IgfHwgZGVmaW5lcy5VU0VfSU5TVEFOQ0lOR19DT0xPUn1cclxuICAgICAgICAgICAgQGxvY2F0aW9uKCR7ZGVmaW5lcy52Q29sb3JPdXRMb2NhdGlvbn0pIHZDb2xvcjogdmVjMzxmMzI+LFxyXG4gICAgICAgICNlbmRpZlxyXG5cclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9UQU5HRU5UfVxyXG4gICAgICAgICAgICBAbG9jYXRpb24oJHtkZWZpbmVzLnZUYW5nZW50T3V0TG9jYXRpb259KSB2VGFuZ2VudDogdmVjMzxmMzI+LFxyXG4gICAgICAgICAgICBAbG9jYXRpb24oJHtkZWZpbmVzLnZCaXRhbmdlbnRPdXRMb2NhdGlvbn0pIHZCaXRhbmdlbnQ6IHZlYzM8ZjMyPixcclxuICAgICAgICAjZW5kaWZcclxuICAgIH07XHJcbiAgICBzdHJ1Y3QgR2xvYmFsVW5pZm9ybSB7XHJcbiAgICAgICAgcHJvamVjdGlvbk1hdHJpeDogbWF0NHg0PGYzMj4sXHJcbiAgICAgICAgdmlld01hdHJpeDogbWF0NHg0PGYzMj4sXHJcbiAgICAgICAgaW52ZXJzZVZpZXdNYXRyaXg6IG1hdDR4NDxmMzI+LFxyXG4gICAgICAgIGNhbWVyYVBvc2l0aW9uOiB2ZWMzPGYzMj4sXHJcbiAgICB9O1xyXG5cclxuICAgIC8vdGV4dHVyZSBhbmQgc2FtcGxlclxyXG4gICAgLy8gQGdyb3VwKDApIEBiaW5kaW5nKCR7ZGVmaW5lcy5zYW1wbGVyQmluZGluZ30pIHZhciBiYXNlU2FtcGxlcjogc2FtcGxlcjtcclxuICAgICNpZiAke2RlZmluZXMuVVNFX1NLSU5OSU5HfVxyXG4gICAgICAgIC8vdW5pZm9ybSBoaWdocCBzYW1wbGVyMkQgYm9uZVRleHR1cmU7XHJcbiAgICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKCR7XHJcbiAgICAgICAgICBkZWZpbmVzLmJvbmVUZXh0dXJlQmluZGluZ1xyXG4gICAgICAgIH0pIHZhciBib25lVGV4dHVyZTogdGV4dHVyZV8yZDxmMzI+O1xyXG4gICAgI2VuZGlmXHJcblxyXG4gICAgI2lmICR7ZGVmaW5lcy5VU0VfRElTUExBQ0VNRU5UVEVYVFVSRX1cclxuICAgICAgICAvL3VuaWZvcm0gc2FtcGxlcjJEIGRpc3BsYWNlbWVudE1hcDtcclxuICAgICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtcclxuICAgICAgICAgIGRlZmluZXMuZGlzcGxhY2VtZW50VGV4dHVyZUJpbmRpbmdcclxuICAgICAgICB9KSB2YXIgZGlzcGxhY2VtZW50TWFwOiB0ZXh0dXJlXzJkPGYzMj47XHJcbiAgICAjZW5kaWZcclxuXHJcbiAgICAjaWYgJHtkZWZpbmVzLk1PUlBIVEFSR0VUU19URVhUVVJFfVxyXG4gICAgICAgIC8vdW5pZm9ybSBzYW1wbGVyMkRBcnJheSBtb3JwaFRhcmdldHNUZXh0dXJlO1xyXG4gICAgICAgIEBncm91cCgwKSBAYmluZGluZygke1xyXG4gICAgICAgICAgZGVmaW5lcy5tb3JwaFRhcmdldHNUZXh0dXJlQmluZGluZ1xyXG4gICAgICAgIH0pIHZhciBtb3JwaFRhcmdldHNUZXh0dXJlOiB0ZXh0dXJlXzJkX2FycmF5PGYzMj47XHJcbiAgICAjZW5kaWZcclxuXHJcbiAgICBzdHJ1Y3QgVmVydGV4SW5wdXQge1xyXG4gICAgICAgIEBsb2NhdGlvbigwKSBwb3NpdGlvbjogdmVjMzxmMzI+LCAgXHJcblxyXG4gICAgICAgIEBsb2NhdGlvbigxKSBub3JtYWw6IHZlYzM8ZjMyPixcclxuXHJcbiAgICAgICAgQGxvY2F0aW9uKDIpIHV2OiB2ZWMyPGYzMj4sXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfTElHSFRURVhUVVJFIHx8IGRlZmluZXMuVVNFX0FPVEVYVFVSRX1cclxuICAgICAgICAgICAgQGxvY2F0aW9uKCR7ZGVmaW5lcy51djJMb2NhdGlvbn0pIHV2Mjp2ZWMyPGYzMj4sXHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfSU5TVEFOQ0lOR31cclxuICAgICAgICAgICAgQGxvY2F0aW9uKCR7XHJcbiAgICAgICAgICAgICAgZGVmaW5lcy5pbnN0YW5jZU1hdHJpeExvY2F0aW9uXHJcbiAgICAgICAgICAgIH0pIGluc3RhbmNlTWF0cml4Om1hdDR4NDxmMzI+LFxyXG4gICAgICAgICNlbmRpZlxyXG4gICAgICAgICNpZiAke2RlZmluZXMuVVNFX0lOU1RBTkNJTkdfQ09MT1J9XHJcbiAgICAgICAgICAgIEBsb2NhdGlvbigke2RlZmluZXMuaW5zdGFuY2VDb2xvckxvY2F0aW9ufSkgaW5zdGFuY2VDb2xvcjp2ZWMzPGYzMj4sXHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfVEFOR0VOVH1cclxuICAgICAgICAgICAgQGxvY2F0aW9uKCR7ZGVmaW5lcy50YW5nZW50TG9jYXRpb259KSB0YW5nZW50OnZlYzQ8ZjMyPixcclxuICAgICAgICAjZW5kaWZcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9DT0xPUl9BTFBIQX1cclxuICAgICAgICAgICAgQGxvY2F0aW9uKCR7ZGVmaW5lcy5jb2xvckxvY2F0aW9ufSkgY29sb3I6dmVjNDxmMzI+LFxyXG4gICAgICAgICNlbGlmICR7ZGVmaW5lcy5VU0VfQ09MT1J9XHJcbiAgICAgICAgICAgIEBsb2NhdGlvbigke2RlZmluZXMuY29sb3JMb2NhdGlvbn0pIGNvbG9yOnZlYzM8ZjMyPixcclxuICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfTU9SUEhUQVJHRVRTICYmICFkZWZpbmVzLk1PUlBIVEFSR0VUU19URVhUVVJFfVxyXG4gICAgICAgICAgICBAbG9jYXRpb24oJHtkZWZpbmVzLm1vcnBoVGFyZ2V0MExvY2F0aW9ufSkgbW9ycGhUYXJnZXQwOnZlYzM8ZjMyPixcclxuXHJcbiAgICAgICAgICAgIEBsb2NhdGlvbigke2RlZmluZXMubW9ycGhUYXJnZXQxTG9jYXRpb259KSBtb3JwaFRhcmdldDE6dmVjMzxmMzI+LFxyXG5cclxuICAgICAgICAgICAgQGxvY2F0aW9uKCR7ZGVmaW5lcy5tb3JwaFRhcmdldDJMb2NhdGlvbn0pIG1vcnBoVGFyZ2V0Mjp2ZWMzPGYzMj4sXHJcblxyXG4gICAgICAgICAgICBAbG9jYXRpb24oJHtkZWZpbmVzLm1vcnBoVGFyZ2V0M0xvY2F0aW9ufSkgbW9ycGhUYXJnZXQzOnZlYzM8ZjMyPixcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfTU9SUEhOT1JNQUxTfVxyXG4gICAgICAgICAgICAgICAgQGxvY2F0aW9uKCR7XHJcbiAgICAgICAgICAgICAgICAgIGRlZmluZXMubW9ycGhOb3JtYWwwTG9jYXRpb25cclxuICAgICAgICAgICAgICAgIH0pIG1vcnBoTm9ybWFsMDp2ZWMzPGYzMj4sXHJcblxyXG4gICAgICAgICAgICAgICAgQGxvY2F0aW9uKCR7XHJcbiAgICAgICAgICAgICAgICAgIGRlZmluZXMubW9ycGhOb3JtYWwxTG9jYXRpb25cclxuICAgICAgICAgICAgICAgIH0pIG1vcnBoTm9ybWFsMTp2ZWMzPGYzMj4sXHJcblxyXG4gICAgICAgICAgICAgICAgQGxvY2F0aW9uKCR7XHJcbiAgICAgICAgICAgICAgICAgIGRlZmluZXMubW9ycGhOb3JtYWwyTG9jYXRpb25cclxuICAgICAgICAgICAgICAgIH0pIG1vcnBoTm9ybWFsMjp2ZWMzPGYzMj4sXHJcblxyXG4gICAgICAgICAgICAgICAgQGxvY2F0aW9uKCR7XHJcbiAgICAgICAgICAgICAgICAgIGRlZmluZXMubW9ycGhOb3JtYWwzTG9jYXRpb25cclxuICAgICAgICAgICAgICAgIH0pIG1vcnBoTm9ybWFsMzp2ZWMzPGYzMj4sXHJcbiAgICAgICAgICAgICNlbHNlXHJcbiAgICAgICAgICAgICAgICBAbG9jYXRpb24oJHtcclxuICAgICAgICAgICAgICAgICAgZGVmaW5lcy5tb3JwaFRhcmdldDRMb2NhdGlvblxyXG4gICAgICAgICAgICAgICAgfSkgbW9ycGhUYXJnZXQ0OnZlYzM8ZjMyPixcclxuXHJcbiAgICAgICAgICAgICAgICBAbG9jYXRpb24oJHtcclxuICAgICAgICAgICAgICAgICAgZGVmaW5lcy5tb3JwaFRhcmdldDVMb2NhdGlvblxyXG4gICAgICAgICAgICAgICAgfSkgbW9ycGhUYXJnZXQ1OnZlYzM8ZjMyPixcclxuXHJcbiAgICAgICAgICAgICAgICBAbG9jYXRpb24oJHtcclxuICAgICAgICAgICAgICAgICAgZGVmaW5lcy5tb3JwaFRhcmdldDZMb2NhdGlvblxyXG4gICAgICAgICAgICAgICAgfSkgbW9ycGhUYXJnZXQ2OnZlYzM8ZjMyPixcclxuXHJcbiAgICAgICAgICAgICAgICBAbG9jYXRpb24oJHtcclxuICAgICAgICAgICAgICAgICAgZGVmaW5lcy5tb3JwaFRhcmdldDdMb2NhdGlvblxyXG4gICAgICAgICAgICAgICAgfSkgbW9ycGhUYXJnZXQ3OnZlYzM8ZjMyPixcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfU0tJTk5JTkd9XHJcbiAgICAgICAgICAgIEBsb2NhdGlvbigke2RlZmluZXMuc2tpbkluZGV4TG9jYXRpb259KSBza2luSW5kZXg6dmVjNDxmMzI+LFxyXG4gICAgICAgICAgICBAbG9jYXRpb24oJHtkZWZpbmVzLnNraW5XZWlnaHRMb2NhdGlvbn0pIHNraW5XZWlnaHQ6dmVjNDxmMzI+LFxyXG4gICAgICAgICNlbmRpZlxyXG4gIH1cclxuXHJcbiAgICAjaWYgJHtkZWZpbmVzLk1PUlBIVEFSR0VUU19URVhUVVJFfVxyXG4gICAgICAgIGZuIGdldE1vcnBoKCB2ZXJ0ZXhJbmRleDp1MzIsIG1vcnBoVGFyZ2V0SW5kZXg6dTMyLG9mZnNldDp1MzIgKS0+dmVjNDxmMzI+IHtcclxuICAgICAgICAgICAgbGV0IHRleGVsSW5kZXg6dTMyID0gdmVydGV4SW5kZXggKiBNT1JQSFRBUkdFVFNfVEVYVFVSRV9TVFJJREUgKyBvZmZzZXQ7XHJcbiAgICAgICAgICAgIGxldCB5OnUzMiA9IHRleGVsSW5kZXggLyBtYXRlcmlhbFVuaWZvcm0ubW9ycGhUYXJnZXRzVGV4dHVyZVNpemUueDtcclxuICAgICAgICAgICAgbGV0IHg6dTMyID0gdGV4ZWxJbmRleCAtIHkgKiBtYXRlcmlhbFVuaWZvcm0ubW9ycGhUYXJnZXRzVGV4dHVyZVNpemUueDtcclxuICAgICAgICAgICAgbGV0IG1vcnBoVVY6dmVjMzx1MzI+ID0gdmVjMzx1MzI+KCB4LCB5LCBtb3JwaFRhcmdldEluZGV4ICk7XHJcbiAgICAgICAgICAgIC8vdGV4dHVyZUxvYWRcclxuICAgICAgICAgICAgLy9yZXR1cm4gdGV4ZWxGZXRjaCggbW9ycGhUYXJnZXRzVGV4dHVyZSwgbW9ycGhVViwgMCApO1xyXG4gICAgICAgICAgICByZXR1cm4gdGV4dHVyZUxvYWQoIG1vcnBoVGFyZ2V0c1RleHR1cmUsIG1vcnBoVVYsIDAgKTtcclxuICAgICAgICB9XHJcbiAgICAjZW5kaWZcclxuICAgICNpZiAke2RlZmluZXMuVVNFX1NLSU5OSU5HfVxyXG4gICAgICAgIGZuIGdldEJvbmVNYXRyaXgoIGk6ZjMyICktPm1hdDR4NDxmMzI+IHtcclxuICAgICAgICAgICAgbGV0IGo6ZjMyID0gaSAqIDQuMDtcclxuICAgICAgICAgICAgbGV0IHg6ZjMyID0gaiVmMzIoIG1hdGVyaWFsVW5pZm9ybS5ib25lVGV4dHVyZVNpemUgKTtcclxuICAgICAgICAgICAgbGV0IHk6ZjMyID0gZmxvb3IoIGogLyBmMzIoIG1hdGVyaWFsVW5pZm9ybS5ib25lVGV4dHVyZVNpemUgKSApO1xyXG4gICAgICAgICAgICBsZXQgZHg6ZjMyID0gMS4wIC8gZjMyKCBtYXRlcmlhbFVuaWZvcm0uYm9uZVRleHR1cmVTaXplICk7XHJcbiAgICAgICAgICAgIGxldCBkeTpmMzIgPSAxLjAgLyBmMzIoIG1hdGVyaWFsVW5pZm9ybS5ib25lVGV4dHVyZVNpemUgKTtcclxuICAgICAgICAgICAgeSA9IGR5ICogKCB5ICsgMC41ICk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBsZXQgdjE6dmVjNDxmMzI+ID0gdGV4dHVyZVNhbXBsZShib25lVGV4dHVyZSwgYmFzZVNhbXBsZXIsIHZlYzI8ZjMyPiggZHggKiAoIHggKyAwLjUgKSwgeSApICk7XHJcbiAgICAgICAgICAgIGxldCB2Mjp2ZWM0PGYzMj4gPSB0ZXh0dXJlU2FtcGxlKGJvbmVUZXh0dXJlLCBiYXNlU2FtcGxlciwgdmVjMjxmMzI+KCBkeCAqICggeCArIDEuNSApLCB5ICkgKTtcclxuICAgICAgICAgICAgbGV0IHYzOnZlYzQ8ZjMyPiA9IHRleHR1cmVTYW1wbGUoYm9uZVRleHR1cmUsIGJhc2VTYW1wbGVyLCB2ZWMyPGYzMj4oIGR4ICogKCB4ICsgMi41ICksIHkgKSApO1xyXG4gICAgICAgICAgICBsZXQgdjQ6dmVjNDxmMzI+ID0gdGV4dHVyZVNhbXBsZShib25lVGV4dHVyZSwgYmFzZVNhbXBsZXIsIHZlYzI8ZjMyPiggZHggKiAoIHggKyAzLjUgKSwgeSApICk7XHJcbiAgICAgICAgICAgIGxldCBib25lOm1hdDR4NDxmMzI+ID0gbWF0NHg0PGYzMj4oIHYxLCB2MiwgdjMsIHY0ICk7XHJcbiAgICAgICAgICAgIHJldHVybiBib25lO1xyXG4gICAgICAgIH1cclxuICAgICNlbmRpZlxyXG5cclxuICAgIEBiaW5kaW5nKDApIEBncm91cCgwKSB2YXI8dW5pZm9ybT4gbWF0ZXJpYWxVbmlmb3JtIDogTWF0ZXJpYWxVbmlmb3JtO1xyXG4gICAgQGJpbmRpbmcoMCkgQGdyb3VwKDEpIHZhcjx1bmlmb3JtPiBnbG9iYWxVbmlmb3JtIDogR2xvYmFsVW5pZm9ybTtcclxuICAgIEB2ZXJ0ZXhcclxuICAgIGZuIG1haW4oaW5wdXQ6VmVydGV4SW5wdXQpLT5WZXJ0ZXhPdXRwdXQge1xyXG4gICAgICAgIHZhciB2ZXJ0ZXhPdXRwdXQ6VmVydGV4T3V0cHV0O1xyXG4gICAgICAgICNpZiAke2RlZmluZXMuVVNFX1RFWFRVUkV9XHJcbiAgICAgICAgICAgIHZlcnRleE91dHB1dC52VXYgPSBpbnB1dC51djtcclxuICAgICAgICAjZW5kaWZcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9MSUdIVFRFWFRVUkUgfHwgZGVmaW5lcy5VU0VfQU9URVhUVVJFfVxyXG4gICAgICAgICAgICB2ZXJ0ZXhPdXRwdXQudlV2MiBpbnB1dC51djI7XHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfQ09MT1JfQUxQSEF9XHJcbiAgICAgICAgICAgIHZlcnRleE91dHB1dC52Q29sb3IgPSB2ZWM0KCAxLjAgKTtcclxuICAgICAgICAgICAgI2VsaWYgJHtkZWZpbmVzLlVTRV9DT0xPUiB8fCBkZWZpbmVzLlVTRV9JTlNUQU5DSU5HX0NPTE9SfVxyXG4gICAgICAgICAgICB2ZXJ0ZXhPdXRwdXQudkNvbG9yID0gdmVjMyggMS4wICk7XHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfQ09MT1J9XHJcbiAgICAgICAgICAgIHZlcnRleE91dHB1dC52Q29sb3IgKj0gaW5wdXQuY29sb3I7XHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfSU5TVEFOQ0lOR19DT0xPUn1cclxuICAgICAgICAgICAgdmVydGV4T3V0cHV0LnZDb2xvci54eXogKj0gaW5wdXQuaW5zdGFuY2VDb2xvci54eXo7XHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfTU9SUEhDT0xPUlMgJiYgZGVmaW5lcy5NT1JQSFRBUkdFVFNfVEVYVFVSRX1cclxuICAgICAgICAgICAgdmVydGV4T3V0cHV0LnZDb2xvciAqPSBtYXRlcmlhbFVuaWZvcm0ubW9ycGhUYXJnZXRCYXNlSW5mbHVlbmNlO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpIDogdTMyID0gMHU7IGkgPCBtYXRlcmlhbFVuaWZvcm0uTU9SUEhUQVJHRVRTX0NPVU5UOyBpID0gaSArIDF1ICkge1xyXG4gICAgICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfQ09MT1JfQUxQSEF9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCBtYXRlcmlhbFVuaWZvcm0ubW9ycGhUYXJnZXRJbmZsdWVuY2VzWyBpIF0gISA9IDAuMCApIHZlcnRleE91dHB1dC52Q29sb3IgKz0gZ2V0TW9ycGgoIGdsX1ZlcnRleElELCBpLCAyICkgKiBtYXRlcmlhbFVuaWZvcm0ubW9ycGhUYXJnZXRJbmZsdWVuY2VzWyBpIF07XHJcbiAgICAgICAgICAgICAgICAgICAgI2VsaWYgJHtkZWZpbmVzLlVTRV9DT0xPUn1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIG1hdGVyaWFsVW5pZm9ybS5tb3JwaFRhcmdldEluZmx1ZW5jZXNbIGkgXSAhID0gMC4wICkgdmVydGV4T3V0cHV0LnZDb2xvciArPSBnZXRNb3JwaCggZ2xfVmVydGV4SUQsIGksIDIgKS5yZ2IgKiBtYXRlcmlhbFVuaWZvcm0ubW9ycGhUYXJnZXRJbmZsdWVuY2VzWyBpIF07XHJcbiAgICAgICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICNlbmRpZlxyXG4gICAgICAgIHZhciBvYmplY3ROb3JtYWw6dmVjMzxmMzI+ID0gdmVjMzxmMzI+KGlucHV0Lm5vcm1hbCk7XHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfVEFOR0VOVH1cclxuICAgICAgICAgICAgbGV0IG9iamVjdFRhbmdlbnQ6dmVjMzxmMzI+ID0gdmVjMzxmMzI+KCBpbnB1dC50YW5nZW50Lnh5eiApO1xyXG4gICAgICAgICNlbmRpZlxyXG4gICAgICAgICNpZiAke2RlZmluZXMuVVNFX01PUlBITk9STUFMU31cclxuICAgICAgICAgICAgb2JqZWN0Tm9ybWFsICo9IG1hdGVyaWFsVW5pZm9ybS5tb3JwaFRhcmdldEJhc2VJbmZsdWVuY2U7XHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuTU9SUEhUQVJHRVRTX1RFWFRVUkV9XHJcbiAgICAgICAgICAgICAgICBmb3IgKCBsZXQgaSA6IHUzMiA9IDB1OyBpIDwgbWF0ZXJpYWxVbmlmb3JtLk1PUlBIVEFSR0VUU19DT1VOVDsgaSA9IGkgKyAxdSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICggbWF0ZXJpYWxVbmlmb3JtLm1vcnBoVGFyZ2V0SW5mbHVlbmNlc1sgaSBdICEgPSAwLjAgKSBvYmplY3ROb3JtYWwgKz0gZ2V0TW9ycGgoIGdsX1ZlcnRleElELCBpLCAxICkueHl6ICogbWF0ZXJpYWxVbmlmb3JtLm1vcnBoVGFyZ2V0SW5mbHVlbmNlc1sgaSBdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAjZWxzZVxyXG4gICAgICAgICAgICAgICAgb2JqZWN0Tm9ybWFsICs9IG1vcnBoTm9ybWFsMCAqIG1hdGVyaWFsVW5pZm9ybS5tb3JwaFRhcmdldEluZmx1ZW5jZXNbIDAgXTtcclxuICAgICAgICAgICAgICAgIG9iamVjdE5vcm1hbCArPSBtb3JwaE5vcm1hbDEgKiBtYXRlcmlhbFVuaWZvcm0ubW9ycGhUYXJnZXRJbmZsdWVuY2VzWyAxIF07XHJcbiAgICAgICAgICAgICAgICBvYmplY3ROb3JtYWwgKz0gbW9ycGhOb3JtYWwyICogbWF0ZXJpYWxVbmlmb3JtLm1vcnBoVGFyZ2V0SW5mbHVlbmNlc1sgMiBdO1xyXG4gICAgICAgICAgICAgICAgb2JqZWN0Tm9ybWFsICs9IG1vcnBoTm9ybWFsMyAqIG1hdGVyaWFsVW5pZm9ybS5tb3JwaFRhcmdldEluZmx1ZW5jZXNbIDMgXTtcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfU0tJTk5JTkd9XHJcbiAgICAgICAgICAgIGxldCBib25lTWF0WDptYXQ0eDQ8ZjMyPiA9IGdldEJvbmVNYXRyaXgoIGlucHV0LnNraW5JbmRleC54ICk7XHJcbiAgICAgICAgICAgIGxldCBib25lTWF0WTptYXQ0eDQ8ZjMyPiA9IGdldEJvbmVNYXRyaXgoIGlucHV0LnNraW5JbmRleC55ICk7XHJcbiAgICAgICAgICAgIGxldCBib25lTWF0WjptYXQ0eDQ8ZjMyPiA9IGdldEJvbmVNYXRyaXgoIGlucHV0LnNraW5JbmRleC56ICk7XHJcbiAgICAgICAgICAgIGxldCBib25lTWF0VzptYXQ0eDQ8ZjMyPiA9IGdldEJvbmVNYXRyaXgoIGlucHV0LnNraW5JbmRleC53ICk7XHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfU0tJTk5JTkd9XHJcbiAgICAgICAgICAgIGxldCBza2luTWF0cml4Om1hdDR4NDxmMzI+ID0gbWF0NHg0PGYzMj4oIDAuMCApO1xyXG4gICAgICAgICAgICBza2luTWF0cml4ICs9IGlucHV0LnNraW5XZWlnaHQueCAqIGJvbmVNYXRYO1xyXG4gICAgICAgICAgICBza2luTWF0cml4ICs9IGlucHV0LnNraW5XZWlnaHQueSAqIGJvbmVNYXRZO1xyXG4gICAgICAgICAgICBza2luTWF0cml4ICs9IGlucHV0LnNraW5XZWlnaHQueiAqIGJvbmVNYXRaO1xyXG4gICAgICAgICAgICBza2luTWF0cml4ICs9IGlucHV0LnNraW5XZWlnaHQudyAqIGJvbmVNYXRXO1xyXG4gICAgICAgICAgICBza2luTWF0cml4ID0gbWF0ZXJpYWxVbmlmb3JtLmJpbmRNYXRyaXhJbnZlcnNlICogc2tpbk1hdHJpeCAqIG1hdGVyaWFsVW5pZm9ybS5iaW5kTWF0cml4O1xyXG4gICAgICAgICAgICBvYmplY3ROb3JtYWwgPSB2ZWM0PGYzMj4oIHNraW5NYXRyaXggKiB2ZWM0PGYzMj4oIG9iamVjdE5vcm1hbCwgMC4wICkgKS54eXo7XHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX1RBTkdFTlR9XHJcbiAgICAgICAgICAgICAgICBvYmplY3RUYW5nZW50ID0gdmVjNDxmMzI+KCBza2luTWF0cml4ICogdmVjNDxmMzI+KCBvYmplY3RUYW5nZW50LCAwLjAgKSApLnh5ejtcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgdmFyIHRyYW5zZm9ybWVkTm9ybWFsOnZlYzM8ZjMyPiA9IG9iamVjdE5vcm1hbDtcclxuICAgICAgICAvLyB0cmFuc2Zvcm1lZE5vcm1hbCs9dmVjMzxmMzI+KDAuMCk7XHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfSU5TVEFOQ0lOR31cclxuICAgICAgICAgICAgbGV0IG06bWF0M3gzPGYzMj4gPSBtYXQzeDM8ZjMyPiggaW5wdXQuaW5zdGFuY2VNYXRyaXggKTtcclxuICAgICAgICAgICAgdHJhbnNmb3JtZWROb3JtYWwgLz0gdmVjMzxmMzI+KCBkb3QoIG1bIDAgXSwgbVsgMCBdICksIGRvdCggbVsgMSBdLCBtWyAxIF0gKSwgZG90KCBtWyAyIF0sIG1bIDIgXSApICk7XHJcbiAgICAgICAgICAgIHRyYW5zZm9ybWVkTm9ybWFsID0gbSAqIHRyYW5zZm9ybWVkTm9ybWFsO1xyXG4gICAgICAgICNlbmRpZlxyXG4gICAgICAgIHRyYW5zZm9ybWVkTm9ybWFsID0gbWF0ZXJpYWxVbmlmb3JtLm5vcm1hbE1hdHJpeCAqIHRyYW5zZm9ybWVkTm9ybWFsO1xyXG4gICAgICAgICNpZiAke2RlZmluZXMuRkxJUF9TSURFRH1cclxuICAgICAgICAgICAgdHJhbnNmb3JtZWROb3JtYWwgPSAtIHRyYW5zZm9ybWVkTm9ybWFsO1xyXG4gICAgICAgICNlbmRpZlxyXG4gICAgICAgICNpZiAke2RlZmluZXMuVVNFX1RBTkdFTlR9XHJcbiAgICAgICAgICAgIGxldCB0cmFuc2Zvcm1lZFRhbmdlbnQ6dmVjMzxmMzI+ID0gKGdsb2JhbFVuaWZvcm0udmlld01hdHJpeCptYXRlcmlhbFVuaWZvcm0ubW9kZWxNYXRyaXggKiB2ZWM0PGYzMj4oIG9iamVjdFRhbmdlbnQsIDAuMCApICkueHl6O1xyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLkZMSVBfU0lERUR9XHJcbiAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lZFRhbmdlbnQgPSAtIHRyYW5zZm9ybWVkVGFuZ2VudDtcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgdmVydGV4T3V0cHV0LnZOb3JtYWwgPSBub3JtYWxpemUoIHRyYW5zZm9ybWVkTm9ybWFsICk7XHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5GTEFUX1NIQURFRH1cclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfVEFOR0VOVH1cclxuICAgICAgICAgICAgICAgIHZUYW5nZW50ID0gbm9ybWFsaXplKCB0cmFuc2Zvcm1lZFRhbmdlbnQgKTtcclxuICAgICAgICAgICAgICAgIHZCaXRhbmdlbnQgPSBub3JtYWxpemUoIGNyb3NzKCB2Tm9ybWFsLCB2VGFuZ2VudCApICogaW5wdXQudGFuZ2VudC53ICk7XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICNlbmRpZlxyXG4gICAgICAgIGxldCB0cmFuc2Zvcm1lZDp2ZWMzPGYzMj4gPSB2ZWMzPGYzMj4oIGlucHV0LnBvc2l0aW9uICk7XHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfTU9SUEhUQVJHRVRTfVxyXG4gICAgICAgICAgICB0cmFuc2Zvcm1lZCAqPSBtYXRlcmlhbFVuaWZvcm0ubW9ycGhUYXJnZXRCYXNlSW5mbHVlbmNlO1xyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLk1PUlBIVEFSR0VUU19URVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgZm9yICggbGV0IGkgOiB1MzIgPSAwdTsgaSA8IG1hdGVyaWFsVW5pZm9ybS5NT1JQSFRBUkdFVFNfQ09VTlQ7IGkgPSBpICsgMXUgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCBtYXRlcmlhbFVuaWZvcm0ubW9ycGhUYXJnZXRJbmZsdWVuY2VzWyBpIF0gISA9IDAuMCApIHRyYW5zZm9ybWVkICs9IGdldE1vcnBoKCBnbF9WZXJ0ZXhJRCwgaSwgMCApLnh5eiAqIG1vcnBoVGFyZ2V0SW5mbHVlbmNlc1sgaSBdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAjZWxzZVxyXG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtZWQgKz0gaW5wdXQubW9ycGhUYXJnZXQwICogbWF0ZXJpYWxVbmlmb3JtLm1vcnBoVGFyZ2V0SW5mbHVlbmNlc1sgMCBdO1xyXG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtZWQgKz0gaW5wdXQubW9ycGhUYXJnZXQxICogbWF0ZXJpYWxVbmlmb3JtLm1vcnBoVGFyZ2V0SW5mbHVlbmNlc1sgMSBdO1xyXG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtZWQgKz0gaW5wdXQubW9ycGhUYXJnZXQyICogbWF0ZXJpYWxVbmlmb3JtLm1vcnBoVGFyZ2V0SW5mbHVlbmNlc1sgMiBdO1xyXG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtZWQgKz0gaW5wdXQubW9ycGhUYXJnZXQzICogbWF0ZXJpYWxVbmlmb3JtLm1vcnBoVGFyZ2V0SW5mbHVlbmNlc1sgMyBdO1xyXG4gICAgICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfTU9SUEhOT1JNQUxTfVxyXG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVkICs9IGlucHV0Lm1vcnBoVGFyZ2V0NCAqIG1hdGVyaWFsVW5pZm9ybS5tb3JwaFRhcmdldEluZmx1ZW5jZXNbIDQgXTtcclxuICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lZCArPSBpbnB1dC5tb3JwaFRhcmdldDUgKiBtYXRlcmlhbFVuaWZvcm0ubW9ycGhUYXJnZXRJbmZsdWVuY2VzWyA1IF07XHJcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZWQgKz0gaW5wdXQubW9ycGhUYXJnZXQ2ICogbWF0ZXJpYWxVbmlmb3JtLm1vcnBoVGFyZ2V0SW5mbHVlbmNlc1sgNiBdO1xyXG4gICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVkICs9IGlucHV0Lm1vcnBoVGFyZ2V0NyAqIG1hdGVyaWFsVW5pZm9ybS5tb3JwaFRhcmdldEluZmx1ZW5jZXNbIDcgXTtcclxuICAgICAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAjZW5kaWZcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9TS0lOTklOR31cclxuICAgICAgICAgICAgbGV0IHNraW5WZXJ0ZXg6dmVjNDxmMzI+ID0gbWF0ZXJpYWxVbmlmb3JtLmJpbmRNYXRyaXggKiB2ZWM0PGYzMj4oIHRyYW5zZm9ybWVkLCAxLjAgKTtcclxuICAgICAgICAgICAgbGV0IHNraW5uZWQ6dmVjNDxmMzI+ID0gdmVjNDxmMzI+KCAwLjAgKTtcclxuICAgICAgICAgICAgc2tpbm5lZCArPSBib25lTWF0WCAqIHNraW5WZXJ0ZXggKiBpbnB1dC5za2luV2VpZ2h0Lng7XHJcbiAgICAgICAgICAgIHNraW5uZWQgKz0gYm9uZU1hdFkgKiBza2luVmVydGV4ICogaW5wdXQuc2tpbldlaWdodC55O1xyXG4gICAgICAgICAgICBza2lubmVkICs9IGJvbmVNYXRaICogc2tpblZlcnRleCAqIGlucHV0LnNraW5XZWlnaHQuejtcclxuICAgICAgICAgICAgc2tpbm5lZCArPSBib25lTWF0VyAqIHNraW5WZXJ0ZXggKiBpbnB1dC5za2luV2VpZ2h0Lnc7XHJcbiAgICAgICAgICAgIHRyYW5zZm9ybWVkID0gKCBtYXRlcmlhbFVuaWZvcm0uYmluZE1hdHJpeEludmVyc2UgKiBza2lubmVkICkueHl6O1xyXG4gICAgICAgICNlbmRpZlxyXG4gICAgICAgICNpZiAke2RlZmluZXMuVVNFX0RJU1BMQUNFTUVOVFRFWFRVUkV9IFxyXG4gICAgICAgICAgICB0cmFuc2Zvcm1lZCArPSBub3JtYWxpemUoIG9iamVjdE5vcm1hbCApICogKHRleHR1cmVTYW1wbGUoZGlzcGxhY2VtZW50TWFwLCBiYXNlU2FtcGxlciwgdlV2KS54ICogbWF0ZXJpYWxVbmlmb3JtLmRpc3BsYWNlbWVudFNjYWxlICsgbWF0ZXJpYWxVbmlmb3JtLmRpc3BsYWNlbWVudEJpYXMgKTtcclxuICAgICAgICAjZW5kaWZcclxuICAgICAgICB2YXIgbXZQb3NpdGlvbjp2ZWM0PGYzMj4gPSB2ZWM0PGYzMj4oIHRyYW5zZm9ybWVkLCAxLjAgKTtcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9JTlNUQU5DSU5HfVxyXG4gICAgICAgICAgICBtdlBvc2l0aW9uID0gaW5wdXQuaW5zdGFuY2VNYXRyaXggKiBtdlBvc2l0aW9uO1xyXG4gICAgICAgICNlbmRpZlxyXG4gICAgICAgIG12UG9zaXRpb24gPSBnbG9iYWxVbmlmb3JtLnZpZXdNYXRyaXgqbWF0ZXJpYWxVbmlmb3JtLm1vZGVsTWF0cml4ICogbXZQb3NpdGlvbjtcclxuICAgICAgICB2ZXJ0ZXhPdXRwdXQucG9zaXRpb24gPSBnbG9iYWxVbmlmb3JtLnByb2plY3Rpb25NYXRyaXggKiBtdlBvc2l0aW9uO1xyXG4gICAgICAgIHZlcnRleE91dHB1dC52Vmlld1Bvc2l0aW9uID0gLSBtdlBvc2l0aW9uLnh5ei9tdlBvc2l0aW9uLnc7XHJcbiAgICAgICAgI2lmICR7XHJcbiAgICAgICAgICBkZWZpbmVzLlVTRV9FTlZURVhUVVJFIHx8IGRlZmluZXMuRElTVEFOQ0UgfHwgZGVmaW5lcy5VU0VfVFJBTlNNSVNTSU9OXHJcbiAgICAgICAgfSBcclxuICAgICAgICAgICAgdmFyIHdvcmxkUG9zaXRpb246dmVjNDxmMzI+ID0gdmVjNDxmMzI+KCB0cmFuc2Zvcm1lZCwgMS4wICk7XHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX0lOU1RBTkNJTkd9XHJcbiAgICAgICAgICAgICAgICB3b3JsZFBvc2l0aW9uID0gaW5wdXQuaW5zdGFuY2VNYXRyaXggKiB3b3JsZFBvc2l0aW9uO1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgd29ybGRQb3NpdGlvbiA9IG1hdGVyaWFsVW5pZm9ybS5tb2RlbE1hdHJpeCAqIHdvcmxkUG9zaXRpb247XHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfVFJBTlNNSVNTSU9OfVxyXG4gICAgICAgICAgICB2ZXJ0ZXhPdXRwdXQudldvcmxkUG9zaXRpb24gPSB3b3JsZFBvc2l0aW9uLnh5ejtcclxuICAgICAgICAjZW5kaWZcclxuICAgICAgICByZXR1cm4gdmVydGV4T3V0cHV0O1xyXG4gICAgfVxyXG4gICAgYDtcclxufVxyXG4iLCJpbXBvcnQgeyB3Z3NsUGFyc2VEZWZpbmVzIH0gZnJvbSBcIi4uL1dnc2xQcmVwcm9jZXNzb3JcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHBob25nRnJhZyhkZWZpbmVzKSB7XG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYCAgXG4gICAgc3RydWN0IE1hdGVyaWFsVW5pZm9ybSB7XG4gICAgICBtb2RlbE1hdHJpeDogbWF0NHg0PGYzMj4sXG4gICAgICBjb2xvcjogdmVjMzxmMzI+LFxuICAgICAgb3BhY2l0eTpmMzIsXG4gICAgICBub3JtYWxNYXRyaXg6IG1hdDR4NDxmMzI+LFxuICAgICAgZW1pc3NpdmU6dmVjMzxmMzI+LFxuICAgICAgc2hpbmluZXNzOmYzMixcbiAgICAgIHNwZWN1bGFyOnZlYzM8ZjMyPiwgICAgICBcbiAgIH1cbiAgICAjaW5jbHVkZSA8RnJhZ0lucHV0PlxuICAgICNpbmNsdWRlIDxTeXN0ZW1Vbmlmb3JtPlxuICAgICNpbmNsdWRlIDxUZXh0dXJlQW5kU2FtcGxlckRlZmluZT5cbiAgICAjaW5jbHVkZSA8bGlnaHQ+XG4gICAgQGJpbmRpbmcoJHtkZWZpbmVzLnBob25nQmluZGluZ30pIEBncm91cCgwKSB2YXI8dW5pZm9ybT4gbWF0ZXJpYWxVbmlmb3JtIDogTWF0ZXJpYWxVbmlmb3JtO1xuICAgIEBiaW5kaW5nKCR7ZGVmaW5lcy5jYW1lcmFCaW5kaW5nfSkgQGdyb3VwKDEpIHZhcjx1bmlmb3JtPiBzeXN0ZW1Vbmlmb3JtIDogU3lzdGVtVW5pZm9ybTtcbiAgICBAZnJhZ21lbnRcbiAgICBmbiBtYWluKGlucHV0OkZyYWdJbnB1dCkgLT4gQGxvY2F0aW9uKDApIHZlYzQ8ZjMyPiB7XG4gICAgICAgIHZhciB0b3RhbEVtaXNzaXZlUmFkaWFuY2U6dmVjMzxmMzI+ID0gbWF0ZXJpYWxVbmlmb3JtLmVtaXNzaXZlO1xuICAgICAgICB2YXIgY29sb3I6dmVjNDxmMzI+O1xuICAgICAgICAjaWYke2RlZmluZXMuVVNFX0NPTE9SVEVYVFVSRX1cbiAgICAgICAgICAgIGNvbG9yPSB2ZWM0PGYzMj4odGV4dHVyZVNhbXBsZShiYXNlQ29sb3JUZXh0dXJlLCBiYXNlQ29sb3JTYW1wbGVyLCBpbnB1dC51dikucmdiK21hdGVyaWFsVW5pZm9ybS5jb2xvcixtYXRlcmlhbFVuaWZvcm0ub3BhY2l0eSk7XG4gICAgICAgICNlbHNlXG4gICAgICAgICAgICBjb2xvcj12ZWM0PGYzMj4obWF0ZXJpYWxVbmlmb3JtLmNvbG9yLG1hdGVyaWFsVW5pZm9ybS5vcGFjaXR5KTtcbiAgICAgICAgI2VuZGlmICAgICBcbiAgICAgICAgbGV0ICBWOnZlYzM8ZjMyPiA9ICBub3JtYWxpemUoIHN5c3RlbVVuaWZvcm0uY2FtZXJhUG9zaXRpb24gLSBpbnB1dC53b3JsZFBvcyk7XG4gICAgICAgICNpZiAke2RlZmluZXMuVVNFX05PUk1BTFRFWFRVUkV9XG4gICAgICAgICAgICBsZXQgTjp2ZWMzPGYzMj4gPSBnZXROb3JtYWxCeU5vcm1hbFRleHR1cmUoaW5wdXQpOyAgXG4gICAgICAgICNlbHNlXG4gICAgICAgICAgICBsZXQgTjp2ZWMzPGYzMj4gPSBnZXROb3JtYWwoaW5wdXQpO1xuICAgICAgICAjZW5kaWZcbiAgICAgICAgdmFyIGdlb21ldHJ5Okdlb21ldHJ5O1xuICAgICAgICBnZW9tZXRyeS5ub3JtYWw9TjtcbiAgICAgICAgZ2VvbWV0cnkudmlld0Rpcj1WO1xuICAgICAgICBnZW9tZXRyeS5wb3NpdGlvbj1pbnB1dC53b3JsZFBvcztcbiAgICAgICAgbGV0IGxpZ2h0Q29sb3I6UmVmbGVjdGVkTGlnaHQ9cGFyc2VMaWdodHMoZ2VvbWV0cnksbWF0ZXJpYWxVbmlmb3JtLnNoaW5pbmVzcyk7XG4gICAgICAgIC8vIHZhciBmaW5uYWxDb2xvcjp2ZWMzPGYzMj49Y29sb3IueHl6ICsgKGxpZ2h0Q29sb3IuZGlyZWN0RGlmZnVzZSArIGxpZ2h0Q29sb3IuZGlyZWN0U3BlY3VsYXIgKyBsaWdodENvbG9yLmFtYmllbnQpO1xuICAgICAgICB2YXIgZmlubmFsQ29sb3I6dmVjMzxmMzI+PWNvbG9yLnh5eiAqIChsaWdodENvbG9yLmRpcmVjdERpZmZ1c2UgKyBsaWdodENvbG9yLmRpcmVjdFNwZWN1bGFyICsgbGlnaHRDb2xvci5hbWJpZW50KTtcblxuICAgICAgICAvLyBmaW5uYWxDb2xvciA9IGxpZ2h0Q29sb3IudGVzdENvbG9yLnh5ejtcblxuICAgICAgICByZXR1cm4gdmVjNDxmMzI+KGZpbm5hbENvbG9yLGNvbG9yLmEpO1xuICAgIH1gO1xufVxuIiwiaW1wb3J0IHsgd2dzbFBhcnNlRGVmaW5lcyB9IGZyb20gXCIuLi9XZ3NsUHJlcHJvY2Vzc29yXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBwaG9uZ1ZlcnQoZGVmaW5lcykge1xuXHRyZXR1cm4gd2dzbFBhcnNlRGVmaW5lc2BcbiAgICAgIHN0cnVjdCBNYXRlcmlhbFVuaWZvcm0ge1xuICAgICAgICAgICAgbW9kZWxNYXRyaXg6IG1hdDR4NDxmMzI+LFxuICAgICAgICAgICAgY29sb3I6IHZlYzM8ZjMyPixcbiAgICAgICAgICAgIG9wYWNpdHk6ZjMyLFxuICAgICAgICAgICAgbm9ybWFsTWF0cml4OiBtYXQ0eDQ8ZjMyPixcbiAgICAgICAgICAgIGVtaXNzaXZlOnZlYzM8ZjMyPixcbiAgICAgICAgICAgIHNwZWN1bGFyOnZlYzM8ZjMyPixcbiAgICAgICAgICAgIHNoaW5pbmVzczpmMzIsXG4gICAgICB9XG4gICAgICAjaW5jbHVkZSA8VmVydGV4T3V0cHV0PlxuICAgICAgI2luY2x1ZGUgPFN5c3RlbVVuaWZvcm0+XG4gICAgICAjaW5jbHVkZSA8VmVydGV4SW5wdXQ+XG4gICAgICBAYmluZGluZygke2RlZmluZXMucGhvbmdCaW5kaW5nfSkgQGdyb3VwKDApIHZhcjx1bmlmb3JtPiBzZWxmVW5pZm9ybSA6IE1hdGVyaWFsVW5pZm9ybTtcbiAgICAgIEBiaW5kaW5nKCR7ZGVmaW5lcy5jYW1lcmFCaW5kaW5nfSkgQGdyb3VwKDEpIHZhcjx1bmlmb3JtPiBzeXN0ZW1Vbmlmb3JtIDogU3lzdGVtVW5pZm9ybTtcbiAgICAgIEB2ZXJ0ZXhcbiAgICAgIGZuIG1haW4oaW5wdXQ6IFZlcnRleElucHV0KSAtPiBWZXJ0ZXhPdXRwdXQge1xuICAgICAgICAgICAgdmFyIG91dHB1dDogVmVydGV4T3V0cHV0O1xuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5IQVNfVVZ9XG4gICAgICAgICAgICAgICBvdXRwdXQudXYgPSBpbnB1dC51djtcbiAgICAgICAgICAgICNlbmRpZiBcbiAgICAgICAgICAgIGxldCBtb2RlbFBvcz1zZWxmVW5pZm9ybS5tb2RlbE1hdHJpeCAqdmVjNDxmMzI+KGlucHV0LnBvc2l0aW9uLDEuMCk7XG4gICAgICAgICAgICBvdXRwdXQud29ybGRQb3MgPSBtb2RlbFBvcy54eXovbW9kZWxQb3MudztcbiAgICAgICAgICAgIGxldCB2Tm9ybWFsVmlldyA9IHNlbGZVbmlmb3JtLm5vcm1hbE1hdHJpeCAqIHZlYzQ8ZjMyPihpbnB1dC5ub3JtYWwsMC4wKTtcbiAgICAgICAgICAgIG91dHB1dC5ub3JtYWwgPSAgdk5vcm1hbFZpZXcueHl6O1xuICAgICAgICAgICAgb3V0cHV0LnZpZXcgPSBzeXN0ZW1Vbmlmb3JtLmNhbWVyYVBvc2l0aW9uLnh5eiAtIG1vZGVsUG9zLnh5ejtcbiAgICAgICAgICAgIGxldCB2aWV3UG9zaXRpb249c3lzdGVtVW5pZm9ybS52aWV3TWF0cml4ICogbW9kZWxQb3M7XG4gICAgICAgICAgICBvdXRwdXQudmlld1Bvc2l0aW9uID0gLXZpZXdQb3NpdGlvbi54eXo7XG4gICAgICAgICAgICBvdXRwdXQucG9zaXRpb24gPSBzeXN0ZW1Vbmlmb3JtLnByb2plY3Rpb25NYXRyaXggKiBzeXN0ZW1Vbmlmb3JtLnZpZXdNYXRyaXggKiBtb2RlbFBvcztcbiAgICAgICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgICB9YDtcbn1cbiIsImltcG9ydCB7IHdnc2xQYXJzZURlZmluZXMgfSBmcm9tIFwiLi4vV2dzbFByZXByb2Nlc3NvclwiO1xuXG5leHBvcnQgZnVuY3Rpb24gcG9pbnRfZnMoZGVmaW5lcykge1xuXHRyZXR1cm4gd2dzbFBhcnNlRGVmaW5lc2BcbiAgI2luY2x1ZGUgPFBvaW50RnJhZ0lucHV0PlxuICBzdHJ1Y3QgU2VsZlVuaWZvcm0ge1xuICAgIG1vZGVsTWF0cml4OiBtYXQ0eDQ8ZjMyPixcbiAgICBjb2xvcjp2ZWMzPGYzMj4sXG4gICAgc2l6ZTpmMzIsXG4gICAgb3BhY2l0eTpmMzIsXG4gIH1cbiAgQGJpbmRpbmcoJHtkZWZpbmVzLnBvaW50QmluZGluZ30pIEBncm91cCgwKSB2YXI8dW5pZm9ybT4gc2VsZlVuaWZvcm0gOiBTZWxmVW5pZm9ybTtcbiAgI2lmJHtkZWZpbmVzLlVTRV9DT0xPUlRFWFRVUkV9XG4gICAgQGdyb3VwKDApIEBiaW5kaW5nKCR7ZGVmaW5lcy5iYXNlQ29sb3JTYW1wbGVyQmluZGluZ30pIHZhciBiYXNlQ29sb3JTYW1wbGVyOiBzYW1wbGVyO1xuICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMuYmFzZUNvbG9yVGV4dHVyZUJpbmRpbmd9KSB2YXIgYmFzZUNvbG9yVGV4dHVyZTogdGV4dHVyZV8yZDxmMzI+O1xuICAjZW5kaWZcbiAgQGZyYWdtZW50XG4gIGZuIG1haW4oaW5wdXQ6UG9pbnRGcmFnSW5wdXQpIC0+IEBsb2NhdGlvbigwKSB2ZWM0PGYzMj4ge1xuICAgIHZhciBjb2xvcjp2ZWM0PGYzMj49dmVjNDxmMzI+KHNlbGZVbmlmb3JtLmNvbG9yLHNlbGZVbmlmb3JtLm9wYWNpdHkpO1xuICAgICNpZiR7ZGVmaW5lcy5VU0VfQ09MT1JURVhUVVJFfVxuICAgICAgY29sb3I9dGV4dHVyZVNhbXBsZShiYXNlQ29sb3JUZXh0dXJlLCBiYXNlQ29sb3JTYW1wbGVyLCBpbnB1dC51dik7XG4gICAgI2VuZGlmXG4gICAgI2lmJHtkZWZpbmVzLkhBU19DT0xPUn1cbiAgICAgIGNvbG9yPXZlYzQ8ZjMyPihpbnB1dC5jb2xvcixzZWxmVW5pZm9ybS5vcGFjaXR5KTtcbiAgICAjZW5kaWZcbiAgICByZXR1cm4gY29sb3I7XG4gIH1cbiAgYDtcbn1cbiIsImltcG9ydCB7IHdnc2xQYXJzZURlZmluZXMgfSBmcm9tIFwiLi4vV2dzbFByZXByb2Nlc3NvclwiO1xuXG5leHBvcnQgZnVuY3Rpb24gcG9pbnRfdnMoZGVmaW5lcykge1xuXHRyZXR1cm4gd2dzbFBhcnNlRGVmaW5lc2BcbiAgICAjaW5jbHVkZSA8UG9pbnRWZXJ0T3V0cHV0PlxuICAgICNpbmNsdWRlIDxTeXN0ZW1Vbmlmb3JtPlxuICAgICNpbmNsdWRlIDxQb2ludFZlcnRJbnB1dD5cbiAgICBzdHJ1Y3QgU2VsZlVuaWZvcm0ge1xuICAgICAgbW9kZWxNYXRyaXg6IG1hdDR4NDxmMzI+LFxuICAgICAgY29sb3I6dmVjMzxmMzI+LFxuICAgICAgc2l6ZTpmMzIsXG4gICAgICBvcGFjaXR5OmYzMixcbiAgICB9XG4gICAgQGJpbmRpbmcoJHtkZWZpbmVzLnBvaW50QmluZGluZ30pIEBncm91cCgwKSB2YXI8dW5pZm9ybT4gc2VsZlVuaWZvcm0gOiBTZWxmVW5pZm9ybTtcbiAgICBAYmluZGluZygke2RlZmluZXMuY2FtZXJhQmluZGluZ30pIEBncm91cCgxKSB2YXI8dW5pZm9ybT4gc3lzdGVtVW5pZm9ybSA6IFN5c3RlbVVuaWZvcm07XG4gICAgQHZlcnRleFxuICAgICAgZm4gbWFpbihpbnB1dDogUG9pbnRWZXJ0SW5wdXQpIC0+IFBvaW50VmVydE91dHB1dCB7XG4gICAgICB2YXIgb3V0cHV0OlBvaW50VmVydE91dHB1dDtcbiAgICAgIGxldCBtdlBvc2l0aW9uOnZlYzQ8ZjMyPj0geXN0ZW1Vbmlmb3JtLnZpZXdNYXRyaXggKnNlbGZVbmlmb3JtLm1vZGVsTWF0cml4KnZlYzQ8ZjMyPigwLjAsMC4wLDAuMCwgMS4wICk7XG4gICAgICAjaWYgJHtkZWZpbmVzLkhBU19VVn1cbiAgICAgICAgICBvdXRwdXQudXY9aW5wdXQudXY7XG4gICAgICAjZW5kaWZcbiAgICAgICNpZiAke2RlZmluZXMuSEFTX0NPTE9SfVxuICAgICAgICAgIG91dHB1dC5jb2xvcj1pbnB1dC5jb2xvcjtcbiAgICAgICNlbmRpZlxuICAgICAgI2lmICR7ZGVmaW5lcy5IQVNfU0laRX1cbiAgICAgICAgICBvdXRwdXQuc2l6ZT1pbnB1dC5zaXplO1xuICAgICAgI2VuZGlmXG4gICAgICB2ZWMyIGFsaWduZWRQb3NpdGlvbiA9IGlucHV0LnBvc2l0aW9uLnh5KiBzZWxmVW5pZm9ybS5zaXplO1xuICAgICAgbXZQb3NpdGlvbi54eSArPSBhbGlnbmVkUG9zaXRpb247XG4gICAgICBvdXRwdXQucG9zaXRpb24gPSBzeXN0ZW1Vbmlmb3JtLnByb2plY3Rpb25NYXRyaXggKiBtdlBvc2l0aW9uO1xuICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICAgIH1cbiAgIGA7XG59XG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBxdWFkRnJhZyhkZWZpbmVzKSB7XHJcblx0cmV0dXJuIGBcclxuICAgIEBncm91cCgwKSBAYmluZGluZygxKSB2YXIgYmFzZVNhbXBsZXI6IHNhbXBsZXI7XHJcbiAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgdmFyIGNvbG9yVGV4dHVyZTogdGV4dHVyZV8yZDxmMzI+O1xyXG4gICAgc3RydWN0IFZlcnRleE91dHB1dCB7XHJcbiAgICAgICAgQGJ1aWx0aW4ocG9zaXRpb24pIHBvc2l0aW9uOiB2ZWM0PGYzMj4sXHJcbiAgICAgICAgQGxvY2F0aW9uKDApIHV2OiB2ZWMyPGYzMj4sXHJcbiAgICB9O1xyXG4gICAgQGZyYWdtZW50XHJcbiAgICBmbiBtYWluKGlucHV0OlZlcnRleE91dHB1dCkgLT4gQGxvY2F0aW9uKDApIHZlYzQ8ZjMyPiB7XHJcbiAgICAgIHJldHVybiB0ZXh0dXJlU2FtcGxlKGNvbG9yVGV4dHVyZSwgYmFzZVNhbXBsZXIsIHZlYzI8ZjMyPihpbnB1dC51di54LDEuMC1pbnB1dC51di55KSk7XHJcbiAgICB9XHJcbiAgICBgO1xyXG59XHJcbiIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHF1YWRWZXJ0KGRlZmluZXMpIHtcblx0cmV0dXJuIGBcbiAgICBzdHJ1Y3QgVmVydGV4SW5wdXQge1xuICAgICAgICAgQGxvY2F0aW9uKCR7ZGVmaW5lcy5wb3NpdGlvbkxvY2F0aW9ufSkgcG9zaXRpb246IHZlYzI8ZjMyPiwgICAgICAgXG4gICAgfVxuICAgIHN0cnVjdCBWZXJ0ZXhPdXRwdXQge1xuICAgICAgICAgQGJ1aWx0aW4ocG9zaXRpb24pIHBvc2l0aW9uOiB2ZWM0PGYzMj4sXG4gICAgICAgICBAbG9jYXRpb24oMCkgdXY6IHZlYzI8ZjMyPixcbiAgICAgfTtcbiAgICBAdmVydGV4XG4gICAgZm4gbWFpbihpbnB1dDogVmVydGV4SW5wdXQpIC0+IFZlcnRleE91dHB1dCB7XG4gICAgIHZhciBvdXRwdXQ6VmVydGV4T3V0cHV0O1xuICAgICBvdXRwdXQudXYgPSBpbnB1dC5wb3NpdGlvbiAqIDAuNSArIDAuNTtcbiAgICAgb3V0cHV0LnBvc2l0aW9uID0gdmVjNDxmMzI+KGlucHV0LnBvc2l0aW9uLCAwLjAsIDEuMCk7O1xuICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH1cbiAgICBgO1xufVxuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gc2t5Qm94RnJhZyhkZWZpbmVzKSB7XHJcbiAgcmV0dXJuIGBcclxuICAgIGZuIGxlc3NUaGFuRXF1YWwoYTp2ZWMzPGYzMj4sYjp2ZWMzPGYzMj4pLT52ZWMzPGYzMj57XHJcbiAgICAgICAgbGV0IHhWYWx1ZTpmMzI9c2VsZWN0KGIueCxhLngsYS54PD1iLngpO1xyXG4gICAgICAgIGxldCB5VmFsdWU6ZjMyPXNlbGVjdChiLnksYS55LGEueTw9Yi55KTtcclxuICAgICAgICBsZXQgelZhbHVlOmYzMj1zZWxlY3QoYi56LGEueixhLno8PWIueik7XHJcbiAgICAgICAgcmV0dXJuIHZlYzM8ZjMyPih4VmFsdWUseVZhbHVlLHpWYWx1ZSk7ICAgIFxyXG4gICAgIH1cclxuICAgIGZuIExpbmVhclRvc1JHQiggdmFsdWU6dmVjNDxmMzI+ICktPnZlYzQ8ZjMyPiB7XHJcbiAgICAgICAgcmV0dXJuIHZlYzQ8ZjMyPiggbWl4KCBwb3coIHZhbHVlLnJnYiwgdmVjMzxmMzI+KCAwLjQxNjY2ICkgKSAqIDEuMDU1IC0gdmVjMzxmMzI+KCAwLjA1NSApLCB2YWx1ZS5yZ2IgKiAxMi45MiwgdmVjMzxmMzI+KCBsZXNzVGhhbkVxdWFsKCB2YWx1ZS5yZ2IsIHZlYzM8ZjMyPiggMC4wMDMxMzA4ICkgKSApICksIHZhbHVlLmEgKTtcclxuICAgIH1cclxuICBzdHJ1Y3QgRnJhZ21lbnRJbnB1dCB7XHJcbiAgICBAbG9jYXRpb24oMCkgdGV4Q29vcmQgOiB2ZWMzPGYzMj5cclxuICB9O1xyXG4gIEBncm91cCgwKSBAYmluZGluZygyKSB2YXIgZGVmYXVsdFNhbXBsZXI6IHNhbXBsZXI7XHJcbiAgQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciBza3lib3hUZXh0dXJlOiB0ZXh0dXJlX2N1YmU8ZjMyPjtcclxuICBAZnJhZ21lbnRcclxuICBmbiBtYWluKGlucHV0IDogRnJhZ21lbnRJbnB1dCkgLT4gQGxvY2F0aW9uKDApIHZlYzQ8ZjMyPiB7XHJcbiAgICBsZXQgY29sb3IgPSB0ZXh0dXJlU2FtcGxlKHNreWJveFRleHR1cmUsIGRlZmF1bHRTYW1wbGVyLCBpbnB1dC50ZXhDb29yZCk7XHJcbiAgICByZXR1cm4gTGluZWFyVG9zUkdCKGNvbG9yKTtcclxuICB9XHJcbmA7XHJcbn1cclxuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gc2t5Qm94VmVydChkZWZpbmVzKSB7XG5cdHJldHVybiBgXG4gICBzdHJ1Y3QgU3lzdGVtVW5pZm9ybSB7XG4gICAgICAgcHJvamVjdGlvbk1hdHJpeDogbWF0NHg0PGYzMj4sXG4gICAgICAgdmlld01hdHJpeDogbWF0NHg0PGYzMj4sXG4gICAgICAgaW52ZXJzZVZpZXdNYXRyaXg6IG1hdDR4NDxmMzI+LFxuICAgICAgIGNhbWVyYVBvc2l0aW9uOiB2ZWMzPGYzMj4sXG4gICB9OyBcbiAgIHN0cnVjdCBNYXRlcmlhbFVuaWZvcm0ge1xuICAgIG1vZGVsTWF0cml4OiBtYXQ0eDQ8ZjMyPixcbiB9XG4gICBAYmluZGluZygke2RlZmluZXMuc2t5Ym94QmluZGluZ30pIEBncm91cCgwKSB2YXI8dW5pZm9ybT4gc2VsZlVuaWZvcm0gOiBNYXRlcmlhbFVuaWZvcm07XG4gICBAYmluZGluZygke2RlZmluZXMuY2FtZXJhQmluZGluZ30pIEBncm91cCgxKSB2YXI8dW5pZm9ybT4gc3lzdGVtVW5pZm9ybSA6IFN5c3RlbVVuaWZvcm07XG4gICAgIHN0cnVjdCBWZXJ0ZXhJbnB1dCB7XG4gICAgICAgQGxvY2F0aW9uKCR7ZGVmaW5lcy5wb3NpdGlvbkxvY2F0aW9ufSkgcG9zaXRpb24gOiB2ZWMzPGYzMj4sXG4gICAgIH07XG4gICAgIHN0cnVjdCBWZXJ0ZXhPdXRwdXQge1xuICAgICAgIEBidWlsdGluKHBvc2l0aW9uKSBwb3NpdGlvbiA6IHZlYzQ8ZjMyPixcbiAgICAgICBAbG9jYXRpb24oMCkgdGV4Q29vcmQgOiB2ZWMzPGYzMj4sXG4gICAgIH07XG4gICAgIEB2ZXJ0ZXhcbiAgICAgZm4gbWFpbihpbnB1dCA6IFZlcnRleElucHV0KSAtPiBWZXJ0ZXhPdXRwdXQge1xuICAgICAgIHZhciBvdXRwdXQgOiBWZXJ0ZXhPdXRwdXQ7XG4gICAgICAgb3V0cHV0LnRleENvb3JkID0gaW5wdXQucG9zaXRpb24ueHl6O1xuICAgICAgIHZhciBtb2RlbFZpZXcgPSBzeXN0ZW1Vbmlmb3JtLnZpZXdNYXRyaXg7XG4gICAgICAgLy8gRHJvcCB0aGUgdHJhbnNsYXRpb24gcG9ydGlvbiBvZiB0aGUgbW9kZWxWaWV3IG1hdHJpeFxuICAgICAgIG1vZGVsVmlld1szXSA9IHZlYzQoMC4wLCAwLjAsIDAuMCwgbW9kZWxWaWV3WzNdLncpO1xuICAgICAgIG91dHB1dC5wb3NpdGlvbiA9IHN5c3RlbVVuaWZvcm0ucHJvamVjdGlvbk1hdHJpeCAqIG1vZGVsVmlldyAqIHZlYzQ8ZjMyPihpbnB1dC5wb3NpdGlvbiwxLjApO1xuICAgICAgIG91dHB1dC5wb3NpdGlvbiA9IG91dHB1dC5wb3NpdGlvbi54eXd3O1xuICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgIH1cbiAgIGA7XG59XG4iLCJpbXBvcnQgeyB3Z3NsUGFyc2VEZWZpbmVzIH0gZnJvbSBcIi4uL1dnc2xQcmVwcm9jZXNzb3JcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHNwcml0ZV9mcyhkZWZpbmVzKSB7XG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYFxuICAjaW5jbHVkZSA8VmVydGV4T3V0cHV0PlxuICBzdHJ1Y3QgU2VsZlVuaWZvcm0ge1xuICAgIG1vZGVsTWF0cml4OiBtYXQ0eDQ8ZjMyPixcbiAgICBjb2xvcjp2ZWMzPGYzMj4sXG4gICAgcm90YXRpb246ZjMyLFxuICAgIGNlbnRlcjp2ZWMyPGYzMj4sXG4gICAgb3BhY2l0eTpmMzIsXG4gIH1cbiAgQGJpbmRpbmcoJHtkZWZpbmVzLnNwcml0ZUJpbmRpbmd9KSBAZ3JvdXAoMCkgdmFyPHVuaWZvcm0+IHNlbGZVbmlmb3JtIDogU2VsZlVuaWZvcm07XG4gICNpZiR7ZGVmaW5lcy5VU0VfQ09MT1JURVhUVVJFfVxuICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMuYmFzZUNvbG9yU2FtcGxlckJpbmRpbmd9KSB2YXIgYmFzZUNvbG9yU2FtcGxlcjogc2FtcGxlcjtcbiAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLmJhc2VDb2xvclRleHR1cmVCaW5kaW5nfSkgdmFyIGJhc2VDb2xvclRleHR1cmU6IHRleHR1cmVfMmQ8ZjMyPjtcbiAgI2VuZGlmXG4gIEBmcmFnbWVudFxuICBmbiBtYWluKGlucHV0OlZlcnRleE91dHB1dCkgLT4gQGxvY2F0aW9uKDApIHZlYzQ8ZjMyPiB7XG4gICAgI2lmJHtkZWZpbmVzLlVTRV9DT0xPUlRFWFRVUkV9XG4gICAgICByZXR1cm4gdGV4dHVyZVNhbXBsZShiYXNlQ29sb3JUZXh0dXJlLCBiYXNlQ29sb3JTYW1wbGVyLCBpbnB1dC51dik7XG4gICAgI2Vsc2VcbiAgICAgIHJldHVybiB2ZWM0PGYzMj4oc2VsZlVuaWZvcm0uY29sb3Isc2VsZlVuaWZvcm0ub3BhY2l0eSk7XG4gICAgI2VuZGlmXG4gIH1cbiAgYDtcbn1cbiIsImltcG9ydCB7IHdnc2xQYXJzZURlZmluZXMgfSBmcm9tIFwiLi4vV2dzbFByZXByb2Nlc3NvclwiO1xuZXhwb3J0IGZ1bmN0aW9uIHNwcml0ZV92cyhkZWZpbmVzKSB7XG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYFxuXG4gICNpbmNsdWRlIDxWZXJ0ZXhJbnB1dD5cbiAgI2luY2x1ZGUgPFZlcnRleE91dHB1dD5cbiAgI2luY2x1ZGUgPFN5c3RlbVVuaWZvcm0+XG4gIHN0cnVjdCBTZWxmVW5pZm9ybSB7XG4gICAgbW9kZWxNYXRyaXg6IG1hdDR4NDxmMzI+LFxuICAgIGNvbG9yOnZlYzM8ZjMyPixcbiAgICByb3RhdGlvbjpmMzIsXG4gICAgY2VudGVyOnZlYzI8ZjMyPixcbiAgICBvcGFjaXR5OmYzMixcbiAgfVxuICBAYmluZGluZygke2RlZmluZXMuc3ByaXRlQmluZGluZ30pIEBncm91cCgwKSB2YXI8dW5pZm9ybT4gc2VsZlVuaWZvcm0gOiBTZWxmVW5pZm9ybTtcbiAgQGJpbmRpbmcoJHtkZWZpbmVzLmNhbWVyYUJpbmRpbmd9KSBAZ3JvdXAoMSkgdmFyPHVuaWZvcm0+IHN5c3RlbVVuaWZvcm0gOiBTeXN0ZW1Vbmlmb3JtO1xuICBAdmVydGV4XG4gIGZuIG1haW4oaW5wdXQ6IFZlcnRleElucHV0KSAtPiBWZXJ0ZXhPdXRwdXQge1xuICAgICAgdmFyIG91dHB1dDpWZXJ0ZXhPdXRwdXQ7XG4gICAgICB2YXIgbXZQb3NpdGlvbjp2ZWM0PGYzMj49IHN5c3RlbVVuaWZvcm0udmlld01hdHJpeCAqc2VsZlVuaWZvcm0ubW9kZWxNYXRyaXgqdmVjNDxmMzI+KDAuMCwwLjAsMC4wLDEuMCk7XG4gICAgICAjaWYgJHtkZWZpbmVzLkhBU19VVn1cbiAgICAgICAgb3V0cHV0LnV2PWlucHV0LnV2O1xuICAgICAgI2VuZGlmXG4gICAgICB2YXIgc2NhbGU6dmVjMjxmMzI+O1xuICAgICAgc2NhbGUueCA9IGxlbmd0aCh2ZWMzPGYzMj4oc2VsZlVuaWZvcm0ubW9kZWxNYXRyaXhbMF0ueCwgc2VsZlVuaWZvcm0ubW9kZWxNYXRyaXhbMF0ueSwgc2VsZlVuaWZvcm0ubW9kZWxNYXRyaXhbMF0ueikpO1xuICAgICAgc2NhbGUueSA9IGxlbmd0aCh2ZWMzPGYzMj4oc2VsZlVuaWZvcm0ubW9kZWxNYXRyaXhbMV0ueCwgc2VsZlVuaWZvcm0ubW9kZWxNYXRyaXhbMV0ueSwgc2VsZlVuaWZvcm0ubW9kZWxNYXRyaXhbMV0ueikpO1xuICAgICAgLy8gc2NhbGUgKj0gLSBtdlBvc2l0aW9uLno7XG4gICAgICB2YXIgYWxpZ25lZFBvc2l0aW9uOnZlYzI8ZjMyPiA9KGlucHV0LnBvc2l0aW9uLnh5LSAoc2VsZlVuaWZvcm0uY2VudGVyIC0gdmVjMjxmMzI+KDAuNSwwLjUpKSkgKiBzY2FsZTtcbiAgICAgIGxldCByb3RhdGVkUG9zaXRpb25YID0gY29zKHNlbGZVbmlmb3JtLnJvdGF0aW9uKSAqIGFsaWduZWRQb3NpdGlvbi54IC0gc2luKCBzZWxmVW5pZm9ybS5yb3RhdGlvbiApICogYWxpZ25lZFBvc2l0aW9uLnk7XG4gICAgICBsZXQgcm90YXRlZFBvc2l0aW9uWSA9IHNpbihzZWxmVW5pZm9ybS5yb3RhdGlvbikgKiBhbGlnbmVkUG9zaXRpb24ueCArIGNvcyggc2VsZlVuaWZvcm0ucm90YXRpb24gKSAqIGFsaWduZWRQb3NpdGlvbi55O1xuICAgICAgdmFyIHJvdGF0ZWRQb3NpdGlvbj12ZWMyPGYzMj4ocm90YXRlZFBvc2l0aW9uWCxyb3RhdGVkUG9zaXRpb25ZKTtcbiAgICAgIGxldCBuZXdQb2ludCA9bXZQb3NpdGlvbi54eSsgcm90YXRlZFBvc2l0aW9uO1xuICAgICAgb3V0cHV0LnBvc2l0aW9uID0gc3lzdGVtVW5pZm9ybS5wcm9qZWN0aW9uTWF0cml4ICogdmVjNDxmMzI+KG5ld1BvaW50LngsbmV3UG9pbnQueSxtdlBvc2l0aW9uLnosbXZQb3NpdGlvbi53KTtcbiAgICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cbiAgYDtcbn1cbiIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGJsZW5kRnJhZyhkZWZpbmVzKSB7XHJcblx0cmV0dXJuIGBcclxuICAgIHN0cnVjdCBGcmFnSW5wdXQge1xyXG4gICAgICAgIEBsb2NhdGlvbigwKSB1djogdmVjMjxmMzI+LFxyXG4gICAgfTtcclxuICAgIEBncm91cCgwKSBAYmluZGluZyh7e3REaWZmdXNlQmluZGluZ319KSB2YXIgdERpZmZ1c2U6IHRleHR1cmVfMmQ8ZjMyPjtcclxuICAgIEBncm91cCgwKSBAYmluZGluZyh7e2Jhc2VDb2xvclRleHR1cmVCaW5kaW5nfX0pIHZhciBiYXNlQ29sb3JUZXh0dXJlOiB0ZXh0dXJlXzJkPGYzMj47XHJcbiAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoe3t0U2FtcGxlckJpbmRpbmd9fSkgdmFyIHRTYW1wbGVyOiBzYW1wbGVyO1xyXG4gICAgQGZyYWdtZW50XHJcbiAgICBmbiBtYWluKGlucHV0OkZyYWdJbnB1dCkgLT4gQGxvY2F0aW9uKDApIHZlYzQ8ZjMyPiB7XHJcbiAgICAgICAgbGV0IHBvc3RDb2xvcjp2ZWM0PGYzMj4gPSB0ZXh0dXJlU2FtcGxlKHREaWZmdXNlLCB0U2FtcGxlciwgaW5wdXQudXYpO1xyXG4gICAgICAgIGxldCBiYXNlQ29sb3I6dmVjNDxmMzI+ID0gdGV4dHVyZVNhbXBsZShiYXNlQ29sb3JUZXh0dXJlLCB0U2FtcGxlciwgaW5wdXQudXYpO1xyXG4gICAgICByZXR1cm4gYmFzZUNvbG9yK3Bvc3RDb2xvcjtcclxuICAgIH0gICBcclxuICAgIGA7XHJcbn1cclxuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQmx1cihkZWZpbmVzKSB7XHJcblx0cmV0dXJuIGBcclxuICAgIHN0cnVjdCBGcmFnSW5wdXQge1xyXG4gICAgICAgIEBsb2NhdGlvbigwKSB1djogdmVjMjxmMzI+LFxyXG4gICAgfVxyXG4gICAgc3RydWN0IEJsdXJVbmlmb3JtcyB7XHJcbiAgICAgICAgZGlyZWN0aW9uOnZlYzI8ZjMyPixcclxuICAgIH1cclxuICAgIGZuIGdhdXNzaWFuUGRmKHg6ZjMyLCBzaWdtYTpmMzIpLT5mMzIge1xyXG4gICAgICAgIHJldHVybiAwLjM5ODk0ICogZXhwKCAtMC41ICogeCAqIHgvKCBzaWdtYSAqIHNpZ21hKSkvc2lnbWE7XHJcbiAgICB9XHJcbiAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgIHZhcjx1bmlmb3JtPiBibHVyVW5pZm9ybXMgOiBCbHVyVW5pZm9ybXM7XHJcbiAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoe3t0RGlmZnVzZUJpbmRpbmd9fSkgdmFyIHREaWZmdXNlOiB0ZXh0dXJlXzJkPGYzMj47XHJcbiAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoe3t0U2FtcGxlckJpbmRpbmd9fSkgdmFyIHRTYW1wbGVyOiBzYW1wbGVyO1xyXG4gICAgQGZyYWdtZW50XHJcbiAgICBmbiBtYWluKGlucHV0OkZyYWdJbnB1dCkgLT4gQGxvY2F0aW9uKDApIHZlYzQ8ZjMyPiB7XHJcbiAgICAgICAgbGV0IGludlNpemU6dmVjMjxmMzI+ID0gdmVjMjxmMzI+KDEuMCwxLjApIC8gdmVjMjxmMzI+KHRleHR1cmVEaW1lbnNpb25zKHREaWZmdXNlKSk7XHJcbiAgICAgICAgbGV0IGZTaWdtYTpmMzIgPWYzMigke2RlZmluZXMuU0lHTUF9KTtcclxuICAgICAgICB2YXIgd2VpZ2h0U3VtOmYzMiA9IGdhdXNzaWFuUGRmKDAuMCwgZlNpZ21hKTtcclxuICAgICAgICBsZXQgYmFzZUNvbG9yPXRleHR1cmVTYW1wbGUodERpZmZ1c2UsIHRTYW1wbGVyLCBpbnB1dC51dik7XHJcbiAgICAgICAgdmFyIGRpZmZ1c2VTdW06dmVjMzxmMzI+ID0gYmFzZUNvbG9yLnJnYiAqIHdlaWdodFN1bTtcclxuICAgICAgICBsZXQgdXZPZmZzZXQ6dmVjMjxmMzI+ID0gYmx1clVuaWZvcm1zLmRpcmVjdGlvbiAqIGludlNpemU7XHJcbiAgICAgICAgZm9yKCB2YXIgaSA6IHUzMiA9IDE7IGkgPCAke2RlZmluZXMuS0VSTkVMX1JBRElVU307aSA9IGkgKyAxICkge1xyXG4gICAgICAgICAgICBsZXQgeDpmMzIgPSBmMzIoaSk7XHJcbiAgICAgICAgICAgIGxldCB3OmYzMiA9IGdhdXNzaWFuUGRmKHgsIGZTaWdtYSk7XHJcbiAgICAgICAgICAgIGxldCBzYW1wbGUxOnZlYzM8ZjMyPj10ZXh0dXJlU2FtcGxlKHREaWZmdXNlLCB0U2FtcGxlciwgaW5wdXQudXYrIHV2T2Zmc2V0KngpLnJnYjtcclxuICAgICAgICAgICAgbGV0IHNhbXBsZTI6dmVjMzxmMzI+PXRleHR1cmVTYW1wbGUodERpZmZ1c2UsIHRTYW1wbGVyLCBpbnB1dC51di0gdXZPZmZzZXQqeCkucmdiO1xyXG4gICAgICAgICAgICBkaWZmdXNlU3VtID1kaWZmdXNlU3VtKyAoc2FtcGxlMitzYW1wbGUyKSogdztcclxuICAgICAgICAgICAgd2VpZ2h0U3VtICs9IDIuMCAqIHc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGRpZmZ1c2VTdW0vPXdlaWdodFN1bTtcclxuICAgICAgcmV0dXJuIHZlYzQ8ZjMyPihkaWZmdXNlU3VtLGJhc2VDb2xvci5hKTtcclxuICAgIH1cclxuICBgO1xyXG59XHJcbiIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEx1bWlub3NpdHlIaWdoKGRlZmluZXMpIHtcclxuXHRyZXR1cm4gYFxyXG4gICAgc3RydWN0IEx1bWlub3NpdHlVbmlmb3Jtc3tcclxuICAgICAgICBsdW1pbm9zaXR5VGhyZXNob2xkOmYzMixcclxuICAgICAgICBzbW9vdGhXaWR0aDpmMzIsXHJcbiAgICAgICAgZGVmYXVsdENvbG9yOnZlYzM8ZjMyPixcclxuICAgICAgICBkZWZhdWx0T3BhY2l0eTpmMzIsXHJcbiAgICB9XHJcbiAgICBzdHJ1Y3QgRnJhZ0lucHV0IHtcclxuICAgICAgICBAbG9jYXRpb24oMCkgdXY6IHZlYzI8ZjMyPixcclxuICAgIH07XHJcbiAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoMCkgIHZhcjx1bmlmb3JtPiBsdW1pbm9zaXR5VW5pZm9ybXMgOiBMdW1pbm9zaXR5VW5pZm9ybXM7XHJcbiAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoe3t0RGlmZnVzZUJpbmRpbmd9fSkgdmFyIHREaWZmdXNlOiB0ZXh0dXJlXzJkPGYzMj47XHJcbiAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoe3t0U2FtcGxlckJpbmRpbmd9fSkgdmFyIHRTYW1wbGVyOiBzYW1wbGVyO1xyXG4gICAgQGZyYWdtZW50XHJcbiAgICBmbiBtYWluKGlucHV0OkZyYWdJbnB1dCktPiBAbG9jYXRpb24oMCkgdmVjNDxmMzI+IHtcclxuXHJcbiAgICAgICAgbGV0IHRleGVsOnZlYzQ8ZjMyPiA9IHRleHR1cmVTYW1wbGUodERpZmZ1c2UsIHRTYW1wbGVyLCBpbnB1dC51dik7XHJcblxyXG4gICAgICAgIGxldCBsdW1hOnZlYzM8ZjMyPiA9IHZlYzM8ZjMyPiggMC4yOTksMC41ODcsMC4xMTQgKTtcclxuXHJcbiAgICAgICAgbGV0IHY6ZjMyID0gZG90KCB0ZXhlbC54eXosIGx1bWEgKTtcclxuXHJcbiAgICAgICAgbGV0IG91dHB1dENvbG9yOnZlYzQ8ZjMyPiA9IHZlYzQ8ZjMyPiggbHVtaW5vc2l0eVVuaWZvcm1zLmRlZmF1bHRDb2xvci5yZ2IsIGx1bWlub3NpdHlVbmlmb3Jtcy5kZWZhdWx0T3BhY2l0eSApO1xyXG5cclxuICAgICAgICBsZXQgYWxwaGE6ZjMyID0gc21vb3Roc3RlcCggbHVtaW5vc2l0eVVuaWZvcm1zLmx1bWlub3NpdHlUaHJlc2hvbGQsIGx1bWlub3NpdHlVbmlmb3Jtcy5sdW1pbm9zaXR5VGhyZXNob2xkICsgbHVtaW5vc2l0eVVuaWZvcm1zLnNtb290aFdpZHRoLCB2ICk7XHJcblxyXG4gICAgICAgcmV0dXJuIG1peCggb3V0cHV0Q29sb3IsIHRleGVsLCBhbHBoYSApO1xyXG4gICAgfVxyXG4gICAgYDtcclxufVxyXG4iLCJpbXBvcnQgeyB3Z3NsUGFyc2VEZWZpbmVzIH0gZnJvbSBcIi4uLy4uL1dnc2xQcmVwcm9jZXNzb3JcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIEZyYWdJbnB1dChkZWZpbmVzKSB7XG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYFxuICAgIHN0cnVjdCBGcmFnSW5wdXQge1xuICAgICAgQGJ1aWx0aW4oZnJvbnRfZmFjaW5nKSBmcm9udEZhY2luZzogYm9vbCxcbiAgICAgIEBsb2NhdGlvbigwKSB3b3JsZFBvczp2ZWMzPGYzMj4sXG4gICAgICBAbG9jYXRpb24oMSkgbm9ybWFsOnZlYzM8ZjMyPixcbiAgICAgIEBsb2NhdGlvbigyKSB1djp2ZWMyPGYzMj4sXG4gICAgICBAbG9jYXRpb24oMykgdmlldzogdmVjMzxmMzI+LCAvLyBWZWN0b3IgZnJvbSB2ZXJ0ZXggdG8gY2FtZXJhLlxuICAgICAgQGxvY2F0aW9uKDQpIGNvbG9yOiB2ZWM0PGYzMj4sXG4gICAgICBAbG9jYXRpb24oNSkgdmlld1Bvc2l0aW9uOiB2ZWMzPGYzMj4sXG4gIH0gXG4gIGA7XG59XG4iLCJleHBvcnQgZnVuY3Rpb24gUG9pbnRGcmFnSW5wdXQoZGVmaW5lcykge1xuXHRyZXR1cm4gYFxuICAgICAgc3RydWN0IFBvaW50RnJhZ0lucHV0e1xuICAgICAgICBAbG9jYXRpb24oMCkgdXY6dmVjMjxmMzI+LFxuICAgICAgICBAbG9jYXRpb24oMSkgY29sb3I6IHZlYzQ8ZjMyPixcbiAgICAgICAgQGxvY2F0aW9uKDIpIHNpemU6IGYzMixcbiAgICAgIH1cbiAgICBgO1xufVxuIiwiaW1wb3J0IHsgd2dzbFBhcnNlRGVmaW5lcyB9IGZyb20gXCIuLi8uLi9XZ3NsUHJlcHJvY2Vzc29yXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBQb2ludFZlcnRJbnB1dChkZWZpbmVzKSB7XG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYFxuICBzdHJ1Y3QgUG9pbnRWZXJ0SW5wdXQge1xuICAgIEBsb2NhdGlvbigke2RlZmluZXMucG9zaXRpb25Mb2NhdGlvbn0pIHBvc2l0aW9uOiB2ZWMzPGYzMj4sICAgICAgIFxuICAgIEBsb2NhdGlvbigke2RlZmluZXMudXZMb2NhdGlvbn0pIHV2OiB2ZWMyPGYzMj4sXG4gICAgI2lmJHtkZWZpbmVzLkhBU19DT0xPUn0gXG4gICAgICAgIEBsb2NhdGlvbigke2RlZmluZXMuY29sb3JMb2NhdGlvbn0pIGNvbG9yOiB2ZWMzPGYzMj4sXG4gICAgI2VuZGlmXG4gICAgI2lmICR7ZGVmaW5lcy5IQVNfU0laRX1cbiAgICAgICAgQGxvY2F0aW9uKCR7ZGVmaW5lcy5zaXplTG9jYXRpb259KSBzaXplOiBmMzIsXG4gICAgI2VuZGlmXG4gICAgI2lmICR7ZGVmaW5lcy5VU0VfSU5TVEFOQ0V9XG4gICAgICAgIEBidWlsdGluKGluc3RhbmNlX2luZGV4KSBpbnN0YW5jZUlkeCA6IHUzMlxuICAgICNlbmRpZlxuICB9XG4gIGA7XG59XG4iLCJleHBvcnQgZnVuY3Rpb24gUG9pbnRWZXJ0T3V0cHV0KGRlZmluZXMpIHtcblx0cmV0dXJuIGBcbiAgICBzdHJ1Y3QgUG9pbnRWZXJ0T3V0cHV0e1xuICAgICAgICBAYnVpbHRpbihwb3NpdGlvbikgcG9zaXRpb246dmVjNDxmMzI+LFxuICAgICAgICBAbG9jYXRpb24oMCkgdXY6dmVjMjxmMzI+LFxuICAgICAgICBAbG9jYXRpb24oMSkgY29sb3I6IHZlYzQ8ZjMyPixcbiAgICAgICAgQGxvY2F0aW9uKDIpIHNpemU6IGYzMixcbiAgICB9XG4gICBgO1xufVxuIiwiaW1wb3J0IHsgd2dzbFBhcnNlRGVmaW5lcyB9IGZyb20gXCIuLi8uLi9XZ3NsUHJlcHJvY2Vzc29yXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBWZXJ0ZXhJbnB1dChkZWZpbmVzKSB7XG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYFxuICAgICAgICBzdHJ1Y3QgVmVydGV4SW5wdXQge1xuICAgICAgICAgICAgQGxvY2F0aW9uKCR7ZGVmaW5lcy5wb3NpdGlvbkxvY2F0aW9ufSkgcG9zaXRpb246IHZlYzM8ZjMyPiwgICBcbiAgICAgICAgICAgICNpZiR7ZGVmaW5lcy5IQVNfTk9STUFMfSAgXG4gICAgICAgICAgICAgICAgQGxvY2F0aW9uKCR7ZGVmaW5lcy5ub3JtYWxMb2NhdGlvbn0pIG5vcm1hbDogdmVjMzxmMzI+LFxuICAgICAgICAgICAgI2VuZGlmXG4gICAgICAgICAgICAjaWYke2RlZmluZXMuSEFTX0NPTE9SfSBcbiAgICAgICAgICAgICAgICBAbG9jYXRpb24oJHtkZWZpbmVzLmNvbG9yTG9jYXRpb259KSBjb2xvcjogdmVjMzxmMzI+LFxuICAgICAgICAgICAgI2VuZGlmXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLkhBU19VVn1cbiAgICAgICAgICAgICAgICBAbG9jYXRpb24oJHtkZWZpbmVzLnV2TG9jYXRpb259KSB1djogdmVjMjxmMzI+LFxuICAgICAgICAgICAgI2VuZGlmXG4gICAgICAgICAgICAjaWYke2RlZmluZXMuSEFTX1NLSU59IFxuICAgICAgICAgICAgICAgIEBsb2NhdGlvbigke2RlZmluZXMuam9pbnQwTG9jYXRpb259KSBqb2ludDA6dmVjNDxmMzI+LFxuICAgICAgICAgICAgICAgIEBsb2NhdGlvbigke2RlZmluZXMud2VpZ2h0MExvY2F0aW9ufSkgd2VpZ2h0MDp2ZWM0PGYzMj4sXG4gICAgICAgICAgICAjZW5kaWZcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX0lOU1RBTkNFfVxuICAgICAgICAgICAgICAgIEBidWlsdGluKGluc3RhbmNlX2luZGV4KSBpbnN0YW5jZUlkeCA6IHUzMlxuICAgICAgICAgICAgI2VuZGlmXG4gICAgICAgIH1cbiAgIGA7XG59XG4iLCJpbXBvcnQgeyB3Z3NsUGFyc2VEZWZpbmVzIH0gZnJvbSBcIi4uLy4uL1dnc2xQcmVwcm9jZXNzb3JcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIFZlcnRleE91dHB1dChkZWZpbmVzKSB7XG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYFxuICAgIHN0cnVjdCBWZXJ0ZXhPdXRwdXQge1xuICAgICAgICBAYnVpbHRpbihwb3NpdGlvbikgcG9zaXRpb246dmVjNDxmMzI+LFxuICAgICAgICBAbG9jYXRpb24oMCkgd29ybGRQb3M6dmVjMzxmMzI+LFxuICAgICAgICBAbG9jYXRpb24oMSkgbm9ybWFsOnZlYzM8ZjMyPixcbiAgICAgICAgQGxvY2F0aW9uKDIpIHV2OnZlYzI8ZjMyPixcbiAgICAgICAgQGxvY2F0aW9uKDMpIHZpZXc6IHZlYzM8ZjMyPiwgLy8gVmVjdG9yIGZyb20gdmVydGV4IHRvIGNhbWVyYS5cbiAgICAgICAgQGxvY2F0aW9uKDQpIGNvbG9yOiB2ZWM0PGYzMj4sXG4gICAgICAgIEBsb2NhdGlvbig1KSB2aWV3UG9zaXRpb246IHZlYzM8ZjMyPixcbiAgICB9IFxuICAgIGA7XG59XG4iLCJpbXBvcnQgeyB3Z3NsUGFyc2VEZWZpbmVzIH0gZnJvbSBcIi4uLy4uL1dnc2xQcmVwcm9jZXNzb3JcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIFN5c3RlbVVuaWZvcm0oZGVmaW5lcykge1xuXHRyZXR1cm4gd2dzbFBhcnNlRGVmaW5lc2BcbiAgICAgIHN0cnVjdCBTeXN0ZW1Vbmlmb3JtIHtcbiAgICAgICAgICBwcm9qZWN0aW9uTWF0cml4OiBtYXQ0eDQ8ZjMyPixcbiAgICAgICAgICB2aWV3TWF0cml4OiBtYXQ0eDQ8ZjMyPixcbiAgICAgICAgICBpbnZlcnNlVmlld01hdHJpeDogbWF0NHg0PGYzMj4sXG4gICAgICAgICAgY2FtZXJhUG9zaXRpb246IHZlYzM8ZjMyPixcbiAgICAgIH07IFxuICBgO1xufVxuIiwiaW1wb3J0IHsgd2dzbFBhcnNlRGVmaW5lcyB9IGZyb20gXCIuLi8uLi9XZ3NsUHJlcHJvY2Vzc29yXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBUZXh0dXJlQW5kU2FtcGxlckRlZmluZShkZWZpbmVzKSB7XG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYFxuICAgICNpZiAke2RlZmluZXMuVVNFX0lCTH1cbiAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMuc3BlY3VsYXJFbnZUZXh0dXJlQmluZGluZ30pIHZhciBzcGVjdWxhckVudlRleHR1cmU6IHRleHR1cmVfY3ViZTxmMzI+O1xuICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKCR7ZGVmaW5lcy5zcGVjdWxhckVudlNhbXBsZXJCaW5kaW5nfSkgdmFyIHNwZWN1bGFyRW52U2FtcGxlcjogc2FtcGxlcjtcbiAgICAjZW5kaWZcbiAgICAjaWYgJHtkZWZpbmVzLlVTRV9URVhUVVJFfVxuICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKCR7ZGVmaW5lcy5iYXNlQ29sb3JUZXh0dXJlQmluZGluZ30pIHZhciBiYXNlQ29sb3JUZXh0dXJlOiB0ZXh0dXJlXzJkPGYzMj47XG4gICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLmJhc2VDb2xvclNhbXBsZXJCaW5kaW5nfSkgdmFyIGJhc2VDb2xvclNhbXBsZXI6IHNhbXBsZXI7XG4gICAgI2VuZGlmXG4gICAgLy8gbm9ybWFsIG1hcFxuICAgICNpZiAke2RlZmluZXMuVVNFX05PUk1BTFRFWFRVUkV9XG4gICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLm5vcm1hbFRleHR1cmVCaW5kaW5nfSkgdmFyIG5vcm1hbFRleHR1cmU6IHRleHR1cmVfMmQ8ZjMyPjtcbiAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMubm9ybWFsU2FtcGxlckJpbmRpbmd9KSB2YXIgbm9ybWFsU2FtcGxlcjogc2FtcGxlcjtcbiAgICAjZW5kaWZcbiAgICAvLyBlbW1pc3ZlIG1hcFxuICAgICNpZiAke2RlZmluZXMuVVNFX0VNSVNTSVZFVEVYVFVSRX1cbiAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMuZW1pc3NpdmVUZXh0dXJlQmluZGluZ30pIHZhciBlbWlzc2l2ZVRleHR1cmU6IHRleHR1cmVfMmQ8ZjMyPjtcbiAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMuZW1pc3NpdmVTYW1wbGVyQmluZGluZ30pIHZhciBlbWlzc2l2ZVNhbXBsZXI6IHNhbXBsZXI7XG4gICAgI2VuZGlmXG5cbiAgICAvLyBtZXRhbCByb3VnaG5lc3NcbiAgICAjaWYgJHtkZWZpbmVzLlVTRV9NRVRBTE5FU1NURVhUVVJFfVxuICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKCR7ZGVmaW5lcy5tZXRhbG5lc3NSb3VnaG5lc3NUZXh0dXJlQmluZGluZ30pIHZhciBtZXRhbG5lc3NSb3VnaG5lc3NUZXh0dXJlOiB0ZXh0dXJlXzJkPGYzMj47XG4gICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLm1ldGFsbmVzc1JvdWdobmVzc1NhbXBsZXJCaW5kaW5nfSkgdmFyIG1ldGFsbmVzc1JvdWdobmVzc1NhbXBsZXI6IHNhbXBsZXI7XG4gICAgI2VuZGlmXG4gICAgLy8gb2NjbHVzaW9uIHRleHR1cmVcbiAgICAjaWYgJHtkZWZpbmVzLlVTRV9BT1RFWFRVUkV9XG4gICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLmFvVGV4dHVyZUJpbmRpbmd9KSB2YXIgYW9UZXh0dXJlOiB0ZXh0dXJlXzJkPGYzMj47XG4gICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLmFvU2FtcGxlckJpbmRpbmd9KSB2YXIgYW9TYW1wbGVyOiBzYW1wbGVyO1xuICAgICNlbmRpZlxuICAgICNpZiAke2RlZmluZXMuVVNFX05PUk1BTFRFWFRVUkV9XG4gICAgICAjaW5jbHVkZSA8Z2V0VEJOPlxuICAgICAgI2luY2x1ZGUgPGdldE5vcm1hbEJ5Tm9ybWFsVGV4dHVyZT5cbiAgICAjZWxzZVxuICAgICAgI2luY2x1ZGUgPGdldE5vcm1hbD5cbiAgICAjZW5kaWZcbiAgYDtcbn1cbiIsImltcG9ydCB7IHdnc2xQYXJzZURlZmluZXMgfSBmcm9tIFwiLi4vLi4vV2dzbFByZXByb2Nlc3NvclwiO1xyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBlbnZpcm9ubWVudChkZWZpbmVzKSB7XHJcbiAgcmV0dXJuIHdnc2xQYXJzZURlZmluZXNgXHJcbiAgICNpZiAke2RlZmluZXMuRU5WVEVYVFVSRV9UWVBFX0NVQkVfVVZ9XHJcbiAgICAgICAgY29uc3QgY3ViZVVWX21pbk1pcExldmVsOmYzMj0gNC4wO1xyXG4gICAgICAgIGNvbnN0IGN1YmVVVl9taW5UaWxlU2l6ZTpmMzI9IDE2LjA7XHJcbiAgICAgICAgY29uc3QgQ1VCRVVWX01BWF9NSVA6ZjMyPTYuMDtcclxuICAgICAgICBjb25zdCBDVUJFVVZfVEVYRUxfV0lEVEg6ZjMyPTEuMC8yNTYuMDtcclxuICAgICAgICBjb25zdCBDVUJFVVZfVEVYRUxfSEVJR0hUOmYzMj0xLjAvMjU2LjA7XHJcbiAgICAgICAgZm4gZ2V0RmFjZShkaXJlY3Rpb246dmVjMzxmMzI+ICktPmYzMiB7XHJcbiAgICAgICAgICAgIGxldCBhYnNEaXJlY3Rpb246dmVjMzxmMzI+ID0gYWJzKCBkaXJlY3Rpb24gKTtcclxuICAgICAgICAgICAgdmFyIGZhY2U6ZjMyID0gLSAxLjA7XHJcbiAgICAgICAgICAgIGlmICggYWJzRGlyZWN0aW9uLnggPiBhYnNEaXJlY3Rpb24ueiApIHtcclxuICAgICAgICAgICAgICAgIGlmICggYWJzRGlyZWN0aW9uLnggPiBhYnNEaXJlY3Rpb24ueSApe1xyXG4gICAgICAgICAgICAgICAgICAgIGZhY2UgPXNlbGVjdCgzLjAsMC4wLGRpcmVjdGlvbi54ID4gMC4wKTtcclxuICAgICAgICAgICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICAgICAgICAgIGZhY2UgPXNlbGVjdCg0LjAsMS4wLGRpcmVjdGlvbi55ID4gMC4wKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKCBhYnNEaXJlY3Rpb24ueiA+IGFic0RpcmVjdGlvbi55ICl7XHJcbiAgICAgICAgICAgICAgICAgICAgZmFjZSA9c2VsZWN0KDUuMCwyLjAsZGlyZWN0aW9uLnogPiAwLjApO1xyXG4gICAgICAgICAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgICAgICAgICAgZmFjZSA9c2VsZWN0KDQuMCwxLjAsZGlyZWN0aW9uLnkgPiAwLjApO1xyXG4gICAgICAgICAgICAgICAgfSAgICAgICBcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gZmFjZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm4gZ2V0VVYoIGRpcmVjdGlvbjp2ZWMzPGYzMj4sIGZhY2U6ZjMyICktPnZlYzI8ZjMyPiB7XHJcbiAgICAgICAgICAgIHZhciB1djp2ZWMyPGYzMj47XHJcbiAgICAgICAgICAgIGlmICggZmFjZSA9PSAwLjAgKSB7XHJcbiAgICAgICAgICAgICAgICB1diA9IHZlYzI8ZjMyPiggZGlyZWN0aW9uLnosIGRpcmVjdGlvbi55ICkgLyBhYnMoIGRpcmVjdGlvbi54ICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoIGZhY2UgPT0gMS4wICkge1xyXG4gICAgICAgICAgICAgICAgdXYgPSB2ZWMyPGYzMj4oIC0gZGlyZWN0aW9uLngsIC0gZGlyZWN0aW9uLnogKSAvIGFicyggZGlyZWN0aW9uLnkgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICggZmFjZSA9PSAyLjAgKSB7XHJcbiAgICAgICAgICAgICAgICB1diA9IHZlYzI8ZjMyPiggLSBkaXJlY3Rpb24ueCwgZGlyZWN0aW9uLnkgKSAvIGFicyggZGlyZWN0aW9uLnogKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICggZmFjZSA9PSAzLjAgKSB7XHJcbiAgICAgICAgICAgICAgICB1diA9IHZlYzI8ZjMyPiggLSBkaXJlY3Rpb24ueiwgZGlyZWN0aW9uLnkgKSAvIGFicyggZGlyZWN0aW9uLnggKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICggZmFjZSA9PSA0LjAgKSB7XHJcbiAgICAgICAgICAgICAgICB1diA9IHZlYzI8ZjMyPiggLSBkaXJlY3Rpb24ueCwgZGlyZWN0aW9uLnogKSAvIGFicyggZGlyZWN0aW9uLnkgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHV2ID0gdmVjMjxmMzI+KCBkaXJlY3Rpb24ueCwgZGlyZWN0aW9uLnkgKSAvIGFicyggZGlyZWN0aW9uLnogKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gMC41ICogKCB1diArIDEuMCApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmbiBiaWxpbmVhckN1YmVVVihlbnZUZXh0dXJlOnRleHR1cmVfY3ViZTxmMzI+LGJhc2VTYW1wbGVyOnNhbXBsZXIsZGlyZWN0aW9uOnZlYzM8ZjMyPiwgbWlwSW50OmYzMiApLT52ZWMzPGYzMj4ge1xyXG4gICAgICAgICAgICB2YXIgZmFjZTpmMzIgPSBnZXRGYWNlKCBkaXJlY3Rpb24gKTtcclxuICAgICAgICAgICAgbGV0IGZpbHRlckludDpmMzIgPSBtYXgoIGN1YmVVVl9taW5NaXBMZXZlbCAtIG1pcEludCwgMC4wICk7XHJcbiAgICAgICAgICAgIGxldCB0ZW1wTWlwSW50ID0gbWF4KCBtaXBJbnQsIGN1YmVVVl9taW5NaXBMZXZlbCApO1xyXG4gICAgICAgICAgICBsZXQgZmFjZVNpemU6ZjMyID0gZXhwMiggdGVtcE1pcEludCApO1xyXG4gICAgICAgICAgICB2YXIgdXY6dmVjMjxmMzI+ID0gZ2V0VVYoIGRpcmVjdGlvbiwgZmFjZSApICogKCBmYWNlU2l6ZSAtIDIuMCApICsgMS4wO1xyXG4gICAgICAgICAgICBpZiAoIGZhY2UgPiAyLjAgKSB7XHJcbiAgICAgICAgICAgICAgICB1di55ICs9IGZhY2VTaXplO1xyXG4gICAgICAgICAgICAgICAgZmFjZSAtPSAzLjA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdXYueCArPSBmYWNlICogZmFjZVNpemU7XHJcbiAgICAgICAgICAgIHV2LnggKz0gZmlsdGVySW50ICogMy4wICogY3ViZVVWX21pblRpbGVTaXplO1xyXG4gICAgICAgICAgICB1di55ICs9IDQuMCAqICggZXhwMiggQ1VCRVVWX01BWF9NSVAgKSAtIGZhY2VTaXplICk7XHJcbiAgICAgICAgICAgIHV2LnggKj0gQ1VCRVVWX1RFWEVMX1dJRFRIO1xyXG4gICAgICAgICAgICB1di55ICo9IENVQkVVVl9URVhFTF9IRUlHSFQ7XHJcbiAgICAgICAgICAgIHJldHVybiB0ZXh0dXJlU2FtcGxlKGVudlRleHR1cmUsYmFzZVNhbXBsZXIsZGlyZWN0aW9uKS5yZ2I7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGN1YmVVVl9yMDpmMzI9IDEuMDtcclxuICAgICAgICBjb25zdCBjdWJlVVZfdjA6ZjMyPSAwLjMzOTtcclxuICAgICAgICBjb25zdCBjdWJlVVZfbTA6ZjMyPSAtIDIuMDtcclxuICAgICAgICBjb25zdCBjdWJlVVZfcjE6ZjMyPSAwLjg7XHJcbiAgICAgICAgY29uc3QgY3ViZVVWX3YxOmYzMj0gMC4yNzY7XHJcbiAgICAgICAgY29uc3QgY3ViZVVWX20xOmYzMj0gLSAxLjA7XHJcbiAgICAgICAgY29uc3QgY3ViZVVWX3I0OmYzMj0gMC40O1xyXG4gICAgICAgIGNvbnN0IGN1YmVVVl92NDpmMzI9IDAuMDQ2O1xyXG4gICAgICAgIGNvbnN0IGN1YmVVVl9tNDpmMzI9IDIuMDtcclxuICAgICAgICBjb25zdCBjdWJlVVZfcjU6ZjMyPSAwLjMwNTtcclxuICAgICAgICBjb25zdCBjdWJlVVZfdjU6ZjMyPSAwLjAxNjtcclxuICAgICAgICBjb25zdCBjdWJlVVZfbTU6ZjMyPSAzLjA7XHJcbiAgICAgICAgY29uc3QgY3ViZVVWX3I2OmYzMj0gMC4yMTtcclxuICAgICAgICBjb25zdCBjdWJlVVZfdjY6ZjMyPSAwLjAwMzg7XHJcbiAgICAgICAgY29uc3QgY3ViZVVWX202OmYzMj0gNC4wO1xyXG4gICAgICAgIGZuIHJvdWdobmVzc1RvTWlwKCByb3VnaG5lc3M6ZjMyKS0+ZjMyIHtcclxuICAgICAgICAgICAgdmFyIG1pcDpmMzIgPSAwLjA7XHJcbiAgICAgICAgICAgIGlmICggcm91Z2huZXNzID49IGN1YmVVVl9yMSApIHtcclxuICAgICAgICAgICAgICAgIG1pcCA9ICggY3ViZVVWX3IwIC0gcm91Z2huZXNzICkgKiAoIGN1YmVVVl9tMSAtIGN1YmVVVl9tMCApIC8gKCBjdWJlVVZfcjAgLSBjdWJlVVZfcjEgKSArIGN1YmVVVl9tMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICggcm91Z2huZXNzID49IGN1YmVVVl9yNCApIHtcclxuICAgICAgICAgICAgICAgIG1pcCA9ICggY3ViZVVWX3IxIC0gcm91Z2huZXNzICkgKiAoIGN1YmVVVl9tNCAtIGN1YmVVVl9tMSApIC8gKCBjdWJlVVZfcjEgLSBjdWJlVVZfcjQgKSArIGN1YmVVVl9tMTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICggcm91Z2huZXNzID49IGN1YmVVVl9yNSApIHtcclxuICAgICAgICAgICAgICAgIG1pcCA9ICggY3ViZVVWX3I0IC0gcm91Z2huZXNzICkgKiAoIGN1YmVVVl9tNSAtIGN1YmVVVl9tNCApIC8gKCBjdWJlVVZfcjQgLSBjdWJlVVZfcjUgKSArIGN1YmVVVl9tNDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICggcm91Z2huZXNzID49IGN1YmVVVl9yNiApIHtcclxuICAgICAgICAgICAgICAgIG1pcCA9ICggY3ViZVVWX3I1IC0gcm91Z2huZXNzICkgKiAoIGN1YmVVVl9tNiAtIGN1YmVVVl9tNSApIC8gKCBjdWJlVVZfcjUgLSBjdWJlVVZfcjYgKSArIGN1YmVVVl9tNTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIG1pcCA9IC0gMi4wICogbG9nMiggMS4xNiAqIHJvdWdobmVzcyApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBtaXA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZuIHRleHR1cmVDdWJlVVYoZW52VGV4dHVyZTp0ZXh0dXJlX2N1YmU8ZjMyPiwgYmFzZVNhbXBsZXI6c2FtcGxlcixzYW1wbGVEaXI6dmVjMzxmMzI+LHJvdWdobmVzczpmMzIgKS0+dmVjNDxmMzI+IHtcclxuICAgICAgICAgICAgbGV0IG1pcCA9IGNsYW1wKCByb3VnaG5lc3NUb01pcCggcm91Z2huZXNzICksIGN1YmVVVl9tMCwgQ1VCRVVWX01BWF9NSVAgKTtcclxuICAgICAgICAgICAgbGV0IG1pcEYgPSBmcmFjdCggbWlwICk7XHJcbiAgICAgICAgICAgIGxldCBtaXBJbnQgPSBmbG9vciggbWlwICk7XHJcbiAgICAgICAgICAgIGxldCBjb2xvcjA6dmVjMzxmMzI+ID0gYmlsaW5lYXJDdWJlVVYoIGVudlRleHR1cmUsYmFzZVNhbXBsZXIsc2FtcGxlRGlyLCBtaXBJbnQgKTtcclxuICAgICAgICAgICAgaWYgKCBtaXBGID09IDAuMCApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB2ZWM0PGYzMj4oY29sb3IwLCAxLjAgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGxldCBjb2xvcjE6dmVjMzxmMzI+ID0gYmlsaW5lYXJDdWJlVVYoIGVudlRleHR1cmUsYmFzZVNhbXBsZXIsIHNhbXBsZURpciwgbWlwSW50ICsgMS4wICk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdmVjNDxmMzI+KG1peCggY29sb3IwLCBjb2xvcjEsIG1pcEYgKSwgMS4wICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICB9XHJcbiAgICNlbmRpZlxyXG4gICAjaWYgJHtkZWZpbmVzLlVTRV9FTlZURVhUVVJFfVxyXG4gICAgICAgIGZuIGdldElCTElycmFkaWFuY2UoIG5vcm1hbDp2ZWMzPGYzMj4sYmFzZVNhbXBsZXI6c2FtcGxlcix2aWV3TWF0cml4Om1hdDR4NDxmMzI+KS0+dmVjMzxmMzI+IHtcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5FTlZURVhUVVJFX1RZUEVfQ1VCRV9VVn1cclxuICAgICAgICAgICAgICAgIGxldCB3b3JsZE5vcm1hbDp2ZWMzPGYzMj4gPSBpbnZlcnNlVHJhbnNmb3JtRGlyZWN0aW9uKCBub3JtYWwsIHZpZXdNYXRyaXggKTtcclxuICAgICAgICAgICAgICAgIGxldCBlbnZUZXh0dXJlQ29sb3I6dmVjNDxmMzI+ID0gdGV4dHVyZUN1YmVVViggZW52VGV4dHVyZSxiYXNlU2FtcGxlciwgd29ybGROb3JtYWwsIDEuMCApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFBJICogZW52VGV4dHVyZUNvbG9yLnJnYiAqIG1hdGVyaWFsVW5pZm9ybS5lbnZUZXh0dXJlSW50ZW5zaXR5O1xyXG4gICAgICAgICAgICAjZWxzZVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZlYzM8ZjMyPiggMC4wICk7XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgIH1cclxuICAgICAgICBmbiBnZXRJQkxSYWRpYW5jZSggdmlld0Rpcjp2ZWMzPGYzMj4sYmFzZVNhbXBsZXI6c2FtcGxlcix2aWV3TWF0cml4Om1hdDR4NDxmMzI+LG5vcm1hbDp2ZWMzPGYzMj4sIHJvdWdobmVzczpmMzIgKS0+dmVjMzxmMzI+IHtcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5FTlZURVhUVVJFX1RZUEVfQ1VCRV9VVn1cclxuICAgICAgICAgICAgICAgIHZhciByZWZsZWN0VmVjOnZlYzM8ZjMyPiA9IHJlZmxlY3QoIC0gdmlld0Rpciwgbm9ybWFsICk7XHJcbiAgICAgICAgICAgICAgICByZWZsZWN0VmVjID0gbm9ybWFsaXplKCBtaXgoIHJlZmxlY3RWZWMsIG5vcm1hbCwgcm91Z2huZXNzICogcm91Z2huZXNzKSApO1xyXG4gICAgICAgICAgICAgICAgcmVmbGVjdFZlYyA9IGludmVyc2VUcmFuc2Zvcm1EaXJlY3Rpb24oIHJlZmxlY3RWZWMsIHZpZXdNYXRyaXggKTtcclxuICAgICAgICAgICAgICAgIGxldCBlbnZUZXh0dXJlQ29sb3I6dmVjNDxmMzI+ID0gdGV4dHVyZUN1YmVVViggZW52VGV4dHVyZSxiYXNlU2FtcGxlciwgcmVmbGVjdFZlYywgcm91Z2huZXNzICk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZW52VGV4dHVyZUNvbG9yLnJnYiAqIG1hdGVyaWFsVW5pZm9ybS5lbnZUZXh0dXJlSW50ZW5zaXR5O1xyXG4gICAgICAgICAgICAjZWxzZVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZlYzM8ZjMyPiggMC4wICk7XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICB9XHJcbiAgICAjZW5kaWZcclxuICAgYDtcclxufVxyXG4iLCJpbXBvcnQgeyB3Z3NsUGFyc2VEZWZpbmVzIH0gZnJvbSBcIi4uLy4uL1dnc2xQcmVwcm9jZXNzb3JcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGluc3RhbmNlVmVydEhlYWRlcihkZWZpbmVzKSB7XG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYFxuICAgI2lmICR7ZGVmaW5lcy5VU0VfSU5TVEFOQ0V9XG4gICAgICBzdHJ1Y3QgSW5zdGFuY2VzVW5pZm9ybSB7XG4gICAgICAgICBpbnN0YW5jZU1hdHJpeHM6ICBhcnJheTxtYXQ0eDQ8ZjMyPiwgJHtkZWZpbmVzLmluc3RhbmNlQ291bnR9PixcbiAgICAgIH07XG4gICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLmluc3RhbmNlTWF0cml4c0J1ZmZlckJpbmRpbmd9KSB2YXI8c3RvcmFnZSwgcmVhZD4gaW5zdGFuY2VzVW5pZm9ybTogSW5zdGFuY2VzVW5pZm9ybTtcbiAgICAjZW5kaWZcbiAgIGA7XG59XG5leHBvcnQgZnVuY3Rpb24gaW5zdGFuY2VWZXJ0TWFpbihkZWZpbmVzKSB7XG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYFxuICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfSU5TVEFOQ0V9XG4gICAgICAgICBtb2RlbE1hdHJpeD1pbnN0YW5jZXNVbmlmb3JtLmluc3RhbmNlTWF0cml4c1tpbnB1dC5pbnN0YW5jZUlkeF07XG4gICAgICAjZW5kaWZcbiAgIGA7XG59XG4iLCJpbXBvcnQgeyB3Z3NsUGFyc2VEZWZpbmVzIH0gZnJvbSBcIi4uLy4uL1dnc2xQcmVwcm9jZXNzb3JcIjtcclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbGlnaHQoZGVmaW5lcykge1xyXG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYCBcclxuICAgIHN0cnVjdCBSZWZsZWN0ZWRMaWdodCB7XHJcbiAgICAgICAgYW1iaWVudDogdmVjMzxmMzI+LFxyXG4gICAgICAgIGRpcmVjdERpZmZ1c2U6dmVjMzxmMzI+LFxyXG4gICAgICAgIGRpcmVjdFNwZWN1bGFyOnZlYzM8ZjMyPixcclxuICAgICAgICBpbmRpcmVjdERpZmZ1c2U6dmVjMzxmMzI+LFxyXG4gICAgICAgIGluZGlyZWN0U3BlY3VsYXI6dmVjMzxmMzI+LFxyXG4gICAgICAgIHRlc3RDb2xvcjogdmVjMzxmMzI+LFxyXG4gICAgfTsgXHJcbiAgICBzdHJ1Y3QgSW5jaWRlbnRMaWdodCB7XHJcbiAgICAgICAgY29sb3I6IHZlYzM8ZjMyPixcclxuICAgICAgICBkaXJlY3Rpb246IHZlYzM8ZjMyPixcclxuICAgICAgICB2aXNpYmxlOiBib29sLFxyXG4gICAgfTtcclxuICAgIHN0cnVjdCBHZW9tZXRyeSB7XHJcbiAgICAgICAgcG9zaXRpb246IHZlYzM8ZjMyPixcclxuICAgICAgICBub3JtYWw6IHZlYzM8ZjMyPixcclxuICAgICAgICB2aWV3RGlyOiB2ZWMzPGYzMj4sXHJcbiAgICAgICAgZG90TlY6ZjMyLFxyXG4gICAgICAgICNpZiAke2RlZmluZXMuVVNFX0NMRUFSQ09BVH1cclxuICAgICAgICAgICAgdmVjMyBjbGVhcmNvYXROb3JtYWw7XHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICB9O1xyXG5cclxuICAgICNpZiAke2RlZmluZXMuc3BvdExpZ2h0c0NvdW50ID4gMH1cclxuICAgICAgICBzdHJ1Y3QgU3BvdExpZ2h0IHtcclxuICAgICAgICAgICAgcG9zaXRpb246IHZlYzM8ZjMyPixcclxuICAgICAgICAgICAgZGlzdGFuY2U6IGYzMixcclxuICAgICAgICAgICAgZGlyZWN0aW9uOiB2ZWMzPGYzMj4sXHJcbiAgICAgICAgICAgIGNvbmVDb3M6IGYzMixcclxuICAgICAgICAgICAgY29sb3I6IHZlYzM8ZjMyPixcclxuICAgICAgICAgICAgcGVudW1icmFDb3M6IGYzMixcclxuICAgICAgICAgICAgZGVjYXk6IGYzMixcclxuICAgICAgICB9O1xyXG4gICAgICAgIGZuIGdldFNwb3RMaWdodEluZm8oc3BvdExpZ2h0OlNwb3RMaWdodCx3b3JsZFBvczp2ZWMzPGYzMj4sc2hpbmluZXNzOmYzMixOOnZlYzM8ZjMyPixWOnZlYzM8ZjMyPiktPlJlZmxlY3RlZExpZ2h0e1xyXG4gICAgICAgICAgICAgICAgdmFyIGRpcmVjdGlvbjp2ZWMzPGYzMj4gPSBzcG90TGlnaHQucG9zaXRpb24gLSB3b3JsZFBvcztcclxuICAgICAgICAgICAgICAgIHZhciBsaWdodENvbG9yOlJlZmxlY3RlZExpZ2h0O1xyXG4gICAgICAgICAgICAgICAgbGV0IGxpZ2h0RGlzdGFuY2U6ZjMyID0gbGVuZ3RoKGRpcmVjdGlvbik7XHJcbiAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSBub3JtYWxpemUoZGlyZWN0aW9uKTtcclxuICAgICAgICAgICAgICAgIGxldCBhbmdsZUNvczpmMzIgPSBkb3QoIGRpcmVjdGlvbiwgc3BvdExpZ2h0LmRpcmVjdGlvbiApO1xyXG4gICAgICAgICAgICAgICAgbGV0IGRlY2F5OmYzMiA9IGNsYW1wKDEuMCAtIHBvdyhsaWdodERpc3RhbmNlL3Nwb3RMaWdodC5kaXN0YW5jZSwgc3BvdExpZ2h0LmRlY2F5KSwgMC4wLCAxLjApO1xyXG4gICAgICAgICAgICAgICAgbGV0IHNwb3RFZmZlY3Q6ZjMyID0gc21vb3Roc3RlcCggc3BvdExpZ2h0LnBlbnVtYnJhQ29zLCBzcG90TGlnaHQuY29uZUNvcywgYW5nbGVDb3MgKTtcclxuICAgICAgICAgICAgICAgIGxldCBkZWNheVRvdGFsOmYzMiA9IGRlY2F5ICogc3BvdEVmZmVjdDtcclxuICAgICAgICAgICAgICAgIGxldCBkOmYzMiA9IG1heCggZG90KCBOLCBkaXJlY3Rpb24gKSwgMC4wICkgICogZGVjYXlUb3RhbDtcclxuICAgICAgICAgICAgICAgIGxpZ2h0Q29sb3IuZGlyZWN0RGlmZnVzZT0gc3BvdExpZ2h0LmNvbG9yICogZDtcclxuICAgICAgICAgICAgICAgIGxldCBoYWxmRGlyOnZlYzM8ZjMyPiA9IG5vcm1hbGl6ZSggViArIGRpcmVjdGlvbiApO1xyXG4gICAgICAgICAgICAgICAgbGV0IHM6ZjMyID0gcG93KCBjbGFtcCggZG90KCBOLCBoYWxmRGlyICksIDAuMCwgMS4wICksIHNoaW5pbmVzcyApICogZGVjYXlUb3RhbDtcclxuICAgICAgICAgICAgICAgIGxpZ2h0Q29sb3IuZGlyZWN0U3BlY3VsYXI9IHNwb3RMaWdodC5jb2xvciAqIHM7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbGlnaHRDb2xvcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm4gZ2V0U3BvdExpZ2h0SW5jaWRlbnRMaWdodChzcG90TGlnaHQ6U3BvdExpZ2h0LCBnZW9tZXRyeTpHZW9tZXRyeSktPkluY2lkZW50TGlnaHQge1xyXG4gICAgICAgICAgICB2YXIgaW5jaWRlbnRMaWdodDpJbmNpZGVudExpZ2h0O1xyXG4gICAgICAgICAgICBsZXQgbFZlY3Rvcjp2ZWMzPGYzMj4gPSBzcG90TGlnaHQucG9zaXRpb24gLSBnZW9tZXRyeS5wb3NpdGlvbjtcclxuICAgICAgICAgICAgaW5jaWRlbnRMaWdodC5kaXJlY3Rpb24gPSBub3JtYWxpemUoIGxWZWN0b3IgKTtcclxuICAgIFxyXG4gICAgICAgICAgICBsZXQgbGlnaHREaXN0YW5jZTpmMzIgPSBsZW5ndGgoIGxWZWN0b3IgKTtcclxuICAgICAgICAgICAgbGV0IGFuZ2xlQ29zOmYzMiA9IGRvdCggaW5jaWRlbnRMaWdodC5kaXJlY3Rpb24sIHNwb3RMaWdodC5kaXJlY3Rpb24gKTtcclxuICAgIFxyXG4gICAgICAgICAgICBsZXQgc3BvdEVmZmVjdDpmMzIgPSBzbW9vdGhzdGVwKCBzcG90TGlnaHQucGVudW1icmFDb3MsIHNwb3RMaWdodC5jb25lQ29zLCBhbmdsZUNvcyApO1xyXG4gICAgICAgICAgICBsZXQgZGVjYXlFZmZlY3Q6ZjMyID0gY2xhbXAoMS4wIC0gcG93KGxpZ2h0RGlzdGFuY2Uvc3BvdExpZ2h0LmRpc3RhbmNlLCA0LjApLCAwLjAsIDEuMCk7XHJcbiAgICBcclxuICAgICAgICAgICAgaW5jaWRlbnRMaWdodC5jb2xvcj1zcG90TGlnaHQuY29sb3Iqc3BvdEVmZmVjdCAqIGRlY2F5RWZmZWN0OyBcclxuICAgICAgICAgICAgcmV0dXJuICBpbmNpZGVudExpZ2h0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAjZW5kaWYgXHJcblxyXG4gICAgI2lmICR7ZGVmaW5lcy5wb2ludExpZ2h0c0NvdW50ID4gMH1cclxuICAgICAgICBzdHJ1Y3QgUG9pbnRMaWdodCB7XHJcbiAgICAgICAgICAgIHBvc2l0aW9uOiB2ZWMzPGYzMj4sXHJcbiAgICAgICAgICAgIGRpc3RhbmNlOiBmMzIsXHJcbiAgICAgICAgICAgIGNvbG9yOiB2ZWMzPGYzMj4sXHJcbiAgICAgICAgICAgIGRlY2F5OiBmMzIsXHJcbiAgICAgICAgfTtcclxuICAgICAgICBmbiBnZXRQb2ludExpZ2h0SW5mbyhwb2ludExpZ2h0OlBvaW50TGlnaHQsd29ybGRQb3M6dmVjMzxmMzI+LHNoaW5pbmVzczpmMzIsTjp2ZWMzPGYzMj4sVjp2ZWMzPGYzMj4pLT5SZWZsZWN0ZWRMaWdodHtcclxuICAgICAgICAgICAgdmFyIGxpZ2h0Q29sb3I6UmVmbGVjdGVkTGlnaHQ7XHJcbiAgICAgICAgICAgIHZhciBkaXJlY3Rpb246dmVjMzxmMzI+ID0gd29ybGRQb3MgLSBwb2ludExpZ2h0LnBvc2l0aW9uO1xyXG4gICAgICAgICAgICBsZXQgZGlzdDpmMzIgPSBsZW5ndGgoIGRpcmVjdGlvbiApO1xyXG4gICAgICAgICAgICBkaXJlY3Rpb24gPSBub3JtYWxpemUoZGlyZWN0aW9uKTtcclxuICAgICAgICAgICAgbGV0IGRlY2F5ID0gY2xhbXAoMS4wIC0gcG93KGRpc3QgLyBwb2ludExpZ2h0LmRpc3RhbmNlLCBwb2ludExpZ2h0LmRlY2F5KSwgMC4wLCAxLjApO1xyXG4gICAgXHJcbiAgICAgICAgICAgIGxldCBkID0gIG1heCggZG90KCBOLCAtZGlyZWN0aW9uICksIDAuMCApICogZGVjYXk7XHJcbiAgICAgICAgICAgIGxpZ2h0Q29sb3IuZGlyZWN0RGlmZnVzZSA9IHBvaW50TGlnaHQuY29sb3IgKiBkO1xyXG4gICAgXHJcbiAgICAgICAgICAgIGxldCBoYWxmRGlyOnZlYzM8ZjMyPiA9IG5vcm1hbGl6ZSggViAtIGRpcmVjdGlvbiApO1xyXG4gICAgICAgICAgICBsZXQgczpmMzIgPSBwb3coIGNsYW1wKCBkb3QoIE4sIGhhbGZEaXIgKSwgMC4wLCAxLjAgKSwgc2hpbmluZXNzICkgICogZGVjYXk7XHJcbiAgICAgICAgICAgIGxpZ2h0Q29sb3IuZGlyZWN0U3BlY3VsYXIgPSBwb2ludExpZ2h0LmNvbG9yICogcztcclxuICAgICAgICAgICAgcmV0dXJuIGxpZ2h0Q29sb3I7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZuIGdldFBvaW50TGlnaHRJbmNpZGVudExpZ2h0KHBvaW50TGlnaHQ6UG9pbnRMaWdodCwgZ2VvbWV0cnk6R2VvbWV0cnkpLT5JbmNpZGVudExpZ2h0IHtcclxuICAgICAgICAgICAgdmFyIGluY2lkZW50TGlnaHQ6SW5jaWRlbnRMaWdodDtcclxuICAgICAgICAgICAgbGV0IGxWZWN0b3I6dmVjMzxmMzI+ID0gcG9pbnRMaWdodC5wb3NpdGlvbi1nZW9tZXRyeS5wb3NpdGlvbjtcclxuICAgICAgICAgICAgaW5jaWRlbnRMaWdodC5kaXJlY3Rpb249IG5vcm1hbGl6ZSggbFZlY3RvciApO1xyXG4gICAgICAgICAgICBsZXQgbGlnaHREaXN0YW5jZTpmMzIgPSBsZW5ndGgoIGxWZWN0b3IgKTtcclxuICAgICAgICAgICAgLy8gbGV0IHdlaWdodDpmMzI9MS4wIC0gcG93KGxpZ2h0RGlzdGFuY2UvcG9pbnRMaWdodC5kaXN0YW5jZSwgNC4wKTtcclxuICAgICAgICAgICAgaW5jaWRlbnRMaWdodC5jb2xvcj1wb2ludExpZ2h0LmNvbG9yKmNsYW1wKDEuMCAtIHBvdyhsaWdodERpc3RhbmNlL3BvaW50TGlnaHQuZGlzdGFuY2UsIDQuMCksIDAuMCwgMS4wKTtcclxuICAgICAgICAgICAgcmV0dXJuIGluY2lkZW50TGlnaHQ7XHJcbiAgICAgICAgfVxyXG4gICAgI2VuZGlmXHJcbiAgICAjaWYgJHtkZWZpbmVzLmRpcnRlY3RMaWdodHNDb3VudCA+IDB9XHJcbiAgICAgICAgc3RydWN0IERpcmVjdGlvbmFsTGlnaHQge1xyXG4gICAgICAgICAgICBkaXJlY3Rpb246IHZlYzM8ZjMyPixcclxuICAgICAgICAgICAgY29sb3I6IHZlYzM8ZjMyPixcclxuICAgICAgICB9O1xyXG4gICAgICAgIGZuIGdldERpcmVjdExpZ2h0SW5mbyhkaXJlY3Rpb25hbExpZ2h0OkRpcmVjdGlvbmFsTGlnaHQsc2hpbmluZXNzOmYzMixOOnZlYzM8ZjMyPixWOnZlYzM8ZjMyPiktPlJlZmxlY3RlZExpZ2h0e1xyXG4gICAgICAgICAgICB2YXIgbGlnaHRDb2xvcjpSZWZsZWN0ZWRMaWdodDtcclxuICAgICAgICAgICAgbGV0IGQ6ZjMyID0gbWF4KGRvdChOLCAtZGlyZWN0aW9uYWxMaWdodC5kaXJlY3Rpb24pLCAwLjApO1xyXG4gICAgICAgICAgICBsaWdodENvbG9yLmRpcmVjdERpZmZ1c2UgKz0gZGlyZWN0aW9uYWxMaWdodC5jb2xvciAqIGQ7XHJcbiAgICBcclxuICAgICAgICAgICAgbGV0IGhhbGZEaXI6dmVjMzxmMzI+ID0gbm9ybWFsaXplKCBWIC0gZGlyZWN0aW9uYWxMaWdodC5kaXJlY3Rpb24gKTtcclxuICAgICAgICAgICAgbGV0IHM6ZjMyID0gcG93KCBjbGFtcCggZG90KCBOLCBoYWxmRGlyICksIDAuMCwgMS4wICksIHNoaW5pbmVzcyApO1xyXG4gICAgICAgICAgICBsaWdodENvbG9yLmRpcmVjdFNwZWN1bGFyICs9IGRpcmVjdGlvbmFsTGlnaHQuY29sb3IgKiBzO1xyXG4gICAgICAgICAgICByZXR1cm4gbGlnaHRDb2xvcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm4gZ2V0RGlyZWN0aW9uYWxEaXJlY3RMaWdodEluY2lkZW50TGlnaHQoZGlyZWN0aW9uYWxMaWdodDpEaXJlY3Rpb25hbExpZ2h0LGdlb21ldHJ5Okdlb21ldHJ5KS0+SW5jaWRlbnRMaWdodCB7XHJcbiAgICAgICAgICAgIHZhciBpbmNpZGVudExpZ2h0OkluY2lkZW50TGlnaHQ7XHJcbiAgICAgICAgICAgIGluY2lkZW50TGlnaHQuY29sb3IgPSBkaXJlY3Rpb25hbExpZ2h0LmNvbG9yO1xyXG4gICAgICAgICAgICBpbmNpZGVudExpZ2h0LmRpcmVjdGlvbiA9IG5vcm1hbGl6ZShkaXJlY3Rpb25hbExpZ2h0LmRpcmVjdGlvbik7XHJcbiAgICAgICAgICAgIHJldHVybiBpbmNpZGVudExpZ2h0OyAgICAgICAgIFxyXG4gICAgICAgIH1cclxuICAgICNlbmRpZlxyXG5cclxuICAgICNpZiAke2RlZmluZXMub3BlblNoYWRvd30gXHJcbiAgICAgICAgc3RydWN0IExpZ2h0SW5mbyB7XHJcbiAgICAgICAgICAgIGRpcmVjdGlvbjogdmVjMzxmMzI+LFxyXG4gICAgICAgICAgICB2aWV3cG9ydDogdmVjNDxmMzI+LFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgXHJcbiAgICAgICAgZm4gbGluZWFyaXplRGVwdGgoZGVwdGg6IGYzMiwgbmVhcjogZjMyLCBmYXI6IGYzMiktPmYzMiB7XHJcbiAgICAgICAgICAgIHJldHVybiAyICogKG5lYXIgKiBmYXIpIC8gKGZhciArIG5lYXIgLSBkZXB0aCAqIChmYXIgLSBuZWFyKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmbiBnZXRDdWJlRmFjZSh2IDogdmVjMzxmMzI+KSAtPiBpMzJ7XHJcbiAgICAgICAgICAgIGxldCB2QWJzID0gYWJzKHYpO1xyXG4gICAgICAgIFxyXG4gICAgICAgICAgICBpZiAodkFicy56ID49IHZBYnMueCAmJiB2QWJzLnogPj0gdkFicy55KSB7XHJcbiAgICAgICAgICAgICAgaWYgKHYueiA8IDAuMCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIDM7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIHJldHVybiAyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgIGlmICh2QWJzLnkgPj0gdkFicy54KSB7XHJcbiAgICAgICAgICAgICAgaWYgKHYueSA8IDAuMCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIDU7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIHJldHVybiA0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgIGlmICh2LnggPCAwLjApIHtcclxuICAgICAgICAgICAgICByZXR1cm4gMTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gMDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZuIGdldFNoYWRvd1ZhbHVlKHNoYWRvd01hcEFycmF5OnRleHR1cmVfZGVwdGhfMmRfYXJyYXksIHNoYWRvd1NhbXBsZXI6c2FtcGxlcl9jb21wYXJpc29uLCBsaWdodFBvczp2ZWM0PGYzMj4sIGdlb21ldHJ5Okdlb21ldHJ5LCBsaWdodEluZm86TGlnaHRJbmZvLCBpbmRleDp1MzIsIGlzUG9pbnRMaWdodDogYm9vbCwgbmVhcjogZjMyLCBmYXI6IGYzMiktPmYzMiB7XHJcbiAgICAgICAgICAgIHZhciB2aXNpYmlsaXR5ID0gMC4wO1xyXG4gICAgICAgICAgICB2YXIgcHJvamVjdFBvczogdmVjMzxmMzI+ID0gbGlnaHRQb3MueHl6IC8gbGlnaHRQb3MudztcclxuICAgICAgICAgICAgdmFyIHNoYWRvd1BvczogdmVjMzxmMzI+ID0gdmVjMyhwcm9qZWN0UG9zLnh5ICogdmVjMigwLjUsIC0wLjUpICsgdmVjMigwLjUpLCBwcm9qZWN0UG9zLnopO1xyXG4gICAgICAgICAgICB2YXIgZDpmMzIgPSBkb3QoZ2VvbWV0cnkubm9ybWFsLCAtbGlnaHRJbmZvLmRpcmVjdGlvbik7XHJcbiAgICAgICAgICAgIHZhciBiaWFzID0gbWF4KDAuMDEyICogKDEuMCAtIGQpLCAwLjAwMSkgLyBsaWdodFBvcy53O1xyXG4gICAgICAgICAgICBsZXQgb25lT3ZlclNoYWRvd0RlcHRoVGV4dHVyZVNpemUgPSAxLjAgLyAxMDI0LjA7XHJcbiAgICAgICAgICAgIC8vIHZhciBkZXB0aCA9IHNlbGVjdChzaGFkb3dQb3MueiwgKGxpbmVhcml6ZURlcHRoKHNoYWRvd1Bvcy56LCBuZWFyLCBmYXIpIC0gbmVhcikgLyAoZmFyLSBuZWFyKSwgaXNQZXJzcGVjdGl2ZUNhbWVyYSk7XHJcbiAgICAgICAgICAgIHZhciBkZXB0aCA9IHNoYWRvd1Bvcy56O1xyXG5cclxuICAgICAgICAgICAgaWYgKGlzUG9pbnRMaWdodCkge1xyXG4gICAgICAgICAgICAgICAgc2hhZG93UG9zLnggPSBzaGFkb3dQb3MueCAqIGxpZ2h0SW5mby52aWV3cG9ydC56O1xyXG4gICAgICAgICAgICAgICAgc2hhZG93UG9zLnkgPSBzaGFkb3dQb3MueSAqIGxpZ2h0SW5mby52aWV3cG9ydC53O1xyXG4gICAgICAgICAgICAgICAgdmFyIHZpZXdwb3J0WCA9IGxpZ2h0SW5mby52aWV3cG9ydC54ICogbGlnaHRJbmZvLnZpZXdwb3J0Lno7XHJcbiAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRZID0gbGlnaHRJbmZvLnZpZXdwb3J0LnkgKiBsaWdodEluZm8udmlld3BvcnQudztcclxuICAgICAgICAgICAgICAgIHZhciB1dk9mZnNldCA9IDEuNSAvIDEwMjQuMDtcclxuICAgICAgICAgICAgICAgIHNoYWRvd1Bvcy54ID0gY2xhbXAoc2hhZG93UG9zLnggKyB2aWV3cG9ydFgsIHZpZXdwb3J0WCArIHV2T2Zmc2V0LCB2aWV3cG9ydFggKyBsaWdodEluZm8udmlld3BvcnQueiAtIHV2T2Zmc2V0KTtcclxuICAgICAgICAgICAgICAgIHNoYWRvd1Bvcy55ID0gY2xhbXAoc2hhZG93UG9zLnkgKyB2aWV3cG9ydFksIHZpZXdwb3J0WSArIHV2T2Zmc2V0LCB2aWV3cG9ydFkgKyBsaWdodEluZm8udmlld3BvcnQudyAtIHV2T2Zmc2V0KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZm9yICh2YXIgeSA9IC0xOyB5IDw9IDE7IHkrKykge1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgeCA9IC0xOyB4IDw9IDE7IHgrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBvZmZzZXQgPSB2ZWMyPGYzMj4odmVjMih4LCB5KSkgKiBvbmVPdmVyU2hhZG93RGVwdGhUZXh0dXJlU2l6ZTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIHZpc2liaWxpdHkgKz0gdGV4dHVyZVNhbXBsZUNvbXBhcmUoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNoYWRvd01hcEFycmF5LCBzaGFkb3dTYW1wbGVyLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaGFkb3dQb3MueHkgKyBvZmZzZXQsIGluZGV4LCBkZXB0aCAtIGJpYXMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZpc2liaWxpdHkgLz0gOS4wO1xyXG4gICAgICAgICAgICB2YXIgaW5GcnVzdHVtID0gc2hhZG93UG9zLnggPj0gMC4wICYmIHNoYWRvd1Bvcy54IDw9IDEuMCAmJiBzaGFkb3dQb3MueSA+PSAwLjAgJiYgc2hhZG93UG9zLnkgPD0gMS4wO1xyXG4gICAgICAgICAgICBpZiAoIWluRnJ1c3R1bSB8fCBkZXB0aCA+IDEuMCkge1xyXG4gICAgICAgICAgICAgICAgdmlzaWJpbGl0eSA9IDEuMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdmlzaWJpbGl0eTtcclxuICAgICAgICB9XHJcbiAgICAjZW5kaWZcclxuXHJcbiAgICAjaWYgJHtcclxuXHRcdGRlZmluZXMuYW1iaWVudExpZ2h0Q291bnQgfHwgZGVmaW5lcy5zcG90TGlnaHRzQ291bnQgfHwgZGVmaW5lcy5wb2ludExpZ2h0c0NvdW50IHx8IGRlZmluZXMuZGlydGVjdExpZ2h0c0NvdW50XHJcblx0fVxyXG4gICAgICAgIHN0cnVjdCBMaWdodFVuaWZvcm1ze1xyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLmFtYmllbnRMaWdodENvdW50fVxyXG4gICAgICAgICAgICAgICAgYW1iaWVudDp2ZWM0PGYzMj4sXHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLnNwb3RMaWdodHNDb3VudH1cclxuICAgICAgICAgICAgICAgIHNwb3RMaWdodHM6YXJyYXk8U3BvdExpZ2h0LCR7ZGVmaW5lcy5zcG90TGlnaHRzQ291bnR9PixcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMucG9pbnRMaWdodHNDb3VudH1cclxuICAgICAgICAgICAgICAgIHBvaW50TGlnaHRzOmFycmF5PFBvaW50TGlnaHQsJHtkZWZpbmVzLnBvaW50TGlnaHRzQ291bnR9PixcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuZGlydGVjdExpZ2h0c0NvdW50fVxyXG4gICAgICAgICAgICAgICAgZGlydGVjdExpZ2h0czphcnJheTxEaXJlY3Rpb25hbExpZ2h0LCR7ZGVmaW5lcy5kaXJ0ZWN0TGlnaHRzQ291bnR9PixcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgfVxyXG4gICAgICAgIEBncm91cCgyKSBAYmluZGluZygke2RlZmluZXMubGlnaHRCaW5kaW5nfSkgdmFyPHN0b3JhZ2UsIHJlYWQ+IGxpZ2h0VW5pZm9ybXM6IExpZ2h0VW5pZm9ybXM7XHJcblxyXG4gICAgICAgICNpZiAke2RlZmluZXMub3BlblNoYWRvd31cclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5zcG90TGlnaHRTaGFkb3dNYXBzQ291bnR9XHJcbiAgICAgICAgICAgICAgICBzdHJ1Y3QgU3BvdExpZ2h0U2hhZG93IHtcclxuICAgICAgICAgICAgICAgICAgICBzaGFkb3dDYW1lcmFWUE1hdHJpeDogbWF0NHg0PGYzMj4sXHJcbiAgICAgICAgICAgICAgICAgICAgc2hhZG93Q2FtZXJhTmVhcjogZjMyLFxyXG4gICAgICAgICAgICAgICAgICAgIHNoYWRvd0NhbWVyYUZhcjogZjMyXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLnBvaW50TGlnaHRTaGFkb3dNYXBzQ291bnR9XHJcbiAgICAgICAgICAgICAgICBzdHJ1Y3QgUG9pbnRMaWdodFNoYWRvdyB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2hhZG93Q2FtZXJhVlBNYXRyaXhBcnJheTogYXJyYXk8bWF0NHg0PGYzMj4sIDY+LFxyXG4gICAgICAgICAgICAgICAgICAgIHNoYWRvd0NhbWVyYVZpZXdwb3J0QXJyYXk6IGFycmF5PHZlYzQ8ZjMyPiwgNj4sXHJcbiAgICAgICAgICAgICAgICAgICAgc2hhZG93Q2FtZXJhTmVhcjogZjMyLFxyXG4gICAgICAgICAgICAgICAgICAgIHNoYWRvd0NhbWVyYUZhcjogZjMyLFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHNoYWRvd0NhbWVyYVZQTWF0cml4OiBtYXQ0eDQ8ZjMyPixcclxuICAgICAgICAgICAgICAgICAgICAvLyBzaGFkb3dDYW1lcmFWUE1hdHJpeEFycmF5OiBhcnJheTxtYXQ0eDQ8ZjMyPiwgNj4sXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gc2hhZG93Q2FtZXJhVmlld3BvcnRBcnJheTogYXJyYXk8dmVjNDxmMzI+LCA2PixcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuZGlyZWN0TGlnaHRTaGFkb3dNYXBzQ291bnR9XHJcbiAgICAgICAgICAgICAgICBzdHJ1Y3QgRGlyZWN0TGlnaHRTaGFkb3cge1xyXG4gICAgICAgICAgICAgICAgICAgIHNoYWRvd0NhbWVyYVZQTWF0cml4OiBtYXQ0eDQ8ZjMyPixcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgICAgIHN0cnVjdCBTaGFkb3dVbmlmb3Jtc3tcclxuICAgICAgICAgICAgICAgICNpZiAke2RlZmluZXMuc3BvdExpZ2h0U2hhZG93TWFwc0NvdW50fVxyXG4gICAgICAgICAgICAgICAgICAgIHNwb3RMaWdodFNoYWRvd3M6YXJyYXk8U3BvdExpZ2h0U2hhZG93LCR7ZGVmaW5lcy5zcG90TGlnaHRTaGFkb3dNYXBzQ291bnR9PixcclxuICAgICAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5wb2ludExpZ2h0U2hhZG93TWFwc0NvdW50fVxyXG4gICAgICAgICAgICAgICAgICAgIHBvaW50TGlnaHRTaGFkb3dzOmFycmF5PFBvaW50TGlnaHRTaGFkb3csJHtkZWZpbmVzLnBvaW50TGlnaHRTaGFkb3dNYXBzQ291bnR9PixcclxuICAgICAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5kaXJlY3RMaWdodFNoYWRvd01hcHNDb3VudH1cclxuICAgICAgICAgICAgICAgICAgICBkaXJlY3RMaWdodFNoYWRvd3M6YXJyYXk8RGlyZWN0TGlnaHRTaGFkb3csJHtkZWZpbmVzLmRpcmVjdExpZ2h0U2hhZG93TWFwc0NvdW50fT4sXHJcbiAgICAgICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBAZ3JvdXAoMikgQGJpbmRpbmcoJHtkZWZpbmVzLnNoYWRvd0JpbmRpbmd9KSB2YXI8c3RvcmFnZSwgcmVhZD4gc2hhZG93VW5pZm9ybXM6IFNoYWRvd1VuaWZvcm1zO1xyXG5cclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5zcG90TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXlCaW5kaW5nfVxyXG4gICAgICAgICAgICAgICAgQGdyb3VwKDIpIEBiaW5kaW5nKCR7XHJcblx0XHRcdFx0XHRkZWZpbmVzLnNwb3RMaWdodFNoYWRvd01hcFRleHR1cmVBcnJheUJpbmRpbmdcclxuXHRcdFx0XHR9KSB2YXIgc3BvdExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5OiB0ZXh0dXJlX2RlcHRoXzJkX2FycmF5O1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5wb2ludExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5QmluZGluZ31cclxuICAgICAgICAgICAgICAgIEBncm91cCgyKSBAYmluZGluZygke1xyXG5cdFx0XHRcdFx0ZGVmaW5lcy5wb2ludExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5QmluZGluZ1xyXG5cdFx0XHRcdH0pIHZhciBwb2ludExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5OiB0ZXh0dXJlX2RlcHRoXzJkX2FycmF5O1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5kaXJlY3RMaWdodFNoYWRvd01hcFRleHR1cmVBcnJheUJpbmRpbmd9XHJcbiAgICAgICAgICAgICAgICBAZ3JvdXAoMikgQGJpbmRpbmcoJHtcclxuXHRcdFx0XHRcdGRlZmluZXMuZGlyZWN0TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXlCaW5kaW5nXHJcblx0XHRcdFx0fSkgdmFyIGRpcmVjdExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5OiB0ZXh0dXJlX2RlcHRoXzJkX2FycmF5O1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgQGdyb3VwKDIpIEBiaW5kaW5nKCR7ZGVmaW5lcy5zaGFkb3dTYW1wbGVyQmluZGluZ30pIHZhciBzaGFkb3dTYW1wbGVyOiBzYW1wbGVyX2NvbXBhcmlzb247XHJcbiAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgI2VuZGlmXHJcbiAgICAjaWYgJHtkZWZpbmVzLm1hdGVyaWFsUGhvbmd9XHJcbiAgICAgICAgZm4gcGFyc2VMaWdodHMoZ2VvbWV0cnk6R2VvbWV0cnksc2hpbmluZXNzOmYzMiktPlJlZmxlY3RlZExpZ2h0IHtcclxuICAgICNlbGlmICR7ZGVmaW5lcy5tYXRlcmlhbFBicn1cclxuICAgICAgICBmbiBwYXJzZUxpZ2h0cyhnZW9tZXRyeTpHZW9tZXRyeSxtYXRlcmlhbDpQaHlzaWNhbE1hdGVyaWFsKS0+UmVmbGVjdGVkTGlnaHR7XHJcbiAgICAjZW5kaWZcclxuICAgICAgICB2YXIgcmVmbGVjdGVkTGlnaHQ6UmVmbGVjdGVkTGlnaHQ7XHJcbiAgICAgICAgdmFyIHNoYWRvd1ZhbHVlOmYzMiA9IDEuMDtcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLmFtYmllbnRMaWdodENvdW50ID4gMH1cclxuICAgICAgICAgICAgLy/lpITnkIbnjq/looPlhYlcclxuICAgICAgICAgICAgdmFyIGFtYmllbnRDb2xvcjp2ZWMzPGYzMj4gPSBsaWdodFVuaWZvcm1zLmFtYmllbnQueHl6ICogbGlnaHRVbmlmb3Jtcy5hbWJpZW50Lnc7XHJcbiAgICAgICAgICAgIHJlZmxlY3RlZExpZ2h0LmFtYmllbnQgKz0gYW1iaWVudENvbG9yO1xyXG4gICAgICAgICNlbmRpZlxyXG5cclxuICAgICAgICAjaWYgJHtkZWZpbmVzLnNwb3RMaWdodHNDb3VudCA+IDB9XHJcbiAgICAgICAgICAgIC8v5aSE55CG6IGa5YWJ54GvXHJcbiAgICAgICAgICAgIHZhciBzcG90TGlnaHQ6U3BvdExpZ2h0O1xyXG4gICAgICAgICAgICBmb3IgKHZhciBrID0gMHU7IGsgPCAke2RlZmluZXMuc3BvdExpZ2h0c0NvdW50fTsgayA9IGsgKyAxdSkge1xyXG4gICAgICAgICAgICAgICAgc3BvdExpZ2h0PSBsaWdodFVuaWZvcm1zLnNwb3RMaWdodHNba107XHJcbiAgICAgICAgICAgICAgICAjaWYgJHtkZWZpbmVzLm1hdGVyaWFsUGhvbmcgJiYgZGVmaW5lcy5vcGVuU2hhZG93ICYmIGRlZmluZXMuc3BvdExpZ2h0U2hhZG93TWFwc0NvdW50fVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIGsgPCB0ZXh0dXJlTnVtTGF5ZXJzKHNwb3RMaWdodFNoYWRvd01hcFRleHR1cmVBcnJheSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3BvdExpZ2h0U2hhZG93OlNwb3RMaWdodFNoYWRvdyA9IHNoYWRvd1VuaWZvcm1zLnNwb3RMaWdodFNoYWRvd3Nba107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsaWdodFBvczogdmVjNDxmMzI+ID0gc3BvdExpZ2h0U2hhZG93LnNoYWRvd0NhbWVyYVZQTWF0cml4ICogdmVjNDxmMzI+KGdlb21ldHJ5LnBvc2l0aW9uLDEuMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsaWdodEluZm86TGlnaHRJbmZvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsaWdodEluZm8uZGlyZWN0aW9uID0gbm9ybWFsaXplKGdlb21ldHJ5LnBvc2l0aW9uIC0gc3BvdExpZ2h0LnBvc2l0aW9uKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNoYWRvd1ZhbHVlID0gZ2V0U2hhZG93VmFsdWUoc3BvdExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5LCBzaGFkb3dTYW1wbGVyLCBsaWdodFBvcywgZ2VvbWV0cnksIGxpZ2h0SW5mbywgaywgZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcG90TGlnaHRTaGFkb3cuc2hhZG93Q2FtZXJhTmVhciwgc3BvdExpZ2h0U2hhZG93LnNoYWRvd0NhbWVyYUZhcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHNwb3RMaWdodC5jb2xvciAqPSBzaGFkb3dWYWx1ZTtcclxuICAgICAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5tYXRlcmlhbFBob25nfVxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBzcFJlZmxlY3RlZExpZ2h0PWdldFNwb3RMaWdodEluZm8oc3BvdExpZ2h0LGdlb21ldHJ5LnBvc2l0aW9uLHNoaW5pbmVzcyxnZW9tZXRyeS5ub3JtYWwsZ2VvbWV0cnkudmlld0Rpcik7XHJcbiAgICAgICAgICAgICAgICAjZWxpZiAke2RlZmluZXMubWF0ZXJpYWxQYnJ9XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGluY2lkZW50TGlnaHQ9Z2V0U3BvdExpZ2h0SW5jaWRlbnRMaWdodChzcG90TGlnaHQsZ2VvbWV0cnkpO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBzcFJlZmxlY3RlZExpZ2h0PWRpcmVjdF9QaHlzaWNhbChpbmNpZGVudExpZ2h0LCBnZW9tZXRyeSwgbWF0ZXJpYWwpO1xyXG4gICAgICAgICAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgICAgICAgICAgcmVmbGVjdGVkTGlnaHQuZGlyZWN0RGlmZnVzZSs9c3BSZWZsZWN0ZWRMaWdodC5kaXJlY3REaWZmdXNlO1xyXG4gICAgICAgICAgICAgICAgcmVmbGVjdGVkTGlnaHQuZGlyZWN0U3BlY3VsYXIrPXNwUmVmbGVjdGVkTGlnaHQuZGlyZWN0U3BlY3VsYXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAjZW5kaWZcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLnBvaW50TGlnaHRzQ291bnQgPiAwfVxyXG4gICAgICAgICAgICAvL+WkhOeQhueCueWFiea6kFxyXG4gICAgICAgICAgICB2YXIgcG9pbnRMaWdodDpQb2ludExpZ2h0O1xyXG4gICAgICAgICAgICBmb3IgKHZhciBqID0gMHU7IGogPCAke2RlZmluZXMucG9pbnRMaWdodHNDb3VudH07aiA9IGogKyAxdSkge1xyXG4gICAgICAgICAgICAgICAgcG9pbnRMaWdodCA9IGxpZ2h0VW5pZm9ybXMucG9pbnRMaWdodHNbal07XHJcbiAgICAgICAgICAgICAgICAjaWYgJHtkZWZpbmVzLm1hdGVyaWFsUGhvbmcgJiYgZGVmaW5lcy5vcGVuU2hhZG93ICYmIGRlZmluZXMucG9pbnRMaWdodFNoYWRvd01hcHNDb3VudH1cclxuICAgICAgICAgICAgICAgICAgICBpZiBqIDwgdGV4dHVyZU51bUxheWVycyhwb2ludExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb2ludExpZ2h0U2hhZG93OlBvaW50TGlnaHRTaGFkb3cgPSBzaGFkb3dVbmlmb3Jtcy5wb2ludExpZ2h0U2hhZG93c1tqXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxpZ2h0SW5mbzpMaWdodEluZm87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpZ2h0SW5mby5kaXJlY3Rpb24gPSBub3JtYWxpemUoZ2VvbWV0cnkucG9zaXRpb24gLSBwb2ludExpZ2h0LnBvc2l0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1YmVGYWNlID0gZ2V0Q3ViZUZhY2UobGlnaHRJbmZvLmRpcmVjdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsaWdodFBvczogdmVjNDxmMzI+ID0gcG9pbnRMaWdodFNoYWRvdy5zaGFkb3dDYW1lcmFWUE1hdHJpeEFycmF5W2N1YmVGYWNlXSAqIHZlYzQ8ZjMyPihnZW9tZXRyeS5wb3NpdGlvbiwxLjApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsaWdodEluZm8udmlld3BvcnQgPSBwb2ludExpZ2h0U2hhZG93LnNoYWRvd0NhbWVyYVZpZXdwb3J0QXJyYXlbY3ViZUZhY2VdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmFyIGxpZ2h0UG9zOiB2ZWM0PGYzMj4gPSBwb2ludExpZ2h0U2hhZG93LnNoYWRvd0NhbWVyYVZQTWF0cml4ICogdmVjNDxmMzI+KGdlb21ldHJ5LnBvc2l0aW9uLDEuMCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaGFkb3dWYWx1ZSA9IGdldFNoYWRvd1ZhbHVlKHBvaW50TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXksIHNoYWRvd1NhbXBsZXIsIGxpZ2h0UG9zLCBnZW9tZXRyeSwgbGlnaHRJbmZvLCBqLCB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRMaWdodFNoYWRvdy5zaGFkb3dDYW1lcmFOZWFyLCBwb2ludExpZ2h0U2hhZG93LnNoYWRvd0NhbWVyYUZhcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyByZWZsZWN0ZWRMaWdodC50ZXN0Q29sb3IgPSB2ZWMzKHBvaW50TGlnaHRTaGFkb3cuc2hhZG93Q2FtZXJhRmFyIC8gMTAwMCwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICBwb2ludExpZ2h0U2hhZG93LnNoYWRvd0NhbWVyYVZQTWF0cml4QXJyYXlbNV1bM11bMl0gLyAyNTUsIHBvaW50TGlnaHRTaGFkb3cuc2hhZG93Q2FtZXJhVlBNYXRyaXhBcnJheVs1XVszXVszXSAvIDI1NSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlZmxlY3RlZExpZ2h0LnRlc3RDb2xvciA9IHZlYzMocG9pbnRMaWdodFNoYWRvdy5zaGFkb3dDYW1lcmFOZWFyLCBwb2ludExpZ2h0U2hhZG93LnNoYWRvd0NhbWVyYU5lYXIsIHBvaW50TGlnaHRTaGFkb3cuc2hhZG93Q2FtZXJhTmVhcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHBvaW50TGlnaHQuY29sb3IgKj0gc2hhZG93VmFsdWU7XHJcbiAgICAgICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgICAgICNpZiAke2RlZmluZXMubWF0ZXJpYWxQaG9uZ31cclxuICAgICAgICAgICAgICAgICAgICBsZXQgcG9pUmVmbGVjdGVkTGlnaHQ9Z2V0UG9pbnRMaWdodEluZm8ocG9pbnRMaWdodCxnZW9tZXRyeS5wb3NpdGlvbixzaGluaW5lc3MsZ2VvbWV0cnkubm9ybWFsLGdlb21ldHJ5LnZpZXdEaXIpO1xyXG4gICAgICAgICAgICAgICAgI2VsaWYgJHtkZWZpbmVzLm1hdGVyaWFsUGJyfVxyXG4gICAgICAgICAgICAgICAgICAgbGV0IGluY2lkZW50TGlnaHQ9Z2V0UG9pbnRMaWdodEluY2lkZW50TGlnaHQocG9pbnRMaWdodCxnZW9tZXRyeSk7XHJcbiAgICAgICAgICAgICAgICAgICBsZXQgcG9pUmVmbGVjdGVkTGlnaHQ9ZGlyZWN0X1BoeXNpY2FsKGluY2lkZW50TGlnaHQsIGdlb21ldHJ5LCBtYXRlcmlhbCk7XHJcbiAgICAgICAgICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgICAgICAgICByZWZsZWN0ZWRMaWdodC5kaXJlY3REaWZmdXNlKz1wb2lSZWZsZWN0ZWRMaWdodC5kaXJlY3REaWZmdXNlO1xyXG4gICAgICAgICAgICAgICAgcmVmbGVjdGVkTGlnaHQuZGlyZWN0U3BlY3VsYXIrPXBvaVJlZmxlY3RlZExpZ2h0LmRpcmVjdFNwZWN1bGFyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5kaXJ0ZWN0TGlnaHRzQ291bnQgPiAwfVxyXG4gICAgICAgICAgICAvL+WkhOeQhuaWueWQkeWFiVxyXG4gICAgICAgICAgICB2YXIgZGlyZWN0aW9uYWxMaWdodDpEaXJlY3Rpb25hbExpZ2h0O1xyXG4gICAgICAgICAgICBmb3IgKHZhciBpPSAwdTsgaSA8JHtkZWZpbmVzLmRpcnRlY3RMaWdodHNDb3VudH07IGkgPSBpICsgMXUpIHtcclxuICAgICAgICAgICAgICAgIGRpcmVjdGlvbmFsTGlnaHQgPSBsaWdodFVuaWZvcm1zLmRpcnRlY3RMaWdodHNbaV07XHJcbiAgICAgICAgICAgICAgICAjaWYgJHtkZWZpbmVzLm1hdGVyaWFsUGhvbmcgJiYgZGVmaW5lcy5vcGVuU2hhZG93ICYmIGRlZmluZXMuZGlyZWN0TGlnaHRTaGFkb3dNYXBzQ291bnR9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgaSA8IHRleHR1cmVOdW1MYXllcnMoZGlyZWN0TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRpcmVjdExpZ2h0U2hhZG93OkRpcmVjdExpZ2h0U2hhZG93ID0gc2hhZG93VW5pZm9ybXMuZGlyZWN0TGlnaHRTaGFkb3dzW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbGlnaHRQb3M6IHZlYzQ8ZjMyPiA9IGRpcmVjdExpZ2h0U2hhZG93LnNoYWRvd0NhbWVyYVZQTWF0cml4ICogdmVjNDxmMzI+KGdlb21ldHJ5LnBvc2l0aW9uLDEuMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsaWdodEluZm86TGlnaHRJbmZvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsaWdodEluZm8uZGlyZWN0aW9uID0gZGlyZWN0aW9uYWxMaWdodC5kaXJlY3Rpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2hhZG93VmFsdWUgPSBnZXRTaGFkb3dWYWx1ZShkaXJlY3RMaWdodFNoYWRvd01hcFRleHR1cmVBcnJheSwgc2hhZG93U2FtcGxlciwgbGlnaHRQb3MsIGdlb21ldHJ5LCBsaWdodEluZm8sIGksIGZhbHNlLCAwLCAwKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uYWxMaWdodC5jb2xvciAqPSBzaGFkb3dWYWx1ZTtcclxuICAgICAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICNpZiAke2RlZmluZXMubWF0ZXJpYWxQaG9uZ31cclxuICAgICAgICAgICAgICAgICAgICBsZXQgZGlyUmVmbGVjdGVkTGlnaHQ9Z2V0RGlyZWN0TGlnaHRJbmZvKGRpcmVjdGlvbmFsTGlnaHQsc2hpbmluZXNzLGdlb21ldHJ5Lm5vcm1hbCxnZW9tZXRyeS52aWV3RGlyKTtcclxuICAgICAgICAgICAgICAgICNlbGlmICR7ZGVmaW5lcy5tYXRlcmlhbFBicn1cclxuICAgICAgICAgICAgICAgICAgICBsZXQgaW5jaWRlbnRMaWdodD1nZXREaXJlY3Rpb25hbERpcmVjdExpZ2h0SW5jaWRlbnRMaWdodChkaXJlY3Rpb25hbExpZ2h0LGdlb21ldHJ5KTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgZGlyUmVmbGVjdGVkTGlnaHQ9ZGlyZWN0X1BoeXNpY2FsKGluY2lkZW50TGlnaHQsIGdlb21ldHJ5LCBtYXRlcmlhbCk7XHJcbiAgICAgICAgICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgICAgICAgICByZWZsZWN0ZWRMaWdodC5kaXJlY3REaWZmdXNlKz1kaXJSZWZsZWN0ZWRMaWdodC5kaXJlY3REaWZmdXNlO1xyXG4gICAgICAgICAgICAgICAgcmVmbGVjdGVkTGlnaHQuZGlyZWN0U3BlY3VsYXIrPWRpclJlZmxlY3RlZExpZ2h0LmRpcmVjdFNwZWN1bGFyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgcmV0dXJuIHJlZmxlY3RlZExpZ2h0O1xyXG4gICAgfWA7XHJcbn1cclxuIiwiaW1wb3J0IHsgd2dzbFBhcnNlRGVmaW5lcyB9IGZyb20gXCIuLi8uLi9XZ3NsUHJlcHJvY2Vzc29yXCI7XHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGxpZ2h0Q29tbW9uKGRlZmluZXMpIHtcclxuXHRyZXR1cm4gd2dzbFBhcnNlRGVmaW5lc2BcclxuICAgIHN0cnVjdCBSZWZsZWN0ZWRMaWdodCB7XHJcbiAgICAgICAgZGlyZWN0RGlmZnVzZTp2ZWMzPGYzMj4sXHJcbiAgICAgICAgZGlyZWN0U3BlY3VsYXI6dmVjMzxmMzI+LFxyXG4gICAgICAgIGluZGlyZWN0RGlmZnVzZTp2ZWMzPGYzMj4sXHJcbiAgICAgICAgaW5kaXJlY3RTcGVjdWxhcjp2ZWMzPGYzMj4sXHJcbiAgICB9O1xyXG4gICAgc3RydWN0IEdlb21ldHJ5IHtcclxuICAgICAgICBwb3NpdGlvbjogdmVjMzxmMzI+LFxyXG4gICAgICAgIG5vcm1hbDogdmVjMzxmMzI+LFxyXG4gICAgICAgIHZpZXdEaXI6IHZlYzM8ZjMyPixcclxuICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9DTEVBUkNPQVR9XHJcbiAgICAgICAgICAgIHZlYzMgY2xlYXJjb2F0Tm9ybWFsO1xyXG4gICAgICAgICNlbmRpZlxyXG4gICAgfTtcclxuICAgIGZuIGdldEFtYmllbnRMaWdodElycmFkaWFuY2UoYW1iaWVudExpZ2h0Q29sb3I6IHZlYzM8ZjMyPikgLT4gdmVjMzxmMzI+IHtcclxuICAgICAgICBsZXQgaXJyYWRpYW5jZSA9IGFtYmllbnRMaWdodENvbG9yO1xyXG4gICAgICAgIHJldHVybiBpcnJhZGlhbmNlO1xyXG4gICAgfVxyXG4gICAgZm4gZ2V0RGlzdGFuY2VBdHRlbnVhdGlvbihsaWdodERpc3RhbmNlOiBmMzIsIGN1dG9mZkRpc3RhbmNlOiBmMzIsIGRlY2F5RXhwb25lbnQ6IGYzMikgLT4gZjMyIHtcclxuICAgICAgICBpZiAoY3V0b2ZmRGlzdGFuY2UgPiAwLjAgJiYgZGVjYXlFeHBvbmVudCA+IDAuMCkge1xyXG4gICAgICAgICAgICBsZXQgeDpmMzIgPSBzYXR1cmF0ZSgtIGxpZ2h0RGlzdGFuY2UgLyBjdXRvZmZEaXN0YW5jZSArIDEuMCk7XHJcbiAgICAgICAgICAgIHJldHVybiBwb3coeCwgZGVjYXlFeHBvbmVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiAxLjA7XHJcbiAgICB9XHJcbiAgICBmbiBnZXRTcG90QXR0ZW51YXRpb24oY29uZUNvc2luZTogZjMyLCBwZW51bWJyYUNvc2luZTogZjMyLCBhbmdsZUNvc2luZTogZjMyKSAtPiBmMzIge1xyXG4gICAgICAgIHJldHVybiBzbW9vdGhzdGVwKGNvbmVDb3NpbmUsIHBlbnVtYnJhQ29zaW5lLCBhbmdsZUNvc2luZSk7XHJcbiAgICB9XHJcbiAgICBmbiBzaEdldElycmFkaWFuY2VBdCggbm9ybWFsOnZlYzM8ZjMyPiwgc2hDb2VmZmljaWVudHM6YXJyYXk8dmVjMzxmMzI+LDk+KS0+dmVjMzxmMzI+IHtcclxuICAgICAgICBsZXQgeDpmMzIgPSBub3JtYWwueDsgXHJcbiAgICAgICAgbGV0IHk6ZjMyID0gbm9ybWFsLnk7IFxyXG4gICAgICAgIGxldCB6OmYzMiA9IG5vcm1hbC56O1xyXG4gICAgICAgIHZhciByZXN1bHQ6dmVjMzxmMzI+ID0gc2hDb2VmZmljaWVudHNbIDAgXSAqIDAuODg2MjI3O1xyXG4gICAgICAgIHJlc3VsdCArPSBzaENvZWZmaWNpZW50c1sgMSBdICogMi4wICogMC41MTE2NjQgKiB5O1xyXG4gICAgICAgIHJlc3VsdCArPSBzaENvZWZmaWNpZW50c1sgMiBdICogMi4wICogMC41MTE2NjQgKiB6O1xyXG4gICAgICAgIHJlc3VsdCArPSBzaENvZWZmaWNpZW50c1sgMyBdICogMi4wICogMC41MTE2NjQgKiB4O1xyXG4gICAgICAgIHJlc3VsdCArPSBzaENvZWZmaWNpZW50c1sgNCBdICogMi4wICogMC40MjkwNDMgKiB4ICogeTtcclxuICAgICAgICByZXN1bHQgKz0gc2hDb2VmZmljaWVudHNbIDUgXSAqIDIuMCAqIDAuNDI5MDQzICogeSAqIHo7XHJcbiAgICAgICAgcmVzdWx0ICs9IHNoQ29lZmZpY2llbnRzWyA2IF0gKiAoIDAuNzQzMTI1ICogeiAqIHogLSAwLjI0NzcwOCApO1xyXG4gICAgICAgIHJlc3VsdCArPSBzaENvZWZmaWNpZW50c1sgNyBdICogMi4wICogMC40MjkwNDMgKiB4ICogejtcclxuICAgICAgICByZXN1bHQgKz0gc2hDb2VmZmljaWVudHNbIDggXSAqIDAuNDI5MDQzICogKCB4ICogeCAtIHkgKiB5ICk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuICAgIGZuIGludmVyc2VUcmFuc2Zvcm1EaXJlY3Rpb24oIGRpcjp2ZWMzPGYzMj4sIG1hdHJpeDptYXQ0eDQ8ZjMyPiApLT52ZWMzPGYzMj4ge1xyXG4gICAgICAgIHJldHVybiBub3JtYWxpemUoICggdmVjNDxmMzI+KCBkaXIsIDAuMCApICogbWF0cml4ICkueHl6ICk7XHJcbiAgICB9XHJcbiBgO1xyXG59XHJcbiIsImltcG9ydCB7IHdnc2xQYXJzZURlZmluZXMgfSBmcm9tIFwiLi4vLi4vV2dzbFByZXByb2Nlc3NvclwiO1xuZXhwb3J0IGZ1bmN0aW9uIGdldE5vcm1hbChkZWZpbmVzKSB7XG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYFxuICAgICAgZm4gZ2V0Tm9ybWFsKGlucHV0OkZyYWdJbnB1dCktPnZlYzM8ZjMyPntcbiAgICAgICAgdmFyIG5vcm1hbDp2ZWMzPGYzMj47XG4gICAgICAgICNpZiAke2RlZmluZXMuSEFTX05PUk1BTH1cbiAgICAgICAgICAgIG5vcm1hbD0gaW5wdXQubm9ybWFsO1xuICAgICAgICAjZWxzZVxuICAgICAgICAgIGxldCBwb3NfZHggPSBkcGR4KGlucHV0LndvcmxkUG9zKTtcbiAgICAgICAgICBsZXQgcG9zX2R5ID0gZHBkeShpbnB1dC53b3JsZFBvcyk7XG4gICAgICAgICAgbm9ybWFsID0gbm9ybWFsaXplKCBjcm9zcyhwb3NfZHksIHBvc19keCkgKTtcbiAgICAgICAgI2VuZGlmXG4gICAgICAgIHJldHVybiBub3JtYWwqKGYzMihpbnB1dC5mcm9udEZhY2luZykgKiAyLjAgLSAxLjApO1xuICAgICAgfVxuICAgIGA7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0Tm9ybWFsQnlOb3JtYWxUZXh0dXJlKGRlZmluZXMpIHtcblx0cmV0dXJuIHdnc2xQYXJzZURlZmluZXNgXG4gICAgICBmbiBnZXROb3JtYWxCeU5vcm1hbFRleHR1cmUoaW5wdXQ6RnJhZ0lucHV0KS0+dmVjMzxmMzI+e1xuICAgICAgICB2YXIgbjp2ZWMzPGYzMj4gPSB0ZXh0dXJlU2FtcGxlKG5vcm1hbFRleHR1cmUsbm9ybWFsU2FtcGxlciwgaW5wdXQudXYpLnJnYjtcbiAgICAgICAgbGV0IHRibjptYXQzeDM8ZjMyPiA9Z2V0VEJOKGlucHV0KTtcbiAgICAgICAgbiA9IG5vcm1hbGl6ZSh0Ym4gKiAoMi4wICogbiAtIHZlYzMoMS4wKSkpO1xuICAgICAgICBuPW4qKGYzMihpbnB1dC5mcm9udEZhY2luZykgKiAyLjAgLSAxLjApO1xuICAgICAgICByZXR1cm4gbjtcbiAgICAgIH1cbiAgICBgO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldFRCTihkZWZpbmVzKSB7XG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYFxuICAgICAgICBmbiBnZXRUQk4oaW5wdXQ6RnJhZ0lucHV0KS0+bWF0M3gzPGYzMj57XG4gICAgICAgICNpZiAke2RlZmluZXMuSEFTX1RBTkdFTlR9XG4gICAgICAgICAgICBsZXQgdGJuOm1hdDN4MzxmMzI+ID0gaW5wdXQudGJuO1xuICAgICAgICAjZWxzZVxuICAgICAgICAgICAgbGV0IG5vcm1hbDp2ZWMzPGYzMj4gPW5vcm1hbGl6ZShpbnB1dC5ub3JtYWwpO1xuICAgICAgICAgICAgbGV0IHV2OnZlYzI8ZjMyPiA9IHNlbGVjdCgtaW5wdXQudXYsaW5wdXQudXYsaW5wdXQuZnJvbnRGYWNpbmcpO1xuICAgICAgICAgICAgICAvLyByZWY6IGh0dHA6Ly93d3cudGhldGVudGhwbGFuZXQuZGUvYXJjaGl2ZXMvMTE4MFxuICAgICAgICAgICAgICAvLyBnZXQgZWRnZSB2ZWN0b3JzIG9mIHRoZSBwaXhlbCB0cmlhbmdsZVxuICAgICAgICAgICAgICBsZXQgZHAxOnZlYzM8ZjMyPiA9ICB2ZWMzPGYzMj4oZHBkeChpbnB1dC53b3JsZFBvcy54KSwgZHBkeChpbnB1dC53b3JsZFBvcy55KSwgZHBkeChpbnB1dC53b3JsZFBvcy56KSk7XG4gICAgICAgICAgICAgIGxldCBkcDI6dmVjMzxmMzI+ID0gIHZlYzM8ZjMyPihkcGR5KGlucHV0LndvcmxkUG9zLngpLCBkcGR5KGlucHV0LndvcmxkUG9zLnkpLCBkcGR5KGlucHV0LndvcmxkUG9zLnopKTtcbiAgICAgICAgICAgICAgbGV0IGR1djE6dmVjMjxmMzI+ID0gZHBkeCh1dik7XG4gICAgICAgICAgICAgIGxldCBkdXYyOnZlYzI8ZjMyPiA9IGRwZHkodXYpO1xuXG4gICAgICAgICAgICAgIC8vIHNvbHZlIHRoZSBsaW5lYXIgc3lzdGVtXG4gICAgICAgICAgICAgIGxldCBkcDJwZXJwOnZlYzM8ZjMyPiA9IGNyb3NzKGRwMiwgbm9ybWFsKTtcbiAgICAgICAgICAgICAgbGV0IGRwMXBlcnA6dmVjMzxmMzI+ID0gY3Jvc3Mobm9ybWFsLCBkcDEpO1xuICAgICAgICAgICAgICBsZXQgdGFuZ2VudDp2ZWMzPGYzMj4gPSBkcDJwZXJwICogZHV2MS54ICsgZHAxcGVycCAqIGR1djIueDtcbiAgICAgICAgICAgICAgbGV0IGJpbm9ybWFsOnZlYzM8ZjMyPiA9IGRwMnBlcnAgKiBkdXYxLnkgKyBkcDFwZXJwICogZHV2Mi55O1xuICAgICAgICAgICAgICAvLyBjb25zdHJ1Y3QgYSBzY2FsZS1pbnZhcmlhbnQgZnJhbWUgXG4gICAgICAgICAgICAgIGxldCByZXN1bHQ6ZjMyPW1heChkb3QodGFuZ2VudCwgdGFuZ2VudCksIGRvdChiaW5vcm1hbCwgYmlub3JtYWwpKTtcbiAgICAgICAgICAgICAgbGV0IGludm1heDpmMzIgPSAxLjAvc3FydChyZXN1bHQpO1xuICAgICAgICAgICAgICBsZXQgdGJuOm1hdDN4MzxmMzI+ID0gbWF0M3gzPGYzMj4odGFuZ2VudCAqIGludm1heCwgYmlub3JtYWwgKiBpbnZtYXgsIG5vcm1hbCk7XG4gICAgICAgICNlbmRpZlxuICAgICAgICByZXR1cm4gdGJuO1xuICAgICAgfVxuICBgO1xufVxuIiwiaW1wb3J0IHsgd2dzbFBhcnNlRGVmaW5lcyB9IGZyb20gXCIuLi8uLi9XZ3NsUHJlcHJvY2Vzc29yXCI7XHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGJyZGYoZGVmaW5lcykge1xyXG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYFxyXG4gICAgICAgICNpZiAke2RlZmluZXMuVVNFX1NIRUVOfVxyXG4gICAgICAgICAgICAgICAgZm4gRF9DaGFybGllKCByb3VnaG5lc3M6ZjMyLGRvdE5IOmYzMiApLT5mMzIge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBhbHBoYTpmMzIgPSBwb3cyKCByb3VnaG5lc3MgKTtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgaW52QWxwaGE6ZjMyID0gMS4wIC8gYWxwaGE7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvczJoOmYzMiA9IGRvdE5IICogZG90Tkg7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHNpbjJoOmYzMiA9IG1heCggMS4wIC0gY29zMmgsIDAuMDA3ODEyNSApO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoIDIuMCArIGludkFscGhhICkgKiBwb3coIHNpbjJoLCBpbnZBbHBoYSAqIDAuNSApIC8gKCAyLjAgKiBQSSApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZm4gVl9OZXViZWx0KCBkb3ROVjpmMzIsIGRvdE5MOmYzMiApLT5mMzIge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzYXR1cmF0ZSggMS4wIC8gKCA0LjAgKiAoIGRvdE5MICsgZG90TlYgLSBkb3ROTCAqIGRvdE5WICkgKSApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZm4gQlJERl9TaGVlbihsaWdodERpcjp2ZWMzPGYzMj4sIHZpZXdEaXI6dmVjMzxmMzI+LCBub3JtYWw6dmVjMzxmMzI+LHNoZWVuQ29sb3I6dmVjMzxmMzI+LHNoZWVuUm91Z2huZXNzOmYzMiApLT52ZWMzPGYzMj4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBoYWxmRGlyOnZlYzM8ZjMyPiA9IG5vcm1hbGl6ZSggbGlnaHREaXIgKyB2aWV3RGlyICk7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGRvdE5MOmYzMiA9IHNhdHVyYXRlKCBkb3QoIG5vcm1hbCwgbGlnaHREaXIgKSApO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBkb3ROVjpmMzIgPSBzYXR1cmF0ZSggZG90KCBub3JtYWwsIHZpZXdEaXIgKSApO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBkb3ROSDpmMzIgPSBzYXR1cmF0ZSggZG90KCBub3JtYWwsIGhhbGZEaXIgKSApO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBEOmYzMiA9IERfQ2hhcmxpZSggc2hlZW5Sb3VnaG5lc3MsIGRvdE5IICk7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IFY6ZjMyID0gVl9OZXViZWx0KCBkb3ROViwgZG90TkwgKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2hlZW5Db2xvciAqICggRCAqIFYgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAjZW5kaWZcclxuICAgICAgICBmbiBCUkRGX0xhbWJlcnQoZGlmZnVzZUNvbG9yOnZlYzM8ZjMyPiktPnZlYzM8ZjMyPiB7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gUkVDSVBST0NBTF9QSSAqIGRpZmZ1c2VDb2xvcjtcclxuXHJcbiAgICAgICAgfSAvLyB2YWxpZGF0ZWRcclxuXHJcbiAgICAgICAgZm4gRl9TY2hsaWNrKCBmMDp2ZWMzPGYzMj4sIGRvdFZIOmYzMiApLT52ZWMzPGYzMj4ge1xyXG5cclxuICAgICAgICAgICAgLy8gT3JpZ2luYWwgYXBwcm94aW1hdGlvbiBieSBDaHJpc3RvcGhlIFNjaGxpY2sgJzk0XHJcbiAgICAgICAgICAgIC8vIGZsb2F0IGZyZXNuZWwgPSBwb3coIDEuMCAtIGRvdFZILCA1LjAgKTtcclxuXHJcbiAgICAgICAgICAgIC8vIE9wdGltaXplZCB2YXJpYW50IChwcmVzZW50ZWQgYnkgRXBpYyBhdCBTSUdHUkFQSCAnMTMpXHJcbiAgICAgICAgICAgIC8vIGh0dHBzOi8vY2RuMi51bnJlYWxlbmdpbmUuY29tL1Jlc291cmNlcy9maWxlcy8yMDEzU2lnZ3JhcGhQcmVzZW50YXRpb25zTm90ZXMtMjY5MTU3MzgucGRmXHJcbiAgICAgICAgICAgbGV0IGZyZXNuZWwgPSBleHAyKCAoIC0gNS41NTQ3MyAqIGRvdFZIIC0gNi45ODMxNiApICogZG90VkggKTtcclxuICAgICAgICAgICByZXR1cm4gKCAxLjAgLSBmMCApICogZnJlc25lbCArIGYwO1xyXG5cclxuICAgICAgICB9IC8vIHZhbGlkYXRlZFxyXG5cclxuICAgICAgICBmbiBTY2hsaWNrX3RvX0YwKGY6dmVjMzxmMzI+LCBmOTA6ZjMyLCBkb3RWSDpmMzIgKS0+dmVjMzxmMzI+IHtcclxuICAgICAgICAgICAgbGV0IHg6ZjMyID0gY2xhbXAoIDEuMCAtIGRvdFZILCAwLjAsIDEuMCApO1xyXG4gICAgICAgICAgICBsZXQgeDI6ZjMyID0geCAqIHg7XHJcbiAgICAgICAgICAgIGxldCB4NTpmMzIgPSBjbGFtcCggeCAqIHgyICogeDIsIDAuMCwgMC45OTk5ICk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gKCBmIC0gdmVjMyggZjkwICkgKiB4NSApIC8gKCAxLjAgLSB4NSApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmbiBWX0dHWF9TbWl0aENvcnJlbGF0ZWQoIGFscGhhOmYzMiwgZG90Tkw6ZjMyLGRvdE5WOmYzMiApLT5mMzIge1xyXG5cclxuICAgICAgICAgICAgbGV0IGEyIDpmMzI9IHBvdzIoIGFscGhhICk7XHJcblxyXG4gICAgICAgICAgICBsZXQgZ3Y6ZjMyID0gZG90TkwgKiBzcXJ0KCBhMiArICggMS4wIC0gYTIgKSAqIHBvdzIoIGRvdE5WICkgKTtcclxuICAgICAgICAgICAgbGV0IGdsOmYzMiA9IGRvdE5WICogc3FydCggYTIgKyAoIDEuMCAtIGEyICkgKiBwb3cyKCBkb3ROTCApICk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gMC41IC8gbWF4KChndiArIGdsKSwgMC4wMDAwMDAwMDEgKTtcclxuXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZuIERfR0dYKCBhbHBoYTpmMzIsIGRvdE5IOmYzMiApLT5mMzIge1xyXG5cclxuICAgICAgICAgICAgbGV0IGEyOmYzMiA9IHBvdzIoIGFscGhhICk7XHJcblxyXG4gICAgICAgICAgICBsZXQgZGVub206ZjMyID0gcG93MiggZG90TkggKSAqICggYTIgLSAxLjAgKSArIDEuMDsgLy8gYXZvaWQgYWxwaGEgPSAwIHdpdGggZG90TkggPSAxXHJcblxyXG4gICAgICAgICAgICByZXR1cm4gUkVDSVBST0NBTF9QSSAqIGEyIC8gcG93MiggZGVub20gKTtcclxuXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZuIEJSREZfR0dYKCBsaWdodERpcjp2ZWMzPGYzMj4sIHZpZXdEaXI6dmVjMzxmMzI+LCBub3JtYWw6dmVjMzxmMzI+LCBmMDp2ZWMzPGYzMj4sICByb3VnaG5lc3M6ZjMyICktPnZlYzM8ZjMyPiB7XHJcblxyXG4gICAgICAgICAgICBsZXQgYWxwaGE6ZjMyID0gcG93Miggcm91Z2huZXNzICk7IC8vIFVFNCdzIHJvdWdobmVzc1xyXG5cclxuICAgICAgICAgICAgbGV0IGhhbGZEaXIgPSBub3JtYWxpemUoIGxpZ2h0RGlyICsgdmlld0RpciApO1xyXG5cclxuICAgICAgICAgICAgbGV0IGRvdE5MOmYzMiA9IHNhdHVyYXRlKCBkb3QoIG5vcm1hbCwgbGlnaHREaXIgKSApO1xyXG4gICAgICAgICAgICBsZXQgZG90TlY6ZjMyID0gc2F0dXJhdGUoIGRvdCggbm9ybWFsLCB2aWV3RGlyICkgKTtcclxuICAgICAgICAgICAgbGV0IGRvdE5IOmYzMiA9IHNhdHVyYXRlKCBkb3QoIG5vcm1hbCwgaGFsZkRpciApICk7XHJcbiAgICAgICAgICAgIGxldCBkb3RWSDpmMzIgPSBzYXR1cmF0ZSggZG90KCBsaWdodERpciwgaGFsZkRpciApICk7XHJcblxyXG4gICAgICAgICAgICBsZXQgRiA9IEZfU2NobGljayggZjAsICBkb3RWSCApO1xyXG5cclxuICAgICAgICAgICAgbGV0IFYgPSBWX0dHWF9TbWl0aENvcnJlbGF0ZWQoIGFscGhhLCBkb3ROTCwgZG90TlYgKTtcclxuXHJcbiAgICAgICAgICAgIGxldCBEID0gRF9HR1goIGFscGhhLCBkb3ROSCApO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIEYgKiAoIFYgKiBEICk7XHJcblxyXG4gICAgICAgIH1cclxuICAgICAgICBmbiBkaXJlY3RfUGh5c2ljYWwoIGRpcmVjdExpZ2h0OkluY2lkZW50TGlnaHQsIGdlb21ldHJ5Okdlb21ldHJ5LG1hdGVyaWFsOlBoeXNpY2FsTWF0ZXJpYWwpLT5SZWZsZWN0ZWRMaWdodCB7XHJcbiAgICAgICAgICAgIHZhciByZWZsZWN0ZWRMaWdodDpSZWZsZWN0ZWRMaWdodDtcclxuICAgICAgICAgICAgbGV0IGRvdE5MOmYzMiA9IHNhdHVyYXRlKGRvdCggZ2VvbWV0cnkubm9ybWFsLGdlb21ldHJ5LnZpZXdEaXIpKTtcclxuICAgICAgICAgICAgbGV0IGlycmFkaWFuY2U6dmVjMzxmMzI+ID0gZG90TkwgKiBkaXJlY3RMaWdodC5jb2xvciozLjE0MTU5MjY7XHJcbiAgICAgICAgICAgIHJlZmxlY3RlZExpZ2h0LmRpcmVjdFNwZWN1bGFyID0gaXJyYWRpYW5jZSAqIEJSREZfR0dYKCBkaXJlY3RMaWdodC5kaXJlY3Rpb24sIGdlb21ldHJ5LnZpZXdEaXIsIGdlb21ldHJ5Lm5vcm1hbCwgbWF0ZXJpYWwuc3BlY3VsYXJDb2xvciwgbWF0ZXJpYWwucm91Z2huZXNzICk7XHJcbiAgICAgICAgICAgIHJlZmxlY3RlZExpZ2h0LmRpcmVjdERpZmZ1c2UgPSBpcnJhZGlhbmNlICogQlJERl9MYW1iZXJ0KCBtYXRlcmlhbC5kaWZmdXNlQ29sb3IgKTtcclxuICAgICAgICAgICAgcmV0dXJuIHJlZmxlY3RlZExpZ2h0O1xyXG4gICAgICAgIH1cclxuICBgO1xyXG59XHJcbiIsImltcG9ydCB7IHdnc2xQYXJzZURlZmluZXMgfSBmcm9tIFwiLi4vLi4vV2dzbFByZXByb2Nlc3NvclwiO1xyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpYmwoZGVmaW5lcykge1xyXG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYFxyXG4gIGZuIGdldExpZ2h0UHJvYmVSYWRpYW5jZSggdmlld0Rpcjp2ZWMzPGYzMj4sbm9ybWFsOnZlYzM8ZjMyPiwgcm91Z2huZXNzOmYzMiApLT52ZWMzPGYzMj57XHJcbiAgICB2YXIgcmVmbGVjdFZlYzp2ZWMzPGYzMj4gPSByZWZsZWN0KCAtdmlld0Rpciwgbm9ybWFsICk7XHJcbiAgICByZWZsZWN0VmVjLnggPSAtcmVmbGVjdFZlYy54OyAvLyBUZXh0dXJlQ3ViZSBpcyBsZWZ0LWhhbmQsc28geCBuZWVkIGludmVyc2VcclxuICAgIGxldCBtaXBDb3VudDpmMzIgPSAxMC4wOyAvLyByZXNvbHV0aW9uIG9mIDI1NngyNTZcclxuICAgIGxldCBsb2Q6ZjMyID0gcm91Z2huZXNzICogbWlwQ291bnQ7XHJcbiAgICBsZXQgc3BlY3VsYXJMaWdodDp2ZWMzPGYzMj4gPSB0ZXh0dXJlU2FtcGxlTGV2ZWwoc3BlY3VsYXJFbnZUZXh0dXJlLHNwZWN1bGFyRW52U2FtcGxlciwgcmVmbGVjdFZlYywgbG9kKS5yZ2I7XHJcbiAgICByZXR1cm4gc3BlY3VsYXJMaWdodDtcclxuICB9XHJcbiAgZm4gZ2V0TGlnaHRQcm9iZUlycmFkaWFuY2UoIGxpZ2h0UHJvYmU6YXJyYXk8dmVjMzxmMzI+LDk+LCBub3JtYWw6dmVjMzxmMzI+KS0+dmVjMzxmMzI+IHtcclxuICAgIHZhciB3b3JsZE5vcm1hbDp2ZWMzPGYzMj4gPSBub3JtYWw7XHJcbiAgICB3b3JsZE5vcm1hbC54ID0gLW5vcm1hbC54O1xyXG4gICAgdmFyIGlycmFkaWFuY2U6dmVjMzxmMzI+ID0gbGlnaHRQcm9iZVswXTtcclxuICAgIGlycmFkaWFuY2UrPWxpZ2h0UHJvYmVbMV0gKiAobm9ybWFsLnkpO1xyXG4gICAgaXJyYWRpYW5jZSs9bGlnaHRQcm9iZVsyXSAqIChub3JtYWwueikgO1xyXG4gICAgaXJyYWRpYW5jZSs9bGlnaHRQcm9iZVszXSAqIChub3JtYWwueCkgO1xyXG5cclxuICAgIGlycmFkaWFuY2UrPWxpZ2h0UHJvYmVbNF0gKiAobm9ybWFsLnkgKiBub3JtYWwueCkgO1xyXG4gICAgaXJyYWRpYW5jZSs9bGlnaHRQcm9iZVs1XSAqIChub3JtYWwueSAqIG5vcm1hbC56KSA7XHJcbiAgICBpcnJhZGlhbmNlKz1saWdodFByb2JlWzZdICogKDMuMCAqIG5vcm1hbC56ICogbm9ybWFsLnogLSAxLjApO1xyXG4gICAgaXJyYWRpYW5jZSs9bGlnaHRQcm9iZVs3XSAqIChub3JtYWwueiAqIG5vcm1hbC54KSA7XHJcbiAgICBpcnJhZGlhbmNlKz1saWdodFByb2JlWzhdICogKG5vcm1hbC54ICogbm9ybWFsLnggLSBub3JtYWwueSAqIG5vcm1hbC55KTtcclxuXHJcbiAgICByZXR1cm4gbWF4KGlycmFkaWFuY2UsIHZlYzM8ZjMyPigwLjAsMC4wLDAuMCkpO1xyXG4gIH1cclxuICBmbiBERkdBcHByb3goIHNwZWN1bGFyQ29sb3I6dmVjMzxmMzI+LCByb3VnaG5lc3M6ZjMyLGRvdE5WOmYzMiApLT52ZWMzPGYzMj4ge1xyXG4gICAgY29uc3QgYzA6dmVjNDxmMzI+ID0gdmVjNDxmMzI+KCAtIDEsIC0gMC4wMjc1LCAtIDAuNTcyLCAwLjAyMiApO1xyXG4gICAgbGV0IGMxOnZlYzQ8ZjMyPiA9IHZlYzQ8ZjMyPiggMSwgMC4wNDI1LCAxLjA0LCAtIDAuMDQgKTtcclxuICAgIGxldCByOnZlYzQ8ZjMyPiA9IHJvdWdobmVzcyAqIGMwICsgYzE7XHJcbiAgICBsZXQgYTAwNDpmMzIgPSBtaW4oIHIueCAqIHIueCwgZXhwMiggLSA5LjI4ICogZG90TlYgKSApICogci54ICsgci55O1xyXG4gICAgbGV0IGZhYjp2ZWMyPGYzMj4gPSB2ZWMyPGYzMj4oIC0gMS4wNCwgMS4wNCApICogYTAwNCArIHIuenc7XHJcbiAgICByZXR1cm4gc3BlY3VsYXJDb2xvciAqIGZhYi54ICsgZmFiLnk7XHJcbiAgfVxyXG4gIC8v6Ze05o6l5YWJ54WnXHJcbiAgZm4gaW5kaXJlY3REaWZmdXNlX1BoeXNpY2FsKGdlb21ldHJ5Okdlb21ldHJ5LCBtYXRlcmlhbDpQaHlzaWNhbE1hdGVyaWFsICktPlJlZmxlY3RlZExpZ2h0IHtcclxuICAgICAgdmFyIHJlZmxlY3RlZExpZ2h0OlJlZmxlY3RlZExpZ2h0O1xyXG4gICAgICB2YXIgaXJyYWRpYW5jZTp2ZWMzPGYzMj4gPSBsaWdodFVuaWZvcm1zLmFtYmllbnQueHl6KmxpZ2h0VW5pZm9ybXMuYW1iaWVudC53O1xyXG4gICAgICBpcnJhZGlhbmNlICo9IFBJO1xyXG4gICAgICByZWZsZWN0ZWRMaWdodC5pbmRpcmVjdERpZmZ1c2UgKz0gaXJyYWRpYW5jZSAqIEJSREZfTGFtYmVydCggbWF0ZXJpYWwuZGlmZnVzZUNvbG9yICk7XHJcbiAgICAgIHJldHVybiByZWZsZWN0ZWRMaWdodDtcclxuICB9XHJcbiAgLy/pl7TmjqXpq5jlhYlcclxuICBmbiBpbmRpcmVjdFNwZWN1bGFyX1BoeXNpY2FsKGdlb21ldHJ5Okdlb21ldHJ5LCBtYXRlcmlhbDpQaHlzaWNhbE1hdGVyaWFsKS0+UmVmbGVjdGVkTGlnaHQge1xyXG4gICAgICB2YXIgcmVmbGVjdGVkTGlnaHQ6UmVmbGVjdGVkTGlnaHQ7XHJcbiAgICAgIC8vIElCTCBzcGVjdWxhclxyXG4gICAgICBsZXQgcmFkaWFuY2U6dmVjMzxmMzI+ID0gZ2V0TGlnaHRQcm9iZVJhZGlhbmNlKGdlb21ldHJ5LnZpZXdEaXIsIGdlb21ldHJ5Lm5vcm1hbCwgbWF0ZXJpYWwucm91Z2huZXNzKTtcclxuICAgICAgbGV0IHJhZGlhbmNlQXR0ZW51YXRpb246ZjMyID0gMS4wO1xyXG4gICAgICByZWZsZWN0ZWRMaWdodC5pbmRpcmVjdFNwZWN1bGFyICs9IHJhZGlhbmNlQXR0ZW51YXRpb24gKiByYWRpYW5jZSAqIERGR0FwcHJveChtYXRlcmlhbC5zcGVjdWxhckNvbG9yLCBtYXRlcmlhbC5yb3VnaG5lc3MsIGdlb21ldHJ5LmRvdE5WICk7XHJcbiAgICAgIHJldHVybiByZWZsZWN0ZWRMaWdodDtcclxuICAgIH1cclxuICBgO1xyXG59XHJcbiIsImltcG9ydCB7IHdnc2xQYXJzZURlZmluZXMgfSBmcm9tIFwiLi4vLi4vV2dzbFByZXByb2Nlc3NvclwiO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcGJyRnVuY3Rpb24oZGVmaW5lcykge1xyXG5cdHJldHVybiB3Z3NsUGFyc2VEZWZpbmVzYFxyXG5cclxuICAgICNpZiAke2RlZmluZXMuRElUSEVSSU5HfVxyXG4gICAgICAgIGZuIGRpdGhlcmluZyhjb2xvcjp2ZWMzPGYzMj4gKS0+dmVjMzxmMzI+IHtcclxuICAgICAgICAgICAgbGV0IGdyaWRfcG9zaXRpb246ZjMyID0gcmFuZCggZ2xfRnJhZ0Nvb3JkLnh5ICk7XHJcbiAgICAgICAgICAgIGxldCBkaXRoZXJfc2hpZnRfUkdCOnZlYzM8ZjMyPiA9IHZlYzM8ZjMyPiggMC4yNSAvIDI1NS4wLCAtMC4yNSAvIDI1NS4wLCAwLjI1IC8gMjU1LjAgKTtcclxuICAgICAgICAgICAgZGl0aGVyX3NoaWZ0X1JHQiA9IG1peCggMi4wICogZGl0aGVyX3NoaWZ0X1JHQiwgLTIuMCAqIGRpdGhlcl9zaGlmdF9SR0IsIGdyaWRfcG9zaXRpb24gKTtcclxuICAgICAgICAgICAgcmV0dXJuIGNvbG9yICsgZGl0aGVyX3NoaWZ0X1JHQjtcclxuICAgICAgICB9XHJcbiAgICAjZW5kaWZcclxuXHJcbiAgICAjaWYgJHtkZWZpbmVzLlVTRV9JUklERVNDRU5DRX1cclxuICAgICAgICBmbiBCUkRGX0dHWF9JcmlkZXNjZW5jZSggbGlnaHREaXI6dmVjMzxmMzI+LCB2aWV3RGlyOnZlYzM8ZjMyPixub3JtYWw6dmVjMzxmMzI+LCBmMDp2ZWMzPGYzMj4sIGY5MDpmMzIsaXJpZGVzY2VuY2U6ZjMyLCBpcmlkZXNjZW5jZUZyZXNuZWw6dmVjMzxmMzI+LHJvdWdobmVzczpmMzIgKS0+dmVjMzxmMzI+IHtcclxuICAgICAgICAgICAgbGV0IGFscGhhOmYzMiA9IHBvdzIoIHJvdWdobmVzcyApO1xyXG4gICAgICAgICAgICBsZXQgaGFsZkRpcjp2ZWMzPGYzMj4gPSBub3JtYWxpemUoIGxpZ2h0RGlyICsgdmlld0RpciApO1xyXG4gICAgICAgICAgICBsZXQgZG90Tkw6ZjMyID0gc2F0dXJhdGUoIGRvdCggbm9ybWFsLCBsaWdodERpciApICk7XHJcbiAgICAgICAgICAgIGxldCBkb3ROVjpmMzIgPSBzYXR1cmF0ZSggZG90KCBub3JtYWwsIHZpZXdEaXIgKSApO1xyXG4gICAgICAgICAgICBsZXQgZG90Tkg6ZjMyID0gc2F0dXJhdGUoIGRvdCggbm9ybWFsLCBoYWxmRGlyICkgKTtcclxuICAgICAgICAgICAgbGV0IGRvdFZIOmYzMiA9IHNhdHVyYXRlKCBkb3QoIHZpZXdEaXIsIGhhbGZEaXIgKSApO1xyXG4gICAgICAgICAgICBsZXQgRjp2ZWMzPGYzMj4gPSBtaXgoIEZfU2NobGljayggZjAsIGY5MCwgZG90VkggKSwgaXJpZGVzY2VuY2VGcmVzbmVsLCBpcmlkZXNjZW5jZSApO1xyXG4gICAgICAgICAgICBsZXQgVjpmMzIgPSBWX0dHWF9TbWl0aENvcnJlbGF0ZWQoIGFscGhhLCBkb3ROTCwgZG90TlYgKTtcclxuICAgICAgICAgICAgbGV0IEQ6ZjMyID0gRF9HR1goIGFscGhhLCBkb3ROSCApO1xyXG4gICAgICAgICAgICByZXR1cm4gRiAqICggViAqIEQgKTtcclxuICAgICAgICB9XHJcbiAgICAjZW5kaWZcclxuXHJcbiAgICAjaWYgJHtkZWZpbmVzLlVTRV9TSEVFTn1cclxuICAgICAgICBmbiBEX0NoYXJsaWUoIHJvdWdobmVzczpmMzIsZG90Tkg6ZjMyICktPmYzMiB7XHJcbiAgICAgICAgICAgIGxldCBhbHBoYTpmMzIgPSBwb3cyKCByb3VnaG5lc3MgKTtcclxuICAgICAgICAgICAgbGV0IGludkFscGhhOmYzMiA9IDEuMCAvIGFscGhhO1xyXG4gICAgICAgICAgICBsZXQgY29zMmg6ZjMyID0gZG90TkggKiBkb3ROSDtcclxuICAgICAgICAgICAgbGV0IHNpbjJoOmYzMiA9IG1heCggMS4wIC0gY29zMmgsIDAuMDA3ODEyNSApO1xyXG4gICAgICAgICAgICByZXR1cm4gKCAyLjAgKyBpbnZBbHBoYSApICogcG93KCBzaW4yaCwgaW52QWxwaGEgKiAwLjUgKSAvICggMi4wICogUEkgKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm4gVl9OZXViZWx0KCBkb3ROVjpmMzIsIGRvdE5MOmYzMiApLT5mMzIge1xyXG4gICAgICAgICAgICByZXR1cm4gc2F0dXJhdGUoIDEuMCAvICggNC4wICogKCBkb3ROTCArIGRvdE5WIC0gZG90TkwgKiBkb3ROViApICkgKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm4gQlJERl9TaGVlbihsaWdodERpcjp2ZWMzPGYzMj4sIHZpZXdEaXI6dmVjMzxmMzI+LCBub3JtYWw6dmVjMzxmMzI+LHNoZWVuQ29sb3I6dmVjMzxmMzI+LHNoZWVuUm91Z2huZXNzOmYzMiApLT52ZWMzPGYzMj4ge1xyXG4gICAgICAgICAgICBsZXQgaGFsZkRpcjp2ZWMzPGYzMj4gPSBub3JtYWxpemUoIGxpZ2h0RGlyICsgdmlld0RpciApO1xyXG4gICAgICAgICAgICBsZXQgZG90Tkw6ZjMyID0gc2F0dXJhdGUoIGRvdCggbm9ybWFsLCBsaWdodERpciApICk7XHJcbiAgICAgICAgICAgIGxldCBkb3ROVjpmMzIgPSBzYXR1cmF0ZSggZG90KCBub3JtYWwsIHZpZXdEaXIgKSApO1xyXG4gICAgICAgICAgICBsZXQgZG90Tkg6ZjMyID0gc2F0dXJhdGUoIGRvdCggbm9ybWFsLCBoYWxmRGlyICkgKTtcclxuICAgICAgICAgICAgbGV0IEQ6ZjMyID0gRF9DaGFybGllKCBzaGVlblJvdWdobmVzcywgZG90TkggKTtcclxuICAgICAgICAgICAgbGV0IFY6ZjMyID0gVl9OZXViZWx0KCBkb3ROViwgZG90TkwgKTtcclxuICAgICAgICAgICAgcmV0dXJuIHNoZWVuQ29sb3IgKiAoIEQgKiBWICk7XHJcbiAgICAgICAgfVxyXG4gICAgI2VuZGlmXHJcblxyXG4gICAgI2lmICR7ZGVmaW5lcy5VU0VfSVJJREVTQ0VOQ0V9XHJcbiAgICAgICAgbGV0IFhZWl9UT19SRUM3MDk6IG1hdDN4MzxmMzI+ID0gbWF0M3gzPGYzMj4oXHJcbiAgICAgICAgMy4yNDA0NTQyLCAtMC45NjkyNjYwLCAwLjA1NTY0MzQsIC0xLjUzNzEzODUsIDEuODc2MDEwOCwgLTAuMjA0MDI1OSwgLTAuNDk4NTMxNCwgMC4wNDE1NTYwLCAxLjA1NzIyNTJcclxuICAgICAgICApO1xyXG4gICAgICAgIGZuIEZyZXNuZWwwVG9Jb3IoIGZyZXNuZWwwOnZlYzM8ZjMyPiApLT52ZWMzPGYzMj4ge1xyXG4gICAgICAgICAgICBsZXQgc3FydEYwOnZlYzM8ZjMyPiA9IHNxcnQoIGZyZXNuZWwwICk7XHJcbiAgICAgICAgICAgIHJldHVybiAoIHZlYzM8ZjMyPiggMS4wICkgKyBzcXJ0RjAgKSAvICggdmVjMzxmMzI+KCAxLjAgKSAtIHNxcnRGMCApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmbiBJb3JUb0ZyZXNuZWwwKHRyYW5zbWl0dGVkSW9yOnZlYzM8ZjMyPixpbmNpZGVudElvcjpmMzIgKS0+dmVjMzxmMzI+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHBvdzJWZWN0b3IoICggdHJhbnNtaXR0ZWRJb3IgLSB2ZWMzPGYzMj4oIGluY2lkZW50SW9yICkgKSAvICggdHJhbnNtaXR0ZWRJb3IgKyB2ZWMzPGYzMj4oIGluY2lkZW50SW9yICkgKSApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmbiBJb3JUb0ZyZXNuZWwwKHRyYW5zbWl0dGVkSW9yOmYzMiwgaW5jaWRlbnRJb3I6ZjMyICktPmYzMiB7XHJcbiAgICAgICAgICAgIHJldHVybiBwb3cyVmVjdG9yKCAoIHRyYW5zbWl0dGVkSW9yIC0gaW5jaWRlbnRJb3IgKSAvICggdHJhbnNtaXR0ZWRJb3IgKyBpbmNpZGVudElvciApKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm4gZXZhbFNlbnNpdGl2aXR5KE9QRDpmMzIsc2hpZnQ6dmVjMzxmMzI+ICktPnZlYzM8ZjMyPiB7XHJcbiAgICAgICAgICAgIGxldCBwaGFzZTpmMzIgPSAyLjAgKiBQSSAqIE9QRCAqIDEuMGUtOTtcclxuICAgICAgICAgICAgbGV0IHZhbDp2ZWMzPGYzMj4gPSB2ZWMzPGYzMj4oIDUuNDg1NmUtMTMsIDQuNDIwMWUtMTMsIDUuMjQ4MWUtMTMgKTtcclxuICAgICAgICAgICAgbGV0IHBvczp2ZWMzPGYzMj4gPSB2ZWMzPGYzMj4oIDEuNjgxMGUrMDYsIDEuNzk1M2UrMDYsIDIuMjA4NGUrMDYgKTtcclxuICAgICAgICAgICAgbGV0IHZhcnQ6dmVjMzxmMzI+ID0gdmVjMzxmMzI+KCA0LjMyNzhlKzA5LCA5LjMwNDZlKzA5LCA2LjYxMjFlKzA5ICk7XHJcbiAgICAgICAgICAgIGxldCB4eXo6dmVjMzxmMzI+ID0gdmFsICogc3FydCggMi4wICogUEkgKiB2YXJ0ICkgKiBjb3MoIHBvcyAqIHBoYXNlICsgc2hpZnQgKSAqIGV4cCggLSBwb3cyKCBwaGFzZSApICogdmFydCApO1xyXG4gICAgICAgICAgICB4eXoueCArPSA5Ljc0NzBlLTE0ICogc3FydCggMi4wICogUEkgKiA0LjUyODJlKzA5ICkgKiBjb3MoIDIuMjM5OWUrMDYgKiBwaGFzZSArIHNoaWZ0WyAwIF0gKSAqIGV4cCggLSA0LjUyODJlKzA5ICogcG93MiggcGhhc2UgKSApO1xyXG4gICAgICAgICAgICB4eXogLz0gMS4wNjg1ZS03O1xyXG4gICAgICAgICAgICBsZXQgcmdiOnZlYzM8ZjMyPiA9IFhZWl9UT19SRUM3MDkgKiB4eXo7XHJcbiAgICAgICAgICAgIHJldHVybiByZ2I7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZuIGV2YWxJcmlkZXNjZW5jZShvdXRzaWRlSU9SOmYzMiwgZXRhMjpmMzIsY29zVGhldGExOmYzMix0aGluRmlsbVRoaWNrbmVzczpmMzIsYmFzZUYwOnZlYzM8ZjMyPiApLT52ZWMzPGYzMj4ge1xyXG4gICAgICAgICAgICB2YXIgSTp2ZWMzPGYzMj47XHJcbiAgICAgICAgICAgIGxldCBpcmlkZXNjZW5jZUlPUjpmMzIgPSBtaXgoIG91dHNpZGVJT1IsIGV0YTIsIHNtb290aHN0ZXAoIDAuMCwgMC4wMywgdGhpbkZpbG1UaGlja25lc3MgKSApO1xyXG4gICAgICAgICAgICBsZXQgc2luVGhldGEyU3E6ZjMyID0gcG93Miggb3V0c2lkZUlPUiAvIGlyaWRlc2NlbmNlSU9SICkgKiAoIDEuMCAtIHBvdzIoIGNvc1RoZXRhMSApICk7XHJcbiAgICAgICAgICAgIGxldCBjb3NUaGV0YTJTcTpmMzIgPSAxLjAgLSBzaW5UaGV0YTJTcTtcclxuICAgICAgICAgICAgaWYgKCBjb3NUaGV0YTJTcSA8IDAuMCApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB2ZWMzPGYzMj4oIDEuMCApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGxldCBjb3NUaGV0YTI6ZjMyID0gc3FydCggY29zVGhldGEyU3EgKTtcclxuICAgICAgICAgICAgbGV0IFIwOmYzMiA9IElvclRvRnJlc25lbDAoIGlyaWRlc2NlbmNlSU9SLCBvdXRzaWRlSU9SICk7XHJcbiAgICAgICAgICAgIGxldCBSMTI6ZjMyID0gRl9TY2hsaWNrKCBSMCwgMS4wLCBjb3NUaGV0YTEgKTtcclxuICAgICAgICAgICAgbGV0IFIyMTpmMzIgPSBSMTI7XHJcbiAgICAgICAgICAgIGxldCBUMTIxOmYzMiA9IDEuMCAtIFIxMjtcclxuICAgICAgICAgICAgbGV0IHBoaTEyOmYzMiA9IDAuMDtcclxuICAgICAgICAgICAgaWYgKCBpcmlkZXNjZW5jZUlPUiA8IG91dHNpZGVJT1IgKSBwaGkxMiA9IFBJO1xyXG4gICAgICAgICAgICBsZXQgcGhpMjE6ZjMyID0gUEkgLSBwaGkxMjtcclxuICAgICAgICAgICAgbGV0IGJhc2VJT1I6dmVjMzxmMzI+ID0gRnJlc25lbDBUb0lvciggY2xhbXAoIGJhc2VGMCwgMC4wLCAwLjk5OTkgKSApO1xyXG4gICAgICAgICAgICBsZXQgUjE6dmVjMzxmMzI+ID0gSW9yVG9GcmVzbmVsMCggYmFzZUlPUiwgaXJpZGVzY2VuY2VJT1IgKTtcclxuICAgICAgICAgICAgbGV0IFIyMzp2ZWMzPGYzMj4gPSBGX1NjaGxpY2soIFIxLCAxLjAsIGNvc1RoZXRhMiApO1xyXG4gICAgICAgICAgICBsZXQgcGhpMjM6dmVjMzxmMzI+ID0gdmVjMzxmMzI+KCAwLjAgKTtcclxuICAgICAgICAgICAgaWYgKCBiYXNlSU9SWyAwIF0gPCBpcmlkZXNjZW5jZUlPUiApIHBoaTIzWyAwIF0gPSBQSTtcclxuICAgICAgICAgICAgaWYgKCBiYXNlSU9SWyAxIF0gPCBpcmlkZXNjZW5jZUlPUiApIHBoaTIzWyAxIF0gPSBQSTtcclxuICAgICAgICAgICAgaWYgKCBiYXNlSU9SWyAyIF0gPCBpcmlkZXNjZW5jZUlPUiApIHBoaTIzWyAyIF0gPSBQSTtcclxuICAgICAgICAgICAgbGV0IE9QRDpmMzIgPSAyLjAgKiBpcmlkZXNjZW5jZUlPUiAqIHRoaW5GaWxtVGhpY2tuZXNzICogY29zVGhldGEyO1xyXG4gICAgICAgICAgICBsZXQgcGhpOnZlYzM8ZjMyPiA9IHZlYzM8ZjMyPiggcGhpMjEgKSArIHBoaTIzO1xyXG4gICAgICAgICAgICBsZXQgUjEyMzp2ZWMzPGYzMj4gPSBjbGFtcCggUjEyICogUjIzLCAxZS01LCAwLjk5OTkgKTtcclxuICAgICAgICAgICAgbGV0IHIxMjM6dmVjMzxmMzI+ID0gc3FydCggUjEyMyApO1xyXG4gICAgICAgICAgICBsZXQgUnM6dmVjMzxmMzI+ID0gcG93MiggVDEyMSApICogUjIzIC8gKCB2ZWMzPGYzMj4oIDEuMCApIC0gUjEyMyApO1xyXG4gICAgICAgICAgICBsZXQgQzA6dmVjMzxmMzI+ID0gUjEyICsgUnM7XHJcbiAgICAgICAgICAgIEkgPSBDMDtcclxuICAgICAgICAgICAgbGV0IENtOnZlYzM8ZjMyPiA9IFJzIC0gVDEyMTtcclxuICAgICAgICAgICAgZm9yICggbGV0IG0gOiB1MzIgPSAxO20gPD0gMjsgKysgbSApIHtcclxuICAgICAgICAgICAgICAgIENtICo9IHIxMjM7XHJcbiAgICAgICAgICAgICAgICBTbTp2ZWMzPGYzMj4gPSAyLjAgKiBldmFsU2Vuc2l0aXZpdHkoIGYzMiggbSApICogT1BELCBmMzIoIG0gKSAqIHBoaSApO1xyXG4gICAgICAgICAgICAgICAgSSArPSBDbSAqIFNtO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBtYXgoIEksIHZlYzM8ZjMyPiggMC4wICkgKTtcclxuICAgICAgICB9XHJcbiAgICAjZW5kaWZcclxuICAgIGNvbnN0IGNsZWFyY29hdFNwZWN1bGFyOnZlYzM8ZjMyPiA9IHZlYzM8ZjMyPiggMC4wICk7XHJcbiAgICBjb25zdCBzaGVlblNwZWN1bGFyOnZlYzM8ZjMyPiA9IHZlYzM8ZjMyPiggMC4wICk7XHJcblxyXG4gICAgZm4gSUJMU2hlZW5CUkRGKCBub3JtYWw6dmVjMzxmMzI+LCB2aWV3RGlyOnZlYzM8ZjMyPiwgcm91Z2huZXNzOmYzMiApLT5mMzIge1xyXG4gICAgICAgIGxldCBkb3ROVjpmMzIgPSBzYXR1cmF0ZSggZG90KCBub3JtYWwsIHZpZXdEaXIgKSApO1xyXG4gICAgICAgIGxldCByMjpmMzIgPSByb3VnaG5lc3MgKiByb3VnaG5lc3M7XHJcbiAgICAgICAgbGV0IGE6ZjMyID1zZWxlY3QoLTguNDggKiByMiArIDE0LjMgKiByb3VnaG5lc3MgLSA5Ljk1LC0zMzkuMiAqIHIyICsgMTYxLjQgKiByb3VnaG5lc3MgLSAyNS45LHJvdWdobmVzcyA8IDAuMjUpO1xyXG4gICAgICAgIC8vbGV0IGE6ZjMyID0gcm91Z2huZXNzIDwgMC4yNSA/IC0zMzkuMiAqIHIyICsgMTYxLjQgKiByb3VnaG5lc3MgLSAyNS45IDogLTguNDggKiByMiArIDE0LjMgKiByb3VnaG5lc3MgLSA5Ljk1O1xyXG4gICAgICAgIGxldCBiOmYzMj1zZWxlY3QoMS45NyAqIHIyIC0gMy4yNyAqIHJvdWdobmVzcyArIDAuNzIsNDQuMCAqIHIyIC0gMjMuNyAqIHJvdWdobmVzcyArIDMuMjYsIHJvdWdobmVzcyA8IDAuMjUpO1xyXG4gICAgICAgIC8vbGV0IGI6ZjMyID0gcm91Z2huZXNzIDwgMC4yNSA/IDQ0LjAgKiByMiAtIDIzLjcgKiByb3VnaG5lc3MgKyAzLjI2IDogMS45NyAqIHIyIC0gMy4yNyAqIHJvdWdobmVzcyArIDAuNzI7XHJcbiAgICAgICAgLy9sZXQgREc6ZjMyID0gZXhwKCBhICogZG90TlYgKyBiICkgKyAoIHJvdWdobmVzcyA8IDAuMjUgPyAwLjAgOiAwLjEgKiAoIHJvdWdobmVzcyAtIDAuMjUgKSApO1xyXG4gICAgICAgIGxldCBERzpmMzIgPSBleHAoIGEgKiBkb3ROViArIGIgKSArIHNlbGVjdCgwLjEgKiAoIHJvdWdobmVzcyAtIDAuMjUgKSwwLjAscm91Z2huZXNzIDwgMC4yNSk7XHJcbiAgICAgICAgcmV0dXJuIHNhdHVyYXRlKCBERyAqIFJFQ0lQUk9DQUxfUEkgKTtcclxuICAgIH1cclxuICAgIGZuIERGR0FwcHJveCggc3BlY3VsYXJDb2xvcjp2ZWMzPGYzMj4sIHJvdWdobmVzczpmMzIsZG90TlY6ZjMyICktPnZlYzM8ZjMyPiB7XHJcbiAgICAgICAgY29uc3QgYzA6dmVjNDxmMzI+ID0gdmVjNDxmMzI+KCAtIDEsIC0gMC4wMjc1LCAtIDAuNTcyLCAwLjAyMiApO1xyXG4gICAgICAgIGxldCBjMTp2ZWM0PGYzMj4gPSB2ZWM0PGYzMj4oIDEsIDAuMDQyNSwgMS4wNCwgLSAwLjA0ICk7XHJcbiAgICAgICAgbGV0IHI6dmVjNDxmMzI+ID0gcm91Z2huZXNzICogYzAgKyBjMTtcclxuICAgICAgICBsZXQgYTAwNDpmMzIgPSBtaW4oIHIueCAqIHIueCwgZXhwMiggLSA5LjI4ICogZG90TlYgKSApICogci54ICsgci55O1xyXG4gICAgICAgIGxldCBmYWI6dmVjMjxmMzI+ID0gdmVjMjxmMzI+KCAtIDEuMDQsIDEuMDQgKSAqIGEwMDQgKyByLnp3O1xyXG4gICAgICAgIHJldHVybiBzcGVjdWxhckNvbG9yICogZmFiLnggKyBmYWIueTtcclxuICAgIH1cclxuICAgIGZuIEVudmlyb25tZW50QlJERiggbm9ybWFsOnZlYzM8ZjMyPix2aWV3RGlyOnZlYzM8ZjMyPixzcGVjdWxhckNvbG9yOnZlYzM8ZjMyPiwgc3BlY3VsYXJGOTA6ZjMyLHJvdWdobmVzczpmMzIgKS0+dmVjMzxmMzI+IHtcclxuICAgICAgICBsZXQgZmFiOnZlYzI8ZjMyPiA9IERGR0FwcHJveCggbm9ybWFsLCB2aWV3RGlyLCByb3VnaG5lc3MgKTtcclxuICAgICAgICByZXR1cm4gc3BlY3VsYXJDb2xvciAqIGZhYi54ICsgc3BlY3VsYXJGOTAgKiBmYWIueTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgZm4gY29tcHV0ZVNwZWN1bGFyT2NjbHVzaW9uKCBkb3ROVjpmMzIsIGFtYmllbnRPY2NsdXNpb246ZjMyLCByb3VnaG5lc3M6ZjMyICktPmYzMiB7XHJcbiAgICAgICAgcmV0dXJuIHNhdHVyYXRlKCBwb3coIGRvdE5WICsgYW1iaWVudE9jY2x1c2lvbiwgZXhwMiggLSAxNi4wICogcm91Z2huZXNzIC0gMS4wICkgKSAtIDEuMCArIGFtYmllbnRPY2NsdXNpb24gKTtcclxuICAgIH1cclxuICAgICNpZiAke2RlZmluZXMuVVNFX1RSQU5TTUlTU0lPTn1cclxuXHJcbiAgICBmbiBnZXRWb2x1bWVUcmFuc21pc3Npb25SYXkoIG46dmVjMzxmMzI+LCB2OnZlYzM8ZjMyPiwgdGhpY2tuZXNzOmYzMiwgaW9yOmYzMiwgbW9kZWxNYXRyaXg6bWF0NHg0OmYzMiktPnZlYzM8ZjMyPiB7XHJcbiAgICAgICAgdmFyIHJlZnJhY3Rpb25WZWN0b3I6dmVjMzxmMzI+ID0gcmVmcmFjdCggLSB2LCBub3JtYWxpemUoIG4gKSwgMS4wIC8gaW9yICk7XHJcbiAgICAgICAgdmFyIG1vZGVsU2NhbGU6dmVjMzxmMzI+O1xyXG4gICAgICAgIG1vZGVsU2NhbGUueCA9IGxlbmd0aCggdmVjMzxmMzI+KCBtb2RlbE1hdHJpeFswXS54eXogKSApO1xyXG4gICAgICAgIG1vZGVsU2NhbGUueSA9IGxlbmd0aCggdmVjMzxmMzI+KCBtb2RlbE1hdHJpeFsxXS54eXogKSApO1xyXG4gICAgICAgIG1vZGVsU2NhbGUueiA9IGxlbmd0aCggdmVjMzxmMzI+KCBtb2RlbE1hdHJpeFsyXS54eXogKSApO1xyXG4gICAgICAgIHJldHVybiBub3JtYWxpemUoIHJlZnJhY3Rpb25WZWN0b3IgKSAqIHRoaWNrbmVzcyAqIG1vZGVsU2NhbGU7XHJcbiAgICB9XHJcbiAgICBmbiBhcHBseUlvclRvUm91Z2huZXNzKHJvdWdobmVzczpmMzIsIGlvcjpmMzIgKS0+ZjMyIHtcclxuICAgICAgICByZXR1cm4gcm91Z2huZXNzICogY2xhbXAoIGlvciAqIDIuMCAtIDIuMCwgMC4wLCAxLjAgKTtcclxuICAgIH1cclxuICAgIGZuIGdldFRyYW5zbWlzc2lvblNhbXBsZSggZnJhZ0Nvb3JkOnZlYzI8ZjMyPiwgcm91Z2huZXNzOmYzMixpb3I6ZjMyICktPnZlYzQ8ZjMyPiB7XHJcbiAgICAgICAgbGV0IGZyYW1lYnVmZmVyTG9kOmYzMiA9IGxvZzIoIG1hdGVyaWFsVW5pZm9ybS50cmFuc21pc3Npb25TYW1wbGVyU2l6ZS54ICkgKiBhcHBseUlvclRvUm91Z2huZXNzKCByb3VnaG5lc3MsIGlvciApO1xyXG4gICAgICAgIHJldHVybiB0ZXh0dXJlU2FtcGxlTGV2ZWwodHJhbnNtaXNzaW9uU2FtcGxlclRleHR1cmUsYmFzZVNhbXBsZXIsZnJhZ0Nvb3JkLnh5LCBmcmFtZWJ1ZmZlckxvZCk7XHJcblxyXG4gICAgfVxyXG4gICAgZm4gYXBwbHlWb2x1bWVBdHRlbnVhdGlvbiggcmFkaWFuY2U6dmVjMzx2ZWMzPiwgdHJhbnNtaXNzaW9uRGlzdGFuY2U6ZjMyLGF0dGVudWF0aW9uQ29sb3I6dmVjMzxmMzI+LGF0dGVudWF0aW9uRGlzdGFuY2U6ZjMyICktPnZlYzM8ZjMyPiB7XHJcbiAgICAgICAgaWYgKCBpc2luZiggYXR0ZW51YXRpb25EaXN0YW5jZSApICkge1xyXG4gICAgICAgICAgICByZXR1cm4gcmFkaWFuY2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBsZXQgYXR0ZW51YXRpb25Db2VmZmljaWVudDp2ZWMzPGYzMj4gPSAtbG9nKCBhdHRlbnVhdGlvbkNvbG9yICkgLyBhdHRlbnVhdGlvbkRpc3RhbmNlO1xyXG4gICAgICAgICAgICBsZXQgdHJhbnNtaXR0YW5jZTp2ZWMzPGYzMj4gPSBleHAoIC0gYXR0ZW51YXRpb25Db2VmZmljaWVudCAqIHRyYW5zbWlzc2lvbkRpc3RhbmNlICk7XHJcbiAgICAgICAgICAgIHJldHVybiB0cmFuc21pdHRhbmNlICogcmFkaWFuY2U7XHJcbiAgICAgICAgfVxyXG4gICAgXHJcbiAgICB9XHJcbiAgICBmbiBnZXRJQkxWb2x1bWVSZWZyYWN0aW9uKCBuOnZlYzM8ZjMyPix2OnZlYzM8ZjMyPiwgcm91Z2huZXNzOmYzMiwgZGlmZnVzZUNvbG9yOnZlYzM8ZjMyPixzcGVjdWxhckNvbG9yOnZlYzM8ZjMyPiwgc3BlY3VsYXJGOTA6ZjMyLHBvc2l0aW9uOnZlYzM8ZjMyPiwgbW9kZWxNYXRyaXg6bWF0NHg0PGYzMj4sIHZpZXdNYXRyaXg6bWF0NHg0PGYzMj4scHJvak1hdHJpeDptYXQ0eDQ8ZjMyPixpb3I6ZjMyLCB0aGlja25lc3M6ZjMyLGF0dGVudWF0aW9uQ29sb3I6dmVjMzxmMzI+LGF0dGVudWF0aW9uRGlzdGFuY2U6ZjMyICktPnZlYzQ8ZjMyPiB7XHJcbiAgICAgICAgbGV0IHRyYW5zbWlzc2lvblJheTp2ZWMzPGYzMj4gPSBnZXRWb2x1bWVUcmFuc21pc3Npb25SYXkoIG4sIHYsIHRoaWNrbmVzcywgaW9yLCBtb2RlbE1hdHJpeCApO1xyXG4gICAgICAgIGxldCByZWZyYWN0ZWRSYXlFeGl0OnZlYzM8ZjMyPiA9IHBvc2l0aW9uICsgdHJhbnNtaXNzaW9uUmF5O1xyXG4gICAgICAgIGxldCBuZGNQb3M6dmVjNDxmMzI+ID0gcHJvak1hdHJpeCAqIHZpZXdNYXRyaXggKiB2ZWM0KCByZWZyYWN0ZWRSYXlFeGl0LCAxLjAgKTtcclxuICAgICAgICBsZXQgcmVmcmFjdGlvbkNvb3Jkczp2ZWMyPGYzMj4gPSBuZGNQb3MueHkgLyBuZGNQb3MudztcclxuICAgICAgICByZWZyYWN0aW9uQ29vcmRzICs9IDEuMDtcclxuICAgICAgICByZWZyYWN0aW9uQ29vcmRzIC89IDIuMDtcclxuICAgICAgICBsZXQgdHJhbnNtaXR0ZWRMaWdodDp2ZWM0PGYzMj4gPSBnZXRUcmFuc21pc3Npb25TYW1wbGUoIHJlZnJhY3Rpb25Db29yZHMsIHJvdWdobmVzcywgaW9yICk7XHJcbiAgICAgICAgbGV0IGF0dGVudWF0ZWRDb2xvcjp2ZWMzPGYzMj4gPSBhcHBseVZvbHVtZUF0dGVudWF0aW9uKCB0cmFuc21pdHRlZExpZ2h0LnJnYiwgbGVuZ3RoKCB0cmFuc21pc3Npb25SYXkgKSwgYXR0ZW51YXRpb25Db2xvciwgYXR0ZW51YXRpb25EaXN0YW5jZSApO1xyXG4gICAgICAgIGxldCBGOnZlYzM8ZjMyPiA9IEVudmlyb25tZW50QlJERiggbiwgdiwgc3BlY3VsYXJDb2xvciwgc3BlY3VsYXJGOTAsIHJvdWdobmVzcyApO1xyXG4gICAgICAgIHJldHVybiB2ZWM0PGYzMj4oICggMS4wIC0gRiApICogYXR0ZW51YXRlZENvbG9yICogZGlmZnVzZUNvbG9yLCB0cmFuc21pdHRlZExpZ2h0LmEgKTtcclxuICAgIH1cclxuICAgICNlbmRpZlxyXG5cclxuICAgICNpZiAke2RlZmluZXMuVVNFX0JVTVBURVhUVVJFfVxyXG4gICAgICAgIGZuIGRIZHh5X2Z3ZCgpLT52ZWMyPGYzMj4ge1xyXG4gICAgICAgICAgICBsZXQgZFNUZHg6dmVjMjxmMzI+ID0gZHBkeCggdlV2ICk7XHJcbiAgICAgICAgICAgIGxldCBkU1RkeTp2ZWMyPGYzMj4gPSBkcGR5KCB2VXYgKTtcclxuXHJcbiAgICAgICAgICAgIGxldCBIbGw6ZjMyID0gbWF0ZXJpYWxVbmlmb3JtLmJ1bXBTY2FsZSAqIHRleHR1cmVTYW1wbGUoYnVtcFRleHR1cmUsIGJhc2VTYW1wbGVyLCB2VXYpLng7XHJcbiAgICAgICAgICAgIGxldCBkQng6ZjMyID0gbWF0ZXJpYWxVbmlmb3JtLmJ1bXBTY2FsZSAqIHRleHR1cmVTYW1wbGUoYnVtcFRleHR1cmUsIGJhc2VTYW1wbGVyLCB2VXYgKyBkU1RkeCkueCAtIEhsbDtcclxuICAgICAgICAgICAgbGV0IGRCeTpmMzIgPSBtYXRlcmlhbFVuaWZvcm0uYnVtcFNjYWxlICogdGV4dHVyZVNhbXBsZShidW1wVGV4dHVyZSwgYmFzZVNhbXBsZXIsIHZVdiArIGRTVGR5KS54IC0gSGxsO1xyXG4gICAgICAgICAgICByZXR1cm4gdmVjMjxmMzI+KCBkQngsIGRCeSApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmbiBwZXJ0dXJiTm9ybWFsQXJiKCBzdXJmX3Bvczp2ZWMzPGYzMj4sIHN1cmZfbm9ybTp2ZWMzPGYzMj4sIGRIZHh5OnZlYzI8ZjMyPiwgZmFjZURpcmVjdGlvbjpmMzIgKS0+dmVjMzxmMzI+IHtcclxuICAgICAgICAgICAgbGV0IHZTaWdtYVg6dmVjMzxmMzI+ID0gZHBkeCggc3VyZl9wb3MueHl6ICk7XHJcbiAgICAgICAgICAgIGxldCB2U2lnbWFZOnZlYzM8ZjMyPiA9IGRwZHkoIHN1cmZfcG9zLnh5eiApO1xyXG4gICAgICAgICAgICBsZXQgdk46dmVjMzxmMzI+ID0gc3VyZl9ub3JtO1xyXG4gICAgICAgICAgICBsZXQgUjE6dmVjMzxmMzI+ID0gY3Jvc3MoIHZTaWdtYVksIHZOICk7XHJcbiAgICAgICAgICAgIGxldCBSMjp2ZWMzPGYzMj4gPSBjcm9zcyggdk4sIHZTaWdtYVggKTtcclxuICAgICAgICAgICAgbGV0IGZEZXQ6ZjMyID0gZG90KCB2U2lnbWFYLCBSMSApICogZmFjZURpcmVjdGlvbjtcclxuICAgICAgICAgICAgbGV0IHZHcmFkOnZlYzM8ZjMyPiA9IHNpZ24oIGZEZXQgKSAqICggZEhkeHkueCAqIFIxICsgZEhkeHkueSAqIFIyICk7XHJcbiAgICAgICAgICAgIHJldHVybiBub3JtYWxpemUoIGFicyggZkRldCApICogc3VyZl9ub3JtIC0gdkdyYWQgKTtcclxuICAgICAgICB9XHJcbiAgICAjZW5kaWZcclxuXHJcbiAgICAvLyEgZGVmaW5lZCAoIFVTRV9UQU5HRU5UICkgJiYgKCBkZWZpbmVkICggVEFOR0VOVFNQQUNFX05PUk1BTFRFWFRVUkUgKSB8fCBkZWZpbmVkICggVVNFX0NMRUFSQ09BVF9OT1JNQUxURVhUVVJFICkgKVxyXG4gICAgI2lmICR7KCFkZWZpbmVzLlVTRV9UQU5HRU5UICYmIGRlZmluZXMuVEFOR0VOVFNQQUNFX05PUk1BTFRFWFRVUkUpIHx8IGRlZmluZXMuVVNFX0NMRUFSQ09BVF9OT1JNQUxURVhUVVJFfVxyXG4gICAgZm4gcGVydHVyYk5vcm1hbDJBcmIoIGV5ZV9wb3M6dmVjMzxmMzI+LCBzdXJmX25vcm06dmVjMzxmMzI+LCB0ZXh0dXJlTjp2ZWMzPGYzMj4sIGZhY2VEaXJlY3Rpb246ZjMyICktPnZlYzM8ZjMyPiB7XHJcbiAgICAgICAgbGV0IHEwOnZlYzM8ZjMyPiA9IGRwZHgoIGV5ZV9wb3MueHl6ICk7XHJcbiAgICAgICAgbGV0IHExOnZlYzM8ZjMyPiA9IGRwZHkoIGV5ZV9wb3MueHl6ICk7XHJcbiAgICAgICAgbGV0IHN0MDp2ZWMyPGYzMj4gPSBkcGR4KCB2VXYuc3QgKTtcclxuICAgICAgICBsZXQgc3QxOnZlYzI8ZjMyPiA9IGRwZHkoIHZVdi5zdCApO1xyXG4gICAgICAgIGxldCBOOnZlYzM8ZjMyPiA9IHN1cmZfbm9ybTtcclxuICAgICAgICBsZXQgcTFwZXJwOnZlYzM8ZjMyPiA9IGNyb3NzKCBxMSwgTiApO1xyXG4gICAgICAgIGxldCBxMHBlcnA6dmVjMzxmMzI+ID0gY3Jvc3MoIE4sIHEwICk7XHJcbiAgICAgICAgbGV0IFQ6dmVjMzxmMzI+ID0gcTFwZXJwICogc3QwLnggKyBxMHBlcnAgKiBzdDEueDtcclxuICAgICAgICBsZXQgQjp2ZWMzPGYzMj4gPSBxMXBlcnAgKiBzdDAueSArIHEwcGVycCAqIHN0MS55O1xyXG4gICAgICAgIGxldCBkZXQ6ZjMyID0gbWF4KCBkb3QoIFQsIFQgKSwgZG90KCBCLCBCICkgKTtcclxuICAgICAgICBsZXQgc2NhbGU6ZjMyID0gKCBkZXQgPT0gMC4wICkgPyAwLjAgOiBmYWNlRGlyZWN0aW9uICogaW52ZXJzZXNxcnQoIGRldCApO1xyXG4gICAgICAgIHJldHVybiBub3JtYWxpemUoIFQgKiAoIHRleHR1cmVOLnggKiBzY2FsZSApICsgQiAqICggdGV4dHVyZU4ueSAqIHNjYWxlICkgKyBOICogdGV4dHVyZU4ueiApO1xyXG4gICAgfVxyXG4gICAgI2VuZGlmXHJcbiAgICBzdHJ1Y3QgTXVsdGlBbmRTaW5nbGVTY2F0dGVye1xyXG4gICAgICAgIG11bHRpU2NhdHRlcjp2ZWMzPGYzMj4sXHJcbiAgICAgICAgc2luZ2xlU2NhdHRlcjp2ZWMzPGYzMj5cclxuICAgIH1cclxuICAgI2lmICR7ZGVmaW5lcy5VU0VfSVJJREVTQ0VOQ0V9XHJcbiAgIC8vLy8vLy8vaW5vdXQgdmVjMyBzaW5nbGVTY2F0dGVyLCBpbm91dCB2ZWMzIG11bHRpU2NhdHRlclxyXG4gICAgICAgZm4gY29tcHV0ZU11bHRpc2NhdHRlcmluZ0lyaWRlc2NlbmNlKCBub3JtYWw6dmVjMzxmMzI+LCB2aWV3RGlyOnZlYzM8ZjMyPiwgc3BlY3VsYXJDb2xvcjp2ZWMzPGYzMj4sIHNwZWN1bGFyRjkwOmYzMiwgaXJpZGVzY2VuY2U6ZjMyLGlyaWRlc2NlbmNlRjA6dmVjMzxmMzI+LCByb3VnaG5lc3M6ZjMyICktPk11bHRpQW5kU2luZ2xlU2NhdHRlciB7XHJcbiAgICNlbHNlXHJcbiAgIC8vLy8vLy8vaW5vdXQgdmVjMyBzaW5nbGVTY2F0dGVyLCBpbm91dCB2ZWMzIG11bHRpU2NhdHRlclxyXG4gICAgICAgZm4gY29tcHV0ZU11bHRpc2NhdHRlcmluZyggbm9ybWFsOnZlYzM8ZjMyPix2aWV3RGlyOnZlYzM8ZjMyPiwgc3BlY3VsYXJDb2xvcjp2ZWMzPGYzMj4sIHNwZWN1bGFyRjkwOmYzMiwgcm91Z2huZXNzOmYzMiktPk11bHRpQW5kU2luZ2xlU2NhdHRlciB7XHJcbiAgICNlbmRpZlxyXG4gICBsZXQgZmFiOnZlYzI8ZjMyPiA9IERGR0FwcHJveCggbm9ybWFsLCB2aWV3RGlyLCByb3VnaG5lc3MgKTtcclxuXHJcbiAgIHZhciBtdWx0aUFuZFNpbmdsZVNjYXR0ZXI6TXVsdGlBbmRTaW5nbGVTY2F0dGVyO1xyXG5cclxuICAgI2lmICR7ZGVmaW5lcy5VU0VfSVJJREVTQ0VOQ0V9XHJcbiAgICAgICBsZXQgRnI6dmVjMzxmMzI+ID0gbWl4KCBzcGVjdWxhckNvbG9yLCBpcmlkZXNjZW5jZUYwLCBpcmlkZXNjZW5jZSApO1xyXG4gICAjZWxzZVxyXG4gICAgICAgbGV0IEZyOnZlYzM8ZjMyPiA9IHNwZWN1bGFyQ29sb3I7XHJcbiAgICNlbmRpZlxyXG4gICAgICAgbGV0IEZzc0Vzczp2ZWMzPGYzMj4gPSBGciAqIGZhYi54ICsgc3BlY3VsYXJGOTAgKiBmYWIueTtcclxuICAgICAgIGxldCBFc3M6ZjMyID0gZmFiLnggKyBmYWIueTtcclxuICAgICAgIGxldCBFbXM6ZjMyID0gMS4wIC0gRXNzO1xyXG4gICAgICAgbGV0IEZhdmc6dmVjMzxmMzI+ID0gRnIgKyAoIDEuMCAtIEZyICkgKiAwLjA0NzYxOTtcclxuICAgICAgIGxldCBGbXM6dmVjMzxmMzI+ID0gRnNzRXNzICogRmF2ZyAvICggMS4wIC0gRW1zICogRmF2ZyApO1xyXG4gICAgLy8gICAgc2luZ2xlU2NhdHRlciArPSBGc3NFc3M7XHJcbiAgICAvLyAgICBtdWx0aVNjYXR0ZXIgKz0gRm1zICogRW1zO1xyXG4gICAgICAgbXVsdGlBbmRTaW5nbGVTY2F0dGVyLm11bHRpU2NhdHRlcj1GbXMgKiBFbXM7XHJcbiAgICAgICBtdWx0aUFuZFNpbmdsZVNjYXR0ZXIuc2luZ2xlU2NhdHRlcj1Gc3NFc3M7XHJcbiAgICAgICByZXR1cm4gbXVsdGlBbmRTaW5nbGVTY2F0dGVyO1xyXG4gICB9XHJcbiAgIC8v55u05o6l5YWJ54WnXHJcbiAgIGZuIFJFX0RpcmVjdF9QaHlzaWNhbCggZGlyZWN0TGlnaHQ6SW5jaWRlbnRMaWdodCwgZ2VvbWV0cnk6R2VvbWV0cmljQ29udGV4dCwgIG1hdGVyaWFsOlBoeXNpY2FsTWF0ZXJpYWwpLT5SZWZsZWN0ZWRMaWdodCB7XHJcbiAgICAgICB2YXIgcmVmbGVjdGVkTGlnaHQ6UmVmbGVjdGVkTGlnaHQ7XHJcbiAgICAgICBsZXQgZG90Tkw6ZjMyID0gc2F0dXJhdGUoZG90KCBnZW9tZXRyeS5ub3JtYWwsIGRpcmVjdExpZ2h0LmRpcmVjdGlvbikpO1xyXG4gICAgICAgbGV0IGlycmFkaWFuY2U6dmVjMzxmMzI+ID0gZG90TkwgKiBkaXJlY3RMaWdodC5jb2xvcjtcclxuICAgICAgICNpZiAke2RlZmluZXMuVVNFX0NMRUFSQ09BVH1cclxuICAgICAgICAgICBsZXQgZG90TkxjYzpmMzIgPSBzYXR1cmF0ZSggZG90KCBnZW9tZXRyeS5jbGVhcmNvYXROb3JtYWwsIGRpcmVjdExpZ2h0LmRpcmVjdGlvbiApICk7XHJcbiAgICAgICAgICAgbGV0IGNjSXJyYWRpYW5jZTp2ZWMzPGYzMj4gPSBkb3ROTGNjICogZGlyZWN0TGlnaHQuY29sb3I7XHJcbiAgICAgICAgICAgY2xlYXJjb2F0U3BlY3VsYXIgKz0gY2NJcnJhZGlhbmNlICogQlJERl9HR1goIGRpcmVjdExpZ2h0LmRpcmVjdGlvbiwgZ2VvbWV0cnkudmlld0RpciwgZ2VvbWV0cnkuY2xlYXJjb2F0Tm9ybWFsLCBtYXRlcmlhbC5jbGVhcmNvYXRGMCwgbWF0ZXJpYWwuY2xlYXJjb2F0RjkwLCBtYXRlcmlhbC5jbGVhcmNvYXRSb3VnaG5lc3MgKTtcclxuICAgICAgICNlbmRpZlxyXG5cclxuICAgICAgICNpZiAke2RlZmluZXMuVVNFX1NIRUVOfVxyXG4gICAgICAgICAgIHNoZWVuU3BlY3VsYXIgKz0gaXJyYWRpYW5jZSAqIEJSREZfU2hlZW4oIGRpcmVjdExpZ2h0LmRpcmVjdGlvbiwgZ2VvbWV0cnkudmlld0RpciwgZ2VvbWV0cnkubm9ybWFsLCBtYXRlcmlhbC5zaGVlbkNvbG9yLCBtYXRlcmlhbC5zaGVlblJvdWdobmVzcyApO1xyXG4gICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfSVJJREVTQ0VOQ0V9XHJcbiAgICAgICAgICAgcmVmbGVjdGVkTGlnaHQuZGlyZWN0U3BlY3VsYXIgPSBpcnJhZGlhbmNlICogQlJERl9HR1hfSXJpZGVzY2VuY2UoIGRpcmVjdExpZ2h0LmRpcmVjdGlvbiwgZ2VvbWV0cnkudmlld0RpciwgZ2VvbWV0cnkubm9ybWFsLCBtYXRlcmlhbC5zcGVjdWxhckNvbG9yLCBtYXRlcmlhbC5zcGVjdWxhckY5MCwgbWF0ZXJpYWwuaXJpZGVzY2VuY2UsIG1hdGVyaWFsLmlyaWRlc2NlbmNlRnJlc25lbCwgbWF0ZXJpYWwucm91Z2huZXNzICk7XHJcbiAgICAgICAjZWxzZVxyXG4gICAgICAgICAgIHJlZmxlY3RlZExpZ2h0LmRpcmVjdFNwZWN1bGFyID0gaXJyYWRpYW5jZSAqIEJSREZfR0dYKCBkaXJlY3RMaWdodC5kaXJlY3Rpb24sIGdlb21ldHJ5LnZpZXdEaXIsIGdlb21ldHJ5Lm5vcm1hbCwgbWF0ZXJpYWwuc3BlY3VsYXJDb2xvciwgbWF0ZXJpYWwuc3BlY3VsYXJGOTAsIG1hdGVyaWFsLnJvdWdobmVzcyApO1xyXG4gICAgICAgI2VuZGlmXHJcbiAgICAgICByZWZsZWN0ZWRMaWdodC5kaXJlY3REaWZmdXNlID0gaXJyYWRpYW5jZSAqIEJSREZfTGFtYmVydCggbWF0ZXJpYWwuZGlmZnVzZUNvbG9yICk7XHJcbiAgICAgICByZXR1cm4gcmVmbGVjdGVkTGlnaHQ7XHJcbiAgIH1cclxuICAgLy/pl7TmjqXlhYnnhadcclxuICAgZm4gUkVfSW5kaXJlY3REaWZmdXNlX1BoeXNpY2FsKCBpcnJhZGlhbmNlOnZlYzM8ZjMyPiwgZ2VvbWV0cnk6R2VvbWV0cmljQ29udGV4dCwgbWF0ZXJpYWw6UGh5c2ljYWxNYXRlcmlhbCApLT5SZWZsZWN0ZWRMaWdodCB7XHJcbiAgICAgICB2YXIgcmVmbGVjdGVkTGlnaHQ6UmVmbGVjdGVkTGlnaHQ7XHJcbiAgICAgICByZWZsZWN0ZWRMaWdodC5pbmRpcmVjdERpZmZ1c2UgPSBpcnJhZGlhbmNlICogQlJERl9MYW1iZXJ0KCBtYXRlcmlhbC5kaWZmdXNlQ29sb3IgKTtcclxuICAgICAgIHJldHVybiByZWZsZWN0ZWRMaWdodDtcclxuICAgfVxyXG4gICAvL+mXtOaOpemrmOWFiVxyXG4gICBmbiBSRV9JbmRpcmVjdFNwZWN1bGFyX1BoeXNpY2FsKCByYWRpYW5jZTp2ZWMzPGYzMj4sIGlycmFkaWFuY2U6dmVjMzxmMzI+LCBjbGVhcmNvYXRSYWRpYW5jZTp2ZWMzPGYzMj4sIGdlb21ldHJ5Okdlb21ldHJpY0NvbnRleHQsIG1hdGVyaWFsOlBoeXNpY2FsTWF0ZXJpYWwpLT5SZWZsZWN0ZWRMaWdodCB7XHJcbiAgICAgICB2YXIgcmVmbGVjdGVkTGlnaHQ6UmVmbGVjdGVkTGlnaHQ7XHJcbiAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9DTEVBUkNPQVR9XHJcbiAgICAgICAgICAgY2xlYXJjb2F0U3BlY3VsYXIgKz0gY2xlYXJjb2F0UmFkaWFuY2UgKiBFbnZpcm9ubWVudEJSREYoIGdlb21ldHJ5LmNsZWFyY29hdE5vcm1hbCwgZ2VvbWV0cnkudmlld0RpciwgbWF0ZXJpYWwuY2xlYXJjb2F0RjAsIG1hdGVyaWFsLmNsZWFyY29hdEY5MCwgbWF0ZXJpYWwuY2xlYXJjb2F0Um91Z2huZXNzICk7XHJcbiAgICAgICAjZW5kaWZcclxuICAgICAgICNpZiAke2RlZmluZXMuVVNFX1NIRUVOfVxyXG4gICAgICAgICAgIHNoZWVuU3BlY3VsYXIgKz0gaXJyYWRpYW5jZSAqIG1hdGVyaWFsLnNoZWVuQ29sb3IgKiBJQkxTaGVlbkJSREYoIGdlb21ldHJ5Lm5vcm1hbCwgZ2VvbWV0cnkudmlld0RpciwgbWF0ZXJpYWwuc2hlZW5Sb3VnaG5lc3MgKTtcclxuICAgICAgICNlbmRpZlxyXG4gICAgICAgdmFyIHNpbmdsZVNjYXR0ZXJpbmc6dmVjMzxmMzI+O1xyXG4gICAgICAgdmFyIG11bHRpU2NhdHRlcmluZzp2ZWMzPGYzMj47XHJcbiAgICAgICBsZXQgY29zaW5lV2VpZ2h0ZWRJcnJhZGlhbmNlOnZlYzM8ZjMyPiA9IGlycmFkaWFuY2UgKiBSRUNJUFJPQ0FMX1BJO1xyXG4gICAgICAgdmFyIHRlbXBNdWx0aUFuZFNpbmdsZVNjYXR0ZXI6TXVsdGlBbmRTaW5nbGVTY2F0dGVyO1xyXG4gICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfSVJJREVTQ0VOQ0V9XHJcbiAgICAgICAgICAgICB0ZW1wTXVsdGlBbmRTaW5nbGVTY2F0dGVyPWNvbXB1dGVNdWx0aXNjYXR0ZXJpbmdJcmlkZXNjZW5jZSggZ2VvbWV0cnkubm9ybWFsLCBnZW9tZXRyeS52aWV3RGlyLCBtYXRlcmlhbC5zcGVjdWxhckNvbG9yLCBtYXRlcmlhbC5zcGVjdWxhckY5MCwgbWF0ZXJpYWwuaXJpZGVzY2VuY2UsIG1hdGVyaWFsLmlyaWRlc2NlbmNlRnJlc25lbCwgbWF0ZXJpYWwucm91Z2huZXNzICk7XHJcbiAgICAgICAjZWxzZVxyXG4gICAgICAgICAgICB0ZW1wTXVsdGlBbmRTaW5nbGVTY2F0dGVyPSBjb21wdXRlTXVsdGlzY2F0dGVyaW5nKCBnZW9tZXRyeS5ub3JtYWwsIGdlb21ldHJ5LnZpZXdEaXIsIG1hdGVyaWFsLnNwZWN1bGFyQ29sb3IsIG1hdGVyaWFsLnNwZWN1bGFyRjkwLCBtYXRlcmlhbC5yb3VnaG5lc3MgKTtcclxuICAgICAgICNlbmRpZlxyXG4gICAgICAgc2luZ2xlU2NhdHRlcmluZz10ZW1wTXVsdGlBbmRTaW5nbGVTY2F0dGVyLnNpbmdsZVNjYXR0ZXI7IFxyXG4gICAgICAgbXVsdGlTY2F0dGVyaW5nPXRlbXBNdWx0aUFuZFNpbmdsZVNjYXR0ZXIubXVsdGlTY2F0dGVyO1xyXG4gICAgICAgbGV0IHRvdGFsU2NhdHRlcmluZzp2ZWMzPGYzMj4gPSBzaW5nbGVTY2F0dGVyaW5nICsgbXVsdGlTY2F0dGVyaW5nO1xyXG4gICAgICAgbGV0IGRpZmZ1c2U6dmVjMzxmMzI+ID0gbWF0ZXJpYWwuZGlmZnVzZUNvbG9yICogKCAxLjAgLSBtYXgoIG1heCggdG90YWxTY2F0dGVyaW5nLnIsIHRvdGFsU2NhdHRlcmluZy5nICksIHRvdGFsU2NhdHRlcmluZy5iICkgKTtcclxuICAgICAgIHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0U3BlY3VsYXIgPSByYWRpYW5jZSAqIHNpbmdsZVNjYXR0ZXJpbmc7XHJcbiAgICAgICByZWZsZWN0ZWRMaWdodC5pbmRpcmVjdFNwZWN1bGFyID0gbXVsdGlTY2F0dGVyaW5nICogY29zaW5lV2VpZ2h0ZWRJcnJhZGlhbmNlO1xyXG4gICAgICAgcmVmbGVjdGVkTGlnaHQuaW5kaXJlY3REaWZmdXNlID0gZGlmZnVzZSAqIGNvc2luZVdlaWdodGVkSXJyYWRpYW5jZTtcclxuICAgICAgIHJldHVybiByZWZsZWN0ZWRMaWdodDtcclxuICAgfVxyXG4gICBgO1xyXG59XHJcbiIsImltcG9ydCB7IHdnc2xQYXJzZURlZmluZXMgfSBmcm9tIFwiLi4vLi4vV2dzbFByZXByb2Nlc3NvclwiO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcGJyU3RydWN0KGRlZmluZXMpIHtcclxuICByZXR1cm4gd2dzbFBhcnNlRGVmaW5lc2BcclxuICAgICAgICBzdHJ1Y3QgTWF0ZXJpYWxVbmlmb3Jte1xyXG5cclxuICAgICAgICAgICAgbW9kZWxNYXRyaXg6IG1hdDR4NDxmMzI+LFxyXG4gICAgXHJcbiAgICAgICAgICAgIGRpZmZ1c2U6dmVjMzxmMzI+LFxyXG4gICAgXHJcbiAgICAgICAgICAgIG9wYWNpdHk6ZjMyLFxyXG4gICAgXHJcbiAgICAgICAgICAgIG5vcm1hbE1hdHJpeDogbWF0M3gzPGYzMj4sXHJcbiAgICBcclxuICAgICAgICAgICAgZW1pc3NpdmU6dmVjMzxmMzI+LFxyXG4gICAgXHJcbiAgICAgICAgICAgIHJvdWdobmVzczpmMzIsXHJcbiAgICBcclxuICAgICAgICAgICAgbWV0YWxuZXNzOmYzMixcclxuICAgIFxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlRPTkVfTUFQUElOR31cclxuICAgICAgICAgICAgICAgIHRvbmVNYXBwaW5nRXhwb3N1cmU6ZjMyLFxyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICBcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5TUEVDVUxBUn1cclxuICAgIFxyXG4gICAgICAgICAgICAgICAgIHNwZWN1bGFyQ29sb3I6dmVjMzxmMzI+LFxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgc3BlY3VsYXJJbnRlbnNpdHk6ZjMyLFxyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX1NIRUVOfVxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICBzaGVlbkNvbG9yOnZlYzM8ZjMyPixcclxuICAgIFxyXG4gICAgICAgICAgICAgICAgc2hlZW5Sb3VnaG5lc3M6ZjMyLFxyXG4gICAgICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX1RSQU5TTUlTU0lPTn1cclxuICAgIFxyXG4gICAgICAgICAgICAgICAgYXR0ZW51YXRpb25Db2xvcjp2ZWMzPGYzMj4sXHJcbiAgICBcclxuICAgICAgICAgICAgICAgIHRyYW5zbWlzc2lvbjpmMzIsXHJcbiAgICBcclxuICAgICAgICAgICAgICAgIHRyYW5zbWlzc2lvblNhbXBsZXJTaXplOnZlYzI8ZjMyPixcclxuICAgIFxyXG4gICAgICAgICAgICAgICAgdGhpY2tuZXNzOmYzMixcclxuICAgIFxyXG4gICAgICAgICAgICAgICAgYXR0ZW51YXRpb25EaXN0YW5jZTpmMzIsXHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9TS0lOTklOR31cclxuICAgIFxyXG4gICAgICAgICAgICAgICAgYmluZE1hdHJpeDptYXQ0eDQ8ZjMyPixcclxuICAgIFxyXG4gICAgICAgICAgICAgICAgYmluZE1hdHJpeEludmVyc2U6bWF0NHg0PGYzMj4sXHJcbiAgICBcclxuICAgICAgICAgICAgICAgIGJvbmVUZXh0dXJlU2l6ZTp1MzIsXHJcbiAgICAgICAgICAgICNlbmRpZlxyXG5cclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfTk9STUFMVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgICBub3JtYWxTY2FsZTp2ZWMyPGYzMj4sXHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuSU9SfVxyXG4gICAgICAgICAgICAgICAgaW9yOmYzMixcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICBcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfQ0xFQVJDT0FUfVxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9DTEVBUkNPQVRfTk9STUFMVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgICAgICBjbGVhcmNvYXROb3JtYWxTY2FsZTp2ZWMyPGYzMj4sXHJcbiAgICAgICAgICAgICAgICAjZW5kaWZcclxuICAgIFxyXG4gICAgICAgICAgICAgICAgIGNsZWFyY29hdDpmMzIsXHJcbiAgICBcclxuICAgICAgICAgICAgICAgICBjbGVhcmNvYXRSb3VnaG5lc3M6ZjMyLFxyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgIFxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9JUklERVNDRU5DRX1cclxuICAgICAgICAgICAgICAgIGlyaWRlc2NlbmNlOmYzMixcclxuICAgIFxyXG4gICAgICAgICAgICAgICAgaXJpZGVzY2VuY2VJT1I6ZjMyLFxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICBpcmlkZXNjZW5jZVRoaWNrbmVzc01pbmltdW06ZjMyLFxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICBpcmlkZXNjZW5jZVRoaWNrbmVzc01heGltdW06ZjMyLFxyXG4gICAgXHJcbiAgICAgICAgICAgICNlbmRpZlxyXG5cclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfQU9URVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgIGFvVGV4dHVyZUludGVuc2l0eTpmMzIsXHJcbiAgICAgICAgICAgICNlbmRpZlxyXG5cclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfTElHSFRURVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgIGxpZ2h0VGV4dHVyZUludGVuc2l0eTpmMzIsXHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX0VOVlRFWFRVUkV9XHJcbiAgICAgICAgICAgICAgICBlbnZUZXh0dXJlSW50ZW5zaXR5OmYzMixcclxuICAgIFxyXG4gICAgICAgICAgICAgICAgZmxpcEVudlRleHR1cmU6ZjMyLFxyXG4gICAgICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX0JVTVBURVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgYnVtcFNjYWxlOmYzMjtcclxuICAgICAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9ESVNQTEFDRU1FTlRURVhUVVJFfVxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICBkaXNwbGFjZW1lbnRTY2FsZTpmMzIsXHJcbiAgICBcclxuICAgICAgICAgICAgICAgIGRpc3BsYWNlbWVudEJpYXM6ZjMyLFxyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX01PUlBIVEFSR0VUU31cclxuICAgIFxyXG4gICAgICAgICAgICAgICAgbW9ycGhUYXJnZXRCYXNlSW5mbHVlbmNlOmYzMixcclxuICAgIFxyXG4gICAgICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5NT1JQSFRBUkdFVFNfVEVYVFVSRX0gXHJcbiAgICBcclxuICAgICAgICAgICAgICAgICAgICBtb3JwaFRhcmdldHNUZXh0dXJlU2l6ZTp2ZWMyPHUzMj4sXHJcbiAgICBcclxuICAgICAgICAgICAgICAgICAgICBNT1JQSFRBUkdFVFNfQ09VTlQ6dTMyLFxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAjZW5kaWZcclxuICAgIFxyXG4gICAgICAgICAgICAgICAgbW9ycGhUYXJnZXRJbmZsdWVuY2VzOmFycmF5PGYzMj4sXHJcbiAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgIH1cclxuXHJcbiAgIGA7XHJcbn1cclxuIiwiaW1wb3J0IHsgd2dzbFBhcnNlRGVmaW5lcyB9IGZyb20gXCIuLi8uLi9XZ3NsUHJlcHJvY2Vzc29yXCI7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBwYnJUZXh0dXJlKGRlZmluZXMpIHtcclxuICByZXR1cm4gd2dzbFBhcnNlRGVmaW5lc2AgICAgICAgIFxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9CVU1QVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMuYnVtcFRleHR1cmVCaW5kaW5nfSkgdmFyIGJ1bXBUZXh0dXJlOiB0ZXh0dXJlXzJkPGYzMj47XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9UUkFOU01JU1NJT059XHJcbiAgICAgICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9UUkFOU01JU1NJT05URVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMudHJhbnNtaXNzaW9uVGV4dHVyZUJpbmRpbmd9KSB2YXIgdHJhbnNtaXNzaW9uVGV4dHVyZTogdGV4dHVyZV8yZDxmMzI+O1xyXG4gICAgICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9USElDS05FU1NURVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMudGhpY2tuZXNzVGV4dHVyZUJpbmRpbmd9KSB2YXIgdGhpY2tuZXNzVGV4dHVyZTogdGV4dHVyZV8yZDxmMzI+O1xyXG4gICAgICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgICAgICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLnRyYW5zbWlzc2lvblNhbXBsZXJUZXh0dXJlQmluZGluZ30pIHZhciB0cmFuc21pc3Npb25TYW1wbGVyVGV4dHVyZTogdGV4dHVyZV8yZDxmMzI+O1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfRU5WVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMuZW52VGV4dHVyZUJpbmRpbmd9KSB2YXIgZW52VGV4dHVyZTogdGV4dHVyZV9jdWJlPGYzMj47XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9OT1JNQUxURVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKCR7ZGVmaW5lcy5ub3JtYWxUZXh0dXJlQmluZGluZ30pIHZhciBub3JtYWxUZXh0dXJlOiB0ZXh0dXJlXzJkPGYzMj47XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfQ0xFQVJDT0FUVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMuY2xlYXJjb2F0VGV4dHVyZUJpbmRpbmd9KSB2YXIgY2xlYXJjb2F0VGV4dHVyZTogdGV4dHVyZV8yZDxmMzI+O1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX0NMRUFSQ09BVF9ST1VHSE5FU1NURVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKCR7ZGVmaW5lcy5jbGVhcmNvYXRSY2xlYXJjb2F0Um91Z2huZXNzVGV4dHVyZUJpbmRpbmd9KSB2YXIgY2xlYXJjb2F0Um91Z2huZXNzVGV4dHVyZTogdGV4dHVyZV8yZDxmMzI+O1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX0NMRUFSQ09BVF9OT1JNQUxURVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKCR7ZGVmaW5lcy5jbGVhcmNvYXROb3JtYWxUZXh0dXJlQmluZGluZ30pIHZhciBjbGVhcmNvYXROb3JtYWxUZXh0dXJlOiB0ZXh0dXJlXzJkPGYzMj47XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfSVJJREVTQ0VOQ0VURVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKCR7ZGVmaW5lcy5pcmlkZXNjZW5jZVRleHR1cmVCaW5kaW5nfSkgdmFyIGlyaWRlc2NlbmNlVGV4dHVyZTogdGV4dHVyZV8yZDxmMzI+O1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX0lSSURFU0NFTkNFX1RISUNLTkVTU1RFWFRVUkV9XHJcbiAgICAgICAgICAgICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLmlyaWRlc2NlbmNlVGhpY2tuZXNzVGV4dHVyZUJpbmRpbmd9KSB2YXIgaXJpZGVzY2VuY2VUaGlja25lc3NUZXh0dXJlOiB0ZXh0dXJlXzJkPGYzMj47XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfUk9VR0hORVNTVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMucm91Z2huZXNzVGV4dHVyZUJpbmRpbmd9KSB2YXIgcm91Z2huZXNzVGV4dHVyZTogdGV4dHVyZV8yZDxmMzI+O1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX01FVEFMTkVTU1RFWFRVUkV9XHJcbiAgICAgICAgICAgICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLm1ldGFsbmVzc1RleHR1cmVCaW5kaW5nfSkgdmFyIG1ldGFsbmVzc1RleHR1cmU6IHRleHR1cmVfMmQ8ZjMyPjtcclxuICAgICAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlNQRUNVTEFSfVxyXG4gICAgICAgICAgICAgICAgI2lmICR7ZGVmaW5lcy5VU0VfU1BFQ1VMQVJJTlRFTlNJVFlURVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMuc3BlY3VsYXJJbnRlbnNpdHlUZXh0dXJlQmluZGluZ30pIHZhciBzcGVjdWxhckludGVuc2l0eVRleHR1cmU6IHRleHR1cmVfMmQ8ZjMyPjtcclxuICAgICAgICAgICAgICAgICNlbmRpZlxyXG5cclxuICAgICAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX1NQRUNVTEFSQ09MT1JURVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMuc3BlY3VsYXJDb2xvclRleHR1cmVCaW5kaW5nfSkgdmFyIHNwZWN1bGFyQ29sb3JUZXh0dXJlOiB0ZXh0dXJlXzJkPGYzMj47XHJcbiAgICAgICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9TSEVFTn1cclxuICAgICAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX1NIRUVOQ09MT1JURVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMuc2hlZW5Db2xvclRleHR1cmVCaW5kaW5nfSkgdmFyIHNoZWVuQ29sb3JUZXh0dXJlOiB0ZXh0dXJlXzJkPGYzMj47XHJcbiAgICAgICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX1NIRUVOUk9VR0hORVNTVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLnNoZWVuUm91Z2huZXNzVGV4dHVyZUJpbmRpbmd9KSB2YXIgc2hlZW5Sb3VnaG5lc3NUZXh0dXJlOiB0ZXh0dXJlXzJkPGYzMj47XHJcbiAgICAgICAgICAgICAgICAjZW5kaWZcclxuICAgICAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9URVhUVVJFfVxyXG4gICAgICAgICAgICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKCR7ZGVmaW5lcy5iYXNlU2FtcGxlckJpbmRpbmd9KSB2YXIgYmFzZVNhbXBsZXI6IHNhbXBsZXI7XHJcbiAgICAgICAgICAgICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLmJhc2VUZXh0dXJlQmluZGluZ30pIHZhciBiYXNlVGV4dHVyZTogdGV4dHVyZV8yZDxmMzI+O1xyXG4gICAgICAgICAgICAjZW5kaWZcclxuXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX0FMUEhBVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMuYWxwaGFUZXh0dXJlQmluZGluZ30pIHZhciBhbHBoYVRleHR1cmU6IHRleHR1cmVfMmQ8ZjMyPjtcclxuICAgICAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9BT1RFWFRVUkV9XHJcbiAgICAgICAgICAgICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLmFvVGV4dHVyZUJpbmRpbmd9KSB2YXIgYW9UZXh0dXJlOiB0ZXh0dXJlXzJkPGYzMj47XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgI2VuZGlmXHJcbiAgICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX0xJR0hUVEVYVFVSRX1cclxuICAgICAgICAgICAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMubGlnaHRUZXh0dXJlQmluZGluZ30pIHZhciBsaWdodFRleHR1cmU6IHRleHR1cmVfMmQ8ZjMyPjtcclxuICAgICAgICAgICAgI2VuZGlmXHJcblxyXG4gICAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9FTUlTU0lWRVRFWFRVUkV9XHJcbiAgICAgICAgICAgICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLmVtaXNzaXZlVGV4dHVyZUJpbmRpbmd9KSB2YXIgZW1pc3NpdmVUZXh0dXJlOiB0ZXh0dXJlXzJkPGYzMj47XHJcbiAgICAgICAgICAgICNlbmRpZlxyXG4gICAgIGA7XHJcbn1cclxuIiwiaW1wb3J0IHsgd2dzbFBhcnNlRGVmaW5lcyB9IGZyb20gXCIuLi8uLi9XZ3NsUHJlcHJvY2Vzc29yXCI7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBwYnJVdGlscyhkZWZpbmVzKSB7XHJcbiAgcmV0dXJuIHdnc2xQYXJzZURlZmluZXNgXHJcbiAgICBjb25zdCBQSTpmMzI9IDMuMTQxNTkyNjUzNTg5NzkzO1xyXG4gICAgY29uc3QgUEkyOmYzMj0gNi4yODMxODUzMDcxNzk1ODY7XHJcbiAgICBjb25zdCBQSV9IQUxGOmYzMj0gMS41NzA3OTYzMjY3OTQ4OTY2O1xyXG4gICAgY29uc3QgUkVDSVBST0NBTF9QSTpmMzI9IDAuMzE4MzA5ODg2MTgzNzkwNztcclxuICAgIGNvbnN0IFJFQ0lQUk9DQUxfUEkyOmYzMj0gMC4xNTkxNTQ5NDMwOTE4OTUzNTtcclxuICAgIGNvbnN0IEVQU0lMT046ZjMyPSAxZS02O1xyXG5cclxuICAgIGZuIHBvdzIoeDpmMzIgKS0+ZjMyIHtcclxuICAgICAgICByZXR1cm4geCp4O1xyXG4gICAgfVxyXG4gICAgZm4gcG93MlZlY3Rvcih4OnZlYzM8ZjMyPiApLT52ZWMzPGYzMj4ge1xyXG4gICAgICAgIHJldHVybiB4Kng7XHJcbiAgICB9XHJcbiAgICBmbiBwb3czKCB4OmYzMiApLT5mMzIge1xyXG4gICAgICAgIHJldHVybiB4KngqeDtcclxuICAgIH1cclxuICAgIGZuIHBvdzQoIHg6ZjMyICktPmYzMiB7XHJcbiAgICAgICAgbGV0IHgyOmYzMiA9IHgqeDtcclxuICAgICAgICByZXR1cm4geDIqeDI7XHJcbiAgICB9XHJcbiAgICBmbiBtYXgzKCB2OnZlYzM8ZjMyPiApLT5mMzIge1xyXG4gICAgICAgIHJldHVybiBtYXgoIG1heCggdi54LCB2LnkgKSwgdi56ICk7XHJcbiAgICB9XHJcbiAgICBmbiBhdmVyYWdlKHY6dmVjMzxmMzI+ICktPmYzMiB7XHJcbiAgICAgICAgcmV0dXJuIGRvdCggdiwgdmVjMzxmMzI+KCAwLjMzMzMzMzMgKSApO1xyXG4gICAgfVxyXG4gICAgZm4gcmFuZCggdXY6dmVjMjxmMzI+ICktPmYzMiB7XHJcbiAgICAgICAgbGV0IGE6ZjMyID0gMTIuOTg5ODtcclxuICAgICAgICBsZXQgYjpmMzIgPSA3OC4yMzM7XHJcbiAgICAgICAgbGV0IGM6ZjMyID0gNDM3NTguNTQ1MztcclxuICAgICAgICBsZXQgZHQ6ZjMyID0gZG90KCB1di54eSwgdmVjMjxmMzI+KCBhLCBiICkgKTtcclxuICAgICAgICBsZXQgc246ZjMyID0gZHQgJSBQSTtcclxuICAgICAgICByZXR1cm4gZnJhY3QoIHNpbiggc24gKSAqIGMgKTtcclxuICAgIH1cclxuICAgIGZuIHRyYW5zZm9ybURpcmVjdGlvbiggZGlyOnZlYzM8ZjMyPiwgbWF0cml4Om1hdDR4NDxmMzI+ICktPnZlYzM8ZjMyPiB7XHJcbiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZSggKCBtYXRyaXggKiB2ZWM0PGYzMj4oIGRpciwgMC4wICkgKS54eXogKTtcclxuICAgIH1cclxuXHJcbiAgICBmbiB0cmFuc3Bvc2VNYXQzKCBtOm1hdDN4MzxmMzI+ICktPm1hdDN4MzxmMzI+IHtcclxuICAgICAgICB2YXIgdG1wOm1hdDN4MzxmMzI+O1xyXG4gICAgICAgIHRtcFsgMCBdID0gdmVjMzxmMzI+KCBtWyAwIF0ueCwgbVsgMSBdLngsIG1bIDIgXS54ICk7XHJcbiAgICAgICAgdG1wWyAxIF0gPSB2ZWMzPGYzMj4oIG1bIDAgXS55LCBtWyAxIF0ueSwgbVsgMiBdLnkgKTtcclxuICAgICAgICB0bXBbIDIgXSA9IHZlYzM8ZjMyPiggbVsgMCBdLnosIG1bIDEgXS56LCBtWyAyIF0ueiApO1xyXG4gICAgICAgIHJldHVybiB0bXA7XHJcbiAgICB9XHJcbiAgICBmbiBsdW1pbmFuY2UoIHJnYjp2ZWMzPGYzMj4gKS0+ZjMyIHtcclxuICAgICAgICBsZXQgd2VpZ2h0czp2ZWMzPGYzMj4gPSB2ZWMzPGYzMj4oMC4yMTI2NzI5LCAwLjcxNTE1MjIsIDAuMDcyMTc1MCApO1xyXG4gICAgICAgIHJldHVybiBkb3QoIHdlaWdodHMsIHJnYiApO1xyXG4gICAgfVxyXG4gICAgZm4gTGluZWFyVG9uZU1hcHBpbmcoIGNvbG9yOnZlYzM8ZjMyPix0b25lTWFwcGluZ0V4cG9zdXJlOmYzMiAgKS0+dmVjMzxmMzI+IHtcclxuICAgICAgICByZXR1cm4gdG9uZU1hcHBpbmdFeHBvc3VyZSAqIGNvbG9yO1xyXG4gICAgfVxyXG5cclxuICAgIGZuIFJlaW5oYXJkVG9uZU1hcHBpbmcoIGNvbG9yOnZlYzM8ZjMyPix0b25lTWFwcGluZ0V4cG9zdXJlOmYzMiApLT52ZWMzPGYzMj4ge1xyXG4gICAgICAgIHZhciB0ZW1wQ29sb3I6dmVjMzxmMzI+O1xyXG4gICAgICAgIHRlbXBDb2xvcj1jb2xvcjtcclxuICAgICAgICB0ZW1wQ29sb3IgKj0gdG9uZU1hcHBpbmdFeHBvc3VyZTtcclxuICAgICAgICByZXR1cm4gc2F0dXJhdGUoIHRlbXBDb2xvciAvICggdmVjMzxmMzI+KCAxLjAgKSArIHRlbXBDb2xvciApICk7XHJcbiAgICB9XHJcbiAgICBmbiBDdXN0b21Ub25lTWFwcGluZyggY29sb3I6dmVjMzxmMzI+ICktPnZlYzM8ZjMyPiB7XHJcbiAgICAgICAgcmV0dXJuIGNvbG9yO1xyXG4gICAgfVxyXG4gICAgZm4gdG9uZU1hcHBpbmcoIGNvbG9yOnZlYzM8ZjMyPix0b25lTWFwcGluZ0V4cG9zdXJlOmYzMiAgKS0+dmVjMzxmMzI+IHtcclxuICAgICAgICByZXR1cm4gUmVpbmhhcmRUb25lTWFwcGluZyggY29sb3IsdG9uZU1hcHBpbmdFeHBvc3VyZSApO1xyXG4gICAgfVxyXG5cclxuICAgIGZuIExpbmVhclRvTGluZWFyKCB2YWx1ZTp2ZWM0PGYzMj4gKS0+dmVjNDxmMzI+IHtcclxuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9XHJcbiAgICBmbiBsZXNzVGhhbkVxdWFsKGE6dmVjMzxmMzI+LGI6dmVjMzxmMzI+KS0+dmVjMzxmMzI+e1xyXG4gICAgICAgbGV0IHhWYWx1ZTpmMzI9c2VsZWN0KGIueCxhLngsYS54PD1iLngpO1xyXG4gICAgICAgbGV0IHlWYWx1ZTpmMzI9c2VsZWN0KGIueSxhLnksYS55PD1iLnkpO1xyXG4gICAgICAgbGV0IHpWYWx1ZTpmMzI9c2VsZWN0KGIueixhLnosYS56PD1iLnopO1xyXG4gICAgICAgcmV0dXJuIHZlYzM8ZjMyPih4VmFsdWUseVZhbHVlLHpWYWx1ZSk7ICAgIFxyXG4gICAgfVxyXG4gICAgZm4gTGluZWFyVG9zUkdCKCB2YWx1ZTp2ZWM0PGYzMj4gKS0+dmVjNDxmMzI+IHtcclxuICAgICAgICByZXR1cm4gdmVjNDxmMzI+KCBtaXgoIHBvdyggdmFsdWUucmdiLCB2ZWMzPGYzMj4oIDAuNDE2NjYgKSApICogMS4wNTUgLSB2ZWMzPGYzMj4oIDAuMDU1ICksIHZhbHVlLnJnYiAqIDEyLjkyLCB2ZWMzPGYzMj4oIGxlc3NUaGFuRXF1YWwoIHZhbHVlLnJnYiwgdmVjMzxmMzI+KCAwLjAwMzEzMDggKSApICkgKSwgdmFsdWUuYSApO1xyXG4gICAgfVxyXG4gICAgZm4gbGluZWFyVG9PdXRwdXRUZXhlbCh2YWx1ZTp2ZWM0PGYzMj4gKS0+dmVjNDxmMzI+IHtcclxuICAgICAgICByZXR1cm4gTGluZWFyVG9zUkdCKCB2YWx1ZSApO1xyXG4gICAgfVxyXG4gICAgYDtcclxufVxyXG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBibGlubl9waG9uZyhkZWZpbmVzKSB7XHJcblx0cmV0dXJuIGBcclxuICAgICAgIGZuIGdldFBvaW50TGlnaHRJbmZvKHBvaW50TGlnaHQ6UG9pbnRMaWdodCx3b3JsZFBvczp2ZWMzPGYzMj4sc2hpbmluZXNzOmYzMixOOnZlYzM8ZjMyPixWOnZlYzM8ZjMyPiktPnZlYzM8ZjMyPntcclxuICAgICAgICB2YXIgY29sb3I9dmVjMzxmMzI+KDAuMCwwLjAsMC4wKTtcclxuICAgICAgICB2YXIgZGlyZWN0aW9uOnZlYzM8ZjMyPiA9IHdvcmxkUG9zIC0gcG9pbnRMaWdodC5wb3NpdGlvbjtcclxuICAgICAgICBsZXQgZGlzdDpmMzIgPSBsZW5ndGgoIGRpcmVjdGlvbiApO1xyXG4gICAgICAgIGRpcmVjdGlvbiA9IG5vcm1hbGl6ZShkaXJlY3Rpb24pO1xyXG4gICAgICAgIGxldCBkZWNheSA9IGNsYW1wKDEuMCAtIHBvdyhkaXN0IC8gcG9pbnRMaWdodC5kaXN0YW5jZSwgNC4wKSwgMC4wLCAxLjApO1xyXG5cclxuICAgICAgICBsZXQgZCA9ICBtYXgoIGRvdCggTiwgLWRpcmVjdGlvbiApLCAwLjAgKSAqIGRlY2F5O1xyXG4gICAgICAgIGNvbG9yICs9IHBvaW50TGlnaHQuY29sb3IgKiBkO1xyXG5cclxuICAgICAgICBsZXQgaGFsZkRpcjp2ZWMzPGYzMj4gPSBub3JtYWxpemUoIFYgLSBkaXJlY3Rpb24gKTtcclxuICAgICAgICBsZXQgczpmMzIgPSBwb3coIGNsYW1wKCBkb3QoIE4sIGhhbGZEaXIgKSwgMC4wLCAxLjAgKSwgc2hpbmluZXNzICkgICogZGVjYXk7XHJcbiAgICAgICAgY29sb3IgKz0gcG9pbnRMaWdodC5jb2xvciAqIHM7XHJcbiAgICAgICAgcmV0dXJuIGNvbG9yO1xyXG4gICAgICAgfVxyXG4gICAgICAgZm4gZ2V0U3BvdExpZ2h0SW5mbyhzcG90TGlnaHQ6U3BvdExpZ2h0LHdvcmxkUG9zOnZlYzM8ZjMyPixzaGluaW5lc3M6ZjMyLE46dmVjMzxmMzI+LFY6dmVjMzxmMzI+KS0+dmVjMzxmMzI+e1xyXG4gICAgICAgIHZhciBjb2xvcj12ZWMzPGYzMj4oMC4wLDAuMCwwLjApO1xyXG4gICAgICAgICAgICB2YXIgZGlyZWN0aW9uOnZlYzM8ZjMyPiA9IHNwb3RMaWdodC5wb3NpdGlvbiAtIHdvcmxkUG9zO1xyXG4gICAgICAgICAgICBsZXQgbGlnaHREaXN0YW5jZTpmMzIgPSBsZW5ndGgoZGlyZWN0aW9uKTtcclxuICAgICAgICAgICAgZGlyZWN0aW9uID0gbm9ybWFsaXplKGRpcmVjdGlvbik7XHJcbiAgICAgICAgICAgIGxldCBhbmdsZUNvczpmMzIgPSBkb3QoIGRpcmVjdGlvbiwgLXNwb3RMaWdodC5kaXJlY3Rpb24gKTtcclxuICAgICAgICAgICAgbGV0IGRlY2F5OmYzMiA9IGNsYW1wKDEuMCAtIHBvdyhsaWdodERpc3RhbmNlL3Nwb3RMaWdodC5kaXN0YW5jZSwgNC4wKSwgMC4wLCAxLjApO1xyXG4gICAgICAgICAgICBsZXQgc3BvdEVmZmVjdDpmMzIgPSBzbW9vdGhzdGVwKCBzcG90TGlnaHQucGVudW1icmFDb3MsIHNwb3RMaWdodC5jb25lQ29zLCBhbmdsZUNvcyApO1xyXG4gICAgICAgICAgICBsZXQgZGVjYXlUb3RhbDpmMzIgPSBkZWNheSAqIHNwb3RFZmZlY3Q7XHJcbiAgICAgICAgICAgIGxldCBkOmYzMiA9IG1heCggZG90KCBOLCBkaXJlY3Rpb24gKSwgMC4wICkgICogZGVjYXlUb3RhbDtcclxuICAgICAgICAgICAgY29sb3IgKz0gc3BvdExpZ2h0LmNvbG9yICogZDtcclxuICAgICAgICAgICAgbGV0IGhhbGZEaXI6dmVjMzxmMzI+ID0gbm9ybWFsaXplKCBWICsgZGlyZWN0aW9uICk7XHJcbiAgICAgICAgICAgIGxldCBzOmYzMiA9IHBvdyggY2xhbXAoIGRvdCggTiwgaGFsZkRpciApLCAwLjAsIDEuMCApLCBzaGluaW5lc3MgKSAqIGRlY2F5VG90YWw7XHJcbiAgICAgICAgICAgIGNvbG9yICs9IHNwb3RMaWdodC5jb2xvciAqIHM7XHJcbiAgICAgICAgICAgIHJldHVybiBjb2xvcjtcclxuICAgICAgIH1cclxuICAgIHN0cnVjdCBEaXJlY3Rpb25hbExpZ2h0IHtcclxuICAgICAgICBkaXJlY3Rpb246IHZlYzM8ZjMyPixcclxuICAgICAgICBjb2xvcjogdmVjMzxmMzI+LFxyXG4gICAgfTtcclxuICAgICAgZm4gZ2V0RGlyZWN0TGlnaHRJbmZvKGRpcmVjdGlvbmFsTGlnaHQ6RGlyZWN0aW9uYWxMaWdodCxzaGluaW5lc3M6ZjMyLE46dmVjMzxmMzI+LFY6dmVjMzxmMzI+KS0+dmVjMzxmMzI+e1xyXG4gICAgICAgIHZhciBjb2xvcj12ZWMzPGYzMj4oMC4wLDAuMCwwLjApO1xyXG4gICAgICAgIGxldCBkOmYzMiA9IG1heChkb3QoTiwgLWRpcmVjdGlvbmFsTGlnaHQuZGlyZWN0aW9uKSwgMC4wKTtcclxuICAgICAgICBjb2xvciArPSBkaXJlY3Rpb25hbExpZ2h0LmNvbG9yICogZDtcclxuXHJcbiAgICAgICAgbGV0IGhhbGZEaXI6dmVjMzxmMzI+ID0gbm9ybWFsaXplKCBWIC0gZGlyZWN0aW9uYWxMaWdodC5kaXJlY3Rpb24gKTtcclxuICAgICAgICBsZXQgczpmMzIgPSBwb3coIGNsYW1wKCBkb3QoIE4sIGhhbGZEaXIgKSwgMC4wLCAxLjAgKSwgc2hpbmluZXNzICk7XHJcbiAgICAgICAgY29sb3IgKz0gZGlyZWN0aW9uYWxMaWdodC5jb2xvciAqIHM7XHJcbiAgICAgICAgcmV0dXJuIGNvbG9yO1xyXG4gICAgICAgfVxyXG4gICAgYDtcclxufVxyXG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBwaG9uZ0Z1bmN0aW9uKGRlZmluZXMpIHtcclxuICByZXR1cm4gYFxyXG4gICAgZm4gR19CbGlublBob25nX0ltcGxpY2l0KCApLT5mMzIge1xyXG5cclxuICAgICAgICAvLyBnZW9tZXRyeSB0ZXJtIGlzIChuIGRvdCBsKShuIGRvdCB2KSAvIDQobiBkb3QgbCkobiBkb3QgdilcclxuICAgICAgICByZXR1cm4gMC4yNTtcclxuXHJcbiAgICB9XHJcbiAgICBmbiBEX0JsaW5uUGhvbmcoIHNoaW5pbmVzczpmMzIsIGRvdE5IOmYzMiApLT5mMzIge1xyXG5cclxuICAgICAgICByZXR1cm4gUkVDSVBST0NBTF9QSSAqICggc2hpbmluZXNzICogMC41ICsgMS4wICkgKiBwb3coZG90TkgsIHNoaW5pbmVzcyk7XHJcblxyXG4gICAgfVxyXG4gICAgZm4gQlJERl9CbGlublBob25nKCBsaWdodERpcjp2ZWMzPGYzMj4sIHZpZXdEaXI6dmVjMzxmMzI+LCBub3JtYWw6dmVjMzxmMzI+LCBzcGVjdWxhckNvbG9yOnZlYzM8ZjMyPiwgc2hpbmluZXNzOmYzMiApLT52ZWMzPGYzMj4ge1xyXG5cclxuICAgICAgICBsZXQgIGhhbGZEaXIgPSBub3JtYWxpemUoIGxpZ2h0RGlyICsgdmlld0RpciApO1xyXG5cclxuICAgICAgICBsZXQgIGRvdE5IOmYzMiA9IHNhdHVyYXRlKCBkb3QoIG5vcm1hbCwgaGFsZkRpciApICk7XHJcbiAgICAgICAgbGV0IGRvdFZIOmYzMiA9IHNhdHVyYXRlKCBkb3QoIHZpZXdEaXIsIGhhbGZEaXIgKSApO1xyXG5cclxuICAgICAgICBsZXQgRiA9IEZfU2NobGljayggc3BlY3VsYXJDb2xvciwgMS4wLCBkb3RWSCApO1xyXG5cclxuICAgICAgICBsZXQgRzpmMzIgPSBHX0JsaW5uUGhvbmdfSW1wbGljaXQoICk7XHJcblxyXG4gICAgICAgIGxldCBEID0gRF9CbGlublBob25nKCBzaGluaW5lc3MsIGRvdE5IICk7XHJcblxyXG4gICAgICAgIHJldHVybiBGICogKCBHICogRCApO1xyXG5cclxuICAgIH0gXHJcbiAgICBmbiBSRV9EaXJlY3RfQmxpbm5QaG9uZyggIGRpcmVjdExpZ2h0OkluY2lkZW50TGlnaHQsZ2VvbWV0cnk6R2VvbWV0cmljQ29udGV4dCwgbWF0ZXJpYWw6Qmxpbm5QaG9uZ01hdGVyaWFsICktPlJlZmxlY3RlZExpZ2h0e1xyXG4gICAgICAgIHZhciByZWZsZWN0ZWRMaWdodDpSZWZsZWN0ZWRMaWdodDsgXHJcbiAgICAgICAgbGV0IGRvdE5MOmYzMiA9IHNhdHVyYXRlKGRvdChnZW9tZXRyeS5ub3JtYWwsIGRpcmVjdExpZ2h0LmRpcmVjdGlvbikpO1xyXG4gICAgICAgIGxldCBpcnJhZGlhbmNlOnZlYzM8ZjMyPiA9IGRvdE5MKmRpcmVjdExpZ2h0LmNvbG9yO1xyXG5cclxuICAgICAgICByZWZsZWN0ZWRMaWdodC5kaXJlY3REaWZmdXNlPSBpcnJhZGlhbmNlICogQlJERl9MYW1iZXJ0KCBtYXRlcmlhbC5kaWZmdXNlQ29sb3IgKTtcclxuXHJcbiAgICAgICAgcmVmbGVjdGVkTGlnaHQuZGlyZWN0U3BlY3VsYXI9IGlycmFkaWFuY2UgKiBCUkRGX0JsaW5uUGhvbmcoIGRpcmVjdExpZ2h0LmRpcmVjdGlvbiwgZ2VvbWV0cnkudmlld0RpciwgZ2VvbWV0cnkubm9ybWFsLCBtYXRlcmlhbC5zcGVjdWxhckNvbG9yLCBtYXRlcmlhbC5zcGVjdWxhclNoaW5pbmVzcyApICogbWF0ZXJpYWwuc3BlY3VsYXJTdHJlbmd0aDtcclxuICAgICAgICByZXR1cm4gcmVmbGVjdGVkTGlnaHQ7XHJcbiAgICB9XHJcbiAgICBmbiBSRV9JbmRpcmVjdERpZmZ1c2VfQmxpbm5QaG9uZyggaXJyYWRpYW5jZTp2ZWMzPGYzMj4sIGdlb21ldHJ5Okdlb21ldHJpY0NvbnRleHQsIG1hdGVyaWFsOkJsaW5uUGhvbmdNYXRlcmlhbCktPlJlZmxlY3RlZExpZ2h0IHtcclxuICAgICAgICB2YXIgcmVmbGVjdGVkTGlnaHQ6UmVmbGVjdGVkTGlnaHQ7IFxyXG4gICAgICAgIHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0RGlmZnVzZSArPSBpcnJhZGlhbmNlICogQlJERl9MYW1iZXJ0KCBtYXRlcmlhbC5kaWZmdXNlQ29sb3IgKTtcclxuICAgICAgICByZXR1cm4gcmVmbGVjdGVkTGlnaHQ7XHJcbiAgICB9XHJcbiAgICBgO1xyXG59XHJcbiIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHBob25nVXRpbHMoZGVmaW5lcykge1xyXG4gIHJldHVybiBgXHJcbiAgIHN0cnVjdCBCbGlublBob25nTWF0ZXJpYWwge1xyXG4gICAgICAgIGRpZmZ1c2VDb2xvcjp2ZWMzPGYzMj4sXHJcbiAgICAgICAgc3BlY3VsYXJDb2xvcjp2ZWMzPGYzMj4sXHJcbiAgICAgICAgc3BlY3VsYXJTaGluaW5lc3M6ZjMyLFxyXG4gICAgICAgIHNwZWN1bGFyU3RyZW5ndGg6ZjMyLFxyXG4gICAgfTtcclxuICAgIGNvbnN0IFJFQ0lQUk9DQUxfUEk6ZjMyPSAwLjMxODMwOTg4NjE4Mzc5MDc7XHJcbiAgIGZuIHBvdzIoIHg6ZjMyICktPmYzMiB7IHJldHVybiB4Kng7IH1cclxuICAgZm4gcG93MyggeDpmMzIgKS0+ZjMyIHsgcmV0dXJuIHgqeCp4OyB9XHJcbiAgIGZuIHBvdzQoeDpmMzIgKS0+ZjMyIHsgbGV0IHgyID0geCp4OyByZXR1cm4geDIqeDI7IH1cclxuICAgZm4gbWF4Myggdjp2ZWMzPGYzMj4gKS0+ZjMyIHsgcmV0dXJuIG1heCggbWF4KCB2LngsIHYueSApLCB2LnogKTsgfVxyXG4gICBmbiBhdmVyYWdlKHY6dmVjMzxmMzI+ICktPmYzMiB7IFxyXG4gICAgICAgbGV0IHJlc3VsdD12ZWMzPGYzMj4oIDAuMzMzMzMzMywgIDAuMzMzMzMzMywgMC4zMzMzMzMzKTtcclxuICAgICAgIHJldHVybiBkb3QoIHYscmVzdWx0ICk7IFxyXG4gICB9XHJcbiAgIGA7XHJcbn1cclxuIiwiaW1wb3J0IHsgd2dzbFBhcnNlRGVmaW5lcyB9IGZyb20gXCIuLi8uLi9XZ3NsUHJlcHJvY2Vzc29yXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTa2luTWF0cml4KGRlZmluZXMpIHtcblx0cmV0dXJuIHdnc2xQYXJzZURlZmluZXNgXG4gICAjaWYgJHtkZWZpbmVzLkhBU19TS0lOfSBcbiAgICAgICAgc3RydWN0IEpvaW50c1VuaWZvcm17XG4gICAgICAgICAgICAgbWF0cml4czphcnJheTxtYXQ0eDRmPixcbiAgICAgICAgfVxuICAgICAgICBzdHJ1Y3QgSW52ZXJzZUJpbmRNYXRyaWNlc1VuaWZvcm17XG4gICAgICAgICAgICBtYXRyaXhzOmFycmF5PG1hdDR4NGY+LFxuICAgICAgICB9XG4gICAgICAgIEBiaW5kaW5nKCR7ZGVmaW5lcy5za2luSm9pbnRzQnVmZmVyQmluZGluZ30pIEBncm91cCgwKSB2YXI8c3RvcmFnZSwgcmVhZD4gam9pbnRzVW5pZm9ybSA6IEpvaW50c1VuaWZvcm07XG4gICAgICAgIEBiaW5kaW5nKCR7ZGVmaW5lcy5pbnZzQnVmZmVyQmluZGluZ30pIEBncm91cCgwKSB2YXI8c3RvcmFnZSwgcmVhZD4gaW52ZXJzZUJpbmRNYXRyaWNlc1VuaWZvcm0gOiBJbnZlcnNlQmluZE1hdHJpY2VzVW5pZm9ybTtcbiAgICAgICAgZm4gZ2V0U2tpbk1hdHJpeChqb2ludHM6IHZlYzRmLCB3ZWlnaHRzOiB2ZWM0ZikgLT4gbWF0NHg0PGYzMj4ge1xuICAgICAgICAgICAgbGV0IGpvaW50MCA9IGpvaW50c1VuaWZvcm0ubWF0cml4c1t1MzIoam9pbnRzLngpXSAqIGludmVyc2VCaW5kTWF0cmljZXNVbmlmb3JtLm1hdHJpeHNbdTMyKGpvaW50cy54KV07XG4gICAgICAgICAgICBsZXQgam9pbnQxID0gam9pbnRzVW5pZm9ybS5tYXRyaXhzW3UzMihqb2ludHMueSldICogaW52ZXJzZUJpbmRNYXRyaWNlc1VuaWZvcm0ubWF0cml4c1t1MzIoam9pbnRzLnkpXTtcbiAgICAgICAgICAgIGxldCBqb2ludDIgPSBqb2ludHNVbmlmb3JtLm1hdHJpeHNbdTMyKGpvaW50cy56KV0gKiBpbnZlcnNlQmluZE1hdHJpY2VzVW5pZm9ybS5tYXRyaXhzW3UzMihqb2ludHMueildO1xuICAgICAgICAgICAgbGV0IGpvaW50MyA9IGpvaW50c1VuaWZvcm0ubWF0cml4c1t1MzIoam9pbnRzLncpXSAqIGludmVyc2VCaW5kTWF0cmljZXNVbmlmb3JtLm1hdHJpeHNbdTMyKGpvaW50cy53KV07XG4gICAgICAgIFxuICAgICAgICAgICAgbGV0IHNraW5NYXRyaXggPSBqb2ludDAgKiB3ZWlnaHRzLnggK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpvaW50MSAqIHdlaWdodHMueSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgam9pbnQyICogd2VpZ2h0cy56ICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqb2ludDMgKiB3ZWlnaHRzLnc7XG4gICAgICAgICAgICByZXR1cm4gc2tpbk1hdHJpeDtcbiAgICAgICAgfVxuICAgICAgICAjZW5kaWZcbiAgIGA7XG59XG5leHBvcnQgZnVuY3Rpb24gc2tpblZlcnRIZWFkZXIoZGVmaW5lcykge1xuXHRyZXR1cm4gd2dzbFBhcnNlRGVmaW5lc2BcbiAgICNpZiAke2RlZmluZXMuSEFTX1NLSU59IFxuICAgICAgICBzdHJ1Y3QgSm9pbnRzVW5pZm9ybXtcbiAgICAgICAgICAgICBtYXRyaXhzOmFycmF5PG1hdDR4NGY+LFxuICAgICAgICB9XG4gICAgICAgIHN0cnVjdCBJbnZlcnNlQmluZE1hdHJpY2VzVW5pZm9ybXtcbiAgICAgICAgICAgIG1hdHJpeHM6YXJyYXk8bWF0NHg0Zj4sXG4gICAgICAgIH1cbiAgICAgICAgQGJpbmRpbmcoJHtkZWZpbmVzLnNraW5Kb2ludHNCdWZmZXJCaW5kaW5nfSkgQGdyb3VwKDApIHZhcjxzdG9yYWdlLCByZWFkPiBqb2ludHNVbmlmb3JtIDogSm9pbnRzVW5pZm9ybTtcbiAgICAgICAgQGJpbmRpbmcoJHtkZWZpbmVzLmludnNCdWZmZXJCaW5kaW5nfSkgQGdyb3VwKDApIHZhcjxzdG9yYWdlLCByZWFkPiBpbnZlcnNlQmluZE1hdHJpY2VzVW5pZm9ybSA6IEludmVyc2VCaW5kTWF0cmljZXNVbmlmb3JtO1xuICAgICAgICBmbiBnZXRTa2luTWF0cml4KGpvaW50czogdmVjNGYsIHdlaWdodHM6IHZlYzRmKSAtPiBtYXQ0eDQ8ZjMyPiB7XG4gICAgICAgICAgICBsZXQgam9pbnQwID0gam9pbnRzVW5pZm9ybS5tYXRyaXhzW3UzMihqb2ludHMueCldICogaW52ZXJzZUJpbmRNYXRyaWNlc1VuaWZvcm0ubWF0cml4c1t1MzIoam9pbnRzLngpXTtcbiAgICAgICAgICAgIGxldCBqb2ludDEgPSBqb2ludHNVbmlmb3JtLm1hdHJpeHNbdTMyKGpvaW50cy55KV0gKiBpbnZlcnNlQmluZE1hdHJpY2VzVW5pZm9ybS5tYXRyaXhzW3UzMihqb2ludHMueSldO1xuICAgICAgICAgICAgbGV0IGpvaW50MiA9IGpvaW50c1VuaWZvcm0ubWF0cml4c1t1MzIoam9pbnRzLnopXSAqIGludmVyc2VCaW5kTWF0cmljZXNVbmlmb3JtLm1hdHJpeHNbdTMyKGpvaW50cy56KV07XG4gICAgICAgICAgICBsZXQgam9pbnQzID0gam9pbnRzVW5pZm9ybS5tYXRyaXhzW3UzMihqb2ludHMudyldICogaW52ZXJzZUJpbmRNYXRyaWNlc1VuaWZvcm0ubWF0cml4c1t1MzIoam9pbnRzLncpXTtcbiAgICAgICAgXG4gICAgICAgICAgICBsZXQgc2tpbk1hdHJpeCA9IGpvaW50MCAqIHdlaWdodHMueCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgam9pbnQxICogd2VpZ2h0cy55ICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqb2ludDIgKiB3ZWlnaHRzLnogK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpvaW50MyAqIHdlaWdodHMudztcbiAgICAgICAgICAgIHJldHVybiBza2luTWF0cml4O1xuICAgICAgICB9XG4gICAgICAgICNlbmRpZlxuICAgYDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBza2luVmVydE1haW4oZGVmaW5lcykge1xuXHRyZXR1cm4gd2dzbFBhcnNlRGVmaW5lc2BcbiAgICAgICAgI2lmICR7ZGVmaW5lcy5IQVNfU0tJTn1cbiAgICAgICAgICAgIG1vZGVsTWF0cml4ID1nZXRTa2luTWF0cml4KGlucHV0LmpvaW50MCxpbnB1dC53ZWlnaHQwKTtcbiAgICAgICAgICAgIHZOb3JtYWxWaWV3ID0gbm9ybWFsaXplKChtYXRlcmlhbFVuaWZvcm0ubm9ybWFsTWF0cml4ICogbW9kZWxNYXRyaXggKiB2ZWM0PGYzMj4oaW5wdXQubm9ybWFsLCAwLjApKS54eXopO1xuICAgICAgICAjZW5kaWZcbiAgYDtcbn1cbiIsImltcG9ydCB7IHdnc2xQYXJzZURlZmluZXMgfSBmcm9tIFwiLi4vLi4vV2dzbFByZXByb2Nlc3NvclwiO1xuXG5leHBvcnQgZnVuY3Rpb24gUGJyTWF0ZXJpYWxTdHJ1Y3QoZGVmaW5lcykge1xuXHRyZXR1cm4gd2dzbFBhcnNlRGVmaW5lc2BcbiAgICBzdHJ1Y3QgTWF0ZXJpYWxVbmlmb3JtIHtcbiAgICAgICAgICBtb2RlbE1hdHJpeDogbWF0NHg0PGYzMj4sXG4gICAgICAgICAgY29sb3I6IHZlYzM8ZjMyPixcbiAgICAgICAgICBvcGFjaXR5OmYzMixcbiAgICAgICAgICBub3JtYWxNYXRyaXg6IG1hdDR4NDxmMzI+LFxuICAgICAgICAgIGVtaXNzaXZlOnZlYzM8ZjMyPixcbiAgICAgICAgICBtZXRhbGxpYzpmMzIsXG4gICAgICAgICAgcm91Z2huZXNzOmYzMixcbiAgICAgICAgICAjaWYgJHtkZWZpbmVzLlVTRV9OT1JNQUxURVhUVVJFfVxuICAgICAgICAgICAgICBub3JtYWxUZXh0dXJlU2NhbGU6dmVjMjxmMzI+LFxuICAgICAgICAgICNlbmRpZlxuICAgICAgICAgICNpZiAke2RlZmluZXMuVVNFX0FPVEVYVFVSRX1cbiAgICAgICAgICAgICAgb2NjbHVzaW9uU3RyZW5ndGg6ZjMyLFxuICAgICAgICAgICNlbmRpZlxuICAgICAgfVxuICAgYDtcbn1cbiIsImltcG9ydCB7IEZyYWdJbnB1dCB9IGZyb20gXCIuL2F0dHJpYnV0ZS9GcmFnSW5wdXRcIjtcbmltcG9ydCB7IFBvaW50RnJhZ0lucHV0IH0gZnJvbSBcIi4vYXR0cmlidXRlL1BvaW50RnJhZ0lucHV0XCI7XG5pbXBvcnQgeyBQb2ludFZlcnRJbnB1dCB9IGZyb20gXCIuL2F0dHJpYnV0ZS9Qb2ludFZlcnRJbnB1dFwiO1xuaW1wb3J0IHsgUG9pbnRWZXJ0T3V0cHV0IH0gZnJvbSBcIi4vYXR0cmlidXRlL1BvaW50VmVydE91dHB1dFwiO1xuaW1wb3J0IHsgVmVydGV4SW5wdXQgfSBmcm9tIFwiLi9hdHRyaWJ1dGUvVmVydGV4SW5wdXRcIjtcbmltcG9ydCB7IFZlcnRleE91dHB1dCB9IGZyb20gXCIuL2F0dHJpYnV0ZS9WZXJ0ZXhPdXRwdXRcIjtcbmltcG9ydCB7IFN5c3RlbVVuaWZvcm0gfSBmcm9tIFwiLi9jb21tb24vU3lzdGVtVW5pZm9ybVwiO1xuaW1wb3J0IHsgVGV4dHVyZUFuZFNhbXBsZXJEZWZpbmUgfSBmcm9tIFwiLi9jb21tb24vVGV4dHVyZUFuZFNhbXBsZXJEZWZpbmVcIjtcbmltcG9ydCBlbnZpcm9ubWVudCBmcm9tIFwiLi9lbnZpcm9ubWVudC9lbnZpcm9ubWVudFwiO1xuaW1wb3J0IHsgaW5zdGFuY2VWZXJ0SGVhZGVyLCBpbnN0YW5jZVZlcnRNYWluIH0gZnJvbSBcIi4vaW5zdGFuY2UvSW5zdGFuY2VcIjtcbmltcG9ydCBsaWdodCBmcm9tIFwiLi9saWdodC9saWdodFwiO1xuaW1wb3J0IGxpZ2h0Q29tbW9uIGZyb20gXCIuL2xpZ2h0L2xpZ2h0Q29tbW9uXCI7XG5pbXBvcnQgeyBnZXROb3JtYWxCeU5vcm1hbFRleHR1cmUsIGdldFRCTiwgZ2V0Tm9ybWFsIH0gZnJvbSBcIi4vbm9ybWFsL2dldE5vcm1hbEJhY2tVcFwiO1xuaW1wb3J0IGJyZGYgZnJvbSBcIi4vcGJyL2JyZGZcIjtcbmltcG9ydCBpYmwgZnJvbSBcIi4vcGJyL2libFwiO1xuaW1wb3J0IHBickZ1bmN0aW9uIGZyb20gXCIuL3Bici9wYnJGdW5jdGlvblwiO1xuaW1wb3J0IHBiclN0cnVjdCBmcm9tIFwiLi9wYnIvcGJyU3RydWN0XCI7XG5pbXBvcnQgcGJyVGV4dHVyZSBmcm9tIFwiLi9wYnIvcGJyVGV4dHVyZVwiO1xuaW1wb3J0IHBiclV0aWxzIGZyb20gXCIuL3Bici9wYnJVdGlsc1wiO1xuaW1wb3J0IGJsaW5uX3Bob25nIGZyb20gXCIuL3Bob25nL2JsaW5uX3Bob25nXCI7XG5pbXBvcnQgcGhvbmdGdW5jdGlvbiBmcm9tIFwiLi9waG9uZy9waG9uZ0Z1bmN0aW9uXCI7XG5pbXBvcnQgcGhvbmdVdGlscyBmcm9tIFwiLi9waG9uZy9waG9uZ1V0aWxzXCI7XG4vLyBpbXBvcnQgZ2V0Tm9ybWFsIGZyb20gXCIuL25vcm1hbC9nZXROb3JtYWxcIjtcbmltcG9ydCB7IHNraW5WZXJ0SGVhZGVyLCBza2luVmVydE1haW4gfSBmcm9tIFwiLi9za2luL1NraW5WZXJ0XCI7XG5pbXBvcnQgeyBQYnJNYXRlcmlhbFN0cnVjdCB9IGZyb20gXCIuL3N0cnVjdC9QYnJNYXRlcmlhbFN0cnVjdFwiO1xuY29uc3QgU2hhZGVyQ2h1bmsgPSB7XG5cdGxpZ2h0LFxuXHRicmRmLFxuXHRwaG9uZ0Z1bmN0aW9uLFxuXHRwaG9uZ1V0aWxzLFxuXHRsaWdodENvbW1vbixcblx0cGJyU3RydWN0LFxuXHRwYnJGdW5jdGlvbixcblx0cGJyVGV4dHVyZSxcblx0cGJyVXRpbHMsXG5cdGVudmlyb25tZW50LFxuXHRibGlubl9waG9uZyxcblx0Z2V0Tm9ybWFsLFxuXHRnZXRUQk4sXG5cdGdldE5vcm1hbEJ5Tm9ybWFsVGV4dHVyZSxcblx0aWJsLFxuXHRza2luVmVydE1haW4sXG5cdHNraW5WZXJ0SGVhZGVyLFxuXHRGcmFnSW5wdXQsXG5cdFZlcnRleElucHV0LFxuXHRWZXJ0ZXhPdXRwdXQsXG5cdFBick1hdGVyaWFsU3RydWN0LFxuXHRTeXN0ZW1Vbmlmb3JtLFxuXHRpbnN0YW5jZVZlcnRNYWluLFxuXHRpbnN0YW5jZVZlcnRIZWFkZXIsXG5cdFRleHR1cmVBbmRTYW1wbGVyRGVmaW5lLFxuXHRQb2ludFZlcnRJbnB1dCxcblx0UG9pbnRWZXJ0T3V0cHV0LFxuXHRQb2ludEZyYWdJbnB1dFxufTtcbmV4cG9ydCBkZWZhdWx0IFNoYWRlckNodW5rO1xuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gc2hhZG93TWFwRGVidWdnZXJGcmFnKGRlZmluZXMpIHtcclxuXHRyZXR1cm4gYFxyXG4gICAgQGdyb3VwKDApIEBiaW5kaW5nKDEpIHZhciBzaGFkb3dTYW1wbGVyOiBzYW1wbGVyO1xyXG4gICAgQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhciBzaGFkb3dNYXA6IHRleHR1cmVfZGVwdGhfMmQ7XHJcbiAgICBcclxuICAgIC8vIEBncm91cCgwKSBAYmluZGluZygwKSB2YXIgc2hhZG93TWFwOiB0ZXh0dXJlX2RlcHRoXzJkX2FycmF5O1xyXG4gICAgLy8gQGdyb3VwKDApIEBiaW5kaW5nKDApIHZhciBzaGFkb3dNYXA6IHRleHR1cmVfMmQ8ZjMyPjtcclxuXHJcbiAgICBzdHJ1Y3QgVmVydGV4T3V0cHV0IHtcclxuICAgICAgICBAYnVpbHRpbihwb3NpdGlvbikgcG9zaXRpb246IHZlYzQ8ZjMyPixcclxuICAgICAgICBAbG9jYXRpb24oMCkgdXY6IHZlYzI8ZjMyPixcclxuICAgIH07XHJcblxyXG4gICAgZm4gbGluZWFyaXplRGVwdGgoZGVwdGg6IGYzMiwgbmVhcjogZjMyLCBmYXI6IGYzMiktPmYzMiB7XHJcbiAgICAgIHJldHVybiAyICogKG5lYXIgKiBmYXIpIC8gKGZhciArIG5lYXIgLSBkZXB0aCAqIChmYXIgLSBuZWFyKSk7XHJcbiAgICB9XHJcblxyXG4gICAgQGZyYWdtZW50XHJcbiAgICBmbiBtYWluKGlucHV0OlZlcnRleE91dHB1dCkgLT4gQGxvY2F0aW9uKDApIHZlYzQ8ZjMyPiB7XHJcblx0XHRcdGxldCBjb2xvcjogdmVjNDxmMzI+ID0gdGV4dHVyZUdhdGhlcihzaGFkb3dNYXAsIHNoYWRvd1NhbXBsZXIsIHZlYzI8ZjMyPihpbnB1dC51di54LDEuMC1pbnB1dC51di55KSk7XHJcbiAgICAgIGxldCBkZXB0aCA9IChsaW5lYXJpemVEZXB0aChjb2xvci5yLCAwLjEsIDUwMCkgLSAwLjEpIC8gKDUwMCAtIDAuMSk7XHJcbiAgICAgIHJldHVybiB2ZWM0KHZlYzMoZGVwdGgpLCAxLjApOyAvLyBQZXJzcGVjdGl2ZUNhbWVyYVxyXG4gICAgICAvLyByZXR1cm4gY29sb3I7XHJcblxyXG4gICAgICAvLyByZXR1cm4gdGV4dHVyZVNhbXBsZShzaGFkb3dNYXAsIHNoYWRvd1NhbXBsZXIsIHZlYzI8ZjMyPihpbnB1dC51di54LDEuMC1pbnB1dC51di55KSk7XHJcblxyXG4gICAgfVxyXG4gICAgYDtcclxufVxyXG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBzaGFkb3dNYXBEZWJ1Z2dlclZlcnQoZGVmaW5lcykge1xyXG5cdHJldHVybiBgXHJcbiAgICBzdHJ1Y3QgVmVydGV4SW5wdXQge1xyXG4gICAgICAgICBAbG9jYXRpb24oJHtkZWZpbmVzLnBvc2l0aW9uTG9jYXRpb259KSBwb3NpdGlvbjogdmVjMjxmMzI+LCAgICAgICBcclxuICAgIH1cclxuICAgIHN0cnVjdCBWZXJ0ZXhPdXRwdXQge1xyXG4gICAgICAgICBAYnVpbHRpbihwb3NpdGlvbikgcG9zaXRpb246IHZlYzQ8ZjMyPixcclxuICAgICAgICAgQGxvY2F0aW9uKDApIHV2OiB2ZWMyPGYzMj4sXHJcbiAgICAgfTtcclxuICAgIEB2ZXJ0ZXhcclxuICAgIGZuIG1haW4oaW5wdXQ6IFZlcnRleElucHV0KSAtPiBWZXJ0ZXhPdXRwdXQge1xyXG4gICAgIHZhciBvdXRwdXQ6VmVydGV4T3V0cHV0O1xyXG4gICAgIG91dHB1dC51diA9IGlucHV0LnBvc2l0aW9uICogMC41ICsgMC41O1xyXG4gICAgIG91dHB1dC5wb3NpdGlvbiA9IHZlYzQ8ZjMyPihpbnB1dC5wb3NpdGlvbiwgMC4wLCAxLjApOztcclxuICAgICByZXR1cm4gb3V0cHV0O1xyXG4gICAgfVxyXG4gICAgYDtcclxufVxyXG4iLCIvLyBpbXBvcnQgQ29sb3IgZnJvbSBcIi4uLy4uL21hdGgvQ29sb3JcIjtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHNoYWRvd01hcEZyYWcoZGVmaW5lcykge1xyXG5cdHJldHVybiBgXHJcbiAgICBzdHJ1Y3QgVmVydGV4T3V0cHV0IHtcclxuICAgICAgICBAYnVpbHRpbihwb3NpdGlvbikgcG9zaXRpb246IHZlYzQ8ZjMyPixcclxuICAgICAgICBAbG9jYXRpb24oMCkgY29sb3I6IHZlYzQ8ZjMyPixcclxuICAgIH07XHJcbiAgICBAZnJhZ21lbnRcclxuICAgIGZuIG1haW4oaW5wdXQ6VmVydGV4T3V0cHV0KSAtPiBAbG9jYXRpb24oMCkgdmVjNDxmMzI+IHtcclxuICAgICAgcmV0dXJuIGlucHV0LmNvbG9yO1xyXG4gICAgfVxyXG4gICAgYDtcclxufVxyXG4iLCJpbXBvcnQgeyB3Z3NsUGFyc2VEZWZpbmVzIH0gZnJvbSBcIi4uLy4uL1dnc2xQcmVwcm9jZXNzb3JcIjtcclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gc2hhZG93TWFwVmVydChkZWZpbmVzKSB7XHJcblx0cmV0dXJuIHdnc2xQYXJzZURlZmluZXNgXHJcbiAgIHN0cnVjdCBWZXJ0ZXhJbnB1dCB7XHJcbiAgICAgIEBsb2NhdGlvbigke2RlZmluZXMucG9zaXRpb25Mb2NhdGlvbn0pIHBvc2l0aW9uOiB2ZWMzPGYzMj4sICAgICAgIFxyXG4gICB9O1xyXG4gICBzdHJ1Y3QgVmVydGV4T3V0cHV0IHtcclxuICAgICAgQGJ1aWx0aW4ocG9zaXRpb24pIHBvc2l0aW9uOiB2ZWM0PGYzMj4sXHJcbiAgICB9O1xyXG4gICBzdHJ1Y3QgU2VsZlVuaWZvcm0ge1xyXG4gICAgICBtb2RlbE1hdHJpeDogbWF0NHg0PGYzMj4sXHJcbiAgIH07XHJcbiAgIHN0cnVjdCBTeXN0ZW1Vbmlmb3JtIHtcclxuICAgICAgcHJvamVjdGlvbk1hdHJpeDogbWF0NHg0PGYzMj4sXHJcbiAgICAgIHZpZXdNYXRyaXg6IG1hdDR4NDxmMzI+LFxyXG4gICAgICBpbnZlcnNlVmlld01hdHJpeDogbWF0NHg0PGYzMj4sXHJcbiAgICAgIGNhbWVyYVBvc2l0aW9uOiB2ZWMzPGYzMj4sXHJcbiAgIH07XHJcblxyXG4gICAjaWYgJHtkZWZpbmVzLmlzUG9pbnRMaWdodFNoYWRvd01hcH1cclxuICAgICAgc3RydWN0IFBvaW50TGlnaHRVbmlmb3JtIHtcclxuICAgICAgICAgdnBNYXRyaXg6IG1hdDR4NDxmMzI+LFxyXG4gICAgICAgICAvLyB2cE1hdHJpeEFycmF5OiBhcnJheTxtYXQ0eDQ8ZjMyPiwgNj4sXHJcbiAgICAgIH07XHJcbiAgICAgIEBncm91cCgxKSBAYmluZGluZygke2RlZmluZXMucG9pbnRMaWdodFNoYWRvd0NhbWVyYUJpbmRpbmd9KSB2YXI8c3RvcmFnZSwgcmVhZD4gcG9pbnRMaWdodFVuaWZvcm06IFBvaW50TGlnaHRVbmlmb3JtO1xyXG4gICAjZW5kaWZcclxuXHJcbiAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMuc2VsZkJpbmRpbmd9KSB2YXI8dW5pZm9ybT4gc2VsZlVuaWZvcm0gOiBTZWxmVW5pZm9ybTtcclxuICAgQGdyb3VwKDEpIEBiaW5kaW5nKCR7ZGVmaW5lcy5jYW1lcmFCaW5kaW5nfSkgdmFyPHVuaWZvcm0+IHN5c3RlbVVuaWZvcm0gOiBTeXN0ZW1Vbmlmb3JtO1xyXG5cclxuICAgQHZlcnRleFxyXG4gICBmbiBtYWluKGlucHV0OiBWZXJ0ZXhJbnB1dCkgLT4gVmVydGV4T3V0cHV0IHtcclxuICAgICAgdmFyIG91dHB1dDpWZXJ0ZXhPdXRwdXQ7XHJcbiAgICAgICNpZiAke2RlZmluZXMuaXNQb2ludExpZ2h0U2hhZG93TWFwfVxyXG4gICAgICAgICBvdXRwdXQucG9zaXRpb24gPSBwb2ludExpZ2h0VW5pZm9ybS52cE1hdHJpeCAqIHNlbGZVbmlmb3JtLm1vZGVsTWF0cml4ICogdmVjNDxmMzI+KGlucHV0LnBvc2l0aW9uLDEuMCk7XHJcbiAgICAgICNlbHNlXHJcbiAgICAgICAgIG91dHB1dC5wb3NpdGlvbiA9IHN5c3RlbVVuaWZvcm0ucHJvamVjdGlvbk1hdHJpeCAqIHN5c3RlbVVuaWZvcm0udmlld01hdHJpeCAqIHNlbGZVbmlmb3JtLm1vZGVsTWF0cml4ICogdmVjNDxmMzI+KGlucHV0LnBvc2l0aW9uLDEuMCk7XHJcbiAgICAgICNlbmRpZlxyXG4gICAgICByZXR1cm4gb3V0cHV0O1xyXG4gICB9XHJcbiAgIGA7XHJcbn1cclxuIiwiaW1wb3J0IGNvbG9yRnJhZyBmcm9tIFwiLi9tYXRlcmlhbC9jb2xvckZyYWdcIjtcbmltcG9ydCBjb2xvclZlcnQgZnJvbSBcIi4vbWF0ZXJpYWwvY29sb3JWZXJ0XCI7XG5pbXBvcnQgcGJyX2ZzIGZyb20gXCIuL21hdGVyaWFsL3Bicl9mc1wiO1xuaW1wb3J0IHBicl92cyBmcm9tIFwiLi9tYXRlcmlhbC9wYnJfdnNcIjtcbmltcG9ydCBwYnJGcmFnIGZyb20gXCIuL21hdGVyaWFsL3BickZyYWdcIjtcbmltcG9ydCBwYnJWZXJ0IGZyb20gXCIuL21hdGVyaWFsL3BiclZlcnRcIjtcbmltcG9ydCBwaG9uZ0ZyYWcgZnJvbSBcIi4vbWF0ZXJpYWwvcGhvbmdGcmFnXCI7XG5pbXBvcnQgcGhvbmdWZXJ0IGZyb20gXCIuL21hdGVyaWFsL3Bob25nVmVydFwiO1xuaW1wb3J0IHsgcG9pbnRfZnMgfSBmcm9tIFwiLi9tYXRlcmlhbC9wb2ludF9mc1wiO1xuaW1wb3J0IHsgcG9pbnRfdnMgfSBmcm9tIFwiLi9tYXRlcmlhbC9wb2ludF92c1wiO1xuaW1wb3J0IHF1YWRGcmFnIGZyb20gXCIuL21hdGVyaWFsL3F1YWRGcmFnXCI7XG5pbXBvcnQgcXVhZFZlcnQgZnJvbSBcIi4vbWF0ZXJpYWwvcXVhZFZlcnRcIjtcbmltcG9ydCBza3lCb3hGcmFnIGZyb20gXCIuL21hdGVyaWFsL3NreUJveEZyYWdcIjtcbmltcG9ydCBza3lCb3hWZXJ0IGZyb20gXCIuL21hdGVyaWFsL3NreUJveFZlcnRcIjtcbmltcG9ydCB7IHNwcml0ZV9mcyB9IGZyb20gXCIuL21hdGVyaWFsL3Nwcml0ZV9mc1wiO1xuaW1wb3J0IHsgc3ByaXRlX3ZzIH0gZnJvbSBcIi4vbWF0ZXJpYWwvc3ByaXRlX3ZzXCI7XG5pbXBvcnQgYmxlbmRGcmFnIGZyb20gXCIuL3Bvc3RQcm9jZXNzL2JsZW5kL2JsZW5kRnJhZ1wiO1xuaW1wb3J0IEJsdXIgZnJvbSBcIi4vcG9zdFByb2Nlc3MvYmxvb20vQmx1clwiO1xuaW1wb3J0IEx1bWlub3NpdHlIaWdoIGZyb20gXCIuL3Bvc3RQcm9jZXNzL2Jsb29tL0x1bWlub3NpdHlIaWdoXCI7XG5pbXBvcnQgU2hhZGVyQ2h1bmsgZnJvbSBcIi4vc2hhZGVyQ2h1bmsvU2hhZGVyQ2h1bmtcIjtcbmltcG9ydCBzaGFkb3dNYXBEZWJ1Z2dlckZyYWcgZnJvbSBcIi4vc2hhZGVyQ2h1bmsvc2hhZG93L3NoYWRvd01hcERlYnVnZ2VyRnJhZ1wiO1xuaW1wb3J0IHNoYWRvd01hcERlYnVnZ2VyVmVydCBmcm9tIFwiLi9zaGFkZXJDaHVuay9zaGFkb3cvc2hhZG93TWFwRGVidWdnZXJWZXJ0XCI7XG5pbXBvcnQgc2hhZG93TWFwRnJhZyBmcm9tIFwiLi9zaGFkZXJDaHVuay9zaGFkb3cvc2hhZG93TWFwRnJhZ1wiO1xuaW1wb3J0IHNoYWRvd01hcFZlcnQgZnJvbSBcIi4vc2hhZGVyQ2h1bmsvc2hhZG93L3NoYWRvd01hcFZlcnRcIjtcblxuZnVuY3Rpb24gcmVkdWNlQ29tbWEoc2hhZGVyKSB7XG5cdC8vIOWvueaJgOacieeahGluY2x1ZGXlpITnkIZcblx0cmV0dXJuIHNoYWRlciAhPSB1bmRlZmluZWQgPyByZXNvbHZlSW5jbHVkZXMoc2hhZGVyKSA6IHVuZGVmaW5lZDtcbn1cbmNvbnN0IGluY2x1ZGVQYXR0ZXJuID0gL15bIFxcdF0qI2luY2x1ZGUgKzwoW1xcd1xcZC4vXSspPi9nbTtcbmxldCBjdXJyZW50RGVmaW5lcyA9IHt9O1xuY29uc3Qgc2hhZGVycyA9IHtcblx0cGhvbmc6IHtcblx0XHRmcmFnOiBwaG9uZ0ZyYWcsXG5cdFx0dmVydDogcGhvbmdWZXJ0XG5cdH0sXG5cdGNvbG9yOiB7XG5cdFx0ZnJhZzogY29sb3JGcmFnLFxuXHRcdHZlcnQ6IGNvbG9yVmVydFxuXHR9LFxuXHRwYnI6IHtcblx0XHRmcmFnOiBwYnJGcmFnLFxuXHRcdHZlcnQ6IHBiclZlcnRcblx0fSxcblx0c2t5Ym94OiB7XG5cdFx0ZnJhZzogc2t5Qm94RnJhZyxcblx0XHR2ZXJ0OiBza3lCb3hWZXJ0XG5cdH0sXG5cdHJlc29sdmU6IHtcblx0XHRmcmFnOiBxdWFkRnJhZyxcblx0XHR2ZXJ0OiBxdWFkVmVydFxuXHR9LFxuXHRwYnJfbWF0OiB7XG5cdFx0ZnJhZzogcGJyX2ZzLFxuXHRcdHZlcnQ6IHBicl92c1xuXHR9LFxuXHRibHVyOiB7XG5cdFx0ZnJhZzogQmx1cixcblx0XHR2ZXJ0OiBxdWFkVmVydFxuXHR9LFxuXHRsdW1pbm9zaXR5SGlnaDoge1xuXHRcdGZyYWc6IEx1bWlub3NpdHlIaWdoLFxuXHRcdHZlcnQ6IHF1YWRWZXJ0XG5cdH0sXG5cdGJsZW5kOiB7XG5cdFx0ZnJhZzogYmxlbmRGcmFnLFxuXHRcdHZlcnQ6IHF1YWRWZXJ0XG5cdH0sXG5cdHNoYWRvd01hcERlYnVnZ2VyOiB7XG5cdFx0ZnJhZzogc2hhZG93TWFwRGVidWdnZXJGcmFnLFxuXHRcdHZlcnQ6IHNoYWRvd01hcERlYnVnZ2VyVmVydFxuXHR9LFxuXHRzaGFkb3dNYXA6IHtcblx0XHR2ZXJ0OiBzaGFkb3dNYXBWZXJ0LFxuXHRcdGZyYWc6IHNoYWRvd01hcEZyYWdcblx0fSxcblx0c3ByaXRlOiB7XG5cdFx0dmVydDogc3ByaXRlX3ZzLFxuXHRcdGZyYWc6IHNwcml0ZV9mc1xuXHR9LFxuXHRwb2ludDoge1xuXHRcdHZlcnQ6IHBvaW50X3ZzLFxuXHRcdGZyYWc6IHBvaW50X2ZzXG5cdH1cbn07XG5cbmZ1bmN0aW9uIHJlc29sdmVJbmNsdWRlcyhzdHJpbmcpIHtcblx0cmV0dXJuIHN0cmluZy5yZXBsYWNlKGluY2x1ZGVQYXR0ZXJuLCBpbmNsdWRlUmVwbGFjZXIpO1xufVxuXG5mdW5jdGlvbiBpbmNsdWRlUmVwbGFjZXIobWF0Y2gsIGluY2x1ZGUpIHtcblx0Y29uc3QgZXhjdXRlID0gU2hhZGVyQ2h1bmtbaW5jbHVkZV07XG5cdGlmIChleGN1dGUgPT09IHVuZGVmaW5lZCkge1xuXHRcdHRocm93IG5ldyBFcnJvcihgQ2FuIG5vdCByZXNvbHZlICNpbmNsdWRlIDwke2luY2x1ZGV9PmApO1xuXHR9XG5cdGNvbnN0IHJlc3VsdCA9IGV4Y3V0ZShjdXJyZW50RGVmaW5lcyk7XG5cdHJldHVybiByZXNvbHZlSW5jbHVkZXMocmVzdWx0KTtcbn1cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldFZlcnRGcmFnKHR5cGUsIGRlZmluZXMgPSB7fSkge1xuXHRjb25zdCBleGN1dGVGdW5jID0gc2hhZGVyc1t0eXBlXTtcblx0Y3VycmVudERlZmluZXMgPSBkZWZpbmVzO1xuXHRyZXR1cm4ge1xuXHRcdHZlcnQ6IHJlZHVjZUNvbW1hKGV4Y3V0ZUZ1bmM/LnZlcnQoY3VycmVudERlZmluZXMpKSxcblx0XHRmcmFnOiByZWR1Y2VDb21tYShleGN1dGVGdW5jPy5mcmFnKGN1cnJlbnREZWZpbmVzKSlcblx0fTtcbn1cbiIsImltcG9ydCB7XG5cdFNoYWRlckRlZmluZSxcblx0U2hhZGVyU3RyaW5nLFxuXHRjb21wdXRlUGFyYW1zLFxuXHRyZW5kZXJQYXJhbXMsXG5cdFNoYWRlck1vZHVsZSxcblx0U2hhZGVyU291cmNlUGFyYW1zLFxuXHRTaGFkZXJGdW5jXG59IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XG5pbXBvcnQgZ2V0VmVydEZyYWcgZnJvbSBcIi4vU2hhZGVyc1wiO1xuZXhwb3J0IGNsYXNzIFNoYWRlclNvdXJjZSB7XG5cdHB1YmxpYyBjb21wdXRlOiBjb21wdXRlUGFyYW1zO1xuXHRwdWJsaWMgcmVuZGVyOiByZW5kZXJQYXJhbXM7XG5cdHB1YmxpYyBzaGFkZXJJZDogc3RyaW5nO1xuXHRwdWJsaWMgZGlydHk6IGJvb2xlYW47XG5cdHB1YmxpYyBkZWZpbmVzPzogU2hhZGVyRGVmaW5lO1xuXHRwcml2YXRlIF91aWQ6IHN0cmluZztcblx0cHJpdmF0ZSBfc2hhZGVyTW9kdWxlOiBTaGFkZXJNb2R1bGU7XG5cdGNvbnN0cnVjdG9yKG9wdGlvbnM6IFNoYWRlclNvdXJjZVBhcmFtcykge1xuXHRcdHRoaXMuc2hhZGVySWQgPSBvcHRpb25zLnNoYWRlcklkO1xuXHRcdHRoaXMuZGVmaW5lcyA9IG9wdGlvbnMuZGVmaW5lcyB8fCB7fTtcblx0XHR0aGlzLnJlbmRlciA9IG9wdGlvbnMucmVuZGVyO1xuXHRcdHRoaXMuY29tcHV0ZSA9IG9wdGlvbnMuY29tcHV0ZTtcblx0XHR0aGlzLmRpcnR5ID0gdHJ1ZTtcblx0fVxuXHRnZXQgdWlkKCkge1xuXHRcdHRoaXMuX3VpZCA9IHRoaXMuc2hhZGVySWQuY29uY2F0KEpTT04uc3RyaW5naWZ5KHRoaXMuZGVmaW5lcykpO1xuXHRcdHJldHVybiB0aGlzLl91aWQ7XG5cdH1cblx0cHVibGljIHNldERlZmluZXMoZGVmaW5lcykge1xuXHRcdGlmICghZGVmaW5lcykgcmV0dXJuO1xuXHRcdHRoaXMuZGlydHkgPSB0cnVlO1xuXHRcdHRoaXMuZGVmaW5lcyA9IE9iamVjdC5hc3NpZ24odGhpcy5kZWZpbmVzLCBkZWZpbmVzKTtcblx0fVxuXHRwdWJsaWMgZ2V0U2hhZGVyTW9kdWxlKGRldmljZTogR1BVRGV2aWNlKTogU2hhZGVyTW9kdWxlIHtcblx0XHRpZiAodGhpcy5kaXJ0eSkge1xuXHRcdFx0Y29uc3QgeyB2ZXJ0LCBmcmFnLCBjb21wdXRlIH0gPSB0aGlzLmdldFNoYWRlclN0cigpIHx8IHt9O1xuXHRcdFx0Y29uc3QgdmVydEdQVU1vZHVsZSA9IHZlcnQgPyBkZXZpY2UuY3JlYXRlU2hhZGVyTW9kdWxlKHsgY29kZTogdmVydCB9KSA6IHVuZGVmaW5lZDtcblx0XHRcdGNvbnN0IGZyYWdHUFVNb2R1bGUgPSBmcmFnID8gZGV2aWNlLmNyZWF0ZVNoYWRlck1vZHVsZSh7IGNvZGU6IGZyYWcgfSkgOiB1bmRlZmluZWQ7XG5cdFx0XHRjb25zdCBjb21wdXRlR1BVTW9kdWxlID0gY29tcHV0ZSA/IGRldmljZS5jcmVhdGVTaGFkZXJNb2R1bGUoeyBjb2RlOiBjb21wdXRlIH0pIDogdW5kZWZpbmVkO1xuXHRcdFx0dGhpcy5fc2hhZGVyTW9kdWxlID0ge1xuXHRcdFx0XHR2ZXJ0OiB2ZXJ0R1BVTW9kdWxlLFxuXHRcdFx0XHRmcmFnOiBmcmFnR1BVTW9kdWxlLFxuXHRcdFx0XHRjb21wdXRlOiBjb21wdXRlR1BVTW9kdWxlXG5cdFx0XHR9O1xuXHRcdFx0dGhpcy5kaXJ0eSA9IGZhbHNlO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5fc2hhZGVyTW9kdWxlO1xuXHR9XG5cdHB1YmxpYyBkZXN0cm95KCkge1xuXHRcdHRoaXMucmVuZGVyID0gbnVsbDtcblx0XHR0aGlzLmNvbXB1dGUgPSBudWxsO1xuXHRcdHRoaXMuX3NoYWRlck1vZHVsZSA9IG51bGw7XG5cdFx0dGhpcy5kZWZpbmVzID0gbnVsbDtcblx0fVxuXHRwcml2YXRlIGdldFNoYWRlclN0cigpOiBTaGFkZXJTdHJpbmcge1xuXHRcdGNvbnN0IHsgZnJhZ1NoYWRlciwgdmVydFNoYWRlciB9ID0gdGhpcy5yZW5kZXIgfHwge307XG5cdFx0Y29uc3QgeyBjb21wdXRlU2hhZGVyIH0gPSB0aGlzLmNvbXB1dGUgfHwge307XG5cdFx0Y29uc3Qgc291cmNlID0gZ2V0VmVydEZyYWcodGhpcy5zaGFkZXJJZCwgdGhpcy5kZWZpbmVzKTtcblx0XHRjb25zdCB2ZXJ0ID1cblx0XHRcdHNvdXJjZT8udmVydCA/PyAodmVydFNoYWRlciBpbnN0YW5jZW9mIEZ1bmN0aW9uID8gKDxTaGFkZXJGdW5jPnZlcnRTaGFkZXIpKHRoaXMuZGVmaW5lcykgOiB2ZXJ0U2hhZGVyKTtcblx0XHRjb25zdCBmcmFnID1cblx0XHRcdHNvdXJjZT8uZnJhZyA/PyAoZnJhZ1NoYWRlciBpbnN0YW5jZW9mIEZ1bmN0aW9uID8gKDxTaGFkZXJGdW5jPmZyYWdTaGFkZXIpKHRoaXMuZGVmaW5lcykgOiBmcmFnU2hhZGVyKTtcblx0XHRjb25zdCBjb21wdXRlID0gY29tcHV0ZVNoYWRlciBpbnN0YW5jZW9mIEZ1bmN0aW9uID8gKGNvbXB1dGVTaGFkZXIgYXMgU2hhZGVyRnVuYykodGhpcy5kZWZpbmVzKSA6IGNvbXB1dGVTaGFkZXI7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHZlcnQsXG5cdFx0XHRmcmFnLFxuXHRcdFx0Y29tcHV0ZVxuXHRcdH07XG5cdH1cblx0c3RhdGljIHJlcGxhY2VNYWluKHNvdXJjZTogc3RyaW5nLCByZW5hbWVkTWFpbjogc3RyaW5nKSB7XG5cdFx0cmVuYW1lZE1haW4gPSBgdm9pZCAke3JlbmFtZWRNYWlufSgpYDtcblx0XHRyZXR1cm4gc291cmNlLnJlcGxhY2UoL3ZvaWRcXHMrbWFpblxccypcXChcXHMqKD86dm9pZCk/XFxzKlxcKS9nLCByZW5hbWVkTWFpbik7XG5cdH1cbn1cbiIsImltcG9ydCB7IElVbmlmb3JtLCBVbmlmb3JtRW51bSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XG5pbXBvcnQgeyBNZXNoIH0gZnJvbSBcIi4uL21lc2gvTWVzaFwiO1xuaW1wb3J0IFNoYWRlckRhdGEgZnJvbSBcIi4uL3JlbmRlci9TaGFkZXJEYXRhXCI7XG5pbXBvcnQgVW5pZm9ybUJ1ZmZlciBmcm9tIFwiLi4vcmVuZGVyL1VuaWZvcm1CdWZmZXJcIjtcbmNvbnN0IHVuaWZvcm1BcnJheU5hbWVzID0gW1wiYXJyYXk8ZjMyPlwiLCBcImFycmF5PHZlYzI8ZjMyPj5cIiwgXCJhcnJheTx2ZWMzPGYzMj4+XCIsIFwiYXJyYXk8dmVjNDxmMzI+PlwiXTtcbmV4cG9ydCBmdW5jdGlvbiBjaGVja0NvbnRhaW5GbG9hdFR5cGUodW5pZm9ybXMpIHtcblx0bGV0IHJlc3VsdCA9IDA7XG5cdGxldCBoYXNBcnJheXR5cGUgPSBmYWxzZTtcblx0Y29uc3QgdW5pZm9ybXNOYW1lcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHVuaWZvcm1zKTtcblx0dW5pZm9ybXNOYW1lcy5tYXAoKHVuaWZvcm1zTmFtZSkgPT4ge1xuXHRcdGlmICh1bmlmb3Jtc1t1bmlmb3Jtc05hbWVdLnR5cGUgPT0gXCJ0ZXh0dXJlXCIgfHwgdW5pZm9ybXNbdW5pZm9ybXNOYW1lXS50eXBlID09IFwic2FtcGxlclwiKSB7XG5cdFx0XHRyZXN1bHQgKz0gMDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0aWYgKFxuXHRcdFx0XHR1bmlmb3JtQXJyYXlOYW1lcy5maW5kKChuYW1lKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIG5hbWUgPT09IHVuaWZvcm1zW3VuaWZvcm1zTmFtZV0udHlwZTtcblx0XHRcdFx0fSlcblx0XHRcdCkge1xuXHRcdFx0XHRoYXNBcnJheXR5cGUgPSB0cnVlO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmVzdWx0ICs9IDE7XG5cdFx0XHR9XG5cdFx0fVxuXHR9KTtcblx0cmV0dXJuIHtcblx0XHRoYXNGbG9hdDogcmVzdWx0LFxuXHRcdGhhc0FycmF5dHlwZVxuXHR9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGFkZFVuaWZvcm1Ub1NoYWRlckRhdGEoXG5cdG5hbWU6IHN0cmluZyxcblx0dW5pZm9ybTogSVVuaWZvcm0sXG5cdHNoYWRlckRhdGE6IFNoYWRlckRhdGEsXG5cdG1lc2g/OiBNZXNoLFxuXHR1bmlmb3JtQnVmZmVyPzogVW5pZm9ybUJ1ZmZlclxuKSB7XG5cdGNvbnN0IHZhbHVlSXNGdW5jID0gdW5pZm9ybT8udmFsdWUgaW5zdGFuY2VvZiBGdW5jdGlvbjtcblx0c3dpdGNoICh1bmlmb3JtLnR5cGUpIHtcblx0XHRjYXNlIFwiZjMyXCI6XG5cdFx0XHR1bmlmb3JtQnVmZmVyLnNldFVuaWZvcm0oXG5cdFx0XHRcdG5hbWUsXG5cdFx0XHRcdHZhbHVlSXNGdW5jXG5cdFx0XHRcdFx0PyB1bmlmb3JtLnZhbHVlXG5cdFx0XHRcdFx0OiAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB1bmlmb3JtLnZhbHVlO1xuXHRcdFx0XHRcdCAgfSxcblx0XHRcdFx0VW5pZm9ybUVudW0uRmxvYXRcblx0XHRcdCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwidmVjMjxmMzI+XCI6XG5cdFx0XHR1bmlmb3JtQnVmZmVyLnNldFVuaWZvcm0oXG5cdFx0XHRcdG5hbWUsXG5cdFx0XHRcdHZhbHVlSXNGdW5jXG5cdFx0XHRcdFx0PyB1bmlmb3JtLnZhbHVlXG5cdFx0XHRcdFx0OiAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB1bmlmb3JtLnZhbHVlO1xuXHRcdFx0XHRcdCAgfSxcblx0XHRcdFx0VW5pZm9ybUVudW0uRmxvYXRWZWMyXG5cdFx0XHQpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcInZlYzM8ZjMyPlwiOlxuXHRcdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XHRuYW1lLFxuXHRcdFx0XHR2YWx1ZUlzRnVuY1xuXHRcdFx0XHRcdD8gdW5pZm9ybS52YWx1ZVxuXHRcdFx0XHRcdDogKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdW5pZm9ybS52YWx1ZTtcblx0XHRcdFx0XHQgIH0sXG5cdFx0XHRcdFVuaWZvcm1FbnVtLkZsb2F0VmVjM1xuXHRcdFx0KTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgXCJjb2xvclwiOlxuXHRcdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XHRuYW1lLFxuXHRcdFx0XHR2YWx1ZUlzRnVuY1xuXHRcdFx0XHRcdD8gdW5pZm9ybS52YWx1ZVxuXHRcdFx0XHRcdDogKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdW5pZm9ybS52YWx1ZTtcblx0XHRcdFx0XHQgIH0sXG5cdFx0XHRcdFVuaWZvcm1FbnVtLkNvbG9yXG5cdFx0XHQpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcInZlYzQ8ZjMyPlwiOlxuXHRcdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XHRuYW1lLFxuXHRcdFx0XHR2YWx1ZUlzRnVuY1xuXHRcdFx0XHRcdD8gdW5pZm9ybS52YWx1ZVxuXHRcdFx0XHRcdDogKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdW5pZm9ybS52YWx1ZTtcblx0XHRcdFx0XHQgIH0sXG5cdFx0XHRcdFVuaWZvcm1FbnVtLkZsb2F0VmVjNFxuXHRcdFx0KTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgXCJtYXQyeDI8ZjMyPlwiOlxuXHRcdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XHRuYW1lLFxuXHRcdFx0XHR2YWx1ZUlzRnVuY1xuXHRcdFx0XHRcdD8gdW5pZm9ybS52YWx1ZVxuXHRcdFx0XHRcdDogKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdW5pZm9ybS52YWx1ZTtcblx0XHRcdFx0XHQgIH0sXG5cdFx0XHRcdFVuaWZvcm1FbnVtLk1hdDJcblx0XHRcdCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwibWF0M3gzPGYzMj5cIjpcblx0XHRcdHVuaWZvcm1CdWZmZXIuc2V0VW5pZm9ybShcblx0XHRcdFx0bmFtZSxcblx0XHRcdFx0dmFsdWVJc0Z1bmNcblx0XHRcdFx0XHQ/IHVuaWZvcm0udmFsdWVcblx0XHRcdFx0XHQ6ICgpID0+IHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHVuaWZvcm0udmFsdWU7XG5cdFx0XHRcdFx0ICB9LFxuXHRcdFx0XHRVbmlmb3JtRW51bS5NYXQzXG5cdFx0XHQpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIm1hdDR4NDxmMzI+XCI6XG5cdFx0XHR1bmlmb3JtQnVmZmVyLnNldFVuaWZvcm0oXG5cdFx0XHRcdG5hbWUsXG5cdFx0XHRcdHZhbHVlSXNGdW5jXG5cdFx0XHRcdFx0PyB1bmlmb3JtLnZhbHVlXG5cdFx0XHRcdFx0OiAoKSA9PlxuXHRcdFx0XHRcdFx0XHRuYW1lID09IFwibW9kZWxNYXRyaXhcIlxuXHRcdFx0XHRcdFx0XHRcdD8gbWVzaD8ubW9kZWxNYXRyaXhcblx0XHRcdFx0XHRcdFx0XHQ6IG5hbWUgPT09IFwibm9ybWFsTWF0cml4XCJcblx0XHRcdFx0XHRcdFx0XHQ/IG1lc2g/Lm5vcm1hbE1hdHJpeFxuXHRcdFx0XHRcdFx0XHRcdDogdW5pZm9ybS52YWx1ZSxcblx0XHRcdFx0VW5pZm9ybUVudW0uTWF0NFxuXHRcdFx0KTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgXCJhcnJheTxmMzI+XCI6XG5cdFx0XHR1bmlmb3JtQnVmZmVyLnNldFVuaWZvcm0oXG5cdFx0XHRcdG5hbWUsXG5cdFx0XHRcdHZhbHVlSXNGdW5jXG5cdFx0XHRcdFx0PyB1bmlmb3JtLnZhbHVlXG5cdFx0XHRcdFx0OiAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB1bmlmb3JtLnZhbHVlO1xuXHRcdFx0XHRcdCAgfSxcblx0XHRcdFx0VW5pZm9ybUVudW0uRmxvYXRBcnJheSxcblx0XHRcdFx0dW5pZm9ybS52YWx1ZS5sZW5ndGhcblx0XHRcdCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiYXJyYXk8dmVjMjxmMzI+PlwiOlxuXHRcdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XHRuYW1lLFxuXHRcdFx0XHR2YWx1ZUlzRnVuY1xuXHRcdFx0XHRcdD8gdW5pZm9ybS52YWx1ZVxuXHRcdFx0XHRcdDogKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdW5pZm9ybS52YWx1ZTtcblx0XHRcdFx0XHQgIH0sXG5cdFx0XHRcdFVuaWZvcm1FbnVtLlZlYzJBcnJheSxcblx0XHRcdFx0dW5pZm9ybS52YWx1ZS5sZW5ndGhcblx0XHRcdCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiYXJyYXk8dmVjMzxmMzI+PlwiOlxuXHRcdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XHRuYW1lLFxuXHRcdFx0XHR2YWx1ZUlzRnVuY1xuXHRcdFx0XHRcdD8gdW5pZm9ybS52YWx1ZVxuXHRcdFx0XHRcdDogKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdW5pZm9ybS52YWx1ZTtcblx0XHRcdFx0XHQgIH0sXG5cdFx0XHRcdFVuaWZvcm1FbnVtLlZlYzNBcnJheSxcblx0XHRcdFx0dW5pZm9ybS52YWx1ZS5sZW5ndGhcblx0XHRcdCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiYXJyYXk8dmVjNDxmMzI+PlwiOlxuXHRcdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XHRuYW1lLFxuXHRcdFx0XHR2YWx1ZUlzRnVuY1xuXHRcdFx0XHRcdD8gdW5pZm9ybS52YWx1ZVxuXHRcdFx0XHRcdDogKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdW5pZm9ybS52YWx1ZTtcblx0XHRcdFx0XHQgIH0sXG5cdFx0XHRcdFVuaWZvcm1FbnVtLlZlYzRBcnJheSxcblx0XHRcdFx0dW5pZm9ybS52YWx1ZS5sZW5ndGhcblx0XHRcdCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwidGV4dHVyZVwiOlxuXHRcdGNhc2UgXCJzdG9yYWdlVGV4dHVyZVwiOlxuXHRcdFx0c2hhZGVyRGF0YS5zZXRUZXh0dXJlKFxuXHRcdFx0XHRuYW1lLFxuXHRcdFx0XHR2YWx1ZUlzRnVuY1xuXHRcdFx0XHRcdD8gdW5pZm9ybS52YWx1ZVxuXHRcdFx0XHRcdDogKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdW5pZm9ybS52YWx1ZTtcblx0XHRcdFx0XHQgIH0sXG5cdFx0XHRcdHVuaWZvcm0/LmJpbmRpbmcsXG5cdFx0XHRcdHVuaWZvcm0/LnR5cGUsXG5cdFx0XHRcdHVuaWZvcm0/LnZpc2liaWxpdHksXG5cdFx0XHRcdHVuaWZvcm0/LnRleHR1cmVWaWV3XG5cdFx0XHQpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcInNhbXBsZXJcIjpcblx0XHRcdHNoYWRlckRhdGEuc2V0U2FtcGxlcihcblx0XHRcdFx0bmFtZSxcblx0XHRcdFx0dmFsdWVJc0Z1bmNcblx0XHRcdFx0XHQ/IHVuaWZvcm0udmFsdWVcblx0XHRcdFx0XHQ6ICgpID0+IHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHVuaWZvcm0udmFsdWU7XG5cdFx0XHRcdFx0ICB9LFxuXHRcdFx0XHR1bmlmb3JtPy5iaW5kaW5nLFxuXHRcdFx0XHR1bmlmb3JtPy52aXNpYmlsaXR5XG5cdFx0XHQpO1xuXHRcdFx0YnJlYWs7XG5cdFx0ZGVmYXVsdDpcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIm5vdCBtYXRjaCB1bmlmcm9tIHR5cGVcIik7XG5cdH1cbn1cbiIsImltcG9ydCBCaW5kR3JvdXBMYXlvdXRFbnRyeSBmcm9tIFwiLi9CaW5kR3JvdXBMYXlvdXRFbnRyeVwiO1xyXG5jb25zdCBsYXlvdXRDYWNoZSA9IG5ldyBNYXAoKTtcclxuY2xhc3MgQmluZEdyb3VwTGF5b3V0IHtcclxuXHRwdWJsaWMgZ3B1QmluZEdyb3VwTGF5b3V0OiBHUFVCaW5kR3JvdXBMYXlvdXQ7XHJcblx0aW5kZXg6IG51bWJlcjtcclxuXHRwcml2YXRlIGNvbnN0cnVjdG9yKGRldmljZTogR1BVRGV2aWNlLCBsYWJlbDogc3RyaW5nLCBwdWJsaWMgZW50cmllczogQmluZEdyb3VwTGF5b3V0RW50cnlbXSA9IFtdLCBpbmRleCA9IDApIHtcclxuXHRcdHRoaXMuaW5kZXggPSBpbmRleCB8fCAwO1xyXG5cdFx0dGhpcy5ncHVCaW5kR3JvdXBMYXlvdXQgPSBkZXZpY2UuY3JlYXRlQmluZEdyb3VwTGF5b3V0KHtcclxuXHRcdFx0bGFiZWw6IGxhYmVsLFxyXG5cdFx0XHRlbnRyaWVzOiBlbnRyaWVzLm1hcCgoeyB2aXNpYmlsaXR5LCBidWZmZXIsIHNhbXBsZXIsIHRleHR1cmUsIHN0b3JhZ2VUZXh0dXJlLCBiaW5kaW5nIH0pID0+ICh7XHJcblx0XHRcdFx0YmluZGluZyxcclxuXHRcdFx0XHR2aXNpYmlsaXR5LFxyXG5cdFx0XHRcdGJ1ZmZlcixcclxuXHRcdFx0XHRzYW1wbGVyLFxyXG5cdFx0XHRcdHRleHR1cmUsXHJcblx0XHRcdFx0c3RvcmFnZVRleHR1cmVcclxuXHRcdFx0fSkpXHJcblx0XHR9KTtcclxuXHR9XHJcblx0c3RhdGljIGdldEJpbmRHcm91cExheW91dEZyb21DYWNoZShcclxuXHRcdGRldmljZTogR1BVRGV2aWNlLFxyXG5cdFx0bGFiZWw6IHN0cmluZyxcclxuXHRcdGVudGlyZXM6IEJpbmRHcm91cExheW91dEVudHJ5W10sXHJcblx0XHRpbmRleFxyXG5cdCk6IEJpbmRHcm91cExheW91dCB7XHJcblx0XHRpZiAobGF5b3V0Q2FjaGUuaGFzKGxhYmVsKSkge1xyXG5cdFx0XHRyZXR1cm4gbGF5b3V0Q2FjaGUuZ2V0KGxhYmVsKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGNvbnN0IGJpbmRHcm91cExheW91dCA9IG5ldyBCaW5kR3JvdXBMYXlvdXQoZGV2aWNlLCBsYWJlbCwgZW50aXJlcywgaW5kZXgpO1xyXG5cdFx0XHRsYXlvdXRDYWNoZS5zZXQobGFiZWwsIGJpbmRHcm91cExheW91dCk7XHJcblx0XHRcdHJldHVybiBiaW5kR3JvdXBMYXlvdXQ7XHJcblx0XHR9XHJcblx0fVxyXG5cdHN0YXRpYyByZW1vdmVCaW5kR3JvdXBMYXlvdXRGcm9tQ2FjaGUoYmluZEdyb3VwTGF5b3V0OiBCaW5kR3JvdXBMYXlvdXQpIHtcclxuXHRcdGxheW91dENhY2hlLmRlbGV0ZShiaW5kR3JvdXBMYXlvdXQpO1xyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQgQmluZEdyb3VwTGF5b3V0O1xyXG4iLCJpbXBvcnQgeyBCaW5kR3JvdXBMYXlvdXRFbnRyeVR5cGUgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVUeXBlc1wiO1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQmluZEdyb3VwTGF5b3V0RW50cnkge1xuXHRiaW5kaW5nOiBudW1iZXI7XG5cdHZpc2liaWxpdHk6IEdQVVNoYWRlclN0YWdlRmxhZ3M7XG5cdHVuaWZvcm1zPzogYW55W107XG5cdGJ1ZmZlcj86IEdQVUJ1ZmZlckJpbmRpbmdMYXlvdXQ7XG5cdHNhbXBsZXI/OiBHUFVTYW1wbGVyQmluZGluZ0xheW91dDtcblx0dGV4dHVyZT86IEdQVVRleHR1cmVCaW5kaW5nTGF5b3V0O1xuXHRzdG9yYWdlVGV4dHVyZT86IEdQVVN0b3JhZ2VUZXh0dXJlQmluZGluZ0xheW91dDtcblx0ZXh0ZXJuYWxUZXh0dXJlPzogR1BVRXh0ZXJuYWxUZXh0dXJlQmluZGluZ0xheW91dDtcblx0Y29uc3RydWN0b3Iob3B0aW9uczogQmluZEdyb3VwTGF5b3V0RW50cnlUeXBlKSB7XG5cdFx0dGhpcy5iaW5kaW5nID0gb3B0aW9ucy5iaW5kaW5nO1xuXHRcdHRoaXMudmlzaWJpbGl0eSA9IG9wdGlvbnMudmlzaWJpbGl0eTtcblx0XHR0aGlzLmJ1ZmZlciA9IG9wdGlvbnMuYnVmZmVyO1xuXHRcdHRoaXMuc2FtcGxlciA9IG9wdGlvbnMuc2FtcGxlcjtcblx0XHR0aGlzLnRleHR1cmUgPSBvcHRpb25zLnRleHR1cmU7XG5cdFx0dGhpcy5zdG9yYWdlVGV4dHVyZSA9IG9wdGlvbnMuc3RvcmFnZVRleHR1cmU7XG5cdFx0dGhpcy5leHRlcm5hbFRleHR1cmUgPSBvcHRpb25zLmV4dGVybmFsVGV4dHVyZTtcblx0fVxuXHRnZXRHUFVMYXlvdXRFbnRpdHkoKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdGJpbmRpbmc6IHRoaXMuYmluZGluZyxcblx0XHRcdHZpc2liaWxpdHk6IHRoaXMudmlzaWJpbGl0eSxcblx0XHRcdGJ1ZmZlcjogdGhpcy5idWZmZXIsXG5cdFx0XHRzYW1wbGVyOiB0aGlzLnNhbXBsZXIsXG5cdFx0XHR0ZXh0dXJlOiB0aGlzLnRleHR1cmUsXG5cdFx0XHRleHRlcm5hbFRleHR1cmU6IHRoaXMuZXh0ZXJuYWxUZXh0dXJlLFxuXHRcdFx0c3RvcmFnZVRleHR1cmU6IHRoaXMuc3RvcmFnZVRleHR1cmVcblx0XHR9O1xuXHR9XG59XG4iLCJpbXBvcnQgeyBTaGFkZXJTdGFnZSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVUNvbnN0YW50XCI7XG5pbXBvcnQgeyBVbmlmb3JtRnVuYywgU2hhZGVyRGVmaW5lIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcbmltcG9ydCBkZWZhdWx0VmFsdWUgZnJvbSBcIi4uL3V0aWxzL2RlZmF1bHRWYWx1ZVwiO1xuaW1wb3J0IEJpbmRHcm91cCBmcm9tIFwiLi9CaW5kR3JvdXBcIjtcbmltcG9ydCBCaW5kR3JvdXBFbnRpdHkgZnJvbSBcIi4vQmluZEdyb3VwRW50aXR5XCI7XG5pbXBvcnQgQmluZEdyb3VwTGF5b3V0IGZyb20gXCIuL0JpbmRHcm91cExheW91dFwiO1xuaW1wb3J0IEJpbmRHcm91cExheW91dEVudHJ5IGZyb20gXCIuL0JpbmRHcm91cExheW91dEVudHJ5XCI7XG5pbXBvcnQgU2FtcGxlciBmcm9tIFwiLi9TYW1wbGVyXCI7XG5pbXBvcnQgVGV4dHVyZSBmcm9tIFwiLi9UZXh0dXJlXCI7XG5pbXBvcnQgVW5pZm9ybUJ1ZmZlciBmcm9tIFwiLi9Vbmlmb3JtQnVmZmVyXCI7XG5pbXBvcnQgeyBVbmlmb3JtU2FtcGxlciwgVW5pZm9ybVRleHR1cmUgfSBmcm9tIFwiLi9Vbmlmb3Jtc1wiO1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2hhZGVyRGF0YSB7XG5cdGN1cnJlbnRCaW5kaW5nOiBudW1iZXI7XG5cblx0ZGVmaW5lczogU2hhZGVyRGVmaW5lO1xuXG5cdGRlZmluZURpcnR5OiBib29sZWFuO1xuXG5cdGxhYmVsOiBzdHJpbmc7XG5cblx0YmluZEdyb3VwOiBCaW5kR3JvdXA7XG5cblx0Z3JvdXBMYXlvdXQ6IEJpbmRHcm91cExheW91dDtcblxuXHRsYXlvdXRJbmRleDogbnVtYmVyO1xuXG5cdGdyb3VwSW5kZXg6IG51bWJlcjtcblxuXHRwcm90ZWN0ZWQgX3VuaWZvcm1zOiBNYXA8c3RyaW5nLCBhbnk+O1xuXG5cdGNvbnN0cnVjdG9yKGxhYmVsOiBzdHJpbmcsIHNpemU/OiBudW1iZXIsIGxheW91dEluZGV4PzogbnVtYmVyLCBncm91cEluZGV4Pykge1xuXHRcdHRoaXMubGFiZWwgPSBsYWJlbDtcblx0XHR0aGlzLmN1cnJlbnRCaW5kaW5nID0gMDtcblx0XHR0aGlzLmRlZmluZURpcnR5ID0gdHJ1ZTtcblx0XHR0aGlzLmRlZmluZXMgPSB7fTtcblx0XHR0aGlzLl91bmlmb3JtcyA9IG5ldyBNYXAoKTtcblx0XHR0aGlzLmdyb3VwSW5kZXggPSBkZWZhdWx0VmFsdWUoZ3JvdXBJbmRleCwgMCk7XG5cdFx0dGhpcy5sYXlvdXRJbmRleCA9IGRlZmF1bHRWYWx1ZShsYXlvdXRJbmRleCwgMCk7XG5cdH1cblx0Z2V0VW5pZm9ybUJ1ZmZlcihuYW1lOiBzdHJpbmcpOiBVbmlmb3JtQnVmZmVyIHtcblx0XHRyZXR1cm4gdGhpcy5fdW5pZm9ybXMuZ2V0KG5hbWUpO1xuXHR9XG5cdGdldFRleHR1cmUobmFtZTogc3RyaW5nKTogVGV4dHVyZSB7XG5cdFx0cmV0dXJuIHRoaXMuX3VuaWZvcm1zLmdldChuYW1lKTtcblx0fVxuXHRnZXRTYW1wbGVyKG5hbWU6IHN0cmluZyk6IFNhbXBsZXIge1xuXHRcdHJldHVybiB0aGlzLl91bmlmb3Jtcy5nZXQobmFtZSk7XG5cdH1cblx0c2V0VW5pZm9ybUJ1ZmZlcihuYW1lOiBzdHJpbmcsIHVuaWZvcm1CdWZmZXI6IFVuaWZvcm1CdWZmZXIsIGJpbmRpbmc/OiBudW1iZXIpIHtcblx0XHRpZiAodGhpcy5fdW5pZm9ybXMuZ2V0KG5hbWUpKSByZXR1cm47XG5cdFx0dW5pZm9ybUJ1ZmZlci5iaW5kaW5nID0gdGhpcy5jdXJyZW50QmluZGluZztcblx0XHR0aGlzLnNldERlZmluZShuYW1lLmNvbmNhdChcIkJpbmRpbmdcIiksIGJpbmRpbmcgPz8gdGhpcy5jdXJyZW50QmluZGluZyk7XG5cdFx0dGhpcy5jdXJyZW50QmluZGluZyArPSAxO1xuXHRcdHRoaXMuX3VuaWZvcm1zLnNldChuYW1lLCB1bmlmb3JtQnVmZmVyKTtcblx0fVxuXHRzZXRUZXh0dXJlKFxuXHRcdG5hbWU6IHN0cmluZyxcblx0XHR2YWx1ZTogVW5pZm9ybUZ1bmMgfCBUZXh0dXJlLFxuXHRcdGJpbmRpbmc/OiBudW1iZXIsXG5cdFx0dHlwZT86IHN0cmluZyxcblx0XHR2aXNpYmlsaXR5PzogU2hhZGVyU3RhZ2UsXG5cdFx0dGV4dHVyZVZpZXc/OiBHUFVUZXh0dXJlVmlld1xuXHQpIHtcblx0XHRpZiAodGhpcy5fdW5pZm9ybXMuZ2V0KG5hbWUpKSByZXR1cm47XG5cdFx0Y29uc3QgdW5pZm9ybSA9IG5ldyBVbmlmb3JtVGV4dHVyZShuYW1lLCBiaW5kaW5nID8/IHRoaXMuY3VycmVudEJpbmRpbmcsIHZhbHVlLCB0eXBlLCB2aXNpYmlsaXR5LCB0ZXh0dXJlVmlldyk7XG5cdFx0dGhpcy5zZXREZWZpbmUobmFtZS5jb25jYXQoXCJCaW5kaW5nXCIpLCBiaW5kaW5nID8/IHRoaXMuY3VycmVudEJpbmRpbmcpO1xuXHRcdHRoaXMuY3VycmVudEJpbmRpbmcgKz0gMTtcblx0XHR0aGlzLl91bmlmb3Jtcy5zZXQobmFtZSwgdW5pZm9ybSk7XG5cdH1cblx0c2V0U2FtcGxlcihuYW1lOiBzdHJpbmcsIHZhbHVlOiBVbmlmb3JtRnVuYyB8IFNhbXBsZXIsIGJpbmRpbmc/OiBudW1iZXIsIHZpc2liaWxpdHk/OiBTaGFkZXJTdGFnZSkge1xuXHRcdGlmICh0aGlzLl91bmlmb3Jtcy5nZXQobmFtZSkpIHJldHVybjtcblx0XHRjb25zdCB1bmlmb3JtID0gbmV3IFVuaWZvcm1TYW1wbGVyKG5hbWUsIGJpbmRpbmcgPz8gdGhpcy5jdXJyZW50QmluZGluZywgdmFsdWUsIHZpc2liaWxpdHkpO1xuXHRcdHRoaXMuc2V0RGVmaW5lKG5hbWUuY29uY2F0KFwiQmluZGluZ1wiKSwgYmluZGluZyA/PyB0aGlzLmN1cnJlbnRCaW5kaW5nKTtcblx0XHR0aGlzLmN1cnJlbnRCaW5kaW5nICs9IDE7XG5cdFx0dGhpcy5fdW5pZm9ybXMuc2V0KG5hbWUsIHVuaWZvcm0pO1xuXHR9XG5cdHNldERlZmluZShuYW1lOiBzdHJpbmcsIHZhbHVlOiBib29sZWFuIHwgbnVtYmVyKSB7XG5cdFx0aWYgKHRoaXMuZGVmaW5lc1tuYW1lXSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHR0aGlzLmRlZmluZURpcnR5ID0gdHJ1ZTtcblx0XHRcdHRoaXMuZGVmaW5lc1tuYW1lXSA9IHZhbHVlO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAodGhpcy5kZWZpbmVzW25hbWVdID09PSB2YWx1ZSkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLmRlZmluZURpcnR5ID0gdHJ1ZTtcblx0XHRcdFx0dGhpcy5kZWZpbmVzW25hbWVdID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJlcGxhY2VVbmlmb3JtQnVmZmVyVmFsdWUobmFtZTogc3RyaW5nLCB2YWx1ZTogVW5pZm9ybUZ1bmMgfCBudW1iZXIgfCBvYmplY3QpIHtcblx0XHR0aGlzLl91bmlmb3Jtcy5mb3JFYWNoKCh1bmlmb3JtKSA9PiB7XG5cdFx0XHRpZiAodW5pZm9ybT8uaXNVbmlmb3JtQnVmZmVyKSB7XG5cdFx0XHRcdHVuaWZvcm0ucmVwbGFjZVVuaWZvcm1WYWx1ZShuYW1lLCB2YWx1ZSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblx0YmluZChkZXZpY2U6IEdQVURldmljZSwgcGFzc0VuY29kZXI6IEdQVVJlbmRlclBhc3NFbmNvZGVyIHwgR1BVQ29tcHV0ZVBhc3NFbmNvZGVyKSB7XG5cdFx0dGhpcy51cGxvYWRVbmlmb3JtKGRldmljZSk7XG5cdFx0aWYgKCF0aGlzLmdyb3VwTGF5b3V0KSB0aGlzLmdyb3VwTGF5b3V0ID0gdGhpcy5jcmVhdGVCaW5kR3JvdXBMYXlvdXQoZGV2aWNlLCB0aGlzLmxhYmVsLCB0aGlzLmxheW91dEluZGV4KTtcblx0XHRpZiAoIXRoaXMuYmluZEdyb3VwKSB0aGlzLmJpbmRHcm91cCA9IHRoaXMuY3JlYXRlQmluZEdyb3VwKGRldmljZSwgdGhpcy5sYWJlbCwgdGhpcy5ncm91cEluZGV4KTtcblx0XHR0aGlzLmJpbmRHcm91cC5iaW5kKHBhc3NFbmNvZGVyKTtcblx0fVxuXHRkZXN0cm95KCkge1xuXHRcdHRoaXMuX3VuaWZvcm1zLmZvckVhY2goKHVuaWZvcm0pID0+IHtcblx0XHRcdGlmICh1bmlmb3JtLmRlc3Ryb3kpIHVuaWZvcm0/LmRlc3Ryb3koKTtcblx0XHR9KTtcblx0XHR0aGlzLmxhYmVsID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMuY3VycmVudEJpbmRpbmcgPSAxO1xuXHRcdHRoaXMuZGVmaW5lRGlydHkgPSB0cnVlO1xuXHRcdHRoaXMuZGVmaW5lcyA9IHVuZGVmaW5lZDtcblx0XHR0aGlzLl91bmlmb3Jtcy5jbGVhcigpO1xuXHRcdEJpbmRHcm91cExheW91dC5yZW1vdmVCaW5kR3JvdXBMYXlvdXRGcm9tQ2FjaGUodGhpcy5ncm91cExheW91dCk7XG5cdFx0dGhpcy5iaW5kR3JvdXAgPSB1bmRlZmluZWQ7XG5cdH1cblx0cHJpdmF0ZSBjcmVhdGVCaW5kR3JvdXAoZGV2aWNlOiBHUFVEZXZpY2UsIGxhYmVsOiBzdHJpbmcsIGdyb3VwSW5kZXg/OiBudW1iZXIpIHtcblx0XHRjb25zdCB7IGVudGl0aWVzLCBkeW5hbWljLCBhbGlnbmVkU2l6ZSwgbWF4T2Zmc2V0IH0gPSB0aGlzLmNyZWF0ZUJpbmRHcm91cEVudGl0eSgpO1xuXHRcdGNvbnN0IGJpbmRHcm91cCA9IG5ldyBCaW5kR3JvdXAoe1xuXHRcdFx0bGFiZWw6IGxhYmVsLFxuXHRcdFx0ZW50aXJlczogZW50aXRpZXMsXG5cdFx0XHRkZXZpY2U6IGRldmljZSxcblx0XHRcdGxheW91dDogdGhpcy5ncm91cExheW91dCxcblx0XHRcdGluZGV4OiBncm91cEluZGV4IHx8IDAsIC8vIOWQjue7reaUueaIkGdyb3VwSW5kZXhcblx0XHRcdGR5bmFtaWMsXG5cdFx0XHRhbGlnbmVkU2l6ZSxcblx0XHRcdG1heE9mZnNldFxuXHRcdH0pO1xuXHRcdHJldHVybiBiaW5kR3JvdXA7XG5cdH1cblx0cHJpdmF0ZSBjcmVhdGVCaW5kR3JvdXBMYXlvdXQoZGV2aWNlOiBHUFVEZXZpY2UsIGxhYmVsOiBzdHJpbmcsIGxheW91dEluZGV4PzogbnVtYmVyKSB7XG5cdFx0Y29uc3QgcmVzdWx0ID0gdGhpcy5jcmVhdGVCaW5kR3JvdXBMYXlvdXRFbnRyeSgpO1xuXHRcdGNvbnN0IGdyb3VwTGF5b3V0ID0gQmluZEdyb3VwTGF5b3V0LmdldEJpbmRHcm91cExheW91dEZyb21DYWNoZShcblx0XHRcdGRldmljZSxcblx0XHRcdGxhYmVsICsgXCItXCIgKyByZXN1bHQudWlkLFxuXHRcdFx0cmVzdWx0LmxheW91dHMsXG5cdFx0XHRsYXlvdXRJbmRleCB8fCAwXG5cdFx0KTtcblx0XHRyZXR1cm4gZ3JvdXBMYXlvdXQ7XG5cdH1cblx0cHJvdGVjdGVkIHVwbG9hZFVuaWZvcm0oZGV2aWNlOiBHUFVEZXZpY2UpIHtcblx0XHR0aGlzLl91bmlmb3Jtcy5mb3JFYWNoKCh1bmlmb3JtKSA9PiB7XG5cdFx0XHR1bmlmb3JtLmJpbmQoZGV2aWNlKTtcblx0XHR9KTtcblx0fVxuXHRwcml2YXRlIGNyZWF0ZUJpbmRHcm91cExheW91dEVudHJ5KCkge1xuXHRcdGxldCB1aWQgPSBcIlwiO1xuXHRcdGNvbnN0IHJlc3VsdCA9IG5ldyBNYXAoKTtcblx0XHR0aGlzLl91bmlmb3Jtcy5mb3JFYWNoKCh1bmlmb3JtKSA9PiB7XG5cdFx0XHRpZiAoIXJlc3VsdC5oYXModW5pZm9ybS5uYW1lKSkge1xuXHRcdFx0XHR1aWQgPSB1aWQgPT09IFwiXCIgPyB1aWQuY29uY2F0KHVuaWZvcm0ubmFtZSkgOiB1aWQuY29uY2F0KFwiLCBcIikuY29uY2F0KHVuaWZvcm0ubmFtZSk7XG5cdFx0XHRcdHJlc3VsdC5zZXQodW5pZm9ybS5uYW1lLCB0aGlzLmNyZWF0ZU9uZUxheW91dEVudHJ5KHVuaWZvcm0pKTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHR1aWQgPSBgdW5pZm9ybXNbJHt1aWR9XWA7XG5cdFx0cmV0dXJuIHsgdWlkLCBsYXlvdXRzOiBbLi4ucmVzdWx0LnZhbHVlcygpXSB9O1xuXHR9XG5cdHByaXZhdGUgY3JlYXRlQmluZEdyb3VwRW50aXR5KCkge1xuXHRcdGNvbnN0IHJlc3VsdCA9IG5ldyBNYXAoKTtcblx0XHRsZXQgZHluYW1pYyA9IGZhbHNlLFxuXHRcdFx0YWxpZ25lZFNpemUgPSAwLFxuXHRcdFx0bWF4T2Zmc2V0ID0gMDtcblx0XHR0aGlzLl91bmlmb3Jtcy5mb3JFYWNoKCh1bmlmb3JtKSA9PiB7XG5cdFx0XHRpZiAoIXJlc3VsdC5oYXModW5pZm9ybS5uYW1lKSkge1xuXHRcdFx0XHRpZiAodW5pZm9ybT8uaGFzRHluYW1pY09mZnNldCkge1xuXHRcdFx0XHRcdGR5bmFtaWMgPSB0cnVlO1xuXHRcdFx0XHRcdG1heE9mZnNldCA9IHVuaWZvcm0ubWF4T2Zmc2V0O1xuXHRcdFx0XHRcdGFsaWduZWRTaXplID0gTWF0aC5jZWlsKHVuaWZvcm0udW5pZm9ybXNTaXplIC8gKDQgKiAyNTYpKSAqIDI1Njtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXN1bHQuc2V0KHVuaWZvcm0ubmFtZSwgdGhpcy5jcmVheWVPbmVHcm91cEVudGl0eSh1bmlmb3JtKSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0cmV0dXJuIHtcblx0XHRcdGVudGl0aWVzOiBbLi4ucmVzdWx0LnZhbHVlcygpXSxcblx0XHRcdGR5bmFtaWMsXG5cdFx0XHRhbGlnbmVkU2l6ZSxcblx0XHRcdG1heE9mZnNldFxuXHRcdH07XG5cdH1cblx0cHJpdmF0ZSBjcmVhdGVPbmVMYXlvdXRFbnRyeSh1bmlmb3JtKSB7XG5cdFx0bGV0IGxheW91dEVudGl0eTtcblx0XHRpZiAodW5pZm9ybS5pc1VuaWZvcm1CdWZmZXIpIHtcblx0XHRcdGxheW91dEVudGl0eSA9IG5ldyBCaW5kR3JvdXBMYXlvdXRFbnRyeSh7XG5cdFx0XHRcdGJpbmRpbmc6IHVuaWZvcm0uYmluZGluZyxcblx0XHRcdFx0YnVmZmVyOiB1bmlmb3JtLmxheW91dFR5cGUsXG5cdFx0XHRcdHZpc2liaWxpdHk6IHVuaWZvcm0udmlzaWJpbGl0eVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIGlmICh1bmlmb3JtLmlzVGV4dHVyZSkge1xuXHRcdFx0bGF5b3V0RW50aXR5ID0gbmV3IEJpbmRHcm91cExheW91dEVudHJ5KHtcblx0XHRcdFx0YmluZGluZzogdW5pZm9ybS5iaW5kaW5nLFxuXHRcdFx0XHR2aXNpYmlsaXR5OiB1bmlmb3JtLnZpc2liaWxpdHksXG5cdFx0XHRcdHRleHR1cmU6IHVuaWZvcm0udHlwZSA9PSBcInRleHR1cmVcIiA/IHVuaWZvcm0ubGF5b3V0VHlwZSA6IHVuZGVmaW5lZCxcblx0XHRcdFx0c3RvcmFnZVRleHR1cmU6IHVuaWZvcm0udHlwZSA9PSBcInN0b3JhZ2VUZXh0dXJlXCIgPyB1bmlmb3JtLnN0b3JhZ2VUZXh0dXJlTGF5b3V0VHlwZSA6IHVuZGVmaW5lZFxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIGlmICh1bmlmb3JtLmlzU2FtcGxlcikge1xuXHRcdFx0bGF5b3V0RW50aXR5ID0gbmV3IEJpbmRHcm91cExheW91dEVudHJ5KHtcblx0XHRcdFx0YmluZGluZzogdW5pZm9ybS5iaW5kaW5nLFxuXHRcdFx0XHR2aXNpYmlsaXR5OiB1bmlmb3JtLnZpc2liaWxpdHksXG5cdFx0XHRcdHNhbXBsZXI6IHVuaWZvcm0ubGF5b3V0VHlwZVxuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdHJldHVybiBsYXlvdXRFbnRpdHk7XG5cdH1cblx0cHJpdmF0ZSBjcmVheWVPbmVHcm91cEVudGl0eSh1bmlmb3JtKSB7XG5cdFx0bGV0IGdyb3VwRW50aXR5O1xuXHRcdGlmICh1bmlmb3JtLmlzVW5pZm9ybUJ1ZmZlcikge1xuXHRcdFx0Z3JvdXBFbnRpdHkgPSBuZXcgQmluZEdyb3VwRW50aXR5KHtcblx0XHRcdFx0YmluZGluZzogdW5pZm9ybS5iaW5kaW5nLFxuXHRcdFx0XHRyZXNvdXJjZToge1xuXHRcdFx0XHRcdGJ1ZmZlcjogdW5pZm9ybS5idWZmZXIuZ3B1QnVmZmVyLFxuXHRcdFx0XHRcdG9mZnNldDogdW5pZm9ybS5vZmZzZXQsXG5cdFx0XHRcdFx0c2l6ZTogdW5pZm9ybS5idWZmZXJTaXplXG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH0gZWxzZSBpZiAodW5pZm9ybS5pc1RleHR1cmUpIHtcblx0XHRcdGdyb3VwRW50aXR5ID0gbmV3IEJpbmRHcm91cEVudGl0eSh7XG5cdFx0XHRcdGJpbmRpbmc6IHVuaWZvcm0uYmluZGluZyxcblx0XHRcdFx0cmVzb3VyY2U6IHVuaWZvcm0/LnRleHR1cmVWaWV3ID8/IHVuaWZvcm0udGV4dHVyZS50ZXh0dXJlVmlld1xuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIGlmICh1bmlmb3JtLmlzU2FtcGxlcikge1xuXHRcdFx0Z3JvdXBFbnRpdHkgPSBuZXcgQmluZEdyb3VwRW50aXR5KHtcblx0XHRcdFx0YmluZGluZzogdW5pZm9ybS5iaW5kaW5nLFxuXHRcdFx0XHRyZXNvdXJjZTogdW5pZm9ybS5zYW1wbGVyLmdwdVNhbXBsZXJcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRyZXR1cm4gZ3JvdXBFbnRpdHk7XG5cdH1cbn1cbiIsImltcG9ydCB7IEZyYW1lU3RhdGUgfSBmcm9tIFwiLi4vY29yZS9GcmFtZVN0YXRlXCI7XG5pbXBvcnQgeyBDdWxsTW9kZSwgUHJpbWl0aXZlVG9wb2xvZ3kgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVDb25zdGFudFwiO1xuaW1wb3J0IENvbG9yIGZyb20gXCIuLi9tYXRoL0NvbG9yXCI7XG5pbXBvcnQgeyBNZXNoIH0gZnJvbSBcIi4uL21lc2gvTWVzaFwiO1xuaW1wb3J0IHsgRGVwdGhTdGVuY2lsLCBSZW5kZXJTdGF0ZSwgVGFyZ2V0LCBQcmltaXRpdmUgfSBmcm9tIFwiLi4vcmVuZGVyL1JlbmRlclN0YXRlXCI7XG5pbXBvcnQgU2FtcGxlciBmcm9tIFwiLi4vcmVuZGVyL1NhbXBsZXJcIjtcbmltcG9ydCBTaGFkZXJEYXRhIGZyb20gXCIuLi9yZW5kZXIvU2hhZGVyRGF0YVwiO1xuaW1wb3J0IFRleHR1cmUgZnJvbSBcIi4uL3JlbmRlci9UZXh0dXJlXCI7XG5pbXBvcnQgeyBTaGFkZXJTb3VyY2UgfSBmcm9tIFwiLi4vc2hhZGVyL1NoYWRlclNvdXJjZVwiO1xuZXhwb3J0IGNsYXNzIE1hdGVyaWFsIHtcblx0cHVibGljIHNoYWRlckRhdGE6IFNoYWRlckRhdGE7XG5cblx0Y29sb3I/OiBDb2xvcjtcblxuXHRiYXNlU2FtcGxlcj86IFNhbXBsZXI7XG5cblx0YmFzZVRleHR1cmU/OiBUZXh0dXJlO1xuXG5cdHR5cGU6IHN0cmluZztcblxuXHRsYWJlbDogc3RyaW5nO1xuXG5cdHNoYWRlclNvdXJjZTogU2hhZGVyU291cmNlO1xuXG5cdHRyYW5zcGFyZW50OiBib29sZWFuO1xuXG5cdGRpcnR5OiBib29sZWFuO1xuXG5cdGxpZ2h0OiBib29sZWFuO1xuXG5cdHJlYWR5OiBib29sZWFuO1xuXG5cdHByaXZhdGUgX2VtaXNzaXZlOiBDb2xvcjtcblxuXHRwcml2YXRlIF9vcGFjaXR5OiBudW1iZXI7XG5cblx0cHJpdmF0ZSBfZW1pc3NpdmVJbnRlbnNpdHk6IG51bWJlcjtcblxuXHRwcml2YXRlIF9kaWZmdXNlOiBDb2xvcjtcblxuXHRwcml2YXRlIF9yZW5kZXJTdGF0ZTogUmVuZGVyU3RhdGU7XG5cblx0cHJpdmF0ZSBfZG91YmxlU2lkZWQ6IGJvb2xlYW47XG5cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0dGhpcy5sYWJlbCA9IHVuZGVmaW5lZDtcblx0XHR0aGlzLnR5cGUgPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy5iYXNlVGV4dHVyZSA9IHVuZGVmaW5lZDtcblx0XHR0aGlzLmJhc2VTYW1wbGVyID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMuX2RpZmZ1c2UgPSBuZXcgQ29sb3IoMC4wLCAwLjAsIDAuMCk7XG5cdFx0dGhpcy5fb3BhY2l0eSA9IDEuMDtcblx0XHQvLyBCdWZmZXJcblx0XHR0aGlzLnNoYWRlckRhdGEgPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy5zaGFkZXJTb3VyY2UgPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy5kaXJ0eSA9IHRydWU7XG5cdFx0dGhpcy5fZW1pc3NpdmUgPSBuZXcgQ29sb3IoMC4wLCAwLjAsIDApO1xuXHRcdHRoaXMuX2VtaXNzaXZlSW50ZW5zaXR5ID0gMS4wO1xuXHRcdHRoaXMuX2RvdWJsZVNpZGVkID0gdHJ1ZTtcblx0XHR0aGlzLmxpZ2h0ID0gZmFsc2U7XG5cdFx0dGhpcy5yZWFkeSA9IGZhbHNlO1xuXHRcdHRoaXMuaW5pdCgpO1xuXHR9XG5cdHB1YmxpYyBzZXQgd2lyZWZyYW1lKHZhbHVlOiBib29sZWFuKSB7XG5cdFx0dGhpcy5yZW5kZXJTdGF0ZS5wcmltaXRpdmUudG9wb2xvZ3kgPSB2YWx1ZSA/IFByaW1pdGl2ZVRvcG9sb2d5LkxpbmVMaXN0IDogUHJpbWl0aXZlVG9wb2xvZ3kuVHJpYW5nbGVMaXN0O1xuXHR9XG5cdHB1YmxpYyBzZXQgdG9wb2xvZ3kodmFsdWU6IFByaW1pdGl2ZVRvcG9sb2d5KSB7XG5cdFx0dGhpcy5yZW5kZXJTdGF0ZS5wcmltaXRpdmUudG9wb2xvZ3kgPSB2YWx1ZTtcblx0fVxuXHRwdWJsaWMgZ2V0IGRvdWJsZVNpZGVkKCkge1xuXHRcdHJldHVybiB0aGlzLl9kb3VibGVTaWRlZDtcblx0fVxuXHRwdWJsaWMgc2V0IGRvdWJsZVNpZGVkKHZhbHVlOiBib29sZWFuKSB7XG5cdFx0dGhpcy5fcmVuZGVyU3RhdGUucHJpbWl0aXZlLmN1bGxNb2RlID0gdmFsdWUgPyBDdWxsTW9kZS5Ob25lIDogQ3VsbE1vZGUuQmFjaztcblx0XHR0aGlzLl9kb3VibGVTaWRlZCA9IHZhbHVlO1xuXHR9XG5cdHB1YmxpYyBnZXQgcmVuZGVyU3RhdGUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX3JlbmRlclN0YXRlO1xuXHR9XG5cdHB1YmxpYyBzZXQgcmVuZGVyU3RhdGUodmFsdWU6IFJlbmRlclN0YXRlKSB7XG5cdFx0dGhpcy5fcmVuZGVyU3RhdGUgPSB2YWx1ZTtcblx0fVxuXHRwdWJsaWMgZ2V0IGRpZmZ1c2UoKTogQ29sb3Ige1xuXHRcdHJldHVybiB0aGlzLl9kaWZmdXNlO1xuXHR9XG5cdHB1YmxpYyBzZXQgZGlmZnVzZSh2OiBDb2xvcikge1xuXHRcdHRoaXMuX2RpZmZ1c2UgPSB2O1xuXHR9XG5cdHB1YmxpYyBnZXQgZW1pc3NpdmUoKTogQ29sb3Ige1xuXHRcdHJldHVybiB0aGlzLl9lbWlzc2l2ZTtcblx0fVxuXHRwdWJsaWMgc2V0IGVtaXNzaXZlKHY6IENvbG9yKSB7XG5cdFx0dGhpcy5fZW1pc3NpdmUgPSB2O1xuXHR9XG5cdHB1YmxpYyBnZXQgZW1pc3NpdmVJbnRlbnNpdHkoKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gdGhpcy5fZW1pc3NpdmVJbnRlbnNpdHk7XG5cdH1cblx0cHVibGljIHNldCBlbWlzc2l2ZUludGVuc2l0eSh2OiBudW1iZXIpIHtcblx0XHR0aGlzLl9lbWlzc2l2ZUludGVuc2l0eSA9IHY7XG5cdH1cblx0cHVibGljIGdldCBvcGFjaXR5KCk6IG51bWJlciB7XG5cdFx0cmV0dXJuIHRoaXMuX29wYWNpdHk7XG5cdH1cblx0cHVibGljIHNldCBvcGFjaXR5KHY6IG51bWJlcikge1xuXHRcdHRoaXMuX29wYWNpdHkgPSB2O1xuXHR9XG5cdG9uQmVmb3JlUmVuZGVyKCkge1xuXHRcdC8vIGNhbGxiYWNrXG5cdH1cblxuXHRvbkJlZm9yZUNvbXBpbGUoKSB7XG5cdFx0Ly8gY2FsbGJhY2tcblx0fVxuXHRjbG9uZSgpOiBNYXRlcmlhbCB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblx0dXBkYXRlKGZyYW1lU3RhdGU/OiBGcmFtZVN0YXRlLCBtZXNoPzogTWVzaCkge1xuXHRcdC8vIHVwZGF0ZSBtYXRlcmlhbFxuXHR9XG5cdHByb3RlY3RlZCBjcmVhdGVTaGFkZXJEYXRhKCkge1xuXHRcdGlmICh0aGlzLnNoYWRlckRhdGEpIHRoaXMuc2hhZGVyRGF0YS5kZXN0cm95KCk7XG5cdFx0dGhpcy5zaGFkZXJEYXRhID0gbmV3IFNoYWRlckRhdGEodGhpcy50eXBlLCAwKTtcblx0XHR0aGlzLnJlYWR5ID0gdHJ1ZTtcblx0fVxuXHRwcml2YXRlIGluaXQoKSB7XG5cdFx0Ly8g6buY6K6k5riy5p+T54q25oCBXG5cdFx0Y29uc3QgcHJpbWl0aXZlID0gbmV3IFByaW1pdGl2ZSgpO1xuXHRcdGNvbnN0IHRhcmdldCA9IG5ldyBUYXJnZXQoKTtcblx0XHRjb25zdCBkZXB0aFN0ZW5jaWwgPSBuZXcgRGVwdGhTdGVuY2lsKCk7XG5cdFx0dGhpcy5fcmVuZGVyU3RhdGUgPSBuZXcgUmVuZGVyU3RhdGUoKTtcblx0XHR0aGlzLl9yZW5kZXJTdGF0ZS5wcmltaXRpdmUgPSBwcmltaXRpdmU7XG5cdFx0dGhpcy5fcmVuZGVyU3RhdGUudGFyZ2V0cyA9IFt0YXJnZXRdO1xuXHRcdHRoaXMuX3JlbmRlclN0YXRlLmRlcHRoU3RlbmNpbCA9IGRlcHRoU3RlbmNpbDtcblx0fVxuXHRwdWJsaWMgZGVzdHJveSgpIHtcblx0XHR0aGlzLmxhYmVsID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMudHlwZSA9IHVuZGVmaW5lZDtcblx0XHR0aGlzLmJhc2VUZXh0dXJlID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMuYmFzZVNhbXBsZXIgPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy5jb2xvciA9IHVuZGVmaW5lZDtcblx0fVxufVxuIiwiaW1wb3J0IHsgRnJhbWVTdGF0ZSB9IGZyb20gXCIuLi9jb3JlL0ZyYW1lU3RhdGVcIjtcbmltcG9ydCB7IEJ1ZmZlckJpbmRpbmdUeXBlLCBCdWZmZXJVc2FnZSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVUNvbnN0YW50XCI7XG5pbXBvcnQgeyBTaGFkZXJNYXRlcmlhbFBhcm1zLCBVbmlmb3JtcyB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XG5pbXBvcnQgeyBNZXNoIH0gZnJvbSBcIi4uL21lc2gvTWVzaFwiO1xuaW1wb3J0IFVuaWZvcm1CdWZmZXIgZnJvbSBcIi4uL3JlbmRlci9Vbmlmb3JtQnVmZmVyXCI7XG5pbXBvcnQgeyBTaGFkZXJTb3VyY2UgfSBmcm9tIFwiLi4vc2hhZGVyL1NoYWRlclNvdXJjZVwiO1xuaW1wb3J0IGRlZmF1bHRWYWx1ZSBmcm9tIFwiLi4vdXRpbHMvZGVmYXVsdFZhbHVlXCI7XG5pbXBvcnQgeyBhZGRVbmlmb3JtVG9TaGFkZXJEYXRhLCBjaGVja0NvbnRhaW5GbG9hdFR5cGUgfSBmcm9tIFwiLi4vdXRpbHMvdW5pZm9ybVV0aWxzXCI7XG5pbXBvcnQgeyBNYXRlcmlhbCB9IGZyb20gXCIuL01hdGVyaWFsXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNoYWRlck1hdGVyaWFsIGV4dGVuZHMgTWF0ZXJpYWwge1xuXHR1bmlmb3JtczogVW5pZm9ybXM7XG5cdHVuaWZvcm1CdWZmZXI6IFVuaWZvcm1CdWZmZXI7XG5cdHByaXZhdGUgc2hhZGVyTWF0ZXJpYWxQYXJtczogU2hhZGVyTWF0ZXJpYWxQYXJtcztcblx0Y29uc3RydWN0b3Iob3B0aW9uczogU2hhZGVyTWF0ZXJpYWxQYXJtcykge1xuXHRcdHN1cGVyKCk7XG5cdFx0Y29uc3QgeyB0eXBlLCBmcmFnLCB2ZXJ0LCBkZWZpbmVzLCBsaWdodCB9ID0gb3B0aW9ucztcblx0XHR0aGlzLnR5cGUgPSB0eXBlO1xuXHRcdHRoaXMuc2hhZGVyTWF0ZXJpYWxQYXJtcyA9IG9wdGlvbnM7XG5cdFx0dGhpcy5zaGFkZXJTb3VyY2UgPSBuZXcgU2hhZGVyU291cmNlKHtcblx0XHRcdHNoYWRlcklkOiB0eXBlLFxuXHRcdFx0cmVuZGVyOiB7XG5cdFx0XHRcdGZyYWdTaGFkZXI6IGZyYWcsXG5cdFx0XHRcdHZlcnRTaGFkZXI6IHZlcnRcblx0XHRcdH0sXG5cdFx0XHRkZWZpbmVzOiBkZWZhdWx0VmFsdWUoZGVmaW5lcywge30pXG5cdFx0fSk7XG5cdFx0dGhpcy51bmlmb3JtcyA9IG9wdGlvbnMudW5pZm9ybXM7XG5cdFx0dGhpcy51bmlmb3JtQnVmZmVyID0gdW5kZWZpbmVkO1xuXHRcdHRoaXMubGlnaHQgPSBsaWdodCB8fCBmYWxzZTtcblx0fVxuXHR1cGRhdGUoZnJhbWVTdGF0ZT86IEZyYW1lU3RhdGUsIG1lc2g/OiBNZXNoKSB7XG5cdFx0aWYgKCF0aGlzLnNoYWRlckRhdGEgfHwgdGhpcy5kaXJ0eSkgdGhpcy5jcmVhdGVTaGFkZXJEYXRhKG1lc2gpO1xuXHR9XG5cdGNsb25lKCkge1xuXHRcdHJldHVybiBuZXcgU2hhZGVyTWF0ZXJpYWwodGhpcy5zaGFkZXJNYXRlcmlhbFBhcm1zKTtcblx0fVxuXHRwcm90ZWN0ZWQgY3JlYXRlU2hhZGVyRGF0YShtZXNoPzogTWVzaCkge1xuXHRcdHN1cGVyLmNyZWF0ZVNoYWRlckRhdGEoKTtcblx0XHRjb25zdCByZXN1bHQgPSBjaGVja0NvbnRhaW5GbG9hdFR5cGUodGhpcy51bmlmb3Jtcyk7XG5cdFx0aWYgKHJlc3VsdC5oYXNGbG9hdCkge1xuXHRcdFx0dGhpcy51bmlmb3JtQnVmZmVyID0gcmVzdWx0Lmhhc0FycmF5dHlwZVxuXHRcdFx0XHQ/IG5ldyBVbmlmb3JtQnVmZmVyKHtcblx0XHRcdFx0XHRcdGxhYmVsOiB0aGlzLnR5cGUgKyBcIlVuaWZvcm1CdWZmZXJcIixcblx0XHRcdFx0XHRcdHR5cGU6IEJ1ZmZlckJpbmRpbmdUeXBlLlJlYWRPbmx5U3RvcmFnZSxcblx0XHRcdFx0XHRcdHVzYWdlOiBCdWZmZXJVc2FnZS5TdG9yYWdlIHwgQnVmZmVyVXNhZ2UuQ29weURzdFxuXHRcdFx0XHQgIH0pXG5cdFx0XHRcdDogbmV3IFVuaWZvcm1CdWZmZXIoeyBsYWJlbDogdGhpcy50eXBlICsgXCJVbmlmb3JtQnVmZmVyXCIgfSk7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0VW5pZm9ybUJ1ZmZlcih0aGlzLnR5cGUsIHRoaXMudW5pZm9ybUJ1ZmZlcik7XG5cdFx0fVxuXHRcdGNvbnN0IHVuaWZvcm1zTmFtZXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0aGlzLnVuaWZvcm1zKTtcblx0XHR1bmlmb3Jtc05hbWVzLm1hcCgodW5pZm9ybXNOYW1lKSA9PiB7XG5cdFx0XHRhZGRVbmlmb3JtVG9TaGFkZXJEYXRhKFxuXHRcdFx0XHR1bmlmb3Jtc05hbWUsXG5cdFx0XHRcdHRoaXMudW5pZm9ybXNbdW5pZm9ybXNOYW1lXSxcblx0XHRcdFx0dGhpcy5zaGFkZXJEYXRhLFxuXHRcdFx0XHRtZXNoLFxuXHRcdFx0XHR0aGlzLnVuaWZvcm1CdWZmZXJcblx0XHRcdCk7XG5cdFx0fSk7XG5cdH1cbn1cbiIsImZ1bmN0aW9uIGNyZWF0ZUd1aWQoKSB7XHJcbiAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMDUwMzQvaG93LXRvLWNyZWF0ZS1hLWd1aWQtdXVpZC1pbi1qYXZhc2NyaXB0XHJcbiAgcmV0dXJuIFwieHh4eHh4eHgteHh4eC00eHh4LXl4eHgteHh4eHh4eHh4eHh4XCIucmVwbGFjZSgvW3h5XS9nLCBmdW5jdGlvbiAoYykge1xyXG4gICAgY29uc3QgciA9IChNYXRoLnJhbmRvbSgpICogMTYpIHwgMDtcclxuICAgIGNvbnN0IHYgPSBjID09PSBcInhcIiA/IHIgOiAociAmIDB4MykgfCAweDg7XHJcbiAgICByZXR1cm4gdi50b1N0cmluZygxNik7XHJcbiAgfSk7XHJcbn1cclxuZXhwb3J0IGRlZmF1bHQgY3JlYXRlR3VpZDtcclxuIiwiaW1wb3J0IENhbWVyYSBmcm9tIFwiLi4vY2FtZXJhL0NhbWVyYVwiO1xuaW1wb3J0IHsgRnJhbWVTdGF0ZSB9IGZyb20gXCIuLi9jb3JlL0ZyYW1lU3RhdGVcIjtcbmltcG9ydCBMaWdodE1hbmdlciBmcm9tIFwiLi4vY29yZS9MaWdodE1hbmdlclwiO1xuaW1wb3J0IFJlbmRlck9iamVjdCBmcm9tIFwiLi4vY29yZS9SZW5kZXJPYmplY3RcIjtcbmltcG9ydCB7IENvbW1hbmRTdWJUeXBlLCBJbnRlcnNlY3QgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVDb25zdGFudFwiO1xuaW1wb3J0IHsgUmVuZGVyT2JqZWN0VHlwZSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XG5pbXBvcnQgR2VvbWV0cnkgZnJvbSBcIi4uL2dlb21ldHJ5L0dlb21ldHJ5XCI7XG5pbXBvcnQgeyBNYXRlcmlhbCB9IGZyb20gXCIuLi9tYXRlcmlhbC9NYXRlcmlhbFwiO1xuaW1wb3J0IERyYXdDb21tYW5kIGZyb20gXCIuLi9yZW5kZXIvRHJhd0NvbW1hbmRcIjtcbmltcG9ydCBjcmVhdGVHdWlkIGZyb20gXCIuLi91dGlscy9jcmVhdGVHdWlkXCI7XG5leHBvcnQgY2xhc3MgTWVzaCBleHRlbmRzIFJlbmRlck9iamVjdCB7XG5cdFt4OiBzdHJpbmddOiBhbnk7XG5cdHVpZDogc3RyaW5nO1xuXHRmcnVzdHVtQ3VsbDogYm9vbGVhbjtcblx0c3ViQ29tbWFuZHM6IHsgW3Byb3A6IHN0cmluZ106IERyYXdDb21tYW5kIH07XG5cdGdlb21ldHJ5PzogR2VvbWV0cnk7XG5cdG1hdGVyaWFsPzogTWF0ZXJpYWw7XG5cdGluc3RhbmNlQ291bnQ/OiBudW1iZXI7XG5cdHByaW9yaXR5PzogbnVtYmVyO1xuXHRkcmF3Q29tbWFuZD86IERyYXdDb21tYW5kO1xuXHRkaXN0YW5jZVRvQ2FtZXJhPzogbnVtYmVyO1xuXHRjb25zdHJ1Y3RvcihnZW9tZXRyeT86IEdlb21ldHJ5LCBtYXRlcmlhbD86IE1hdGVyaWFsKSB7XG5cdFx0c3VwZXIoKTtcblx0XHR0aGlzLmdlb21ldHJ5ID0gZ2VvbWV0cnk7XG5cdFx0dGhpcy5tYXRlcmlhbCA9IG1hdGVyaWFsO1xuXHRcdHRoaXMudHlwZSA9IFJlbmRlck9iamVjdFR5cGUuTWVzaDtcblx0XHR0aGlzLmZydXN0dW1DdWxsID0gdHJ1ZTtcblx0XHR0aGlzLnVpZCA9IGNyZWF0ZUd1aWQoKTtcblx0XHR0aGlzLnN1YkNvbW1hbmRzID0ge307XG5cdH1cblx0Z2V0IHJlYWR5KCkge1xuXHRcdHJldHVybiB0aGlzLm1hdGVyaWFsLnJlYWR5O1xuXHR9XG5cdHVwZGF0ZShmcmFtZVN0YXRlOiBGcmFtZVN0YXRlLCBjYW1lcmE/OiBDYW1lcmEpIHtcblx0XHQvLyB1cGRhdGUgbWF0cml4XG5cdFx0dGhpcy51cGRhdGVNYXRyaXgodGhpcz8ucGFyZW50Py5tb2RlbE1hdHJpeCk7XG5cdFx0Ly8gY3JlYXRlXG5cdFx0dGhpcy5nZW9tZXRyeS51cGRhdGUoZnJhbWVTdGF0ZSk7XG5cdFx0dGhpcy5tYXRlcmlhbC51cGRhdGUoZnJhbWVTdGF0ZSwgdGhpcyk7XG5cdFx0Ly8gdXBkYXRlIGJvdW5kaW5nU3BoZXJlXG5cdFx0dGhpcy5nZW9tZXRyeS5ib3VuZGluZ1NwaGVyZS51cGRhdGUodGhpcy5tb2RlbE1hdHJpeCk7XG5cdFx0dGhpcy5tYXRlcmlhbC5zaGFkZXJTb3VyY2Uuc2V0RGVmaW5lcyhmcmFtZVN0YXRlLmRlZmluZXMpO1xuXHRcdGlmICh0aGlzLnR5cGUgPT0gUmVuZGVyT2JqZWN0VHlwZS5EZWJ1Zykge1xuXHRcdFx0ZnJhbWVTdGF0ZS5yZW5kZXJRdWV1ZS5kZWJ1Z1F1ZXVlLnB1c2godGhpcyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMuZGlzdGFuY2VUb0NhbWVyYSA9IHRoaXMuZ2VvbWV0cnkuYm91bmRpbmdTcGhlcmUuZGlzdGFuY2VUb0NhbWVyYShjYW1lcmEpO1xuXG5cdFx0Y29uc3QgdmlzaWJpbGl0eSA9IGZyYW1lU3RhdGUuY3VsbGluZ1ZvbHVtZS5jb21wdXRlVmlzaWJpbGl0eSh0aGlzLmdlb21ldHJ5LmJvdW5kaW5nU3BoZXJlKTtcblx0XHQvLyDop4bplKXliZTpmaRcblx0XHRpZiAodmlzaWJpbGl0eSA9PT0gSW50ZXJzZWN0Lk9VVFNJREUgfHwgIXRoaXMuZnJ1c3R1bUN1bGwpIHJldHVybjtcblx0XHRpZiAodGhpcy5tYXRlcmlhbC50cmFuc3BhcmVudCkge1xuXHRcdFx0ZnJhbWVTdGF0ZS5yZW5kZXJRdWV1ZS50cmFuc3BhcmVudC5wdXNoKHRoaXMpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRmcmFtZVN0YXRlLnJlbmRlclF1ZXVlLm9wYXF1ZS5wdXNoKHRoaXMpO1xuXHRcdH1cblx0fVxuXHRiZWZvcmVSZW5kZXIoKSB7XG5cdFx0Ly8gYmVmb3JlIHJlbmRlclxuXHR9XG5cdGFmdGVyUmVuZGVyKCkge1xuXHRcdC8vIGFmdGVyIHJlbmRlclxuXHR9XG5cdHB1YmxpYyBnZXREcmF3Q29tbWFuZChvdmVycmlkZU1hdGVyaWFsPzogTWF0ZXJpYWwsIGNvbW1hbmRTdWJUeXBlPzogQ29tbWFuZFN1YlR5cGUsIGxpZ2h0TWFuZ2VyPzogTGlnaHRNYW5nZXIpIHtcblx0XHRpZiAoIXRoaXMuZHJhd0NvbW1hbmQgfHwgdGhpcy5tYXRlcmlhbC5kaXJ0eSkge1xuXHRcdFx0dGhpcy5tYXRlcmlhbC5zaGFkZXJTb3VyY2Uuc2V0RGVmaW5lcyhcblx0XHRcdFx0T2JqZWN0LmFzc2lnbih7fSwgdGhpcy5tYXRlcmlhbC5zaGFkZXJEYXRhLmRlZmluZXMsIHRoaXMuZ2VvbWV0cnkuZGVmaW5lcylcblx0XHRcdCk7XG5cdFx0XHRpZiAodGhpcy5tYXRlcmlhbC5kaXJ0eSkgdGhpcy5tYXRlcmlhbC5kaXJ0eSA9IGZhbHNlO1xuXHRcdFx0dGhpcy5kcmF3Q29tbWFuZCA9IG5ldyBEcmF3Q29tbWFuZCh7XG5cdFx0XHRcdHZlcnRleEJ1ZmZlcnM6IHRoaXMuZ2VvbWV0cnkudmVydGV4QnVmZmVycyxcblx0XHRcdFx0aW5kZXhCdWZmZXI6IHRoaXMuZ2VvbWV0cnkuaW5kZXhCdWZmZXIsXG5cdFx0XHRcdHNoYWRlckRhdGE6IHRoaXMubWF0ZXJpYWwuc2hhZGVyRGF0YSxcblx0XHRcdFx0aW5zdGFuY2VzOiB0aGlzLmluc3RhbmNlQ291bnQsXG5cdFx0XHRcdGNvdW50OiB0aGlzLmdlb21ldHJ5LmNvdW50LFxuXHRcdFx0XHRyZW5kZXJTdGF0ZTogdGhpcy5tYXRlcmlhbC5yZW5kZXJTdGF0ZSxcblx0XHRcdFx0c2hhZGVyU291cmNlOiB0aGlzLm1hdGVyaWFsLnNoYWRlclNvdXJjZSxcblx0XHRcdFx0bGlnaHRTaGFkZXJEYXRhOiB0aGlzLm1hdGVyaWFsLmxpZ2h0ID8gbGlnaHRNYW5nZXI/LmxpZ2h0U2hhZGVyRGF0YSA6IHVuZGVmaW5lZCxcblx0XHRcdFx0dXNlTGlnaHQ6IHRoaXMubWF0ZXJpYWwubGlnaHRcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRpZiAob3ZlcnJpZGVNYXRlcmlhbCkge1xuXHRcdFx0aWYgKCF0aGlzLnN1YkNvbW1hbmRzW2NvbW1hbmRTdWJUeXBlXSkge1xuXHRcdFx0XHRjb25zdCBjb3B5TWF0ID0gb3ZlcnJpZGVNYXRlcmlhbC5jbG9uZSgpO1xuXHRcdFx0XHRjb3B5TWF0LnVwZGF0ZSh1bmRlZmluZWQsIHRoaXMpO1xuXHRcdFx0XHRpZiAoY29weU1hdC5kaXJ0eSkgY29weU1hdC5kaXJ0eSA9IGZhbHNlO1xuXHRcdFx0XHR0aGlzLnN1YkNvbW1hbmRzW2NvbW1hbmRTdWJUeXBlXSA9IHRoaXMuZHJhd0NvbW1hbmQuc2hhbGxvd0Nsb25lKGNvcHlNYXQpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRoaXMuc3ViQ29tbWFuZHNbY29tbWFuZFN1YlR5cGVdO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5kcmF3Q29tbWFuZDtcblx0fVxuXHRkZXN0cm95KCkge1xuXHRcdHRoaXMuZ2VvbWV0cnkuZGVzdHJveSgpO1xuXHRcdHRoaXMubWF0ZXJpYWwuZGVzdHJveSgpO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBSZW5kZXJPYmplY3RUeXBlIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcclxuaW1wb3J0IEdlb21ldHJ5IGZyb20gXCIuLi9nZW9tZXRyeS9HZW9tZXRyeVwiO1xyXG5pbXBvcnQgUGxhbmVHZW9tZXRyeSBmcm9tIFwiLi4vZ2VvbWV0cnkvUGxhbmVHZW9tZXRyeVwiO1xyXG5pbXBvcnQgeyBMaWdodCB9IGZyb20gXCIuLi9saWdodC9MaWdodFwiO1xyXG5pbXBvcnQgU2hhZGVyTWF0ZXJpYWwgZnJvbSBcIi4uL21hdGVyaWFsL1NoYWRlck1hdGVyaWFsXCI7XHJcbmltcG9ydCB7IE1lc2ggfSBmcm9tIFwiLi4vbWVzaC9NZXNoXCI7XHJcbmltcG9ydCB7IFZpZXdQb3J0IH0gZnJvbSBcIi4uL3JlbmRlci9SZW5kZXJTdGF0ZVwiO1xyXG5pbXBvcnQgU2FtcGxlciBmcm9tIFwiLi4vcmVuZGVyL1NhbXBsZXJcIjtcclxuaW1wb3J0IHsgU2NlbmUgfSBmcm9tIFwiLi4vU2NlbmVcIjtcclxuaW1wb3J0IGdldFZlcnRGcmFnIGZyb20gXCIuLi9zaGFkZXIvU2hhZGVyc1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFNoYWRvd01hcERlYnVnZ2VyIHtcclxuXHRwcml2YXRlIG1lc2g6IE1lc2g7XHJcblx0cHJpdmF0ZSBkZWJ1Z2dlclNpemU6IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfTtcclxuXHRwdWJsaWMgbGlnaHQ6IExpZ2h0O1xyXG5cdHByaXZhdGUgZ2VvbWV0cnk6IEdlb21ldHJ5O1xyXG5cdHByaXZhdGUgbWF0ZXJpYWw6IFNoYWRlck1hdGVyaWFsO1xyXG5cdHByaXZhdGUgc2NlbmU6IFNjZW5lO1xyXG5cclxuXHRjb25zdHJ1Y3RvcihsaWdodDogTGlnaHQsIHNjZW5lOiBTY2VuZSkge1xyXG5cdFx0aWYgKCFsaWdodCB8fCAhKGxpZ2h0IGluc3RhbmNlb2YgTGlnaHQpKSB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcGFyYW1ldGVyIG11c3QgYmUgTGlnaHQgaW5zdGFuY2VcIik7XHJcblxyXG5cdFx0dGhpcy5saWdodCA9IGxpZ2h0O1xyXG5cdFx0dGhpcy5zY2VuZSA9IHNjZW5lO1xyXG5cdFx0dGhpcy5kZWJ1Z2dlclNpemUgPSB7XHJcblx0XHRcdHdpZHRoOiAyNTYsXHJcblx0XHRcdGhlaWdodDogMjU2XHJcblx0XHR9O1xyXG5cclxuXHRcdHRoaXMubWVzaCA9IHRoaXMuX2NyZWF0ZVNoYWRvd01hcE1lc2goKTtcclxuXHRcdGNvbnN0IHNoYWRvd01hcCA9IHRoaXMubGlnaHQuc2hhZG93LmdldFNoYWRvd01hcFRleHR1cmUoKTtcclxuXHRcdHRoaXMubWF0ZXJpYWwudW5pZm9ybXMudGV4dHVyZS52YWx1ZSA9IHNoYWRvd01hcDtcclxuXHRcdHRoaXMubWVzaC50eXBlID0gUmVuZGVyT2JqZWN0VHlwZS5EZWJ1ZztcclxuXHRcdHRoaXMuc2NlbmUuYWRkKHRoaXMubWVzaCk7XHJcblx0fVxyXG5cclxuXHRfY3JlYXRlU2hhZG93TWFwTWVzaCgpIHtcclxuXHRcdGNvbnN0IHNoYWRlciA9IGdldFZlcnRGcmFnKFwic2hhZG93TWFwRGVidWdnZXJcIiwge1xyXG5cdFx0XHRwb3NpdGlvbkxvY2F0aW9uOiAwXHJcblx0XHR9KTtcclxuXHRcdHRoaXMuZ2VvbWV0cnkgPSBuZXcgUGxhbmVHZW9tZXRyeSgyLCAyKTtcclxuXHRcdHRoaXMubWF0ZXJpYWwgPSBuZXcgU2hhZGVyTWF0ZXJpYWwoe1xyXG5cdFx0XHR0eXBlOiBcInNoYWRvd01hcERlYnVnZ2VyXCIsXHJcblx0XHRcdGZyYWc6IHNoYWRlci5mcmFnLFxyXG5cdFx0XHR2ZXJ0OiBzaGFkZXIudmVydCxcclxuXHRcdFx0dW5pZm9ybXM6IHtcclxuXHRcdFx0XHR0ZXh0dXJlOiB7XHJcblx0XHRcdFx0XHR0eXBlOiBcInRleHR1cmVcIixcclxuXHRcdFx0XHRcdHZhbHVlOiB1bmRlZmluZWRcclxuXHRcdFx0XHR9LFxyXG5cdFx0XHRcdHNhbXBsZXI6IHtcclxuXHRcdFx0XHRcdHR5cGU6IFwic2FtcGxlclwiLFxyXG5cdFx0XHRcdFx0dmFsdWU6IG5ldyBTYW1wbGVyKHtcclxuXHRcdFx0XHRcdFx0bWFnRmlsdGVyOiBcImxpbmVhclwiLFxyXG5cdFx0XHRcdFx0XHRtaW5GaWx0ZXI6IFwibGluZWFyXCJcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHRcdHRoaXMubWF0ZXJpYWwucmVuZGVyU3RhdGUudmlld3BvcnQgPSBuZXcgVmlld1BvcnQoMCwgMCwgdGhpcy5kZWJ1Z2dlclNpemUud2lkdGgsIHRoaXMuZGVidWdnZXJTaXplLmhlaWdodCk7XHJcblx0XHRyZXR1cm4gbmV3IE1lc2godGhpcy5nZW9tZXRyeSwgdGhpcy5tYXRlcmlhbCk7XHJcblx0fVxyXG5cclxuXHRzZXRTaXplKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XHJcblx0XHRpZiAoIXdpZHRoIHx8ICFoZWlnaHQpIHJldHVybjtcclxuXHRcdHRoaXMuZGVidWdnZXJTaXplLndpZHRoID0gd2lkdGg7XHJcblx0XHR0aGlzLmRlYnVnZ2VyU2l6ZS5oZWlnaHQgPSBoZWlnaHQ7XHJcblx0XHR0aGlzLnVwZGF0ZSgpO1xyXG5cdH1cclxuXHJcblx0dXBkYXRlKCkge1xyXG5cdFx0dGhpcy5tYXRlcmlhbC5yZW5kZXJTdGF0ZS52aWV3cG9ydCA9IG5ldyBWaWV3UG9ydCgwLCAwLCB0aGlzLmRlYnVnZ2VyU2l6ZS53aWR0aCwgdGhpcy5kZWJ1Z2dlclNpemUuaGVpZ2h0KTtcclxuXHR9XHJcbn1cclxuIiwiaW1wb3J0IHsgRnJhbWVTdGF0ZSB9IGZyb20gXCIuLi9jb3JlL0ZyYW1lU3RhdGVcIjtcbmltcG9ydCB7IFVuaWZvcm1FbnVtIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcbmltcG9ydCB7IE1lc2ggfSBmcm9tIFwiLi4vbWVzaC9NZXNoXCI7XG5pbXBvcnQgVW5pZm9ybUJ1ZmZlciBmcm9tIFwiLi4vcmVuZGVyL1VuaWZvcm1CdWZmZXJcIjtcbmltcG9ydCB7IFNoYWRlclNvdXJjZSB9IGZyb20gXCIuLi9zaGFkZXIvU2hhZGVyU291cmNlXCI7XG5pbXBvcnQgeyBNYXRlcmlhbCB9IGZyb20gXCIuL01hdGVyaWFsXCI7XG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDb2xvck1hdGVyaWFsIGV4dGVuZHMgTWF0ZXJpYWwge1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXHRcdHRoaXMudHlwZSA9IFwiY29sb3JcIjtcblx0XHR0aGlzLnNoYWRlclNvdXJjZSA9IG5ldyBTaGFkZXJTb3VyY2Uoe1xuXHRcdFx0c2hhZGVySWQ6IHRoaXMudHlwZSxcblx0XHRcdGRlZmluZXM6IHt9XG5cdFx0fSk7XG5cdH1cblx0dXBkYXRlKGZyYW1lU3RhdGU/OiBGcmFtZVN0YXRlLCBtZXNoPzogTWVzaCkge1xuXHRcdGlmICghdGhpcy5zaGFkZXJEYXRhIHx8IHRoaXMuZGlydHkpIHRoaXMuY3JlYXRlU2hhZGVyRGF0YSgpO1xuXHRcdGNvbnN0IHVuaWZvcm1CdWZmZXIgPSBuZXcgVW5pZm9ybUJ1ZmZlcih7IGxhYmVsOiBcImNvbG9yXCIgfSk7XG5cdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XCJtb2RlbE1hdHJpeFwiLFxuXHRcdFx0KCkgPT4ge1xuXHRcdFx0XHRyZXR1cm4gbWVzaC5tb2RlbE1hdHJpeDtcblx0XHRcdH0sXG5cdFx0XHRVbmlmb3JtRW51bS5NYXQ0XG5cdFx0KTtcblx0XHR0aGlzLnNoYWRlckRhdGEuc2V0VW5pZm9ybUJ1ZmZlcihcImNvbG9yXCIsIHVuaWZvcm1CdWZmZXIpO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBGcmFtZVN0YXRlIH0gZnJvbSBcIi4uL2NvcmUvRnJhbWVTdGF0ZVwiO1xyXG5pbXBvcnQgeyBSZW5kZXJPYmplY3RUeXBlIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcclxuaW1wb3J0IEdlb21ldHJ5IGZyb20gXCIuLi9nZW9tZXRyeS9HZW9tZXRyeVwiO1xyXG5pbXBvcnQgQ29sb3JNYXRlcmlhbCBmcm9tIFwiLi4vbWF0ZXJpYWwvQ29sb3JNYXRlcmlhbFwiO1xyXG5pbXBvcnQgeyBGbG9hdDMyQXR0cmlidXRlIH0gZnJvbSBcIi4uL3JlbmRlci9BdHRyaWJ1dGVcIjtcclxuaW1wb3J0IHsgTWVzaCB9IGZyb20gXCIuL01lc2hcIjtcclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQXhlcyBleHRlbmRzIE1lc2gge1xyXG5cdG1hdGVyaWFsOiBDb2xvck1hdGVyaWFsO1xyXG5cdGNvbnN0cnVjdG9yKCkge1xyXG5cdFx0c3VwZXIoKTtcclxuXHRcdHRoaXMudHlwZSA9IFJlbmRlck9iamVjdFR5cGUuQXhlcztcclxuXHRcdHRoaXMuZGlzdGFuY2VUb0NhbWVyYSA9IDEwO1xyXG5cdFx0dGhpcy5tYXRlcmlhbCA9IG5ldyBDb2xvck1hdGVyaWFsKCk7XHJcblx0XHR0aGlzLm1hdGVyaWFsLndpcmVmcmFtZSA9IHRydWU7XHJcblx0XHR0aGlzLmluaXQoKTtcclxuXHR9XHJcblx0dXBkYXRlKGZyYW1lU3RhdGU6IEZyYW1lU3RhdGUpIHtcclxuXHRcdHRoaXMudXBkYXRlTWF0cml4KCk7XHJcblx0XHR0aGlzLm1hdGVyaWFsLnVwZGF0ZShmcmFtZVN0YXRlLCB0aGlzKTtcclxuXHRcdGZyYW1lU3RhdGUucmVuZGVyUXVldWUub3BhcXVlLnB1c2godGhpcyk7XHJcblx0fVxyXG5cdHByaXZhdGUgaW5pdCgpIHtcclxuXHRcdGNvbnN0IHBvc2l0aW9uID0gWzAsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDFdO1xyXG5cdFx0Y29uc3QgY29sb3JzID0gWzEsIDAsIDAsIDEsIDEsIDAuNSwgMC41LCAxLCAwLCAxLCAwLCAxLCAwLjUsIDEsIDAuNSwgMSwgMCwgMCwgMSwgMSwgMC41LCAwLjUsIDEsIDFdO1xyXG5cdFx0Y29uc3QgaW5kaWNlcyA9IFswLCAxLCAyLCAzLCA0LCA1XTtcclxuXHRcdHRoaXMuZ2VvbWV0cnkgPSBuZXcgR2VvbWV0cnkoe30pO1xyXG5cdFx0dGhpcy5nZW9tZXRyeS5zZXRBdHRyaWJ1dGUobmV3IEZsb2F0MzJBdHRyaWJ1dGUoXCJwb3NpdGlvblwiLCBwb3NpdGlvbiwgMykpO1xyXG5cdFx0dGhpcy5nZW9tZXRyeS5zZXRBdHRyaWJ1dGUobmV3IEZsb2F0MzJBdHRyaWJ1dGUoXCJjb2xvclwiLCBjb2xvcnMsIDQpKTtcclxuXHRcdHRoaXMuZ2VvbWV0cnkuc2V0SW5kaWNlKGluZGljZXMpO1xyXG5cdFx0dGhpcy5nZW9tZXRyeS5jb3VudCA9IGluZGljZXMubGVuZ3RoO1xyXG5cdH1cclxufVxyXG4iLCJpbXBvcnQgeyBGbG9hdDMyQXR0cmlidXRlIH0gZnJvbSBcIi4uL3JlbmRlci9BdHRyaWJ1dGVcIjtcbmltcG9ydCBHZW9tZXRyeSBmcm9tIFwiLi9HZW9tZXRyeVwiO1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2t5Qm94R2VvbWV0cnkgZXh0ZW5kcyBHZW9tZXRyeSB7XG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKHtcblx0XHRcdHR5cGU6IFwic2t5Qm94R2VvbWV0cnlcIlxuXHRcdH0pO1xuXHRcdHRoaXMuaW5pdCgpO1xuXHR9XG5cdHB1YmxpYyBpbml0KCkge1xuXHRcdGNvbnN0IHBvc2l0aW9ucyA9IFtcblx0XHRcdDEuMCxcblx0XHRcdDEuMCxcblx0XHRcdDEuMCwgLy8gMFxuXHRcdFx0LTEuMCxcblx0XHRcdDEuMCxcblx0XHRcdDEuMCwgLy8gMVxuXHRcdFx0MS4wLFxuXHRcdFx0LTEuMCxcblx0XHRcdDEuMCwgLy8gMlxuXHRcdFx0LTEuMCxcblx0XHRcdC0xLjAsXG5cdFx0XHQxLjAsIC8vIDNcblx0XHRcdDEuMCxcblx0XHRcdDEuMCxcblx0XHRcdC0xLjAsIC8vIDRcblx0XHRcdC0xLjAsXG5cdFx0XHQxLjAsXG5cdFx0XHQtMS4wLCAvLyA1XG5cdFx0XHQxLjAsXG5cdFx0XHQtMS4wLFxuXHRcdFx0LTEuMCwgLy8gNlxuXHRcdFx0LTEuMCxcblx0XHRcdC0xLjAsXG5cdFx0XHQtMS4wIC8vIDdcblx0XHRdO1xuXHRcdGNvbnN0IGluZGljZXMgPSBbXG5cdFx0XHQvLyBQb3NYIChSaWdodClcblx0XHRcdDAsIDIsIDQsIDYsIDQsIDIsXG5cblx0XHRcdC8vIE5lZ1ggKExlZnQpXG5cdFx0XHQ1LCAzLCAxLCAzLCA1LCA3LFxuXG5cdFx0XHQvLyBQb3NZIChUb3ApXG5cdFx0XHQ0LCAxLCAwLCAxLCA0LCA1LFxuXG5cdFx0XHQvLyBOZWdZIChCb3R0b20pXG5cdFx0XHQyLCAzLCA2LCA3LCA2LCAzLFxuXG5cdFx0XHQvLyBQb3NaIChGcm9udClcblx0XHRcdDAsIDEsIDIsIDMsIDIsIDEsXG5cblx0XHRcdC8vIE5lZ1ogKEJhY2spXG5cdFx0XHQ2LCA1LCA0LCA1LCA2LCA3XG5cdFx0XTtcblx0XHR0aGlzLnNldEF0dHJpYnV0ZShuZXcgRmxvYXQzMkF0dHJpYnV0ZShcInBvc2l0aW9uXCIsIHBvc2l0aW9ucywgMykpO1xuXHRcdHRoaXMuc2V0SW5kaWNlKGluZGljZXMpO1xuXHRcdHRoaXMuY291bnQgPSBpbmRpY2VzLmxlbmd0aDtcblx0fVxufVxuIiwiZnVuY3Rpb24gcmV0dXJuVHJ1ZSgpIHtcclxuXHRyZXR1cm4gdHJ1ZTtcclxufVxyXG5leHBvcnQgZnVuY3Rpb24gZGVzdHJveU9iamVjdChvYmplY3QpIHtcclxuXHQvLyBtZXNzYWdlID1tZXNzYWdlfHxcIlRoaXMgb2JqZWN0IHdhcyBkZXN0cm95ZWQsIGkuZS4sIGRlc3Ryb3koKSB3YXMgY2FsbGVkLlwiO1xyXG5cclxuXHRmdW5jdGlvbiB0aHJvd09uRGVzdHJveWVkKCkge1xyXG5cdFx0dGhyb3cgbmV3IEVycm9yKFwiVGhpcyBvYmplY3Qgd2FzIGRlc3Ryb3llZCwgaS5lLiwgZGVzdHJveSgpIHdhcyBjYWxsZWQuXCIpO1xyXG5cdH1cclxuXHJcblx0Zm9yIChjb25zdCBrZXkgaW4gb2JqZWN0KSB7XHJcblx0XHRpZiAodHlwZW9mIG9iamVjdFtrZXldID09PSBcImZ1bmN0aW9uXCIpIHtcclxuXHRcdFx0b2JqZWN0W2tleV0gPSB0aHJvd09uRGVzdHJveWVkO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0b2JqZWN0LmlzRGVzdHJveWVkID0gcmV0dXJuVHJ1ZTtcclxuXHJcblx0cmV0dXJuIHVuZGVmaW5lZDtcclxufVxyXG4iLCJpbXBvcnQgU2FtcGxlciBmcm9tIFwiLi4vcmVuZGVyL1NhbXBsZXJcIjtcbmltcG9ydCBUZXh0dXJlIGZyb20gXCIuLi9yZW5kZXIvVGV4dHVyZVwiO1xuaW1wb3J0IGRlZmluZWQgZnJvbSBcIi4uL3V0aWxzL2RlZmluZWRcIjtcbmltcG9ydCB7IGRlc3Ryb3lPYmplY3QgfSBmcm9tIFwiLi4vdXRpbHMvZGVzdHJveU9iamVjdFwiO1xudHlwZSBUZXh0dXJlQ2FjaGVQcm9wID0ge1xuXHR0ZXh0dXJlOiBUZXh0dXJlO1xuXHRjb3VudDogbnVtYmVyO1xufTtcbmNsYXNzIFRleHR1cmVDYWNoZSB7XG5cdHB1YmxpYyBkZWZhdWx0U2FtcGxlcjogU2FtcGxlcjtcblx0cHJpdmF0ZSBfbnVtYmVyT2ZUZXh0dXJlczogbnVtYmVyO1xuXHRwcml2YXRlIF90ZXh0dXJlczogTWFwPHN0cmluZywgVGV4dHVyZUNhY2hlUHJvcD47XG5cdHByaXZhdGUgX3RleHR1cmVzVG9SZWxlYXNlOiBNYXA8c3RyaW5nLCBUZXh0dXJlQ2FjaGVQcm9wPjtcblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0dGhpcy5fbnVtYmVyT2ZUZXh0dXJlcyA9IDA7XG5cdFx0dGhpcy5fdGV4dHVyZXMgPSBuZXcgTWFwKCk7XG5cdFx0dGhpcy5fbnVtYmVyT2ZUZXh0dXJlcyA9IDA7XG5cdFx0dGhpcy5fdGV4dHVyZXNUb1JlbGVhc2UgPSBuZXcgTWFwKCk7XG5cdFx0dGhpcy5kZWZhdWx0U2FtcGxlciA9IG5ldyBTYW1wbGVyKHtcblx0XHRcdG1hZ0ZpbHRlcjogXCJsaW5lYXJcIixcblx0XHRcdG1pbkZpbHRlcjogXCJsaW5lYXJcIixcblx0XHRcdGFkZHJlc3NNb2RlVTogXCJyZXBlYXRcIixcblx0XHRcdGFkZHJlc3NNb2RlVjogXCJyZXBlYXRcIlxuXHRcdH0pO1xuXHR9XG5cdGdldCBudW1iZXJPZlRleHR1cmVzKCk6IG51bWJlciB7XG5cdFx0cmV0dXJuIHRoaXMuX251bWJlck9mVGV4dHVyZXM7XG5cdH1cblx0Z2V0VGV4dHVyZShrZXl3b3JkKSB7XG5cdFx0Y29uc3QgY2FjaGVkVGV4dHVyZSA9IHRoaXMuX3RleHR1cmVzLmdldChrZXl3b3JkKTtcblx0XHRpZiAoIWRlZmluZWQoY2FjaGVkVGV4dHVyZSkpIHtcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdC8vIE5vIGxvbmdlciB3YW50IHRvIHJlbGVhc2UgdGhpcyBpZiBpdCB3YXMgcHJldmlvdXNseSByZWxlYXNlZC5cblx0XHRkZWxldGUgdGhpcy5fdGV4dHVyZXNUb1JlbGVhc2Vba2V5d29yZF07XG5cblx0XHQrK2NhY2hlZFRleHR1cmUuY291bnQ7XG5cdFx0cmV0dXJuIGNhY2hlZFRleHR1cmUudGV4dHVyZTtcblx0fVxuXHRhZGRUZXh0dXJlKGtleXdvcmQsIHRleHR1cmUpIHtcblx0XHRjb25zdCBjYWNoZWRUZXh0dXJlID0ge1xuXHRcdFx0dGV4dHVyZTogdGV4dHVyZSxcblx0XHRcdGNvdW50OiAxXG5cdFx0fTtcblxuXHRcdHRleHR1cmUuZmluYWxEZXN0cm95ID0gdGV4dHVyZS5kZXN0cm95O1xuXG5cdFx0Ly8gY29uc3QgdGhhdCA9IHRoaXM7XG5cdFx0dGV4dHVyZS5kZXN0cm95ID0gKCkgPT4ge1xuXHRcdFx0aWYgKC0tY2FjaGVkVGV4dHVyZS5jb3VudCA9PT0gMCkge1xuXHRcdFx0XHR0aGlzLl90ZXh0dXJlc1RvUmVsZWFzZS5zZXQoa2V5d29yZCwgY2FjaGVkVGV4dHVyZSk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdHRoaXMuX3RleHR1cmVzLnNldChrZXl3b3JkLCBjYWNoZWRUZXh0dXJlKTtcblx0XHQrK3RoaXMuX251bWJlck9mVGV4dHVyZXM7XG5cdH1cblx0cmVsZWFzZWRUZXh0dXJlcygpIHtcblx0XHR0aGlzLl90ZXh0dXJlc1RvUmVsZWFzZS5mb3JFYWNoKChjYWNoZVRleHR1cmUpID0+IHtcblx0XHRcdGNhY2hlVGV4dHVyZS50ZXh0dXJlPy5maW5hbERlc3Ryb3koKTtcblx0XHRcdC0tdGhpcy5fbnVtYmVyT2ZUZXh0dXJlcztcblx0XHR9KTtcblxuXHRcdHRoaXMuX3RleHR1cmVzVG9SZWxlYXNlLmNsZWFyKCk7XG5cdH1cblx0ZGVzdHJveSgpIHtcblx0XHR0aGlzLl90ZXh0dXJlcy5mb3JFYWNoKChjYWNoZWRUZXh0dXJlKSA9PiB7XG5cdFx0XHRjYWNoZWRUZXh0dXJlLnRleHR1cmU/LmZpbmFsRGVzdHJveSgpO1xuXHRcdH0pO1xuXHRcdHJldHVybiBkZXN0cm95T2JqZWN0KHRoaXMpO1xuXHR9XG59XG5jb25zdCB0ZXh0dXJlQ2FjaGUgPSBuZXcgVGV4dHVyZUNhY2hlKCk7XG5leHBvcnQgZGVmYXVsdCB0ZXh0dXJlQ2FjaGU7XG4iLCJpbXBvcnQgU2FtcGxlciBmcm9tIFwiLi4vcmVuZGVyL1NhbXBsZXJcIjtcbmltcG9ydCBUZXh0dXJlIGZyb20gXCIuLi9yZW5kZXIvVGV4dHVyZVwiO1xuXG5leHBvcnQgZGVmYXVsdCBhc3luYyBmdW5jdGlvbiBDdWJlVGV4dHVyZUxvYWRlcih1cmxzKSB7XG5cdGNvbnN0IHByb21pc2VzID0gdXJscy5tYXAoKHNyYykgPT4ge1xuXHRcdGNvbnN0IGltZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIik7XG5cdFx0aW1nLnNyYyA9IHNyYztcblx0XHRyZXR1cm4gaW1nLmRlY29kZSgpLnRoZW4oKCkgPT4gY3JlYXRlSW1hZ2VCaXRtYXAoaW1nKSk7XG5cdH0pO1xuXHRjb25zdCBpbWFnZXMgPSBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG5cdGF3YWl0IFByb21pc2UuYWxsKGltYWdlcyk7XG5cdGNvbnN0IGJhc2VTYW1wbGVyID0gbmV3IFNhbXBsZXIoe1xuXHRcdG1hZ0ZpbHRlcjogXCJsaW5lYXJcIixcblx0XHRtaW5GaWx0ZXI6IFwibGluZWFyXCJcblx0fSk7XG5cdGNvbnN0IGRhdGEgPSBpbWFnZXMubWFwKChpbWFnZSwgaSkgPT4ge1xuXHRcdHJldHVybiB7XG5cdFx0XHRzb3VyY2U6IGltYWdlLFxuXHRcdFx0d2lkdGg6IGltYWdlLndpZHRoLFxuXHRcdFx0aGVpZ2h0OiBpbWFnZS5oZWlnaHQsXG5cdFx0XHRkZXB0aDogMSxcblx0XHRcdHg6IDAsXG5cdFx0XHR5OiAwLFxuXHRcdFx0ejogaVxuXHRcdH07XG5cdH0pO1xuXHRjb25zdCBiYXNlVGV4dHVyZSA9IG5ldyBUZXh0dXJlKHtcblx0XHRzaXplOiB7XG5cdFx0XHR3aWR0aDogaW1hZ2VzWzBdLndpZHRoLFxuXHRcdFx0aGVpZ2h0OiBpbWFnZXNbMF0uaGVpZ2h0LFxuXHRcdFx0ZGVwdGg6IDZcblx0XHR9LFxuXHRcdGZvcm1hdDogXCJyZ2JhOHVub3JtXCIsXG5cdFx0dXNhZ2U6IEdQVVRleHR1cmVVc2FnZS5URVhUVVJFX0JJTkRJTkcgfCBHUFVUZXh0dXJlVXNhZ2UuQ09QWV9EU1QgfCBHUFVUZXh0dXJlVXNhZ2UuUkVOREVSX0FUVEFDSE1FTlQsXG5cdFx0ZGF0YSxcblx0XHR2aWV3Rm9ybWF0czogXCJjdWJlXCIsXG5cdFx0bWlwTGV2ZWxDb3VudDogNixcblx0XHRuZWVkTWlwTWFwOiB0cnVlXG5cdH0pO1xuXHRyZXR1cm4ge1xuXHRcdHRleHR1cmU6IGJhc2VUZXh0dXJlLFxuXHRcdHNhbXBsZXI6IGJhc2VTYW1wbGVyXG5cdH07XG59XG4iLCJpbXBvcnQgeyBGcmFtZVN0YXRlIH0gZnJvbSBcIi4uL2NvcmUvRnJhbWVTdGF0ZVwiO1xuaW1wb3J0IHRleHR1cmVDYWNoZSBmcm9tIFwiLi4vY29yZS9UZXh0dXJlQ2FjaGVcIjtcbmltcG9ydCB7IENvbXBhcmVGdW5jdGlvbiB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVUNvbnN0YW50XCI7XG5pbXBvcnQgeyBVbmlmb3JtRW51bSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XG5pbXBvcnQgQ3ViZVRleHR1cmVMb2FkZXIgZnJvbSBcIi4uL2xvYWRlci9DdWJlVGV4dHVyZUxvYWRlclwiO1xuaW1wb3J0IHsgTWVzaCB9IGZyb20gXCIuLi9tZXNoL01lc2hcIjtcbmltcG9ydCBVbmlmb3JtQnVmZmVyIGZyb20gXCIuLi9yZW5kZXIvVW5pZm9ybUJ1ZmZlclwiO1xuaW1wb3J0IHsgU2hhZGVyU291cmNlIH0gZnJvbSBcIi4uL3NoYWRlci9TaGFkZXJTb3VyY2VcIjtcbmltcG9ydCB7IE1hdGVyaWFsIH0gZnJvbSBcIi4vTWF0ZXJpYWxcIjtcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNreUJveE1hdGVyaWFsIGV4dGVuZHMgTWF0ZXJpYWwge1xuXHRsb2FkRmlzaDogYm9vbGVhbjtcblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblx0XHR0aGlzLnR5cGUgPSBcInNreWJveFwiO1xuXHRcdHRoaXMuc2hhZGVyU291cmNlID0gbmV3IFNoYWRlclNvdXJjZSh7XG5cdFx0XHRzaGFkZXJJZDogdGhpcy50eXBlLFxuXHRcdFx0ZGVmaW5lczoge31cblx0XHR9KTtcblx0XHR0aGlzLmxvYWRGaXNoID0gZmFsc2U7XG5cdFx0dGhpcy5yZW5kZXJTdGF0ZS5kZXB0aFN0ZW5jaWwuZGVwdGhXcml0ZUVuYWJsZWQgPSBmYWxzZTtcblx0XHR0aGlzLnJlbmRlclN0YXRlLmRlcHRoU3RlbmNpbC5kZXB0aENvbXBhcmUgPSBDb21wYXJlRnVuY3Rpb24uTGVzc0VxdWFsO1xuXHR9XG5cdGFzeW5jIGxvYWRUZXh0dXJlKHVybHMpIHtcblx0XHRjb25zdCByZXN1bHQgPSBhd2FpdCBDdWJlVGV4dHVyZUxvYWRlcih1cmxzKTtcblx0XHR0aGlzLmxvYWRGaXNoID0gdHJ1ZTtcblx0XHR0ZXh0dXJlQ2FjaGUuYWRkVGV4dHVyZShcInNwZWN1bGFyXCIsIHJlc3VsdC50ZXh0dXJlKTtcblx0XHR0aGlzLmJhc2VUZXh0dXJlID0gcmVzdWx0LnRleHR1cmU7XG5cdFx0dGhpcy5iYXNlU2FtcGxlciA9IHJlc3VsdC5zYW1wbGVyO1xuXHR9XG5cdHVwZGF0ZShmcmFtZVN0YXRlPzogRnJhbWVTdGF0ZSwgbWVzaD86IE1lc2gpIHtcblx0XHRpZiAoIXRoaXMubG9hZEZpc2gpIHJldHVybjtcblx0XHRpZiAoIXRoaXMuc2hhZGVyRGF0YSkge1xuXHRcdFx0dGhpcy5jcmVhdGVTaGFkZXJEYXRhKG1lc2gpO1xuXHRcdH1cblx0fVxuXHRwcm90ZWN0ZWQgY3JlYXRlU2hhZGVyRGF0YShtZXNoPzogTWVzaCkge1xuXHRcdHN1cGVyLmNyZWF0ZVNoYWRlckRhdGEoKTtcblx0XHRjb25zdCB1bmlmb3JtQnVmZmVyID0gbmV3IFVuaWZvcm1CdWZmZXIoeyBsYWJlbDogXCJza3lib3hcIiB9KTtcblx0XHR1bmlmb3JtQnVmZmVyLnNldFVuaWZvcm0oXG5cdFx0XHRcIm1vZGVsTWF0cml4XCIsXG5cdFx0XHQoKSA9PiB7XG5cdFx0XHRcdHJldHVybiBtZXNoLm1vZGVsTWF0cml4O1xuXHRcdFx0fSxcblx0XHRcdFVuaWZvcm1FbnVtLk1hdDRcblx0XHQpO1xuXHRcdHRoaXMuc2hhZGVyRGF0YS5zZXRVbmlmb3JtQnVmZmVyKFwic2t5Ym94XCIsIHVuaWZvcm1CdWZmZXIpO1xuXHRcdHRoaXMuc2hhZGVyRGF0YS5zZXRUZXh0dXJlKFwiYmFzZVRleHR1cmVcIiwgdGhpcy5iYXNlVGV4dHVyZSk7XG5cdFx0dGhpcy5zaGFkZXJEYXRhLnNldFNhbXBsZXIoXCJiYXNlU2FtcGxlclwiLCB0aGlzLmJhc2VTYW1wbGVyKTtcblx0fVxufVxuIiwiaW1wb3J0IHsgRnJhbWVTdGF0ZSB9IGZyb20gXCIuLi9jb3JlL0ZyYW1lU3RhdGVcIjtcclxuaW1wb3J0IHsgUmVuZGVyT2JqZWN0VHlwZSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XHJcbmltcG9ydCBTa3lCb3hHZW9tZXRyeSBmcm9tIFwiLi4vZ2VvbWV0cnkvU2t5Qm94R2VvbWV0cnlcIjtcclxuaW1wb3J0IFNreUJveE1hdGVyaWFsIGZyb20gXCIuLi9tYXRlcmlhbC9Ta3lCb3hNYXRlcmlhbFwiO1xyXG5pbXBvcnQgeyBNZXNoIH0gZnJvbSBcIi4vTWVzaFwiO1xyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTa3lCb3ggZXh0ZW5kcyBNZXNoIHtcclxuXHRtYXRlcmlhbDogU2t5Qm94TWF0ZXJpYWw7XHJcblx0cHVibGljIHZpc2liaWxpdHk6IGJvb2xlYW47XHJcblx0Y29uc3RydWN0b3IodXJscz86IEFycmF5PHN0cmluZz4pIHtcclxuXHRcdHN1cGVyKCk7XHJcblx0XHR0aGlzLnR5cGUgPSBSZW5kZXJPYmplY3RUeXBlLlNreWJveDtcclxuXHRcdHRoaXMudmlzaWJpbGl0eSA9IHRydWU7XHJcblx0XHR0aGlzLm1hdGVyaWFsID0gbmV3IFNreUJveE1hdGVyaWFsKCk7XHJcblx0XHRpZiAodXJscykgdGhpcy5tYXRlcmlhbC5sb2FkVGV4dHVyZSh1cmxzKTtcclxuXHRcdHRoaXMuZ2VvbWV0cnkgPSBuZXcgU2t5Qm94R2VvbWV0cnkoKTtcclxuXHRcdHRoaXMuaXNTa3lCb3ggPSB0cnVlO1xyXG5cdH1cclxuXHR1cGRhdGUoZnJhbWVTdGF0ZTogRnJhbWVTdGF0ZSkge1xyXG5cdFx0dGhpcy51cGRhdGVNYXRyaXgoKTtcclxuXHRcdHRoaXMuZ2VvbWV0cnkudXBkYXRlKGZyYW1lU3RhdGUpO1xyXG5cdFx0dGhpcy5tYXRlcmlhbC51cGRhdGUoZnJhbWVTdGF0ZSwgdGhpcyk7XHJcblx0XHRpZiAodGhpcy52aXNpYmlsaXR5KSBmcmFtZVN0YXRlLnJlbmRlclF1ZXVlLnByZS5wdXNoKHRoaXMpO1xyXG5cdH1cclxufVxyXG4iLCJpbXBvcnQgUmVuZGVyT2JqZWN0IGZyb20gXCIuLi9jb3JlL1JlbmRlck9iamVjdFwiO1xuaW1wb3J0IE1hdHJpeDQgZnJvbSBcIi4uL21hdGgvTWF0cml4NFwiO1xuaW1wb3J0IGNyZWF0ZUd1aWQgZnJvbSBcIi4uL3V0aWxzL2NyZWF0ZUd1aWRcIjtcblxuZXhwb3J0IGNsYXNzIEluc3RhbmNlIGV4dGVuZHMgUmVuZGVyT2JqZWN0IHtcblx0cHVibGljIGlkOiBzdHJpbmcgfCBudW1iZXI7XG5cdHB1YmxpYyB2aXNpYmxpdHk6IGJvb2xlYW47XG5cdHByaXZhdGUgX25vdFVwZGF0ZU1hdHJpeDogYm9vbGVhbjtcblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblx0XHR0aGlzLl9ub3RVcGRhdGVNYXRyaXggPSBmYWxzZTtcblx0XHR0aGlzLnZpc2libGl0eSA9IGZhbHNlO1xuXHRcdHRoaXMuaWQgPSBjcmVhdGVHdWlkKCk7XG5cdH1cblx0c2V0TWF0cml4NChtYXQ0OiBNYXRyaXg0KSB7XG5cdFx0dGhpcy5tb2RlbE1hdHJpeC5zZXQobWF0NCk7XG5cdFx0dGhpcy5fbm90VXBkYXRlTWF0cml4ID0gdHJ1ZTtcblx0fVxuXHR1cGRhdGVNYXRyaXgobWF0cml4PzogTWF0cml4NCkge1xuXHRcdGlmICh0aGlzLl9ub3RVcGRhdGVNYXRyaXgpIHJldHVybjtcblx0XHRzdXBlci51cGRhdGVNYXRyaXgobWF0cml4KTtcblx0fVxufVxuIiwiaW1wb3J0IENhbWVyYSBmcm9tIFwiLi4vY2FtZXJhL0NhbWVyYVwiO1xuaW1wb3J0IHsgRnJhbWVTdGF0ZSB9IGZyb20gXCIuLi9jb3JlL0ZyYW1lU3RhdGVcIjtcbmltcG9ydCB7IEJ1ZmZlckJpbmRpbmdUeXBlLCBCdWZmZXJVc2FnZSwgSW50ZXJzZWN0IH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVQ29uc3RhbnRcIjtcbmltcG9ydCB7IFVuaWZvcm1FbnVtIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcbmltcG9ydCBHZW9tZXRyeSBmcm9tIFwiLi4vZ2VvbWV0cnkvR2VvbWV0cnlcIjtcbmltcG9ydCB7IE1hdGVyaWFsIH0gZnJvbSBcIi4uL21hdGVyaWFsL01hdGVyaWFsXCI7XG5pbXBvcnQgVW5pZm9ybUJ1ZmZlciBmcm9tIFwiLi4vcmVuZGVyL1VuaWZvcm1CdWZmZXJcIjtcbmltcG9ydCB7IEluc3RhbmNlIH0gZnJvbSBcIi4vSW5zdGFuY2VcIjtcbmltcG9ydCB7IE1lc2ggfSBmcm9tIFwiLi9NZXNoXCI7XG5cbmV4cG9ydCBjbGFzcyBJbnN0YW5jZU1lc2ggZXh0ZW5kcyBNZXNoIHtcblx0cHJpdmF0ZSBpbnN0YW5jZXM6IE1hcDxzdHJpbmcgfCBudW1iZXIsIEluc3RhbmNlPjtcblx0cHJpdmF0ZSByZW5kZXJJbnN0YW5jZXM6IEFycmF5PEluc3RhbmNlPjtcblx0cHJpdmF0ZSBoYXNBZGRJbnN0YW5jZXM6IGJvb2xlYW47XG5cdGNvbnN0cnVjdG9yKGdlbzogR2VvbWV0cnksIG1hdDogTWF0ZXJpYWwpIHtcblx0XHRzdXBlcihnZW8sIG1hdCk7XG5cdFx0dGhpcy5pbnN0YW5jZXMgPSBuZXcgTWFwKCk7XG5cdFx0dGhpcy5yZW5kZXJJbnN0YW5jZXMgPSBbXTtcblx0XHR0aGlzLmhhc0FkZEluc3RhbmNlcyA9IGZhbHNlO1xuXHR9XG5cdHVwZGF0ZShmcmFtZVN0YXRlOiBGcmFtZVN0YXRlLCBjYW1lcmE/OiBDYW1lcmEpIHtcblx0XHQvLyB1cGRhdGUgaW5zdGFuY2VzIHZpc2libGl0eVxuXHRcdHRoaXMuY2hlY2tJbnN0YW5jZXNWaXNpYmxpdHkoeyBmcmFtZVN0YXRlLCBjYW1lcmEgfSk7XG5cdFx0dGhpcy5nZW9tZXRyeS51cGRhdGUoZnJhbWVTdGF0ZSk7XG5cdFx0dGhpcy5tYXRlcmlhbC51cGRhdGUoZnJhbWVTdGF0ZSwgdGhpcyk7XG5cdFx0aWYgKCF0aGlzLmhhc0FkZEluc3RhbmNlcykgdGhpcy5hZGRVbmlmb3Jtc1RvTWF0ZXJpYWwoKTtcblx0XHR0aGlzLmluc3RhbmNlQ291bnQgPSB0aGlzLnJlbmRlckluc3RhbmNlcy5sZW5ndGg7XG5cdFx0aWYgKHRoaXMucmVuZGVySW5zdGFuY2VzLmxlbmd0aCA8IDEpIHJldHVybjtcblx0XHRpZiAodGhpcy5tYXRlcmlhbC50cmFuc3BhcmVudCkge1xuXHRcdFx0ZnJhbWVTdGF0ZS5yZW5kZXJRdWV1ZS50cmFuc3BhcmVudC5wdXNoKHRoaXMpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRmcmFtZVN0YXRlLnJlbmRlclF1ZXVlLm9wYXF1ZS5wdXNoKHRoaXMpO1xuXHRcdH1cblx0fVxuXHRhZGRJbnN0YW5jZShpbnN0YW5jZTogSW5zdGFuY2UpIHtcblx0XHRpZiAodGhpcy5pbnN0YW5jZXMuZ2V0KGluc3RhbmNlLmlkKSkgcmV0dXJuO1xuXHRcdHRoaXMuaW5zdGFuY2VzLnNldChpbnN0YW5jZS5pZCwgaW5zdGFuY2UpO1xuXHR9XG5cdHJlbW92ZUluc3RhbmNlKGtleTogbnVtYmVyIHwgc3RyaW5nKSB7XG5cdFx0cmV0dXJuIHRoaXMuaW5zdGFuY2VzLmRlbGV0ZShrZXkpO1xuXHR9XG5cdGdldEluc3RhbmNlKGtleTogbnVtYmVyIHwgc3RyaW5nKSB7XG5cdFx0cmV0dXJuIHRoaXMuaW5zdGFuY2VzLmdldChrZXkpO1xuXHR9XG5cdHByaXZhdGUgY2hlY2tJbnN0YW5jZXNWaXNpYmxpdHkob3B0aW9uczogeyBmcmFtZVN0YXRlOiBGcmFtZVN0YXRlOyBjYW1lcmE6IENhbWVyYSB9KSB7XG5cdFx0Y29uc3QgeyBmcmFtZVN0YXRlLCBjYW1lcmEgfSA9IG9wdGlvbnM7XG5cdFx0Y29uc3QgcHJlRnJhbWVJbnN0YW5jZUNvdW50ID0gdGhpcy5yZW5kZXJJbnN0YW5jZXMubGVuZ3RoO1xuXHRcdHRoaXMucmVuZGVySW5zdGFuY2VzID0gW107XG5cdFx0dGhpcy5pbnN0YW5jZXMuZm9yRWFjaCgoaW5zdGFuY2U6IEluc3RhbmNlKSA9PiB7XG5cdFx0XHRpbnN0YW5jZS51cGRhdGVNYXRyaXgodGhpcz8ucGFyZW50Py5tb2RlbE1hdHJpeCk7XG5cdFx0XHRpbnN0YW5jZS52aXNpYmxpdHkgPSB0aGlzLmdldEluc3RhbmNlVmlzaWJsaXR5KHsgaW5zdGFuY2UsIGZyYW1lU3RhdGUsIGNhbWVyYSB9KTtcblx0XHRcdGlmIChpbnN0YW5jZS52aXNpYmxpdHkpIHRoaXMucmVuZGVySW5zdGFuY2VzLnB1c2goaW5zdGFuY2UpO1xuXHRcdH0pO1xuXHRcdHRoaXMubWF0ZXJpYWwuZGlydHkgPSB0aGlzLnJlbmRlckluc3RhbmNlcy5sZW5ndGggPT09IHByZUZyYW1lSW5zdGFuY2VDb3VudDtcblx0XHQvLyByZWJ1aWxkIGluc3RhbmNlTWF0cml4c0J1ZmZlclxuXHRcdGlmICh0aGlzLm1hdGVyaWFsLmRpcnR5KSB0aGlzLmhhc0FkZEluc3RhbmNlcyA9IGZhbHNlO1xuXHR9XG5cdHByaXZhdGUgZ2V0SW5zdGFuY2VWaXNpYmxpdHkob3B0aW9uczogeyBpbnN0YW5jZTogSW5zdGFuY2U7IGZyYW1lU3RhdGU6IEZyYW1lU3RhdGU7IGNhbWVyYTogQ2FtZXJhIH0pOiBib29sZWFuIHtcblx0XHRjb25zdCB7IGluc3RhbmNlLCBmcmFtZVN0YXRlLCBjYW1lcmEgfSA9IG9wdGlvbnM7XG5cdFx0dGhpcy5nZW9tZXRyeS5ib3VuZGluZ1NwaGVyZS51cGRhdGUoaW5zdGFuY2UubW9kZWxNYXRyaXgpO1xuXHRcdHRoaXMuZGlzdGFuY2VUb0NhbWVyYSA9IHRoaXMuZ2VvbWV0cnkuYm91bmRpbmdTcGhlcmUuZGlzdGFuY2VUb0NhbWVyYShjYW1lcmEpO1xuXHRcdGNvbnN0IHZpc2liaWxpdHkgPSBmcmFtZVN0YXRlLmN1bGxpbmdWb2x1bWUuY29tcHV0ZVZpc2liaWxpdHkodGhpcy5nZW9tZXRyeS5ib3VuZGluZ1NwaGVyZSk7XG5cdFx0cmV0dXJuIHZpc2liaWxpdHkgPT09IEludGVyc2VjdC5JTlRFUlNFQ1RJTkcgfHwgdmlzaWJpbGl0eSA9PT0gSW50ZXJzZWN0LklOU0lERTtcblx0fVxuXHRwcml2YXRlIGFkZFVuaWZvcm1zVG9NYXRlcmlhbCgpIHtcblx0XHRpZiAoIXRoaXMubWF0ZXJpYWwuc2hhZGVyRGF0YSkgcmV0dXJuO1xuXHRcdHRoaXMuaGFzQWRkSW5zdGFuY2VzID0gdHJ1ZTtcblx0XHRjb25zdCBpbnN0YW5jZU1hdHJpeHNCdWZmZXIgPSBuZXcgVW5pZm9ybUJ1ZmZlcih7XG5cdFx0XHRsYWJlbDogXCJpbnN0YW5jZU1hdHJpeHNCdWZmZXJcIixcblx0XHRcdHR5cGU6IEJ1ZmZlckJpbmRpbmdUeXBlLlJlYWRPbmx5U3RvcmFnZSxcblx0XHRcdHVzYWdlOiBCdWZmZXJVc2FnZS5TdG9yYWdlIHwgQnVmZmVyVXNhZ2UuQ29weURzdCxcblx0XHRcdHNpemU6IHRoaXMuaW5zdGFuY2VzLnNpemUgKiA2NFxuXHRcdH0pO1xuXHRcdGluc3RhbmNlTWF0cml4c0J1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XCJpbnN0YW5jZU1hdHJpeHNcIixcblx0XHRcdCgpID0+IHtcblx0XHRcdFx0cmV0dXJuIHRoaXM/LnJlbmRlckluc3RhbmNlcz8ubWFwKChyZW5kZXJJbnN0YW5jZTogSW5zdGFuY2UpID0+IHJlbmRlckluc3RhbmNlLm1vZGVsTWF0cml4KTtcblx0XHRcdH0sXG5cdFx0XHRVbmlmb3JtRW51bS5NYXQ0QXJyYXksXG5cdFx0XHR0aGlzPy5yZW5kZXJJbnN0YW5jZXM/Lmxlbmd0aFxuXHRcdCk7XG5cdFx0dGhpcy5tYXRlcmlhbC5zaGFkZXJEYXRhLnNldFVuaWZvcm1CdWZmZXIoXCJpbnN0YW5jZU1hdHJpeHNCdWZmZXJcIiwgaW5zdGFuY2VNYXRyaXhzQnVmZmVyKTtcblx0XHR0aGlzLm1hdGVyaWFsLnNoYWRlckRhdGEuc2V0RGVmaW5lKFwiVVNFX0lOU1RBTkNFXCIsIHRydWUpO1xuXHRcdHRoaXMubWF0ZXJpYWwuc2hhZGVyRGF0YS5zZXREZWZpbmUoXCJpbnN0YW5jZUNvdW50XCIsIHRoaXM/LnJlbmRlckluc3RhbmNlcz8ubGVuZ3RoKTtcblx0fVxufVxuIiwiaW1wb3J0IHsgU2hhZGVyU291cmNlIH0gZnJvbSBcIi4uL3NoYWRlci9TaGFkZXJTb3VyY2VcIjtcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tIFwiLi9Db21tYW5kXCI7XG5pbXBvcnQgUGlwZWxpbmUgZnJvbSBcIi4vUGlwZWxpbmVcIjtcbmltcG9ydCBTaGFkZXJEYXRhIGZyb20gXCIuL1NoYWRlckRhdGFcIjtcblxuZXhwb3J0IGNsYXNzIENvbXB1dGVDb21tYW5kIGltcGxlbWVudHMgQ29tbWFuZCB7XG5cdHB1YmxpYyBkaXNwYXRjaD86IHsgeD86IG51bWJlcjsgeT86IG51bWJlcjsgej86IG51bWJlciB9O1xuXHRwdWJsaWMgc2hhZGVyU291cmNlPzogU2hhZGVyU291cmNlO1xuXHRwdWJsaWMgc2hhZGVyRGF0YT86IFNoYWRlckRhdGE7XG5cdGNvbnN0cnVjdG9yKG9wdGlvbnM6IENvbXB1dGVDb21tYW5kVHlwZSkge1xuXHRcdHRoaXMuZGlzcGF0Y2ggPSBvcHRpb25zLmRpc3BhdGNoO1xuXHRcdHRoaXMuc2hhZGVyRGF0YSA9IG9wdGlvbnMuc2hhZGVyRGF0YTtcblx0XHR0aGlzLnNoYWRlclNvdXJjZSA9IG9wdGlvbnMuc2hhZGVyU291cmNlO1xuXHR9XG5cdHJlbmRlcihwYXJhbXM/OiBDb21wdXRlUGFyYW1zKTogdm9pZCB7XG5cdFx0Y29uc3QgeyBkZXZpY2UsIHBhc3NFbmNvZGVyIH0gPSBwYXJhbXM7XG5cdFx0dGhpcy5zaGFkZXJEYXRhPy5iaW5kPy4oZGV2aWNlLCBwYXNzRW5jb2Rlcik7XG5cdFx0Y29uc3QgcGlwZWxpbmUgPSBQaXBlbGluZS5nZXRDb21wdXRlUGlwZWxpbmVGcm9tQ2FjaGUoZGV2aWNlLCB0aGlzLCBbdGhpcy5zaGFkZXJEYXRhLmdyb3VwTGF5b3V0XSk7XG5cdFx0cGlwZWxpbmUuYmluZChwYXNzRW5jb2Rlcik7XG5cdFx0Y29uc3QgeyB4LCB5LCB6IH0gPSB0aGlzLmRpc3BhdGNoO1xuXHRcdHBhc3NFbmNvZGVyLmRpc3BhdGNoV29ya2dyb3Vwcyh4LCB5LCB6KTtcblx0fVxufVxudHlwZSBDb21wdXRlQ29tbWFuZFR5cGUgPSB7XG5cdGRpc3BhdGNoPzogeyB4PzogbnVtYmVyOyB5PzogbnVtYmVyOyB6PzogbnVtYmVyIH07XG5cblx0c2hhZGVyU291cmNlPzogU2hhZGVyU291cmNlO1xuXG5cdHNoYWRlckRhdGE/OiBTaGFkZXJEYXRhO1xufTtcbnR5cGUgQ29tcHV0ZVBhcmFtcyA9IHtcblx0ZGV2aWNlPzogR1BVRGV2aWNlO1xuXHRwYXNzRW5jb2Rlcj86IEdQVUNvbXB1dGVQYXNzRW5jb2Rlcjtcbn07XG4iLCJpbXBvcnQge1xuXHRCdWZmZXJCaW5kaW5nVHlwZSxcblx0QnVmZmVyVXNhZ2UsXG5cdEN1bGxNb2RlLFxuXHRGcm9udEZhY2UsXG5cdElucHV0U3RlcE1vZGUsXG5cdFByaW1pdGl2ZVRvcG9sb2d5XG59IGZyb20gXCIuLi9jb3JlL1dlYkdQVUNvbnN0YW50XCI7XG5pbXBvcnQgeyBNb2RlbFBhcmFtcyB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XG5pbXBvcnQgeyBCdWZmZXJGbG9hdDMyQXR0cmlidXRlLCBGbG9hdDMyQXR0cmlidXRlLCBJbnRlcmxlYXZlZEZsb2F0MzJBdHRyaWJ1dGUgfSBmcm9tIFwiLi4vcmVuZGVyL0F0dHJpYnV0ZVwiO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbW1hbmQgfSBmcm9tIFwiLi4vcmVuZGVyL0NvbXB1dGVDb21tYW5kXCI7XG5pbXBvcnQgRHJhd0NvbW1hbmQgZnJvbSBcIi4uL3JlbmRlci9EcmF3Q29tbWFuZFwiO1xuaW1wb3J0IEluZGV4QnVmZmVyIGZyb20gXCIuLi9yZW5kZXIvSW5kZXhCdWZmZXJcIjtcbmltcG9ydCB7XG5cdEJsZW5kQ29uc3RhbnQsXG5cdERlcHRoU3RlbmNpbCxcblx0RGVwdGhTdGVuY2lsUHJvcHMsXG5cdE11bHRpU2FtcGxlLFxuXHRQcmltaXRpdmUsXG5cdFJlbmRlclN0YXRlLFxuXHRTY2lzc29yVGVzdCxcblx0VGFyZ2V0LFxuXHRWaWV3UG9ydFxufSBmcm9tIFwiLi4vcmVuZGVyL1JlbmRlclN0YXRlXCI7XG5pbXBvcnQgU2hhZGVyRGF0YSBmcm9tIFwiLi4vcmVuZGVyL1NoYWRlckRhdGFcIjtcbmltcG9ydCBUZXh0dXJlIGZyb20gXCIuLi9yZW5kZXIvVGV4dHVyZVwiO1xuaW1wb3J0IFVuaWZvcm1CdWZmZXIgZnJvbSBcIi4uL3JlbmRlci9Vbmlmb3JtQnVmZmVyXCI7XG5pbXBvcnQgVmVydGV4QnVmZmVyIGZyb20gXCIuLi9yZW5kZXIvVmVydGV4QnVmZmVyXCI7XG5pbXBvcnQgeyBTaGFkZXJTb3VyY2UgfSBmcm9tIFwiLi4vc2hhZGVyL1NoYWRlclNvdXJjZVwiO1xuaW1wb3J0IHsgYWRkVW5pZm9ybVRvU2hhZGVyRGF0YSB9IGZyb20gXCIuLi91dGlscy91bmlmb3JtVXRpbHNcIjtcblxuZXhwb3J0IGNsYXNzIE1vZGVsIHtcblx0cHVibGljIG1vZGVsUGFyYW1zOiBNb2RlbFBhcmFtcztcblx0cHVibGljIGNvbW1hbmQ6IERyYXdDb21tYW5kIHwgQ29tcHV0ZUNvbW1hbmQ7XG5cdHB1YmxpYyByZW5kZXJUeXBlOiBzdHJpbmc7XG5cdHByaXZhdGUgdmVydGV4QnVmZmVyczogTWFwPHN0cmluZywgVmVydGV4QnVmZmVyPjtcblx0cHJpdmF0ZSBzaGFkZXJEYXRhOiBTaGFkZXJEYXRhO1xuXHRjb25zdHJ1Y3RvcihwYXJhbXM6IE1vZGVsUGFyYW1zKSB7XG5cdFx0dGhpcy5tb2RlbFBhcmFtcyA9IHBhcmFtcztcblx0XHR0aGlzLnJlbmRlclR5cGUgPSB0aGlzLm1vZGVsUGFyYW1zLmNvbXB1dGUgIT0gdW5kZWZpbmVkID8gXCJjb21wdXRlXCIgOiBcInJlbmRlclwiO1xuXHRcdHRoaXMudmVydGV4QnVmZmVycyA9IG5ldyBNYXAoKTtcblx0fVxuXHRyZW5kZXIocGFyYW1zOiByZW5kZXJNb2RlbFBhcmFtcykge1xuXHRcdGNvbnN0IHsgZGV2aWNlLCBwYXNzRW5jb2RlciB9ID0gcGFyYW1zO1xuXHRcdGlmICghdGhpcy5jb21tYW5kKVxuXHRcdFx0dGhpcy5jb21tYW5kID0gdGhpcy5yZW5kZXJUeXBlID09PSBcInJlbmRlclwiID8gdGhpcy5jcmVhdGVEcmF3Q29tbWFuZCgpIDogdGhpcy5jcmVhdGVDb21wdXRlQ29tbWFuZCgpO1xuXHRcdGlmICh0aGlzLnJlbmRlclR5cGUgPT09IFwicmVuZGVyXCIpIHtcblx0XHRcdCh0aGlzLmNvbW1hbmQgYXMgRHJhd0NvbW1hbmQpLnJlbmRlcih7XG5cdFx0XHRcdGRldmljZSxcblx0XHRcdFx0cGFzc0VuY29kZXI6IDxHUFVSZW5kZXJQYXNzRW5jb2Rlcj5wYXNzRW5jb2RlclxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdCh0aGlzLmNvbW1hbmQgYXMgQ29tcHV0ZUNvbW1hbmQpLnJlbmRlcih7XG5cdFx0XHRcdGRldmljZSxcblx0XHRcdFx0cGFzc0VuY29kZXI6IDxHUFVDb21wdXRlUGFzc0VuY29kZXI+cGFzc0VuY29kZXJcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXHRjb21wdXRlKHBhcmFtczogcmVuZGVyTW9kZWxQYXJhbXMpIHtcblx0XHRjb25zdCB7IGRldmljZSwgcGFzc0VuY29kZXIgfSA9IHBhcmFtcztcblx0XHRpZiAoIXRoaXMuY29tbWFuZCkgdGhpcy5jb21tYW5kID0gdGhpcy5jcmVhdGVDb21wdXRlQ29tbWFuZCgpO1xuXHRcdCh0aGlzLmNvbW1hbmQgYXMgQ29tcHV0ZUNvbW1hbmQpLnJlbmRlcih7XG5cdFx0XHRkZXZpY2UsXG5cdFx0XHRwYXNzRW5jb2RlcjogPEdQVUNvbXB1dGVQYXNzRW5jb2Rlcj5wYXNzRW5jb2RlclxuXHRcdH0pO1xuXHR9XG5cdHB1YmxpYyBnZXRWZXJ0ZXhCdWZmZXJCeVVpZCh1aWQ6IHN0cmluZyk6IFZlcnRleEJ1ZmZlciB7XG5cdFx0cmV0dXJuIHRoaXMudmVydGV4QnVmZmVycy5nZXQodWlkKTtcblx0fVxuXHRwdWJsaWMgZ2V0VW5pZm9ybUJ1ZmZlckJ5VWlkKHVpZDogc3RyaW5nKTogVW5pZm9ybUJ1ZmZlciB7XG5cdFx0cmV0dXJuIHRoaXMuc2hhZGVyRGF0YS5nZXRVbmlmb3JtQnVmZmVyKHVpZCk7XG5cdH1cblx0cHVibGljIGdldFRleHR1cmVCeU5hbWUobmFtZTogc3RyaW5nKTogVGV4dHVyZSB7XG5cdFx0cmV0dXJuIHRoaXMuc2hhZGVyRGF0YS5nZXRUZXh0dXJlKG5hbWUpO1xuXHR9XG5cdHB1YmxpYyBnZXRTYW1wbGVyQnlOYW1lKG5hbWU6IHN0cmluZykge1xuXHRcdHJldHVybiB0aGlzLnNoYWRlckRhdGEuZ2V0U2FtcGxlcihuYW1lKTtcblx0fVxuXHRwdWJsaWMgZGVzdHJveSgpIHtcblx0XHR0aGlzPy52ZXJ0ZXhCdWZmZXJzLmNsZWFyKCk7XG5cdFx0dGhpcz8uc2hhZGVyRGF0YS5kZXN0cm95KCk7XG5cdFx0dGhpcy5jb21tYW5kID0gbnVsbDtcblx0XHR0aGlzLm1vZGVsUGFyYW1zID0gbnVsbDtcblx0fVxuXHRwcml2YXRlIGNyZWF0ZURyYXdDb21tYW5kKCkge1xuXHRcdGNvbnN0IHsgY291bnQsIGluc3RhbmNlcyB9ID0gdGhpcy5tb2RlbFBhcmFtcztcblx0XHRjb25zdCB2ZXJ0ZXhCdWZmZXJzID0gdGhpcy5jcmVhdGVWZXJ0ZXhCdWZmZXIoKTtcblx0XHR0aGlzLnNoYWRlckRhdGEgPSB0aGlzLmNyZWF0ZVNoYWRlckRhdGEoKTtcblx0XHRjb25zdCBpbmRleEJ1ZmZlciA9IHRoaXMuY3JlYXRlSW5kZXhCdWZmZXIoKTtcblx0XHRjb25zdCBzaGFkZXJTb3VyY2UgPSB0aGlzLmNyZWF0ZVNoYWRlclNvdXJjZSgpO1xuXHRcdGNvbnN0IHJlbmRlclN0YXRlID0gdGhpcy5jcmVhdGVSZW5kZXJTdGF0ZSgpO1xuXHRcdHJldHVybiBuZXcgRHJhd0NvbW1hbmQoe1xuXHRcdFx0dmVydGV4QnVmZmVycyxcblx0XHRcdHNoYWRlckRhdGE6IHRoaXMuc2hhZGVyRGF0YSxcblx0XHRcdGluZGV4QnVmZmVyLFxuXHRcdFx0c2hhZGVyU291cmNlLFxuXHRcdFx0cmVuZGVyU3RhdGUsXG5cdFx0XHRjb3VudCxcblx0XHRcdGluc3RhbmNlc1xuXHRcdH0pO1xuXHR9XG5cdHByaXZhdGUgY3JlYXRlQ29tcHV0ZUNvbW1hbmQoKSB7XG5cdFx0Y29uc3QgeyBkaXNwYXRjaCB9ID0gdGhpcy5tb2RlbFBhcmFtcztcblx0XHRjb25zdCBzaGFkZXJEYXRhID0gdGhpcy5jcmVhdGVTaGFkZXJEYXRhKCk7XG5cdFx0Y29uc3Qgc2hhZGVyU291cmNlID0gdGhpcy5jcmVhdGVTaGFkZXJTb3VyY2UoKTtcblx0XHRyZXR1cm4gbmV3IENvbXB1dGVDb21tYW5kKHtcblx0XHRcdGRpc3BhdGNoLFxuXHRcdFx0c2hhZGVyRGF0YSxcblx0XHRcdHNoYWRlclNvdXJjZVxuXHRcdH0pO1xuXHR9XG5cdHByaXZhdGUgY3JlYXRlVmVydGV4QnVmZmVyKCkge1xuXHRcdGNvbnN0IHsgdmVydGV4QnVmZmVycywgc2hhZGVySWQgfSA9IHRoaXMubW9kZWxQYXJhbXM7XG5cdFx0bGV0IGxvY2F0aW9uSW5kZXggPSAwO1xuXHRcdHJldHVybiAoXG5cdFx0XHR2ZXJ0ZXhCdWZmZXJzPy5tYXAoKHZlcnRleEJ1ZmZlck9iamVjdCwgaW5kZXgpID0+IHtcblx0XHRcdFx0Y29uc3QgeyBhdHRyaWJ1dGVzLCBzdGVwTW9kZSwgdWlkLCBhcnJheVN0cmlkZSB9ID0gdmVydGV4QnVmZmVyT2JqZWN0O1xuXHRcdFx0XHRjb25zdCB2ZXJ0ZXhCdWZmZXIgPSBuZXcgVmVydGV4QnVmZmVyKHtcblx0XHRcdFx0XHRsYWJlbDogc2hhZGVySWQsXG5cdFx0XHRcdFx0aW5kZXgsXG5cdFx0XHRcdFx0bG9jYXRpb25JbmRleCxcblx0XHRcdFx0XHRzdGVwTW9kZTogPElucHV0U3RlcE1vZGU+c3RlcE1vZGUsXG5cdFx0XHRcdFx0YXJyYXlTdHJpZGVcblx0XHRcdFx0fSk7XG5cdFx0XHRcdGNvbnN0IGF0dHJpYnV0ZUtleXMgPSBPYmplY3Qua2V5cyhhdHRyaWJ1dGVzKTtcblx0XHRcdFx0YXR0cmlidXRlS2V5cy5mb3JFYWNoKChrZXk6IHN0cmluZykgPT4ge1xuXHRcdFx0XHRcdGNvbnN0IHsgc2l6ZSwgdmFsdWUsIG5hbWVzLCBpdGVtU2l6ZXMsIGJ1ZmZlciB9ID0gYXR0cmlidXRlc1trZXldO1xuXHRcdFx0XHRcdHZlcnRleEJ1ZmZlci5zZXRBdHRyaWJ1dGUoXG5cdFx0XHRcdFx0XHRuYW1lcz8ubGVuZ3RoID4gMFxuXHRcdFx0XHRcdFx0XHQ/IGJ1ZmZlclxuXHRcdFx0XHRcdFx0XHRcdD8gbmV3IEJ1ZmZlckZsb2F0MzJBdHRyaWJ1dGUobmFtZXMsIGJ1ZmZlciwgaXRlbVNpemVzKVxuXHRcdFx0XHRcdFx0XHRcdDogbmV3IEludGVybGVhdmVkRmxvYXQzMkF0dHJpYnV0ZShuYW1lcywgdmFsdWUsIGl0ZW1TaXplcylcblx0XHRcdFx0XHRcdFx0OiBuZXcgRmxvYXQzMkF0dHJpYnV0ZShrZXksIHZhbHVlLCBzaXplKVxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0Y29uc3QgY291bnQgPSBuYW1lcz8ubGVuZ3RoID4gMCA/IG5hbWVzPy5sZW5ndGggOiAxO1xuXHRcdFx0XHRcdGxvY2F0aW9uSW5kZXggKz0gY291bnQ7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHR0aGlzLnZlcnRleEJ1ZmZlcnMuc2V0KHVpZCwgdmVydGV4QnVmZmVyKTtcblx0XHRcdFx0cmV0dXJuIHZlcnRleEJ1ZmZlcjtcblx0XHRcdH0pIHx8IFtdXG5cdFx0KTtcblx0fVxuXHRwcml2YXRlIGNyZWF0ZVNoYWRlclNvdXJjZSgpIHtcblx0XHRjb25zdCB7IHZlcnQsIGZyYWcsIGNvbXB1dGUsIHNoYWRlcklkIH0gPSB0aGlzLm1vZGVsUGFyYW1zO1xuXHRcdHJldHVybiBuZXcgU2hhZGVyU291cmNlKHtcblx0XHRcdHNoYWRlcklkLFxuXHRcdFx0cmVuZGVyOiB7XG5cdFx0XHRcdHZlcnRTaGFkZXI6IHZlcnQsXG5cdFx0XHRcdGZyYWdTaGFkZXI6IGZyYWdcblx0XHRcdH0sXG5cdFx0XHRjb21wdXRlOiB7XG5cdFx0XHRcdGNvbXB1dGVTaGFkZXI6IGNvbXB1dGVcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXHRwcml2YXRlIGNyZWF0ZVNoYWRlckRhdGEoKSB7XG5cdFx0Y29uc3QgeyBzaGFkZXJJZCwgdW5pZm9ybUJ1ZmZlcnMsIHVuaWZvcm1UZXh0dXJlQW5kU2FtcGxlciB9ID0gdGhpcy5tb2RlbFBhcmFtcztcblx0XHRjb25zdCBzaGFkZXJEYXRhID0gbmV3IFNoYWRlckRhdGEoc2hhZGVySWQpO1xuXHRcdC8vIGZpbGwgdW5pZm9ybUJ1ZmZlclxuXHRcdHVuaWZvcm1CdWZmZXJzLmZvckVhY2goKHVuaWZvcm1CdWZmZXIpID0+IHRoaXMuY3JlYXRlVW5pZm9ybUJ1ZmZlcih1bmlmb3JtQnVmZmVyLCBzaGFkZXJEYXRhLCBzaGFkZXJJZCkpO1xuXHRcdC8vIGZpbGwgdGV4dHVyZSBhbmQgc2FtcGxlclxuXHRcdHRoaXMuYWRkVW5pZm9ybVRvU2hhZGVyRGF0YSh1bmlmb3JtVGV4dHVyZUFuZFNhbXBsZXIsIHNoYWRlckRhdGEsIHVuZGVmaW5lZCk7XG5cdFx0cmV0dXJuIHNoYWRlckRhdGE7XG5cdH1cblx0cHJpdmF0ZSBjcmVhdGVSZW5kZXJTdGF0ZSgpIHtcblx0XHRjb25zdCB7XG5cdFx0XHRibGVuZENvbnN0YW50LFxuXHRcdFx0ZGVwdGhTdGVuY2lsLFxuXHRcdFx0dmlld1BvcnQsXG5cdFx0XHRzY2lzc29yVGVzdCxcblx0XHRcdHRhcmdldHMsXG5cdFx0XHRtdWx0aVNhbXBsZSxcblx0XHRcdHByaW1pdGl2ZSxcblx0XHRcdHN0ZW5jaWxSZWZlcmVuY2Vcblx0XHR9ID0gdGhpcy5tb2RlbFBhcmFtcy5yZW5kZXJTdGF0ZTtcblx0XHRyZXR1cm4gbmV3IFJlbmRlclN0YXRlKHtcblx0XHRcdHNjaXNzb3JUZXN0OiBzY2lzc29yVGVzdFxuXHRcdFx0XHQ/IG5ldyBTY2lzc29yVGVzdChzY2lzc29yVGVzdC54LCBzY2lzc29yVGVzdC55LCBzY2lzc29yVGVzdC53aWR0aCwgc2Npc3NvclRlc3QuaGVpZ2h0KVxuXHRcdFx0XHQ6IHVuZGVmaW5lZCxcblx0XHRcdHZpZXdwb3J0OiB2aWV3UG9ydCA/IG5ldyBWaWV3UG9ydCh2aWV3UG9ydC54LCB2aWV3UG9ydC55LCB2aWV3UG9ydC53aWR0aCwgdmlld1BvcnQuaGVpZ2h0KSA6IHVuZGVmaW5lZCxcblx0XHRcdHRhcmdldHM6IHRhcmdldHM/Lm1hcCgodGFyZ2V0KSA9PiB7XG5cdFx0XHRcdHJldHVybiBuZXcgVGFyZ2V0KHRhcmdldCBhcyBhbnkpO1xuXHRcdFx0fSksXG5cdFx0XHRkZXB0aFN0ZW5jaWw6IGRlcHRoU3RlbmNpbCA/IG5ldyBEZXB0aFN0ZW5jaWwoPERlcHRoU3RlbmNpbFByb3BzPmRlcHRoU3RlbmNpbCkgOiB1bmRlZmluZWQsXG5cdFx0XHRibGVuZENvbnN0YW50OiBibGVuZENvbnN0YW50XG5cdFx0XHRcdD8gbmV3IEJsZW5kQ29uc3RhbnQoYmxlbmRDb25zdGFudC5yLCBibGVuZENvbnN0YW50LmcsIGJsZW5kQ29uc3RhbnQuYiwgYmxlbmRDb25zdGFudC5hKVxuXHRcdFx0XHQ6IHVuZGVmaW5lZCxcblx0XHRcdHN0ZW5jaWxSZWZlcmVuY2U6IHN0ZW5jaWxSZWZlcmVuY2UgfHwgMCxcblx0XHRcdG11bHRpc2FtcGxlOiBtdWx0aVNhbXBsZVxuXHRcdFx0XHQ/IG5ldyBNdWx0aVNhbXBsZShtdWx0aVNhbXBsZS5jb3VudCwgbXVsdGlTYW1wbGUubWFzaywgbXVsdGlTYW1wbGUuYWxwaGFUb0NvdmVyYWdlRW5hYmxlZClcblx0XHRcdFx0OiB1bmRlZmluZWQsXG5cdFx0XHRwcmltaXRpdmU6IHByaW1pdGl2ZVxuXHRcdFx0XHQ/IG5ldyBQcmltaXRpdmUoXG5cdFx0XHRcdFx0XHQ8UHJpbWl0aXZlVG9wb2xvZ3k+cHJpbWl0aXZlLnRvcG9sb2d5LFxuXHRcdFx0XHRcdFx0PEN1bGxNb2RlPnByaW1pdGl2ZS5jdWxsTW9kZSxcblx0XHRcdFx0XHRcdDxGcm9udEZhY2U+cHJpbWl0aXZlLmZyb250RmFjZSxcblx0XHRcdFx0XHRcdHByaW1pdGl2ZS51bmNsaXBwZWREZXB0aFxuXHRcdFx0XHQgIClcblx0XHRcdFx0OiB1bmRlZmluZWQsXG5cdFx0XHRzdGVuY2lsRW5hYmxlZDogZmFsc2UsXG5cdFx0XHRzY2lzc29yVGVzdEVuYWJsZWQ6IGZhbHNlXG5cdFx0fSk7XG5cdH1cblx0cHJpdmF0ZSBjcmVhdGVJbmRleEJ1ZmZlcigpIHtcblx0XHRjb25zdCB7IGluZGljZXMsIHNoYWRlcklkIH0gPSB0aGlzLm1vZGVsUGFyYW1zO1xuXHRcdGxldCBpbmRleEJ1ZmZlciA9IHVuZGVmaW5lZDtcblx0XHRpZiAoaW5kaWNlcykge1xuXHRcdFx0aW5kZXhCdWZmZXIgPSBuZXcgSW5kZXhCdWZmZXIoc2hhZGVySWQgKyBcIkluZGV4QnVmZmVyXCIpO1xuXHRcdFx0aW5kZXhCdWZmZXIuc2V0SW5kaWNlcyhpbmRpY2VzKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gaW5kZXhCdWZmZXI7XG5cdH1cblx0cHJpdmF0ZSBjcmVhdGVVbmlmb3JtQnVmZmVyKHVuaWZvcm1CdWZmZXJQYXJhbXMsIHNoYWRlckRhdGE6IFNoYWRlckRhdGEsIHNoYWRlcklkOiBzdHJpbmcpIHtcblx0XHRjb25zdCB7XG5cdFx0XHR0eXBlID0gXCJ1bmlmb3JtXCIsXG5cdFx0XHR1c2FnZSA9IEJ1ZmZlclVzYWdlLlVuaWZvcm0gfCBCdWZmZXJVc2FnZS5Db3B5RHN0LFxuXHRcdFx0dW5pZm9ybXMsXG5cdFx0XHR1aWQsXG5cdFx0XHRiaW5kaW5nLFxuXHRcdFx0YnVmZmVyLFxuXHRcdFx0YnVmZmVyU2l6ZSxcblx0XHRcdHZpc2liaWxpdHlcblx0XHR9ID0gdW5pZm9ybUJ1ZmZlclBhcmFtcztcblx0XHRjb25zdCB1bmlmb3JtQnVmZmVyID0gbmV3IFVuaWZvcm1CdWZmZXIoe1xuXHRcdFx0bGFiZWw6IHVpZCArIFwiX1VuaWZvcm1CdWZmZXJcIixcblx0XHRcdHR5cGU6IDxCdWZmZXJCaW5kaW5nVHlwZT50eXBlLFxuXHRcdFx0dXNhZ2U6IDxCdWZmZXJVc2FnZT51c2FnZSxcblx0XHRcdGJpbmRpbmcsXG5cdFx0XHRidWZmZXIsXG5cdFx0XHR2aXNpYmlsaXR5LFxuXHRcdFx0c2l6ZTogYnVmZmVyPy5zaXplID8/IGJ1ZmZlclNpemVcblx0XHR9KTtcblx0XHRzaGFkZXJEYXRhLnNldFVuaWZvcm1CdWZmZXIodWlkLCB1bmlmb3JtQnVmZmVyKTtcblx0XHRpZiAoIWJ1ZmZlcikgdGhpcy5hZGRVbmlmb3JtVG9TaGFkZXJEYXRhKHVuaWZvcm1zLCBzaGFkZXJEYXRhLCB1bmlmb3JtQnVmZmVyKTtcblx0fVxuXHRwcml2YXRlIGFkZFVuaWZvcm1Ub1NoYWRlckRhdGEodW5pZm9ybXMsIHNoYWRlckRhdGE6IFNoYWRlckRhdGEsIHVuaWZvcm1CdWZmZXI6IFVuaWZvcm1CdWZmZXIpIHtcblx0XHRpZiAoIXVuaWZvcm1zKSByZXR1cm47XG5cdFx0Y29uc3QgdW5pZm9ybXNOYW1lcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHVuaWZvcm1zKTtcblx0XHR1bmlmb3Jtc05hbWVzLm1hcCgodW5pZm9ybXNOYW1lKSA9PiB7XG5cdFx0XHRhZGRVbmlmb3JtVG9TaGFkZXJEYXRhKHVuaWZvcm1zTmFtZSwgdW5pZm9ybXNbdW5pZm9ybXNOYW1lXSwgc2hhZGVyRGF0YSwgdW5kZWZpbmVkLCB1bmlmb3JtQnVmZmVyKTtcblx0XHR9KTtcblx0fVxufVxuXG5leHBvcnQgdHlwZSByZW5kZXJNb2RlbFBhcmFtcyA9IHtcblx0ZGV2aWNlOiBHUFVEZXZpY2U7XG5cdHBhc3NFbmNvZGVyOiBHUFVSZW5kZXJQYXNzRW5jb2RlciB8IEdQVUNvbXB1dGVQYXNzRW5jb2Rlcjtcbn07XG4iLCJpbXBvcnQgeyBJbnRlcmxlYXZlZEZsb2F0MzJBdHRyaWJ1dGUgfSBmcm9tIFwiLi4vcmVuZGVyL0F0dHJpYnV0ZVwiO1xuaW1wb3J0IEdlb21ldHJ5IGZyb20gXCIuL0dlb21ldHJ5XCI7XG5leHBvcnQgY2xhc3MgU3ByaXRlR2VvbWV0cnkgZXh0ZW5kcyBHZW9tZXRyeSB7XG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKHtcblx0XHRcdHR5cGU6IFwic3ByaXRlR2VvbWV0cnlcIlxuXHRcdH0pO1xuXHRcdHRoaXMuaW5pdCgpO1xuXHR9XG5cdHByaXZhdGUgaW5pdCgpIHtcblx0XHQvLyB4eXrjgIF1dlxuXHRcdGNvbnN0IHZlcnRpY2VzID0gWy0wLjUsIC0wLjUsIDAsIDAsIDAsIDAuNSwgLTAuNSwgMCwgMSwgMCwgMC41LCAwLjUsIDAsIDEsIDEsIC0wLjUsIDAuNSwgMCwgMCwgMV07XG5cdFx0Y29uc3QgaW5kaWNlcyA9IFswLCAxLCAyLCAwLCAyLCAzXTtcblx0XHR0aGlzLmNvbXB1dGVCb3VuZGluZ1NwaGVyZSh2ZXJ0aWNlcywgNSk7XG5cdFx0dGhpcy5zZXRBdHRyaWJ1dGUobmV3IEludGVybGVhdmVkRmxvYXQzMkF0dHJpYnV0ZShbXCJwb3NpdGlvblwiLCBcInV2XCJdLCB2ZXJ0aWNlcywgWzMsIDJdKSk7XG5cdFx0dGhpcy5zZXRJbmRpY2UoaW5kaWNlcyk7XG5cdFx0dGhpcy5jb3VudCA9IGluZGljZXMubGVuZ3RoO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBGcmFtZVN0YXRlIH0gZnJvbSBcIi4uL2NvcmUvRnJhbWVTdGF0ZVwiO1xuaW1wb3J0IHRleHR1cmVDYWNoZSBmcm9tIFwiLi4vY29yZS9UZXh0dXJlQ2FjaGVcIjtcbmltcG9ydCB7IFVuaWZvcm1FbnVtIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcbmltcG9ydCBDb2xvciBmcm9tIFwiLi4vbWF0aC9Db2xvclwiO1xuaW1wb3J0IFZlY3RvcjIgZnJvbSBcIi4uL21hdGgvVmVjdG9yMlwiO1xuaW1wb3J0IHsgTWVzaCB9IGZyb20gXCIuLi9tZXNoL01lc2hcIjtcbmltcG9ydCBVbmlmb3JtQnVmZmVyIGZyb20gXCIuLi9yZW5kZXIvVW5pZm9ybUJ1ZmZlclwiO1xuaW1wb3J0IHsgU2hhZGVyU291cmNlIH0gZnJvbSBcIi4uL3NoYWRlci9TaGFkZXJTb3VyY2VcIjtcbmltcG9ydCB7IE1hdGVyaWFsIH0gZnJvbSBcIi4vTWF0ZXJpYWxcIjtcblxuZXhwb3J0IGNsYXNzIFNwcml0ZU1hdGVyaWFsIGV4dGVuZHMgTWF0ZXJpYWwge1xuXHRwdWJsaWMgcm90YXRpb246IG51bWJlcjtcblx0cHVibGljIGNlbnRlcjogVmVjdG9yMjtcblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoKTtcblx0XHR0aGlzLnR5cGUgPSBcInNwcml0ZVwiO1xuXHRcdHRoaXMuc2hhZGVyU291cmNlID0gbmV3IFNoYWRlclNvdXJjZSh7XG5cdFx0XHRzaGFkZXJJZDogdGhpcy50eXBlLFxuXHRcdFx0ZGVmaW5lczoge1xuXHRcdFx0XHRIQVNfVVY6IHRydWVcblx0XHRcdH1cblx0XHR9KTtcblx0XHR0aGlzLnJvdGF0aW9uID0gTWF0aC5QSTtcblx0XHR0aGlzLm9wYWNpdHkgPSAxO1xuXHRcdHRoaXMuY2VudGVyID0gbmV3IFZlY3RvcjIoMCwgMCk7XG5cdFx0dGhpcy5jb2xvciA9IG5ldyBDb2xvcigxLCAwLCAwKTtcblx0fVxuXHR1cGRhdGUoZnJhbWVTdGF0ZT86IEZyYW1lU3RhdGUsIG1lc2g/OiBNZXNoKSB7XG5cdFx0aWYgKCF0aGlzLnNoYWRlckRhdGEgfHwgdGhpcy5kaXJ0eSkgdGhpcy5jcmVhdGVTaGFkZXJEYXRhKG1lc2gpO1xuXHR9XG5cdHByb3RlY3RlZCBjcmVhdGVTaGFkZXJEYXRhKG1lc2g/OiBNZXNoKSB7XG5cdFx0c3VwZXIuY3JlYXRlU2hhZGVyRGF0YSgpO1xuXHRcdGNvbnN0IHVuaWZvcm1CdWZmZXIgPSBuZXcgVW5pZm9ybUJ1ZmZlcih7IGxhYmVsOiBcInNwcml0ZVwiIH0pO1xuXHRcdHVuaWZvcm1CdWZmZXIuc2V0VW5pZm9ybShcblx0XHRcdFwibW9kZWxNYXRyaXhcIixcblx0XHRcdCgpID0+IHtcblx0XHRcdFx0cmV0dXJuIG1lc2gubW9kZWxNYXRyaXg7XG5cdFx0XHR9LFxuXHRcdFx0VW5pZm9ybUVudW0uTWF0NFxuXHRcdCk7XG5cdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFwiY29sb3JcIiwgdGhpcywgVW5pZm9ybUVudW0uQ29sb3IpO1xuXHRcdHVuaWZvcm1CdWZmZXIuc2V0VW5pZm9ybShcInJvdGF0aW9uXCIsIHRoaXMsIFVuaWZvcm1FbnVtLkZsb2F0KTtcblx0XHR1bmlmb3JtQnVmZmVyLnNldFVuaWZvcm0oXCJjZW50ZXJcIiwgdGhpcywgVW5pZm9ybUVudW0uRmxvYXRWZWMyKTtcblx0XHR1bmlmb3JtQnVmZmVyLnNldFVuaWZvcm0oXCJvcGFjaXR5XCIsIHRoaXMsIFVuaWZvcm1FbnVtLkZsb2F0KTtcblx0XHR0aGlzLnNoYWRlckRhdGEuc2V0VW5pZm9ybUJ1ZmZlcihcInNwcml0ZVwiLCB1bmlmb3JtQnVmZmVyKTtcblx0XHRpZiAodGhpcy5iYXNlVGV4dHVyZSkge1xuXHRcdFx0dGhpcy5zaGFkZXJEYXRhLnNldERlZmluZShcIlVTRV9DT0xPUlRFWFRVUkVcIiwgdHJ1ZSk7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0VGV4dHVyZShcImJhc2VDb2xvclRleHR1cmVcIiwgdGhpcy5iYXNlVGV4dHVyZSk7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0U2FtcGxlcihcImJhc2VDb2xvclNhbXBsZXJcIiwgdGhpcy5iYXNlU2FtcGxlciB8fCB0ZXh0dXJlQ2FjaGUuZGVmYXVsdFNhbXBsZXIpO1xuXHRcdH1cblx0fVxuXHRkZXN0cm95KCkge1xuXHRcdHRoaXM/LmJhc2VUZXh0dXJlPy5kZXN0cm95KCk7XG5cdFx0c3VwZXIuZGVzdHJveSgpO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBTcHJpdGVHZW9tZXRyeSB9IGZyb20gXCIuLi9nZW9tZXRyeS9TcHJpdGVHZW9tZXRyeVwiO1xuaW1wb3J0IHsgU3ByaXRlTWF0ZXJpYWwgfSBmcm9tIFwiLi4vbWF0ZXJpYWwvU3ByaXRlTWF0ZXJpYWxcIjtcbmltcG9ydCBTYW1wbGVyIGZyb20gXCIuLi9yZW5kZXIvU2FtcGxlclwiO1xuaW1wb3J0IFRleHR1cmUgZnJvbSBcIi4uL3JlbmRlci9UZXh0dXJlXCI7XG5pbXBvcnQgeyBNZXNoIH0gZnJvbSBcIi4vTWVzaFwiO1xuXG5leHBvcnQgY2xhc3MgU3ByaXRlIGV4dGVuZHMgTWVzaCB7XG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHN1cGVyKCk7XG5cdFx0dGhpcy5tYXRlcmlhbCA9IG5ldyBTcHJpdGVNYXRlcmlhbCgpO1xuXHRcdHRoaXMuZ2VvbWV0cnkgPSBuZXcgU3ByaXRlR2VvbWV0cnkoKTtcblx0fVxuXHRzZXRUZXh0dXJlKHRleHR1cmU6IFRleHR1cmUpIHtcblx0XHR0aGlzLm1hdGVyaWFsLmJhc2VUZXh0dXJlID0gdGV4dHVyZTtcblx0fVxuXHRzZXRTYW1wbGVyKHNhbXBsZXI6IFNhbXBsZXIpIHtcblx0XHR0aGlzLm1hdGVyaWFsLmJhc2VTYW1wbGVyID0gc2FtcGxlcjtcblx0fVxufVxuIiwiLyoqXHJcbiAqIEVuc3VyZSBmaXJzdCBhcmd1bWVudCBwYXNzZWQgdG8gdGhlIHByaW1pdGl2ZSBmdW5jdGlvbnMgaXMgYW4gb2JqZWN0XHJcbiAqIEBwYXJhbSB7Li4uKn0gYXJnc1xyXG4gKi9cclxuZnVuY3Rpb24gY2hlY2tBcmd1bWVudHMoYXJncykge1xyXG5cdGNvbnN0IGFyZ3VtZW50VHlwZSA9IHR5cGVvZiBhcmdzWzBdO1xyXG5cdGlmIChhcmd1bWVudFR5cGUgIT09IFwib2JqZWN0XCIgJiYgYXJndW1lbnRUeXBlICE9PSBcInVuZGVmaW5lZFwiKSB7XHJcblx0XHRjb25zb2xlLmVycm9yKFwiRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xyXG5cdH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5sZXQgVFlQRURfQVJSQVlfVFlQRTtcclxuXHJcbi8qKlxyXG4gKiBTZWxlY3QgY2VsbHMgdHlwZWQgYXJyYXkgZnJvbSBhIHNpemUgZGV0ZXJtaW5lZCBieSBhbW91bnQgb2YgdmVydGljZXMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIFRoZSBtYXggdmFsdWUgZXhwZWN0ZWRcclxuICogQHJldHVybnMgeyhVaW50OEFycmF5fFVpbnQxNkFycmF5fFVpbnQzMkFycmF5KX1cclxuICogQHNlZSBbTUROIFR5cGVkQXJyYXkgb2JqZWN0c117QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvVHlwZWRBcnJheSN0eXBlZGFycmF5X29iamVjdHN9XHJcbiAqL1xyXG5jb25zdCBnZXRDZWxsc1R5cGVkQXJyYXkgPSAoc2l6ZSkgPT5cclxuXHRUWVBFRF9BUlJBWV9UWVBFIHx8IChzaXplIDw9IDI1NSA/IFVpbnQ4QXJyYXkgOiBzaXplIDw9IDY1NTM1ID8gVWludDE2QXJyYXkgOiBVaW50MzJBcnJheSk7XHJcblxyXG4vKipcclxuICogQHByaXZhdGVcclxuICovXHJcbmNvbnN0IFBMQU5FX0RJUkVDVElPTlMgPSB7XHJcblx0ejogWzAsIDEsIDIsIDEsIC0xLCAxXSxcclxuXHRcIi16XCI6IFswLCAxLCAyLCAtMSwgLTEsIC0xXSxcclxuXHRcIi14XCI6IFsyLCAxLCAwLCAxLCAtMSwgLTFdLFxyXG5cdHg6IFsyLCAxLCAwLCAtMSwgLTEsIDFdLFxyXG5cdHk6IFswLCAyLCAxLCAxLCAxLCAxXSxcclxuXHRcIi15XCI6IFswLCAyLCAxLCAxLCAtMSwgLTFdXHJcbn07XHJcblxyXG4vKipcclxuICogQHByaXZhdGVcclxuICovXHJcbmZ1bmN0aW9uIGNvbXB1dGVQbGFuZShcclxuXHRnZW9tZXRyeSxcclxuXHRpbmRpY2VzLFxyXG5cdHN1LFxyXG5cdHN2LFxyXG5cdG51LFxyXG5cdG52LFxyXG5cdGRpcmVjdGlvbiA9IFwielwiLFxyXG5cdHB3ID0gMCxcclxuXHRxdWFkcyA9IGZhbHNlLFxyXG5cdHV2U2NhbGUgPSBbMSwgMV0sXHJcblx0dXZPZmZzZXQgPSBbMCwgMF0sXHJcblx0Y2VudGVyID0gWzAsIDAsIDBdLFxyXG5cdGNjdyA9IHRydWVcclxuKSB7XHJcblx0Y29uc3QgeyBwb3NpdGlvbnMsIG5vcm1hbHMsIHV2cywgY2VsbHMgfSA9IGdlb21ldHJ5O1xyXG5cdGNvbnN0IFt1LCB2LCB3LCBmbGlwVSwgZmxpcFYsIG5vcm1hbF0gPSBQTEFORV9ESVJFQ1RJT05TW2RpcmVjdGlvbl07XHJcblxyXG5cdGNvbnN0IHZlcnRleE9mZnNldCA9IGluZGljZXMudmVydGV4O1xyXG5cclxuXHRmb3IgKGxldCBqID0gMDsgaiA8PSBudjsgaisrKSB7XHJcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8PSBudTsgaSsrKSB7XHJcblx0XHRcdHBvc2l0aW9uc1tpbmRpY2VzLnZlcnRleCAqIDMgKyB1XSA9ICgtc3UgLyAyICsgKGkgKiBzdSkgLyBudSkgKiBmbGlwVSArIGNlbnRlclt1XTtcclxuXHRcdFx0cG9zaXRpb25zW2luZGljZXMudmVydGV4ICogMyArIHZdID0gKC1zdiAvIDIgKyAoaiAqIHN2KSAvIG52KSAqIGZsaXBWICsgY2VudGVyW3ZdO1xyXG5cdFx0XHRwb3NpdGlvbnNbaW5kaWNlcy52ZXJ0ZXggKiAzICsgd10gPSBwdyArIGNlbnRlclt3XTtcclxuXHJcblx0XHRcdG5vcm1hbHNbaW5kaWNlcy52ZXJ0ZXggKiAzICsgd10gPSBub3JtYWw7XHJcblxyXG5cdFx0XHR1dnNbaW5kaWNlcy52ZXJ0ZXggKiAyXSA9IChpIC8gbnUpICogdXZTY2FsZVswXSArIHV2T2Zmc2V0WzBdO1xyXG5cdFx0XHR1dnNbaW5kaWNlcy52ZXJ0ZXggKiAyICsgMV0gPSAoMSAtIGogLyBudikgKiB1dlNjYWxlWzFdICsgdXZPZmZzZXRbMV07XHJcblxyXG5cdFx0XHRpbmRpY2VzLnZlcnRleCsrO1xyXG5cclxuXHRcdFx0aWYgKGogPCBudiAmJiBpIDwgbnUpIHtcclxuXHRcdFx0XHRjb25zdCBuID0gdmVydGV4T2Zmc2V0ICsgaiAqIChudSArIDEpICsgaTtcclxuXHRcdFx0XHRpZiAocXVhZHMpIHtcclxuXHRcdFx0XHRcdGNvbnN0IG8gPSB2ZXJ0ZXhPZmZzZXQgKyAoaiArIDEpICogKG51ICsgMSkgKyBpO1xyXG5cdFx0XHRcdFx0Y2VsbHNbaW5kaWNlcy5jZWxsXSA9IG47XHJcblx0XHRcdFx0XHRjZWxsc1tpbmRpY2VzLmNlbGwgKyAxXSA9IG87XHJcblx0XHRcdFx0XHRjZWxsc1tpbmRpY2VzLmNlbGwgKyAyXSA9IG8gKyAxO1xyXG5cdFx0XHRcdFx0Y2VsbHNbaW5kaWNlcy5jZWxsICsgM10gPSBuICsgMTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0Y2VsbHNbaW5kaWNlcy5jZWxsXSA9IG47XHJcblx0XHRcdFx0XHRjZWxsc1tpbmRpY2VzLmNlbGwgKyAoY2N3ID8gMSA6IDIpXSA9IG4gKyBudSArIDE7XHJcblx0XHRcdFx0XHRjZWxsc1tpbmRpY2VzLmNlbGwgKyAoY2N3ID8gMiA6IDEpXSA9IG4gKyBudSArIDI7XHJcblxyXG5cdFx0XHRcdFx0Y2VsbHNbaW5kaWNlcy5jZWxsICsgM10gPSBuO1xyXG5cdFx0XHRcdFx0Y2VsbHNbaW5kaWNlcy5jZWxsICsgKGNjdyA/IDQgOiA1KV0gPSBuICsgbnUgKyAyO1xyXG5cdFx0XHRcdFx0Y2VsbHNbaW5kaWNlcy5jZWxsICsgKGNjdyA/IDUgOiA0KV0gPSBuICsgMTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aW5kaWNlcy5jZWxsICs9IHF1YWRzID8gNCA6IDY7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJldHVybiBnZW9tZXRyeTtcclxufVxyXG4vKipcclxuICogQHR5cGVkZWYge09iamVjdH0gQ3ViZU9wdGlvbnNcclxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtzeD0xXVxyXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3N5PXN4XVxyXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3N6PXN4XVxyXG4gKiBAcHJvcGVydHkge251bWJlcn0gW254PTFdXHJcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbnk9bnhdXHJcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbno9bnhdXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ3ViZSh7IHN4ID0gMSwgc3kgPSAxLCBzeiA9IDEsIG54ID0gMSwgbnkgPSAxLCBueiA9IDEgfSA9IHt9KSB7XHJcblx0Y2hlY2tBcmd1bWVudHMoYXJndW1lbnRzKTtcclxuXHJcblx0Y29uc3Qgc2l6ZSA9IChueCArIDEpICogKG55ICsgMSkgKiAyICsgKG54ICsgMSkgKiAobnogKyAxKSAqIDIgKyAobnogKyAxKSAqIChueSArIDEpICogMjtcclxuXHJcblx0Y29uc3QgZ2VvbWV0cnkgPSB7XHJcblx0XHRwb3NpdGlvbnM6IG5ldyBGbG9hdDMyQXJyYXkoc2l6ZSAqIDMpLFxyXG5cdFx0bm9ybWFsczogbmV3IEZsb2F0MzJBcnJheShzaXplICogMyksXHJcblx0XHR1dnM6IG5ldyBGbG9hdDMyQXJyYXkoc2l6ZSAqIDIpLFxyXG5cdFx0Y2VsbHM6IG5ldyAoZ2V0Q2VsbHNUeXBlZEFycmF5KHNpemUpKSgobnggKiBueSAqIDIgKyBueCAqIG56ICogMiArIG56ICogbnkgKiAyKSAqIDYpXHJcblx0fTtcclxuXHJcblx0Y29uc3QgaGFsZlNYID0gc3ggKiAwLjU7XHJcblx0Y29uc3QgaGFsZlNZID0gc3kgKiAwLjU7XHJcblx0Y29uc3QgaGFsZlNaID0gc3ogKiAwLjU7XHJcblxyXG5cdGNvbnN0IGluZGljZXMgPSB7IHZlcnRleDogMCwgY2VsbDogMCB9O1xyXG5cclxuXHRjb21wdXRlUGxhbmUoZ2VvbWV0cnksIGluZGljZXMsIHN4LCBzeSwgbngsIG55LCBcInpcIiwgaGFsZlNaKTtcclxuXHRjb21wdXRlUGxhbmUoZ2VvbWV0cnksIGluZGljZXMsIHN4LCBzeSwgbngsIG55LCBcIi16XCIsIC1oYWxmU1opO1xyXG5cdGNvbXB1dGVQbGFuZShnZW9tZXRyeSwgaW5kaWNlcywgc3osIHN5LCBueiwgbnksIFwiLXhcIiwgLWhhbGZTWCk7XHJcblx0Y29tcHV0ZVBsYW5lKGdlb21ldHJ5LCBpbmRpY2VzLCBzeiwgc3ksIG56LCBueSwgXCJ4XCIsIGhhbGZTWCk7XHJcblx0Y29tcHV0ZVBsYW5lKGdlb21ldHJ5LCBpbmRpY2VzLCBzeCwgc3osIG54LCBueiwgXCJ5XCIsIGhhbGZTWSk7XHJcblx0Y29tcHV0ZVBsYW5lKGdlb21ldHJ5LCBpbmRpY2VzLCBzeCwgc3osIG54LCBueiwgXCIteVwiLCAtaGFsZlNZKTtcclxuXHJcblx0cmV0dXJuIGdlb21ldHJ5O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQm94KG9wdGlvbnMpIHtcclxuXHRvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuXHJcblx0Y29uc3QgZGltZW5zaW9ucyA9IG9wdGlvbnMuZGltZW5zaW9ucyB8fCBbMSwgMSwgMV07XHJcblx0Y29uc3QgcG9zaXRpb24gPSBvcHRpb25zLnBvc2l0aW9uIHx8IFstZGltZW5zaW9uc1swXSAvIDIsIC1kaW1lbnNpb25zWzFdIC8gMiwgLWRpbWVuc2lvbnNbMl0gLyAyXTtcclxuXHRjb25zdCB4ID0gcG9zaXRpb25bMF07XHJcblx0Y29uc3QgeSA9IHBvc2l0aW9uWzFdO1xyXG5cdGNvbnN0IHogPSBwb3NpdGlvblsyXTtcclxuXHRjb25zdCB3aWR0aCA9IGRpbWVuc2lvbnNbMF07XHJcblx0Y29uc3QgaGVpZ2h0ID0gZGltZW5zaW9uc1sxXTtcclxuXHRjb25zdCBkZXB0aCA9IGRpbWVuc2lvbnNbMl07XHJcblxyXG5cdGNvbnN0IGZibCA9IHsgeDogeCwgeTogeSwgejogeiArIGRlcHRoIH07XHJcblx0Y29uc3QgZmJyID0geyB4OiB4ICsgd2lkdGgsIHk6IHksIHo6IHogKyBkZXB0aCB9O1xyXG5cdGNvbnN0IGZ0bCA9IHsgeDogeCwgeTogeSArIGhlaWdodCwgejogeiArIGRlcHRoIH07XHJcblx0Y29uc3QgZnRyID0geyB4OiB4ICsgd2lkdGgsIHk6IHkgKyBoZWlnaHQsIHo6IHogKyBkZXB0aCB9O1xyXG5cdGNvbnN0IGJibCA9IHsgeDogeCwgeTogeSwgejogeiB9O1xyXG5cdGNvbnN0IGJiciA9IHsgeDogeCArIHdpZHRoLCB5OiB5LCB6OiB6IH07XHJcblx0Y29uc3QgYnRsID0geyB4OiB4LCB5OiB5ICsgaGVpZ2h0LCB6OiB6IH07XHJcblx0Y29uc3QgYnRyID0geyB4OiB4ICsgd2lkdGgsIHk6IHkgKyBoZWlnaHQsIHo6IHogfTtcclxuXHJcblx0Y29uc3QgcG9zaXRpb25zID0gW1xyXG5cdFx0Ly8gZnJvbnRcclxuXHRcdGZibC54LFxyXG5cdFx0ZmJsLnksXHJcblx0XHRmYmwueixcclxuXHRcdGZici54LFxyXG5cdFx0ZmJyLnksXHJcblx0XHRmYnIueixcclxuXHRcdGZ0bC54LFxyXG5cdFx0ZnRsLnksXHJcblx0XHRmdGwueixcclxuXHRcdGZ0bC54LFxyXG5cdFx0ZnRsLnksXHJcblx0XHRmdGwueixcclxuXHRcdGZici54LFxyXG5cdFx0ZmJyLnksXHJcblx0XHRmYnIueixcclxuXHRcdGZ0ci54LFxyXG5cdFx0ZnRyLnksXHJcblx0XHRmdHIueixcclxuXHJcblx0XHQvLyByaWdodFxyXG5cdFx0ZmJyLngsXHJcblx0XHRmYnIueSxcclxuXHRcdGZici56LFxyXG5cdFx0YmJyLngsXHJcblx0XHRiYnIueSxcclxuXHRcdGJici56LFxyXG5cdFx0ZnRyLngsXHJcblx0XHRmdHIueSxcclxuXHRcdGZ0ci56LFxyXG5cdFx0ZnRyLngsXHJcblx0XHRmdHIueSxcclxuXHRcdGZ0ci56LFxyXG5cdFx0YmJyLngsXHJcblx0XHRiYnIueSxcclxuXHRcdGJici56LFxyXG5cdFx0YnRyLngsXHJcblx0XHRidHIueSxcclxuXHRcdGJ0ci56LFxyXG5cclxuXHRcdC8vIGJhY2tcclxuXHRcdGZici54LFxyXG5cdFx0YmJyLnksXHJcblx0XHRiYnIueixcclxuXHRcdGJibC54LFxyXG5cdFx0YmJsLnksXHJcblx0XHRiYmwueixcclxuXHRcdGJ0ci54LFxyXG5cdFx0YnRyLnksXHJcblx0XHRidHIueixcclxuXHRcdGJ0ci54LFxyXG5cdFx0YnRyLnksXHJcblx0XHRidHIueixcclxuXHRcdGJibC54LFxyXG5cdFx0YmJsLnksXHJcblx0XHRiYmwueixcclxuXHRcdGJ0bC54LFxyXG5cdFx0YnRsLnksXHJcblx0XHRidGwueixcclxuXHJcblx0XHQvLyBsZWZ0XHJcblx0XHRiYmwueCxcclxuXHRcdGJibC55LFxyXG5cdFx0YmJsLnosXHJcblx0XHRmYmwueCxcclxuXHRcdGZibC55LFxyXG5cdFx0ZmJsLnosXHJcblx0XHRidGwueCxcclxuXHRcdGJ0bC55LFxyXG5cdFx0YnRsLnosXHJcblx0XHRidGwueCxcclxuXHRcdGJ0bC55LFxyXG5cdFx0YnRsLnosXHJcblx0XHRmYmwueCxcclxuXHRcdGZibC55LFxyXG5cdFx0ZmJsLnosXHJcblx0XHRmdGwueCxcclxuXHRcdGZ0bC55LFxyXG5cdFx0ZnRsLnosXHJcblxyXG5cdFx0Ly8gdG9wXHJcblx0XHRmdGwueCxcclxuXHRcdGZ0bC55LFxyXG5cdFx0ZnRsLnosXHJcblx0XHRmdHIueCxcclxuXHRcdGZ0ci55LFxyXG5cdFx0ZnRyLnosXHJcblx0XHRidGwueCxcclxuXHRcdGJ0bC55LFxyXG5cdFx0YnRsLnosXHJcblx0XHRidGwueCxcclxuXHRcdGJ0bC55LFxyXG5cdFx0YnRsLnosXHJcblx0XHRmdHIueCxcclxuXHRcdGZ0ci55LFxyXG5cdFx0ZnRyLnosXHJcblx0XHRidHIueCxcclxuXHRcdGJ0ci55LFxyXG5cdFx0YnRyLnosXHJcblxyXG5cdFx0Ly8gYm90dG9tXHJcblx0XHRiYmwueCxcclxuXHRcdGJibC55LFxyXG5cdFx0YmJsLnosXHJcblx0XHRiYnIueCxcclxuXHRcdGJici55LFxyXG5cdFx0YmJyLnosXHJcblx0XHRmYmwueCxcclxuXHRcdGZibC55LFxyXG5cdFx0ZmJsLnosXHJcblx0XHRmYmwueCxcclxuXHRcdGZibC55LFxyXG5cdFx0ZmJsLnosXHJcblx0XHRiYnIueCxcclxuXHRcdGJici55LFxyXG5cdFx0YmJyLnosXHJcblx0XHRmYnIueCxcclxuXHRcdGZici55LFxyXG5cdFx0ZmJyLnpcclxuXHRdO1xyXG5cclxuXHRjb25zdCB1dnMgPSBbXHJcblx0XHQvLyBmcm9udFxyXG5cdFx0MCwgMCwgMSwgMCwgMCwgMSwgMCwgMSwgMSwgMCwgMSwgMSxcclxuXHJcblx0XHQvLyByaWdodFxyXG5cdFx0MCwgMCwgMSwgMCwgMCwgMSwgMCwgMSwgMSwgMCwgMSwgMSxcclxuXHJcblx0XHQvLyBiYWNrXHJcblx0XHQwLCAwLCAxLCAwLCAwLCAxLCAwLCAxLCAxLCAwLCAxLCAxLFxyXG5cclxuXHRcdC8vIGxlZnRcclxuXHRcdDAsIDAsIDEsIDAsIDAsIDEsIDAsIDEsIDEsIDAsIDEsIDEsXHJcblxyXG5cdFx0Ly8gdG9wXHJcblx0XHQwLCAwLCAxLCAwLCAwLCAxLCAwLCAxLCAxLCAwLCAxLCAxLFxyXG5cclxuXHRcdC8vIGJvdHRvbVxyXG5cdFx0MCwgMCwgMSwgMCwgMCwgMSwgMCwgMSwgMSwgMCwgMSwgMVxyXG5cdF07XHJcblxyXG5cdGNvbnN0IG5vcm1hbHMgPSBbXHJcblx0XHQvLyBmcm9udFxyXG5cdFx0MCwgMCwgMSwgMCwgMCwgMSwgMCwgMCwgMSwgMCwgMCwgMSwgMCwgMCwgMSwgMCwgMCwgMSxcclxuXHJcblx0XHQvLyByaWdodFxyXG5cdFx0MSwgMCwgMCwgMSwgMCwgMCwgMSwgMCwgMCwgMSwgMCwgMCwgMSwgMCwgMCwgMSwgMCwgMCxcclxuXHJcblx0XHQvLyBiYWNrXHJcblx0XHQwLCAwLCAtMSwgMCwgMCwgLTEsIDAsIDAsIC0xLCAwLCAwLCAtMSwgMCwgMCwgLTEsIDAsIDAsIC0xLFxyXG5cclxuXHRcdC8vIGxlZnRcclxuXHRcdC0xLCAwLCAwLCAtMSwgMCwgMCwgLTEsIDAsIDAsIC0xLCAwLCAwLCAtMSwgMCwgMCwgLTEsIDAsIDAsXHJcblxyXG5cdFx0Ly8gdG9wXHJcblx0XHQwLCAxLCAwLCAwLCAxLCAwLCAwLCAxLCAwLCAwLCAxLCAwLCAwLCAxLCAwLCAwLCAxLCAwLFxyXG5cclxuXHRcdC8vIGJvdHRvbVxyXG5cdFx0MCwgLTEsIDAsIDAsIC0xLCAwLCAwLCAtMSwgMCwgMCwgLTEsIDAsIDAsIC0xLCAwLCAwLCAtMSwgMFxyXG5cdF07XHJcblx0cmV0dXJuIHtcclxuXHRcdHBvc2l0aW9uczogcG9zaXRpb25zLFxyXG5cdFx0bm9ybWFsczogbm9ybWFscyxcclxuXHRcdHV2czogdXZzXHJcblx0fTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNwaGVyZShvcHRpb25zKSB7XHJcblx0b3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcblxyXG5cdGNvbnN0IGxvbmdCYW5kcyA9IG9wdGlvbnMubG9uZ0JhbmRzIHx8IDMyO1xyXG5cdGNvbnN0IGxhdEJhbmRzID0gb3B0aW9ucy5sYXRCYW5kcyB8fCAzMjtcclxuXHRjb25zdCByYWRpdXMgPSBvcHRpb25zLnJhZGl1cyB8fCAxO1xyXG5cdGNvbnN0IGxhdF9zdGVwID0gTWF0aC5QSSAvIGxhdEJhbmRzO1xyXG5cdGNvbnN0IGxvbmdfc3RlcCA9ICgyICogTWF0aC5QSSkgLyBsb25nQmFuZHM7XHJcblx0Y29uc3QgbnVtX3Bvc2l0aW9ucyA9IGxvbmdCYW5kcyAqIGxhdEJhbmRzICogNDtcclxuXHRjb25zdCBudW1faW5kaWNlcyA9IGxvbmdCYW5kcyAqIGxhdEJhbmRzICogNjtcclxuXHRsZXQgbGF0X2FuZ2xlLCBsb25nX2FuZ2xlO1xyXG5cdGNvbnN0IHBvc2l0aW9ucyA9IG5ldyBBcnJheShudW1fcG9zaXRpb25zICogMyk7XHJcblx0Y29uc3Qgbm9ybWFscyA9IG5ldyBBcnJheShudW1fcG9zaXRpb25zICogMyk7XHJcblx0Y29uc3QgdXZzID0gbmV3IEFycmF5KG51bV9wb3NpdGlvbnMgKiAyKTtcclxuXHRjb25zdCBpbmRpY2VzID0gbmV3IEFycmF5KG51bV9pbmRpY2VzKTtcclxuXHRsZXQgeDEsIHgyLCB4MywgeDQsIHkxLCB5MiwgejEsIHoyLCB6MywgejQsIHUxLCB1MiwgdjEsIHYyO1xyXG5cdGxldCBpLCBqO1xyXG5cdGxldCBrID0gMCxcclxuXHRcdGwgPSAwO1xyXG5cdGxldCB2aSwgdGk7XHJcblxyXG5cdGZvciAoaSA9IDA7IGkgPCBsYXRCYW5kczsgaSsrKSB7XHJcblx0XHRsYXRfYW5nbGUgPSBpICogbGF0X3N0ZXA7XHJcblx0XHR5MSA9IE1hdGguY29zKGxhdF9hbmdsZSk7XHJcblx0XHR5MiA9IE1hdGguY29zKGxhdF9hbmdsZSArIGxhdF9zdGVwKTtcclxuXHRcdGZvciAoaiA9IDA7IGogPCBsb25nQmFuZHM7IGorKykge1xyXG5cdFx0XHRsb25nX2FuZ2xlID0gaiAqIGxvbmdfc3RlcDtcclxuXHRcdFx0eDEgPSBNYXRoLnNpbihsYXRfYW5nbGUpICogTWF0aC5jb3MobG9uZ19hbmdsZSk7XHJcblx0XHRcdHgyID0gTWF0aC5zaW4obGF0X2FuZ2xlKSAqIE1hdGguY29zKGxvbmdfYW5nbGUgKyBsb25nX3N0ZXApO1xyXG5cdFx0XHR4MyA9IE1hdGguc2luKGxhdF9hbmdsZSArIGxhdF9zdGVwKSAqIE1hdGguY29zKGxvbmdfYW5nbGUpO1xyXG5cdFx0XHR4NCA9IE1hdGguc2luKGxhdF9hbmdsZSArIGxhdF9zdGVwKSAqIE1hdGguY29zKGxvbmdfYW5nbGUgKyBsb25nX3N0ZXApO1xyXG5cdFx0XHR6MSA9IE1hdGguc2luKGxhdF9hbmdsZSkgKiBNYXRoLnNpbihsb25nX2FuZ2xlKTtcclxuXHRcdFx0ejIgPSBNYXRoLnNpbihsYXRfYW5nbGUpICogTWF0aC5zaW4obG9uZ19hbmdsZSArIGxvbmdfc3RlcCk7XHJcblx0XHRcdHozID0gTWF0aC5zaW4obGF0X2FuZ2xlICsgbGF0X3N0ZXApICogTWF0aC5zaW4obG9uZ19hbmdsZSk7XHJcblx0XHRcdHo0ID0gTWF0aC5zaW4obGF0X2FuZ2xlICsgbGF0X3N0ZXApICogTWF0aC5zaW4obG9uZ19hbmdsZSArIGxvbmdfc3RlcCk7XHJcblx0XHRcdHUxID0gMSAtIGogLyBsb25nQmFuZHM7XHJcblx0XHRcdHUyID0gMSAtIChqICsgMSkgLyBsb25nQmFuZHM7XHJcblx0XHRcdHYxID0gMSAtIGkgLyBsYXRCYW5kcztcclxuXHRcdFx0djIgPSAxIC0gKGkgKyAxKSAvIGxhdEJhbmRzO1xyXG5cdFx0XHR2aSA9IGsgKiAzO1xyXG5cdFx0XHR0aSA9IGsgKiAyO1xyXG5cclxuXHRcdFx0cG9zaXRpb25zW3ZpXSA9IHgxICogcmFkaXVzO1xyXG5cdFx0XHRwb3NpdGlvbnNbdmkgKyAxXSA9IHkxICogcmFkaXVzO1xyXG5cdFx0XHRwb3NpdGlvbnNbdmkgKyAyXSA9IHoxICogcmFkaXVzOyAvLyB2MFxyXG5cclxuXHRcdFx0cG9zaXRpb25zW3ZpICsgM10gPSB4MiAqIHJhZGl1cztcclxuXHRcdFx0cG9zaXRpb25zW3ZpICsgNF0gPSB5MSAqIHJhZGl1cztcclxuXHRcdFx0cG9zaXRpb25zW3ZpICsgNV0gPSB6MiAqIHJhZGl1czsgLy8gdjFcclxuXHJcblx0XHRcdHBvc2l0aW9uc1t2aSArIDZdID0geDMgKiByYWRpdXM7XHJcblx0XHRcdHBvc2l0aW9uc1t2aSArIDddID0geTIgKiByYWRpdXM7XHJcblx0XHRcdHBvc2l0aW9uc1t2aSArIDhdID0gejMgKiByYWRpdXM7IC8vIHYyXHJcblxyXG5cdFx0XHRwb3NpdGlvbnNbdmkgKyA5XSA9IHg0ICogcmFkaXVzO1xyXG5cdFx0XHRwb3NpdGlvbnNbdmkgKyAxMF0gPSB5MiAqIHJhZGl1cztcclxuXHRcdFx0cG9zaXRpb25zW3ZpICsgMTFdID0gejQgKiByYWRpdXM7IC8vIHYzXHJcblxyXG5cdFx0XHRub3JtYWxzW3ZpXSA9IHgxO1xyXG5cdFx0XHRub3JtYWxzW3ZpICsgMV0gPSB5MTtcclxuXHRcdFx0bm9ybWFsc1t2aSArIDJdID0gejE7XHJcblxyXG5cdFx0XHRub3JtYWxzW3ZpICsgM10gPSB4MjtcclxuXHRcdFx0bm9ybWFsc1t2aSArIDRdID0geTE7XHJcblx0XHRcdG5vcm1hbHNbdmkgKyA1XSA9IHoyO1xyXG5cclxuXHRcdFx0bm9ybWFsc1t2aSArIDZdID0geDM7XHJcblx0XHRcdG5vcm1hbHNbdmkgKyA3XSA9IHkyO1xyXG5cdFx0XHRub3JtYWxzW3ZpICsgOF0gPSB6MztcclxuXHJcblx0XHRcdG5vcm1hbHNbdmkgKyA5XSA9IHg0O1xyXG5cdFx0XHRub3JtYWxzW3ZpICsgMTBdID0geTI7XHJcblx0XHRcdG5vcm1hbHNbdmkgKyAxMV0gPSB6NDtcclxuXHJcblx0XHRcdHV2c1t0aV0gPSB1MTtcclxuXHRcdFx0dXZzW3RpICsgMV0gPSB2MTtcclxuXHJcblx0XHRcdHV2c1t0aSArIDJdID0gdTI7XHJcblx0XHRcdHV2c1t0aSArIDNdID0gdjE7XHJcblxyXG5cdFx0XHR1dnNbdGkgKyA0XSA9IHUxO1xyXG5cdFx0XHR1dnNbdGkgKyA1XSA9IHYyO1xyXG5cclxuXHRcdFx0dXZzW3RpICsgNl0gPSB1MjtcclxuXHRcdFx0dXZzW3RpICsgN10gPSB2MjtcclxuXHJcblx0XHRcdGluZGljZXNbbF0gPSBrO1xyXG5cdFx0XHRpbmRpY2VzW2wgKyAxXSA9IGsgKyAxO1xyXG5cdFx0XHRpbmRpY2VzW2wgKyAyXSA9IGsgKyAyO1xyXG5cdFx0XHRpbmRpY2VzW2wgKyAzXSA9IGsgKyAyO1xyXG5cdFx0XHRpbmRpY2VzW2wgKyA0XSA9IGsgKyAxO1xyXG5cdFx0XHRpbmRpY2VzW2wgKyA1XSA9IGsgKyAzO1xyXG5cclxuXHRcdFx0ayArPSA0O1xyXG5cdFx0XHRsICs9IDY7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4ge1xyXG5cdFx0cG9zaXRpb25zOiBwb3NpdGlvbnMsXHJcblx0XHRub3JtYWxzOiBub3JtYWxzLFxyXG5cdFx0dXZzOiB1dnMsXHJcblx0XHRpbmRpY2VzOiBpbmRpY2VzXHJcblx0fTtcclxufVxyXG4iLCJpbXBvcnQgeyBGbG9hdDMyQXR0cmlidXRlIH0gZnJvbSBcIi4uL3JlbmRlci9BdHRyaWJ1dGVcIjtcclxuaW1wb3J0IHsgY3JlYXRlU3BoZXJlIH0gZnJvbSBcIi4uL3V0aWxzL0dlb21ldHJ5VXRpbHNcIjtcclxuaW1wb3J0IEdlb21ldHJ5IGZyb20gXCIuL0dlb21ldHJ5XCI7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTcGhlcmVHZW9tZXRyeSBleHRlbmRzIEdlb21ldHJ5IHtcclxuXHRyYWRpdXM6IG51bWJlcjtcclxuXHRjb25zdHJ1Y3RvcihyYWRpdXM6IG51bWJlcikge1xyXG5cdFx0c3VwZXIoe1xyXG5cdFx0XHR0eXBlOiBcInNwaGVyZUdlb21ldHJ5XCJcclxuXHRcdH0pO1xyXG5cdFx0dGhpcy5kZWZpbmVzID0ge1xyXG5cdFx0XHRIQVNfTk9STUFMOiB0cnVlXHJcblx0XHR9O1xyXG5cdFx0dGhpcy5yYWRpdXMgPSByYWRpdXM7XHJcblx0XHR0aGlzLmluaXQoKTtcclxuXHR9XHJcblx0cHJpdmF0ZSBpbml0KCkge1xyXG5cdFx0Y29uc3QgeyBwb3NpdGlvbnMsIG5vcm1hbHMsIHV2cywgaW5kaWNlcyB9ID0gY3JlYXRlU3BoZXJlKHsgcmFkaXVzOiB0aGlzLnJhZGl1cyB9KTtcclxuXHRcdC8vIHRoaXMucG9zaXRpb25zID0gcG9zaXRpb25zO1xyXG5cdFx0Ly8gdGhpcy5ub3JtYWxzID0gbm9ybWFscztcclxuXHRcdC8vIHRoaXMudXZzID0gdXZzO1xyXG5cdFx0Ly8gdGhpcy5pbmRpY2VzID0gaW5kaWNlcztcclxuXHRcdHRoaXMuY29tcHV0ZUJvdW5kaW5nU3BoZXJlKHBvc2l0aW9ucyk7XHJcblx0XHR0aGlzLnNldEF0dHJpYnV0ZShuZXcgRmxvYXQzMkF0dHJpYnV0ZShcInBvc2l0aW9uXCIsIHBvc2l0aW9ucywgMykpO1xyXG5cdFx0dGhpcy5zZXRBdHRyaWJ1dGUobmV3IEZsb2F0MzJBdHRyaWJ1dGUoXCJub3JtYWxcIiwgbm9ybWFscywgMykpO1xyXG5cdFx0dGhpcy5zZXRBdHRyaWJ1dGUobmV3IEZsb2F0MzJBdHRyaWJ1dGUoXCJ1dlwiLCB1dnMsIDIpKTtcclxuXHJcblx0XHR0aGlzLnNldEluZGljZShpbmRpY2VzKTtcclxuXHRcdHRoaXMuY291bnQgPSBpbmRpY2VzLmxlbmd0aDtcclxuXHR9XHJcbn1cclxuIiwiaW1wb3J0IHsgRmxvYXQzMkF0dHJpYnV0ZSB9IGZyb20gXCIuLi9yZW5kZXIvQXR0cmlidXRlXCI7XG5pbXBvcnQgeyBjcmVhdGVCb3ggfSBmcm9tIFwiLi4vdXRpbHMvR2VvbWV0cnlVdGlsc1wiO1xuaW1wb3J0IEdlb21ldHJ5IGZyb20gXCIuL0dlb21ldHJ5XCI7XG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCb3hHZW9tZXRyeSBleHRlbmRzIEdlb21ldHJ5IHtcblx0Y29uc3RydWN0b3IocHVibGljIHdpZHRoOiBudW1iZXIgPSAxMCwgcHVibGljIGhlaWdodDogbnVtYmVyID0gMTAsIHB1YmxpYyBkZXB0aDogbnVtYmVyID0gMTApIHtcblx0XHRzdXBlcih7XG5cdFx0XHR0eXBlOiBcImJveEdlb21ldHJ5XCJcblx0XHR9KTtcblx0XHR0aGlzLmRlZmluZXMgPSB7XG5cdFx0XHRIQVNfTk9STUFMOiB0cnVlXG5cdFx0fTtcblx0XHR0aGlzLmluaXQoKTtcblx0fVxuXHRwcml2YXRlIGluaXQoKSB7XG5cdFx0Ly8gZ2VuZXJhdGUgcG9zIHV2IG5vcm1hbCBzbyBvblxuXHRcdGNvbnN0IHsgcG9zaXRpb25zLCBub3JtYWxzLCB1dnMgfSA9IGNyZWF0ZUJveCh7XG5cdFx0XHRkaW1lbnNpb25zOiBbdGhpcy5kZXB0aCwgdGhpcy53aWR0aCwgdGhpcy5oZWlnaHRdXG5cdFx0fSk7XG5cdFx0dGhpcy5jb21wdXRlQm91bmRpbmdTcGhlcmUocG9zaXRpb25zKTtcblx0XHR0aGlzLnNldEF0dHJpYnV0ZShuZXcgRmxvYXQzMkF0dHJpYnV0ZShcInBvc2l0aW9uXCIsIHBvc2l0aW9ucywgMykpO1xuXHRcdHRoaXMuc2V0QXR0cmlidXRlKG5ldyBGbG9hdDMyQXR0cmlidXRlKFwibm9ybWFsXCIsIG5vcm1hbHMsIDMpKTtcblx0XHR0aGlzLnNldEF0dHJpYnV0ZShuZXcgRmxvYXQzMkF0dHJpYnV0ZShcInV2XCIsIHV2cywgMikpO1xuXHRcdHRoaXMuY291bnQgPSAzNjtcblx0fVxufVxuIiwiaW1wb3J0IFZlY3RvcjMgZnJvbSBcIi4uL21hdGgvVmVjdG9yM1wiO1xuaW1wb3J0IHsgRmxvYXQzMkF0dHJpYnV0ZSB9IGZyb20gXCIuLi9yZW5kZXIvQXR0cmlidXRlXCI7XG5pbXBvcnQgR2VvbWV0cnkgZnJvbSBcIi4vR2VvbWV0cnlcIjtcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRvcnVzS25vdEdlb21ldHJ5IGV4dGVuZHMgR2VvbWV0cnkge1xuXHRyYWRpdXM6IG51bWJlcjtcblx0dHViZTogbnVtYmVyO1xuXHR0dWJ1bGFyU2VnbWVudHM6IG51bWJlcjtcblx0cmFkaWFsU2VnbWVudHM6IG51bWJlcjtcblx0cDogbnVtYmVyO1xuXHRxOiBudW1iZXI7XG5cdGNvbnN0cnVjdG9yKHJhZGl1cyA9IDEsIHR1YmUgPSAwLjQsIHR1YnVsYXJTZWdtZW50cyA9IDY0LCByYWRpYWxTZWdtZW50cyA9IDgsIHAgPSAyLCBxID0gMykge1xuXHRcdHN1cGVyKHtcblx0XHRcdHR5cGU6IFwidG9ydXNLbm90R2VvbWV0cnlcIlxuXHRcdH0pO1xuXHRcdHRoaXMuZGVmaW5lcyA9IHtcblx0XHRcdEhBU19OT1JNQUw6IHRydWVcblx0XHR9O1xuXHRcdHRoaXMucmFkaXVzID0gcmFkaXVzO1xuXHRcdHRoaXMudHViZSA9IHR1YmU7XG5cdFx0dGhpcy50dWJ1bGFyU2VnbWVudHMgPSB0dWJ1bGFyU2VnbWVudHM7XG5cdFx0dGhpcy5yYWRpYWxTZWdtZW50cyA9IHJhZGlhbFNlZ21lbnRzO1xuXHRcdHRoaXMucCA9IHA7XG5cdFx0dGhpcy5xID0gcTtcblx0XHR0aGlzLmluaXQoKTtcblx0fVxuXHRwcml2YXRlIGluaXQoKSB7XG5cdFx0Y29uc3QgeyBub3JtYWxzLCB1dnMsIHBvc2l0aW9ucywgaW5kaWNlcyB9ID0gdGhpcy5jcmVhdGVHZW9tZXRyeSgpO1xuXHRcdHRoaXMuY29tcHV0ZUJvdW5kaW5nU3BoZXJlKHBvc2l0aW9ucyk7XG5cdFx0dGhpcy5zZXRBdHRyaWJ1dGUobmV3IEZsb2F0MzJBdHRyaWJ1dGUoXCJwb3NpdGlvblwiLCBwb3NpdGlvbnMsIDMpKTtcblx0XHR0aGlzLnNldEF0dHJpYnV0ZShuZXcgRmxvYXQzMkF0dHJpYnV0ZShcIm5vcm1hbFwiLCBub3JtYWxzLCAzKSk7XG5cdFx0dGhpcy5zZXRBdHRyaWJ1dGUobmV3IEZsb2F0MzJBdHRyaWJ1dGUoXCJ1dlwiLCB1dnMsIDIpKTtcblx0XHR0aGlzLnNldEluZGljZShpbmRpY2VzKTtcblx0XHR0aGlzLmNvdW50ID0gaW5kaWNlcy5sZW5ndGg7XG5cdH1cblx0cHJpdmF0ZSBjcmVhdGVHZW9tZXRyeSgpIHtcblx0XHRjb25zdCBwb3NpdGlvbnMgPSBbXSxcblx0XHRcdG5vcm1hbHMgPSBbXSxcblx0XHRcdHV2cyA9IFtdLFxuXHRcdFx0aW5kaWNlcyA9IFtdO1xuXHRcdGNvbnN0IHR1YnVsYXJTZWdtZW50cyA9IE1hdGguZmxvb3IodGhpcy50dWJ1bGFyU2VnbWVudHMpO1xuXHRcdGNvbnN0IHJhZGlhbFNlZ21lbnRzID0gTWF0aC5mbG9vcih0aGlzLnJhZGlhbFNlZ21lbnRzKTtcblx0XHQvLyBoZWxwZXIgdmFyaWFibGVzXG5cblx0XHRjb25zdCB2ZXJ0ZXggPSBuZXcgVmVjdG9yMygpO1xuXHRcdGNvbnN0IG5vcm1hbCA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHRjb25zdCBQMSA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0Y29uc3QgUDIgPSBuZXcgVmVjdG9yMygpO1xuXG5cdFx0Y29uc3QgQiA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0Y29uc3QgVCA9IG5ldyBWZWN0b3IzKCk7XG5cdFx0Y29uc3QgTiA9IG5ldyBWZWN0b3IzKCk7XG5cblx0XHQvLyBnZW5lcmF0ZSB2ZXJ0aWNlcywgbm9ybWFscyBhbmQgdXZzXG5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8PSB0dWJ1bGFyU2VnbWVudHM7ICsraSkge1xuXHRcdFx0Ly8gdGhlIHJhZGlhbiBcInVcIiBpcyB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgcG9zaXRpb24gb24gdGhlIHRvcnVzIGN1cnZlIG9mIHRoZSBjdXJyZW50IHR1YnVsYXIgc2VnbWVudFxuXG5cdFx0XHRjb25zdCB1ID0gKGkgLyB0dWJ1bGFyU2VnbWVudHMpICogdGhpcy5wICogTWF0aC5QSSAqIDI7XG5cblx0XHRcdC8vIG5vdyB3ZSBjYWxjdWxhdGUgdHdvIHBvaW50cy4gUDEgaXMgb3VyIGN1cnJlbnQgcG9zaXRpb24gb24gdGhlIGN1cnZlLCBQMiBpcyBhIGxpdHRsZSBmYXJ0aGVyIGFoZWFkLlxuXHRcdFx0Ly8gdGhlc2UgcG9pbnRzIGFyZSB1c2VkIHRvIGNyZWF0ZSBhIHNwZWNpYWwgXCJjb29yZGluYXRlIHNwYWNlXCIsIHdoaWNoIGlzIG5lY2Vzc2FyeSB0byBjYWxjdWxhdGUgdGhlIGNvcnJlY3QgdmVydGV4IHBvc2l0aW9uc1xuXG5cdFx0XHRjYWxjdWxhdGVQb3NpdGlvbk9uQ3VydmUodSwgdGhpcy5wLCB0aGlzLnEsIHRoaXMucmFkaXVzLCBQMSk7XG5cdFx0XHRjYWxjdWxhdGVQb3NpdGlvbk9uQ3VydmUodSArIDAuMDEsIHRoaXMucCwgdGhpcy5xLCB0aGlzLnJhZGl1cywgUDIpO1xuXG5cdFx0XHQvLyBjYWxjdWxhdGUgb3J0aG9ub3JtYWwgYmFzaXNcblxuXHRcdFx0VmVjdG9yMy5zdWJ0cmFjdChQMiwgUDEsIFQpO1xuXHRcdFx0Ly8gVC5zdWJWZWN0b3JzKCBQMiwgUDEgKTtcblx0XHRcdFZlY3RvcjMuYWRkKFAyLCBQMSwgTik7XG5cdFx0XHQvLyBOLmFkZFZlY3RvcnMoIFAyLCBQMSApO1xuXHRcdFx0VmVjdG9yMy5jcm9zcyhULCBOLCBCKTtcblx0XHRcdC8vIEIuY3Jvc3NWZWN0b3JzKCBULCBOICk7XG5cdFx0XHRWZWN0b3IzLmNyb3NzKEIsIFQsIE4pO1xuXHRcdFx0Ly8gTi5jcm9zc1ZlY3RvcnMoIEIsIFQgKTtcblxuXHRcdFx0Ly8gbm9ybWFsaXplIEIsIE4uIFQgY2FuIGJlIGlnbm9yZWQsIHdlIGRvbid0IHVzZSBpdFxuXG5cdFx0XHRCLm5vcm1hbGl6ZSgpO1xuXHRcdFx0Ti5ub3JtYWxpemUoKTtcblxuXHRcdFx0Zm9yIChsZXQgaiA9IDA7IGogPD0gcmFkaWFsU2VnbWVudHM7ICsraikge1xuXHRcdFx0XHQvLyBub3cgY2FsY3VsYXRlIHRoZSB2ZXJ0aWNlcy4gdGhleSBhcmUgbm90aGluZyBtb3JlIHRoYW4gYW4gZXh0cnVzaW9uIG9mIHRoZSB0b3J1cyBjdXJ2ZS5cblx0XHRcdFx0Ly8gYmVjYXVzZSB3ZSBleHRydWRlIGEgc2hhcGUgaW4gdGhlIHh5LXBsYW5lLCB0aGVyZSBpcyBubyBuZWVkIHRvIGNhbGN1bGF0ZSBhIHotdmFsdWUuXG5cblx0XHRcdFx0Y29uc3QgdiA9IChqIC8gcmFkaWFsU2VnbWVudHMpICogTWF0aC5QSSAqIDI7XG5cdFx0XHRcdGNvbnN0IGN4ID0gLXRoaXMudHViZSAqIE1hdGguY29zKHYpO1xuXHRcdFx0XHRjb25zdCBjeSA9IHRoaXMudHViZSAqIE1hdGguc2luKHYpO1xuXG5cdFx0XHRcdC8vIG5vdyBjYWxjdWxhdGUgdGhlIGZpbmFsIHZlcnRleCBwb3NpdGlvbi5cblx0XHRcdFx0Ly8gZmlyc3Qgd2Ugb3JpZW50IHRoZSBleHRydXNpb24gd2l0aCBvdXIgYmFzaXMgdmVjdG9ycywgdGhlbiB3ZSBhZGQgaXQgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gb24gdGhlIGN1cnZlXG5cblx0XHRcdFx0dmVydGV4LnggPSBQMS54ICsgKGN4ICogTi54ICsgY3kgKiBCLngpO1xuXHRcdFx0XHR2ZXJ0ZXgueSA9IFAxLnkgKyAoY3ggKiBOLnkgKyBjeSAqIEIueSk7XG5cdFx0XHRcdHZlcnRleC56ID0gUDEueiArIChjeCAqIE4ueiArIGN5ICogQi56KTtcblxuXHRcdFx0XHRwb3NpdGlvbnMucHVzaCh2ZXJ0ZXgueCwgdmVydGV4LnksIHZlcnRleC56KTtcblxuXHRcdFx0XHQvLyBub3JtYWwgKFAxIGlzIGFsd2F5cyB0aGUgY2VudGVyL29yaWdpbiBvZiB0aGUgZXh0cnVzaW9uLCB0aHVzIHdlIGNhbiB1c2UgaXQgdG8gY2FsY3VsYXRlIHRoZSBub3JtYWwpXG5cdFx0XHRcdFZlY3RvcjMuc3VidHJhY3QodmVydGV4LCBQMSwgbm9ybWFsKTtcblx0XHRcdFx0bm9ybWFsLm5vcm1hbGl6ZSgpO1xuXG5cdFx0XHRcdG5vcm1hbHMucHVzaChub3JtYWwueCwgbm9ybWFsLnksIG5vcm1hbC56KTtcblxuXHRcdFx0XHQvLyB1dlxuXG5cdFx0XHRcdHV2cy5wdXNoKGkgLyB0dWJ1bGFyU2VnbWVudHMpO1xuXHRcdFx0XHR1dnMucHVzaChqIC8gcmFkaWFsU2VnbWVudHMpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIGdlbmVyYXRlIGluZGljZXNcblxuXHRcdGZvciAobGV0IGogPSAxOyBqIDw9IHR1YnVsYXJTZWdtZW50czsgaisrKSB7XG5cdFx0XHRmb3IgKGxldCBpID0gMTsgaSA8PSByYWRpYWxTZWdtZW50czsgaSsrKSB7XG5cdFx0XHRcdC8vIGluZGljZXNcblxuXHRcdFx0XHRjb25zdCBhID0gKHJhZGlhbFNlZ21lbnRzICsgMSkgKiAoaiAtIDEpICsgKGkgLSAxKTtcblx0XHRcdFx0Y29uc3QgYiA9IChyYWRpYWxTZWdtZW50cyArIDEpICogaiArIChpIC0gMSk7XG5cdFx0XHRcdGNvbnN0IGMgPSAocmFkaWFsU2VnbWVudHMgKyAxKSAqIGogKyBpO1xuXHRcdFx0XHRjb25zdCBkID0gKHJhZGlhbFNlZ21lbnRzICsgMSkgKiAoaiAtIDEpICsgaTtcblxuXHRcdFx0XHQvLyBmYWNlc1xuXG5cdFx0XHRcdGluZGljZXMucHVzaChhLCBiLCBkKTtcblx0XHRcdFx0aW5kaWNlcy5wdXNoKGIsIGMsIGQpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4ge1xuXHRcdFx0bm9ybWFscyxcblx0XHRcdHV2cyxcblx0XHRcdHBvc2l0aW9ucyxcblx0XHRcdGluZGljZXNcblx0XHR9O1xuXHR9XG59XG5mdW5jdGlvbiBjYWxjdWxhdGVQb3NpdGlvbk9uQ3VydmUodSwgcCwgcSwgcmFkaXVzLCBwb3NpdGlvbikge1xuXHRjb25zdCBjdSA9IE1hdGguY29zKHUpO1xuXHRjb25zdCBzdSA9IE1hdGguc2luKHUpO1xuXHRjb25zdCBxdU92ZXJQID0gKHEgLyBwKSAqIHU7XG5cdGNvbnN0IGNzID0gTWF0aC5jb3MocXVPdmVyUCk7XG5cblx0cG9zaXRpb24ueCA9IHJhZGl1cyAqICgyICsgY3MpICogMC41ICogY3U7XG5cdHBvc2l0aW9uLnkgPSByYWRpdXMgKiAoMiArIGNzKSAqIHN1ICogMC41O1xuXHRwb3NpdGlvbi56ID0gcmFkaXVzICogTWF0aC5zaW4ocXVPdmVyUCkgKiAwLjU7XG59XG4iLCJpbXBvcnQgeyBGcmFtZVN0YXRlIH0gZnJvbSBcIi4uL2NvcmUvRnJhbWVTdGF0ZVwiO1xuaW1wb3J0IHRleHR1cmVDYWNoZSBmcm9tIFwiLi4vY29yZS9UZXh0dXJlQ2FjaGVcIjtcbmltcG9ydCB7IFVuaWZvcm1FbnVtIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcbmltcG9ydCBDb2xvciBmcm9tIFwiLi4vbWF0aC9Db2xvclwiO1xuaW1wb3J0IHsgTWVzaCB9IGZyb20gXCIuLi9tZXNoL01lc2hcIjtcbmltcG9ydCBTYW1wbGVyIGZyb20gXCIuLi9yZW5kZXIvU2FtcGxlclwiO1xuaW1wb3J0IFRleHR1cmUgZnJvbSBcIi4uL3JlbmRlci9UZXh0dXJlXCI7XG5pbXBvcnQgVW5pZm9ybUJ1ZmZlciBmcm9tIFwiLi4vcmVuZGVyL1VuaWZvcm1CdWZmZXJcIjtcbmltcG9ydCB7IFNoYWRlclNvdXJjZSB9IGZyb20gXCIuLi9zaGFkZXIvU2hhZGVyU291cmNlXCI7XG5pbXBvcnQgeyBNYXRlcmlhbCB9IGZyb20gXCIuL01hdGVyaWFsXCI7XG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCbGlublBob25nTWF0ZXJpYWwgZXh0ZW5kcyBNYXRlcmlhbCB7XG5cdHB1YmxpYyBzcGVjdWxhcjogQ29sb3I7XG5cdHB1YmxpYyBzaGluaW5lc3M6IG51bWJlcjtcblx0cHVibGljIG5vcm1hbFRleHR1cmU6IFRleHR1cmU7XG5cdHB1YmxpYyBub3JtYWxTYW1wbGVyOiBTYW1wbGVyO1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXHRcdHRoaXMudHlwZSA9IFwicGhvbmdcIjtcblx0XHR0aGlzLmNvbG9yID0gbmV3IENvbG9yKDEuMCwgMC4wLCAwLjApO1xuXHRcdHRoaXMuc2hhZGVyU291cmNlID0gbmV3IFNoYWRlclNvdXJjZSh7XG5cdFx0XHRzaGFkZXJJZDogdGhpcy50eXBlLFxuXHRcdFx0ZGVmaW5lczoge1xuXHRcdFx0XHRtYXRlcmlhbFBob25nOiB0cnVlXG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0dGhpcy5saWdodCA9IHRydWU7XG5cdFx0dGhpcy5zcGVjdWxhciA9IG5ldyBDb2xvcigxLjAsIDEuMCwgMS4wKTtcblx0XHR0aGlzLnNoaW5pbmVzcyA9IDMwLjA7XG5cdFx0dGhpcy5iYXNlVGV4dHVyZSA9IHVuZGVmaW5lZDtcblx0XHR0aGlzLmJhc2VTYW1wbGVyID0gdW5kZWZpbmVkO1xuXHR9XG5cdHVwZGF0ZShmcmFtZVN0YXRlPzogRnJhbWVTdGF0ZSwgbWVzaD86IE1lc2gpIHtcblx0XHRpZiAoIXRoaXMuc2hhZGVyRGF0YSB8fCB0aGlzLmRpcnR5KSB0aGlzLmNyZWF0ZVNoYWRlckRhdGEobWVzaCk7XG5cdH1cblx0cHJvdGVjdGVkIGNyZWF0ZVNoYWRlckRhdGEobWVzaD86IE1lc2gpIHtcblx0XHRzdXBlci5jcmVhdGVTaGFkZXJEYXRhKCk7XG5cdFx0Y29uc3QgdW5pZm9ybUJ1ZmZlciA9IG5ldyBVbmlmb3JtQnVmZmVyKHsgbGFiZWw6IFwicGhvbmdcIiB9KTtcblx0XHR1bmlmb3JtQnVmZmVyLnNldFVuaWZvcm0oXG5cdFx0XHRcIm1vZGVsTWF0cml4XCIsXG5cdFx0XHQoKSA9PiB7XG5cdFx0XHRcdHJldHVybiBtZXNoLm1vZGVsTWF0cml4O1xuXHRcdFx0fSxcblx0XHRcdFVuaWZvcm1FbnVtLk1hdDRcblx0XHQpO1xuXHRcdHVuaWZvcm1CdWZmZXIuc2V0VW5pZm9ybShcImNvbG9yXCIsIHRoaXMsIFVuaWZvcm1FbnVtLkNvbG9yKTtcblx0XHR1bmlmb3JtQnVmZmVyLnNldFVuaWZvcm0oXCJvcGFjaXR5XCIsIHRoaXMsIFVuaWZvcm1FbnVtLkZsb2F0KTtcblx0XHR1bmlmb3JtQnVmZmVyLnNldFVuaWZvcm0oXG5cdFx0XHRcIm5vcm1hbE10cml4XCIsXG5cdFx0XHQoKSA9PiB7XG5cdFx0XHRcdHJldHVybiBtZXNoLm5vcm1hbE1hdHJpeDtcblx0XHRcdH0sXG5cdFx0XHRVbmlmb3JtRW51bS5NYXQ0XG5cdFx0KTtcblx0XHR1bmlmb3JtQnVmZmVyLnNldFVuaWZvcm0oXCJlbWlzc2l2ZVwiLCB0aGlzLCBVbmlmb3JtRW51bS5Db2xvcik7XG5cdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFwic2hpbmluZXNzXCIsIHRoaXMsIFVuaWZvcm1FbnVtLkZsb2F0KTtcblx0XHR1bmlmb3JtQnVmZmVyLnNldFVuaWZvcm0oXCJzcGVjdWxhclwiLCB0aGlzLCBVbmlmb3JtRW51bS5Db2xvcik7XG5cdFx0dGhpcy5zaGFkZXJEYXRhLnNldFVuaWZvcm1CdWZmZXIoXCJwaG9uZ1wiLCB1bmlmb3JtQnVmZmVyKTtcblx0XHRpZiAodGhpcy5iYXNlVGV4dHVyZSkge1xuXHRcdFx0dGhpcy5zaGFkZXJEYXRhLnNldERlZmluZShcIlVTRV9DT0xPUlRFWFRVUkVcIiwgdHJ1ZSk7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0VGV4dHVyZShcImJhc2VDb2xvclRleHR1cmVcIiwgdGhpcy5iYXNlVGV4dHVyZSk7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0U2FtcGxlcihcImJhc2VDb2xvclNhbXBsZXJcIiwgdGhpcy5iYXNlU2FtcGxlciB8fCB0ZXh0dXJlQ2FjaGUuZGVmYXVsdFNhbXBsZXIpO1xuXHRcdH1cblx0XHRpZiAodGhpcy5ub3JtYWxUZXh0dXJlKSB7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0RGVmaW5lKFwiVVNFX05PUk1BTFRFWFRVUkVcIiwgdHJ1ZSk7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0VGV4dHVyZShcIm5vcm1hbFRleHR1cmVcIiwgdGhpcy5ub3JtYWxUZXh0dXJlKTtcblx0XHRcdHRoaXMuc2hhZGVyRGF0YS5zZXRTYW1wbGVyKFwibm9ybWFsU2FtcGxlclwiLCB0aGlzLm5vcm1hbFNhbXBsZXIgfHwgdGV4dHVyZUNhY2hlLmRlZmF1bHRTYW1wbGVyKTtcblx0XHR9XG5cdH1cblx0ZGVzdHJveSgpIHtcblx0XHR0aGlzPy5iYXNlVGV4dHVyZT8uZGVzdHJveSgpO1xuXHRcdHN1cGVyLmRlc3Ryb3koKTtcblx0fVxufVxuIiwiaW1wb3J0IHsgRnJhbWVTdGF0ZSB9IGZyb20gXCIuLi9jb3JlL0ZyYW1lU3RhdGVcIjtcbmltcG9ydCB0ZXh0dXJlQ2FjaGUgZnJvbSBcIi4uL2NvcmUvVGV4dHVyZUNhY2hlXCI7XG5pbXBvcnQgeyBDdWxsTW9kZSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVUNvbnN0YW50XCI7XG5pbXBvcnQgeyBVbmlmb3JtRW51bSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XG5pbXBvcnQgVmVjdG9yMiBmcm9tIFwiLi4vbWF0aC9WZWN0b3IyXCI7XG5pbXBvcnQgeyBNZXNoIH0gZnJvbSBcIi4uL21lc2gvTWVzaFwiO1xuaW1wb3J0IFNhbXBsZXIgZnJvbSBcIi4uL3JlbmRlci9TYW1wbGVyXCI7XG5pbXBvcnQgVGV4dHVyZSBmcm9tIFwiLi4vcmVuZGVyL1RleHR1cmVcIjtcbmltcG9ydCBVbmlmb3JtQnVmZmVyIGZyb20gXCIuLi9yZW5kZXIvVW5pZm9ybUJ1ZmZlclwiO1xuaW1wb3J0IHsgU2hhZGVyU291cmNlIH0gZnJvbSBcIi4uL3NoYWRlci9TaGFkZXJTb3VyY2VcIjtcbmltcG9ydCB7IE1hdGVyaWFsIH0gZnJvbSBcIi4vTWF0ZXJpYWxcIjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUGJyTWF0ZXJpYWwgZXh0ZW5kcyBNYXRlcmlhbCB7XG5cdHB1YmxpYyBzcGVjdWxhckVudlRleHR1cmU6IFRleHR1cmU7XG5cblx0cHVibGljIHNwZWN1bGFyRW52U2FtcGxlcjogU2FtcGxlcjtcblxuXHRwdWJsaWMgZW1pc3NpdmVUZXh0dXJlOiBUZXh0dXJlO1xuXG5cdHB1YmxpYyBlbWlzc2l2ZVNhbXBsZXI6IFNhbXBsZXI7XG5cblx0cHVibGljIG5vcm1hbFRleHR1cmU6IFRleHR1cmU7XG5cblx0cHVibGljIG5vcm1hbFNhbXBsZXI6IFNhbXBsZXI7XG5cblx0cHVibGljIGFvVGV4dHVyZTogVGV4dHVyZTtcblxuXHRwdWJsaWMgYW9TYW1wbGVyOiBTYW1wbGVyO1xuXG5cdHB1YmxpYyBtZXRhbG5lc3NSb3VnaG5lc3NUZXh0dXJlOiBUZXh0dXJlO1xuXG5cdHB1YmxpYyBtZXRhbG5lc3NSb3VnaG5lc3NTYW1wbGVyOiBTYW1wbGVyO1xuXG5cdHByaXZhdGUgX3JvdWdobmVzczogbnVtYmVyO1xuXG5cdHByaXZhdGUgX21ldGFsbmVzczogbnVtYmVyO1xuXG5cdHByaXZhdGUgX2FvVGV4dHVyZUludGVuc2l0eTogbnVtYmVyO1xuXG5cdHByaXZhdGUgX25vcm1hbFNjYWxlOiBWZWN0b3IyO1xuXG5cdHByaXZhdGUgX0lCTFJlbmRlcjogYm9vbGVhbjtcblxuXHRwdWJsaWMgZ2V0IHJvdWdobmVzcygpOiBudW1iZXIge1xuXHRcdHJldHVybiB0aGlzLl9yb3VnaG5lc3M7XG5cdH1cblx0cHVibGljIHNldCByb3VnaG5lc3ModmFsdWUpIHtcblx0XHR0aGlzLl9yb3VnaG5lc3MgPSB2YWx1ZTtcblx0fVxuXHRwdWJsaWMgZ2V0IG1ldGFsbmVzcygpOiBudW1iZXIge1xuXHRcdHJldHVybiB0aGlzLl9tZXRhbG5lc3M7XG5cdH1cblx0cHVibGljIHNldCBtZXRhbG5lc3ModjogbnVtYmVyKSB7XG5cdFx0dGhpcy5fbWV0YWxuZXNzID0gdjtcblx0fVxuXHRwdWJsaWMgZ2V0IGFvVGV4dHVyZUludGVuc2l0eSgpOiBudW1iZXIge1xuXHRcdHJldHVybiB0aGlzLl9hb1RleHR1cmVJbnRlbnNpdHk7XG5cdH1cblx0cHVibGljIHNldCBhb1RleHR1cmVJbnRlbnNpdHkodjogbnVtYmVyKSB7XG5cdFx0dGhpcy5fYW9UZXh0dXJlSW50ZW5zaXR5ID0gdjtcblx0fVxuXHRwdWJsaWMgZ2V0IG5vcm1hbFNjYWxlKCk6IFZlY3RvcjIge1xuXHRcdGlmICh0aGlzLnJlbmRlclN0YXRlICYmIHRoaXMucmVuZGVyU3RhdGUucHJpbWl0aXZlKSB7XG5cdFx0XHRpZiAodGhpcy5yZW5kZXJTdGF0ZS5wcmltaXRpdmUuY3VsbE1vZGUgPT0gQ3VsbE1vZGUuQmFjaykge1xuXHRcdFx0XHRyZXR1cm4gVmVjdG9yMi5uZWdhdGUodGhpcy5fbm9ybWFsU2NhbGUsIG5ldyBWZWN0b3IyKCkpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5fbm9ybWFsU2NhbGU7XG5cdH1cblx0cHVibGljIHNldCBub3JtYWxTY2FsZSh2OiBWZWN0b3IyKSB7XG5cdFx0dGhpcy5fbm9ybWFsU2NhbGUgPSB2O1xuXHR9XG5cdHB1YmxpYyBzZXQgSUJMUmVuZGVyKHZhbHVlKSB7XG5cdFx0dGhpcy5fSUJMUmVuZGVyID0gdmFsdWU7XG5cdFx0dGhpcy5zaGFkZXJTb3VyY2Uuc2V0RGVmaW5lcyh7XG5cdFx0XHRVU0VfSUJMOiB0aGlzLl9JQkxSZW5kZXJcblx0XHR9KTtcblx0XHR0aGlzLmRpcnR5ID0gdHJ1ZTtcblx0fVxuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXHRcdHRoaXMudHlwZSA9IFwicGJyX21hdFwiO1xuXG5cdFx0dGhpcy5fcm91Z2huZXNzID0gMC4xO1xuXG5cdFx0dGhpcy5fbWV0YWxuZXNzID0gMC4xO1xuXG5cdFx0dGhpcy5fYW9UZXh0dXJlSW50ZW5zaXR5ID0gMS4wO1xuXHRcdHRoaXMubGlnaHQgPSB0cnVlO1xuXHRcdHRoaXMuX25vcm1hbFNjYWxlID0gbmV3IFZlY3RvcjIoMSwgMSk7XG5cdFx0dGhpcy5fSUJMUmVuZGVyID0gdHJ1ZTtcblx0XHR0aGlzLnNoYWRlclNvdXJjZSA9IG5ldyBTaGFkZXJTb3VyY2Uoe1xuXHRcdFx0c2hhZGVySWQ6IHRoaXMudHlwZSxcblx0XHRcdGRlZmluZXM6IHtcblx0XHRcdFx0bWF0ZXJpYWxQYnI6IHRydWUsXG5cdFx0XHRcdFVTRV9JQkw6IHRoaXMuX0lCTFJlbmRlclxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cdHVwZGF0ZShmcmFtZVN0YXRlPzogRnJhbWVTdGF0ZSwgbWVzaD86IE1lc2gpIHtcblx0XHRpZiAoIXRleHR1cmVDYWNoZS5nZXRUZXh0dXJlKFwic3BlY3VsYXJcIikpIHJldHVybjtcblx0XHRpZiAoIXRoaXMuc2hhZGVyRGF0YSB8fCB0aGlzLmRpcnR5KSB7XG5cdFx0XHR0aGlzLmNyZWF0ZVNoYWRlckRhdGEobWVzaCk7XG5cdFx0fVxuXHR9XG5cdHByb3RlY3RlZCBjcmVhdGVTaGFkZXJEYXRhKG1lc2g/OiBNZXNoKSB7XG5cdFx0c3VwZXIuY3JlYXRlU2hhZGVyRGF0YSgpO1xuXHRcdGNvbnN0IHVuaWZvcm1CdWZmZXIgPSBuZXcgVW5pZm9ybUJ1ZmZlcih7IGxhYmVsOiBcInBiclwiIH0pO1xuXHRcdHVuaWZvcm1CdWZmZXIuc2V0VW5pZm9ybShcblx0XHRcdFwibW9kZWxNYXRyaXhcIixcblx0XHRcdCgpID0+IHtcblx0XHRcdFx0cmV0dXJuIG1lc2gubW9kZWxNYXRyaXg7XG5cdFx0XHR9LFxuXHRcdFx0VW5pZm9ybUVudW0uTWF0NFxuXHRcdCk7XG5cdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFwiY29sb3JcIiwgdGhpcywgVW5pZm9ybUVudW0uQ29sb3IpO1xuXHRcdHVuaWZvcm1CdWZmZXIuc2V0VW5pZm9ybShcIm9wYWNpdHlcIiwgdGhpcywgVW5pZm9ybUVudW0uRmxvYXQpO1xuXHRcdHVuaWZvcm1CdWZmZXIuc2V0VW5pZm9ybShcblx0XHRcdFwibm9ybWFsTXRyaXhcIixcblx0XHRcdCgpID0+IHtcblx0XHRcdFx0cmV0dXJuIG1lc2gubm9ybWFsTWF0cml4O1xuXHRcdFx0fSxcblx0XHRcdFVuaWZvcm1FbnVtLk1hdDRcblx0XHQpO1xuXHRcdHVuaWZvcm1CdWZmZXIuc2V0VW5pZm9ybShcImVtaXNzaXZlXCIsIHRoaXMsIFVuaWZvcm1FbnVtLkNvbG9yKTtcblx0XHR1bmlmb3JtQnVmZmVyLnNldFVuaWZvcm0oXCJtZXRhbG5lc3NcIiwgdGhpcywgVW5pZm9ybUVudW0uRmxvYXQpO1xuXHRcdHVuaWZvcm1CdWZmZXIuc2V0VW5pZm9ybShcInJvdWdobmVzc1wiLCB0aGlzLCBVbmlmb3JtRW51bS5GbG9hdCk7XG5cdFx0dGhpcy5zaGFkZXJEYXRhLnNldFVuaWZvcm1CdWZmZXIoXCJwYnJcIiwgdW5pZm9ybUJ1ZmZlcik7XG5cdFx0dGhpcy5zcGVjdWxhckVudlRleHR1cmUgPSB0ZXh0dXJlQ2FjaGUuZ2V0VGV4dHVyZShcInNwZWN1bGFyXCIpO1xuXHRcdGlmICh0aGlzLmJhc2VUZXh0dXJlKSB7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0RGVmaW5lKFwiVVNFX1RFWFRVUkVcIiwgdHJ1ZSk7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0VGV4dHVyZShcImJhc2VDb2xvclRleHR1cmVcIiwgdGhpcy5iYXNlVGV4dHVyZSk7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0U2FtcGxlcihcImJhc2VDb2xvclNhbXBsZXJcIiwgdGhpcy5iYXNlU2FtcGxlciB8fCB0ZXh0dXJlQ2FjaGUuZGVmYXVsdFNhbXBsZXIpO1xuXHRcdH1cblx0XHRpZiAodGhpcy5tZXRhbG5lc3NSb3VnaG5lc3NUZXh0dXJlKSB7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0RGVmaW5lKFwiVVNFX01FVEFMTkVTU1RFWFRVUkVcIiwgdHJ1ZSk7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0VGV4dHVyZShcIm1ldGFsbmVzc1JvdWdobmVzc1RleHR1cmVcIiwgdGhpcy5tZXRhbG5lc3NSb3VnaG5lc3NUZXh0dXJlKTtcblx0XHRcdHRoaXMuc2hhZGVyRGF0YS5zZXRTYW1wbGVyKFxuXHRcdFx0XHRcIm1ldGFsbmVzc1JvdWdobmVzc1NhbXBsZXJcIixcblx0XHRcdFx0dGhpcy5tZXRhbG5lc3NSb3VnaG5lc3NTYW1wbGVyIHx8IHRleHR1cmVDYWNoZS5kZWZhdWx0U2FtcGxlclxuXHRcdFx0KTtcblx0XHR9XG5cdFx0aWYgKHRoaXMubm9ybWFsVGV4dHVyZSkge1xuXHRcdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFwibm9ybWFsU2NhbGVcIiwgdGhpcywgVW5pZm9ybUVudW0uRmxvYXRWZWMyKTtcblx0XHRcdHRoaXMuc2hhZGVyRGF0YS5zZXREZWZpbmUoXCJVU0VfTk9STUFMVEVYVFVSRVwiLCB0cnVlKTtcblx0XHRcdHRoaXMuc2hhZGVyRGF0YS5zZXRUZXh0dXJlKFwibm9ybWFsVGV4dHVyZVwiLCB0aGlzLm5vcm1hbFRleHR1cmUpO1xuXHRcdFx0dGhpcy5zaGFkZXJEYXRhLnNldFNhbXBsZXIoXCJub3JtYWxTYW1wbGVyXCIsIHRoaXMubm9ybWFsU2FtcGxlciB8fCB0ZXh0dXJlQ2FjaGUuZGVmYXVsdFNhbXBsZXIpO1xuXHRcdH1cblx0XHRpZiAodGhpcy5hb1RleHR1cmUpIHtcblx0XHRcdHRoaXMuc2hhZGVyRGF0YS5zZXREZWZpbmUoXCJVU0VfQU9URVhUVVJFXCIsIHRydWUpO1xuXHRcdFx0dGhpcy5zaGFkZXJEYXRhLnNldFRleHR1cmUoXCJhb1RleHR1cmVcIiwgdGhpcy5hb1RleHR1cmUpO1xuXHRcdFx0dGhpcy5zaGFkZXJEYXRhLnNldFNhbXBsZXIoXCJhb1NhbXBsZXJcIiwgdGhpcy5hb1NhbXBsZXIgfHwgdGV4dHVyZUNhY2hlLmRlZmF1bHRTYW1wbGVyKTtcblx0XHRcdHVuaWZvcm1CdWZmZXIuc2V0VW5pZm9ybShcImFvVGV4dHVyZUludGVuc2l0eVwiLCB0aGlzLCBVbmlmb3JtRW51bS5GbG9hdCk7XG5cdFx0fVxuXHRcdGlmICh0aGlzLmVtaXNzaXZlVGV4dHVyZSkge1xuXHRcdFx0dGhpcy5zaGFkZXJEYXRhLnNldERlZmluZShcIlVTRV9FTUlTU0lWRVRFWFRVUkVcIiwgdHJ1ZSk7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0VGV4dHVyZShcImVtaXNzaXZlVGV4dHVyZVwiLCB0aGlzLmVtaXNzaXZlVGV4dHVyZSk7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0U2FtcGxlcihcImVtaXNzaXZlU2FtcGxlclwiLCB0aGlzLmVtaXNzaXZlU2FtcGxlciB8fCB0ZXh0dXJlQ2FjaGUuZGVmYXVsdFNhbXBsZXIpO1xuXHRcdH1cblx0XHRpZiAodGhpcy5zcGVjdWxhckVudlRleHR1cmUgJiYgdGhpcy5fSUJMUmVuZGVyKSB7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0VGV4dHVyZShcInNwZWN1bGFyRW52VGV4dHVyZVwiLCB0aGlzLnNwZWN1bGFyRW52VGV4dHVyZSk7XG5cdFx0XHR0aGlzLnNoYWRlckRhdGEuc2V0U2FtcGxlcihcInNwZWN1bGFyRW52U2FtcGxlclwiLCB0aGlzLnNwZWN1bGFyRW52U2FtcGxlciB8fCB0ZXh0dXJlQ2FjaGUuZGVmYXVsdFNhbXBsZXIpO1xuXHRcdH1cblx0fVxuXHRkZXN0cm95KCkge1xuXHRcdHRoaXM/LmFvVGV4dHVyZT8uZGVzdHJveSgpO1xuXHRcdHRoaXM/LmJhc2VUZXh0dXJlPy5kZXN0cm95KCk7XG5cdFx0dGhpcz8uZW1pc3NpdmVUZXh0dXJlPy5kZXN0cm95KCk7XG5cdFx0dGhpcz8ubm9ybWFsVGV4dHVyZT8uZGVzdHJveSgpO1xuXHRcdHRoaXMuc3BlY3VsYXJFbnZUZXh0dXJlID0gdW5kZWZpbmVkO1xuXHR9XG59XG4iLCJleHBvcnQgY2xhc3MgRXZlbnREaXNwYXRjaGVyIHtcclxuXHRwcml2YXRlIF9saXN0ZW5lcnM6IG9iamVjdDtcclxuXHRjb25zdHJ1Y3RvcigpIHtcclxuXHRcdHRoaXMuX2xpc3RlbmVycyA9IHt9O1xyXG5cdH1cclxuXHJcblx0YWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xyXG5cdFx0aWYgKHRoaXMuX2xpc3RlbmVycyA9PT0gdW5kZWZpbmVkKSB0aGlzLl9saXN0ZW5lcnMgPSB7fTtcclxuXHJcblx0XHRjb25zdCBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnM7XHJcblxyXG5cdFx0aWYgKGxpc3RlbmVyc1t0eXBlXSA9PT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdGxpc3RlbmVyc1t0eXBlXSA9IFtdO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChsaXN0ZW5lcnNbdHlwZV0uaW5kZXhPZihsaXN0ZW5lcikgPT09IC0xKSB7XHJcblx0XHRcdGxpc3RlbmVyc1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGhhc0V2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcclxuXHRcdGlmICh0aGlzLl9saXN0ZW5lcnMgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGZhbHNlO1xyXG5cclxuXHRcdGNvbnN0IGxpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVycztcclxuXHJcblx0XHRyZXR1cm4gbGlzdGVuZXJzW3R5cGVdICE9PSB1bmRlZmluZWQgJiYgbGlzdGVuZXJzW3R5cGVdLmluZGV4T2YobGlzdGVuZXIpICE9PSAtMTtcclxuXHR9XHJcblxyXG5cdHJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcclxuXHRcdGlmICh0aGlzLl9saXN0ZW5lcnMgPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xyXG5cclxuXHRcdGNvbnN0IGxpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVycztcclxuXHRcdGNvbnN0IGxpc3RlbmVyQXJyYXkgPSBsaXN0ZW5lcnNbdHlwZV07XHJcblxyXG5cdFx0aWYgKGxpc3RlbmVyQXJyYXkgIT09IHVuZGVmaW5lZCkge1xyXG5cdFx0XHRjb25zdCBpbmRleCA9IGxpc3RlbmVyQXJyYXkuaW5kZXhPZihsaXN0ZW5lcik7XHJcblxyXG5cdFx0XHRpZiAoaW5kZXggIT09IC0xKSB7XHJcblx0XHRcdFx0bGlzdGVuZXJBcnJheS5zcGxpY2UoaW5kZXgsIDEpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRkaXNwYXRjaEV2ZW50KGV2ZW50KSB7XHJcblx0XHRpZiAodGhpcy5fbGlzdGVuZXJzID09PSB1bmRlZmluZWQpIHJldHVybjtcclxuXHJcblx0XHRjb25zdCBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnM7XHJcblx0XHRjb25zdCBsaXN0ZW5lckFycmF5ID0gbGlzdGVuZXJzW2V2ZW50LnR5cGVdO1xyXG5cclxuXHRcdGlmIChsaXN0ZW5lckFycmF5ICE9PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0ZXZlbnQudGFyZ2V0ID0gdGhpcztcclxuXHJcblx0XHRcdGNvbnN0IGFycmF5ID0gbGlzdGVuZXJBcnJheS5zbGljZSgwKTtcclxuXHJcblx0XHRcdGZvciAobGV0IGkgPSAwLCBsID0gYXJyYXkubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XHJcblx0XHRcdFx0YXJyYXlbaV0uY2FsbCh0aGlzLCBldmVudCk7XHJcblx0XHRcdH1cclxuXHRcdFx0ZXZlbnQudGFyZ2V0ID0gbnVsbDtcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuIiwiaW1wb3J0IENhbWVyYSBmcm9tIFwiLi4vY2FtZXJhL0NhbWVyYVwiO1xuaW1wb3J0IHsgQ29tcHV0ZSB9IGZyb20gXCIuLi9jb21wdXRlL0NvbXB1dGVcIjtcbmltcG9ydCB7IE1hdGVyaWFsIH0gZnJvbSBcIi4uL21hdGVyaWFsL01hdGVyaWFsXCI7XG5pbXBvcnQgeyBNZXNoIH0gZnJvbSBcIi4uL21lc2gvTWVzaFwiO1xuaW1wb3J0IHsgQ29tcHV0ZUNvbW1hbmQgfSBmcm9tIFwiLi4vcmVuZGVyL0NvbXB1dGVDb21tYW5kXCI7XG5pbXBvcnQgQ29udGV4dCBmcm9tIFwiLi4vcmVuZGVyL0NvbnRleHRcIjtcbmltcG9ydCBEcmF3Q29tbWFuZCBmcm9tIFwiLi4vcmVuZGVyL0RyYXdDb21tYW5kXCI7XG5pbXBvcnQgTGlnaHRNYW5nZXIgZnJvbSBcIi4vTGlnaHRNYW5nZXJcIjtcbmltcG9ydCB7IENvbW1hbmRTdWJUeXBlIH0gZnJvbSBcIi4vV2ViR1BVQ29uc3RhbnRcIjtcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlbmRlclF1ZXVlIHtcblx0cHVibGljIHByZTogQXJyYXk8TWVzaD47XG5cdHB1YmxpYyBvcGFxdWU6IEFycmF5PE1lc2g+O1xuXHRwdWJsaWMgdHJhbnNwYXJlbnQ6IEFycmF5PE1lc2g+O1xuXHRwdWJsaWMgZGVidWdRdWV1ZTogQXJyYXk8TWVzaD47XG5cdHB1YmxpYyBjb21wdXRlczogQXJyYXk8Q29tcHV0ZT47XG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHRoaXMucHJlID0gW107XG5cdFx0dGhpcy5vcGFxdWUgPSBbXTtcblx0XHR0aGlzLnRyYW5zcGFyZW50ID0gW107XG5cdFx0dGhpcy5jb21wdXRlcyA9IFtdO1xuXHRcdHRoaXMuZGVidWdRdWV1ZSA9IFtdO1xuXHR9XG5cdHNvcnQoKSB7XG5cdFx0UmVuZGVyUXVldWUuc29ydCh0aGlzLm9wYXF1ZSwgMCwgdGhpcy5vcGFxdWUubGVuZ3RoLCBSZW5kZXJRdWV1ZS5fY29tcGFyZUZyb21OZWFyVG9GYXIpO1xuXHRcdFJlbmRlclF1ZXVlLnNvcnQodGhpcy50cmFuc3BhcmVudCwgMCwgdGhpcy50cmFuc3BhcmVudC5sZW5ndGgsIFJlbmRlclF1ZXVlLl9jb21wYXJlRnJvbUZhclRvTmVhcik7XG5cdH1cblx0b3BhcXVlUmVuZGVyKFxuXHRcdGNhbWVyYTogQ2FtZXJhLFxuXHRcdGNvbnRleHQ6IENvbnRleHQsXG5cdFx0cGFzc0VuY29kZXI/OiBHUFVSZW5kZXJQYXNzRW5jb2Rlcixcblx0XHRyZXBsYWNlTWF0ZXJpYWw/OiBNYXRlcmlhbCxcblx0XHRjb21tYW5kU3ViVHlwZT86IENvbW1hbmRTdWJUeXBlLFxuXHRcdGxpZ2h0TWFuZ2VyPzogTGlnaHRNYW5nZXJcblx0KSB7XG5cdFx0dGhpcy5vcGFxdWUubWFwKChtZXNoKSA9PiB7XG5cdFx0XHRpZiAoIW1lc2gucmVhZHkpIHJldHVybjtcblx0XHRcdG1lc2guYmVmb3JlUmVuZGVyKCk7XG5cdFx0XHRSZW5kZXJRdWV1ZS5leGN1dGVDb21tYW5kKFxuXHRcdFx0XHRtZXNoLmdldERyYXdDb21tYW5kKHJlcGxhY2VNYXRlcmlhbCwgY29tbWFuZFN1YlR5cGUsIGxpZ2h0TWFuZ2VyKSxcblx0XHRcdFx0Y29udGV4dCxcblx0XHRcdFx0cGFzc0VuY29kZXIsXG5cdFx0XHRcdGNhbWVyYVxuXHRcdFx0KTtcblx0XHRcdG1lc2guYWZ0ZXJSZW5kZXIoKTtcblx0XHR9KTtcblx0fVxuXHR0cmFuc3BhcmVudFJlbmRlcihcblx0XHRjYW1lcmE6IENhbWVyYSxcblx0XHRjb250ZXh0OiBDb250ZXh0LFxuXHRcdHBhc3NFbmNvZGVyPzogR1BVUmVuZGVyUGFzc0VuY29kZXIsXG5cdFx0cmVwbGFjZU1hdGVyaWFsPzogTWF0ZXJpYWwsXG5cdFx0Y29tbWFuZFN1YlR5cGU/OiBDb21tYW5kU3ViVHlwZSxcblx0XHRsaWdodE1hbmdlcj86IExpZ2h0TWFuZ2VyXG5cdCkge1xuXHRcdHRoaXMudHJhbnNwYXJlbnQubWFwKChtZXNoKSA9PiB7XG5cdFx0XHRpZiAoIW1lc2gucmVhZHkpIHJldHVybjtcblx0XHRcdG1lc2guYmVmb3JlUmVuZGVyKCk7XG5cdFx0XHRSZW5kZXJRdWV1ZS5leGN1dGVDb21tYW5kKFxuXHRcdFx0XHRtZXNoLmdldERyYXdDb21tYW5kKHJlcGxhY2VNYXRlcmlhbCwgY29tbWFuZFN1YlR5cGUsIGxpZ2h0TWFuZ2VyKSxcblx0XHRcdFx0Y29udGV4dCxcblx0XHRcdFx0cGFzc0VuY29kZXIsXG5cdFx0XHRcdGNhbWVyYVxuXHRcdFx0KTtcblx0XHRcdG1lc2guYWZ0ZXJSZW5kZXIoKTtcblx0XHR9KTtcblx0fVxuXHRjb21wdXRlUmVuZGVyKGNvbnRleHQ6IENvbnRleHQsIHBhc3NFbmNvZGVyPzogR1BVQ29tcHV0ZVBhc3NFbmNvZGVyKSB7XG5cdFx0dGhpcy5jb21wdXRlcy5tYXAoKGNvbXB1dGUpID0+IHtcblx0XHRcdFJlbmRlclF1ZXVlLmV4Y3V0ZUNvbXB1dGUoY29tcHV0ZS5nZXRDb21tYW5kKCksIGNvbnRleHQsIHBhc3NFbmNvZGVyKTtcblx0XHR9KTtcblx0fVxuXHRkZWJ1Z1F1ZXVlUmVuZGVyKFxuXHRcdGNhbWVyYTogQ2FtZXJhLFxuXHRcdGNvbnRleHQ6IENvbnRleHQsXG5cdFx0cGFzc0VuY29kZXI/OiBHUFVSZW5kZXJQYXNzRW5jb2Rlcixcblx0XHRyZXBsYWNlTWF0ZXJpYWw/OiBNYXRlcmlhbCxcblx0XHRjb21tYW5kU3ViVHlwZT86IENvbW1hbmRTdWJUeXBlXG5cdCkge1xuXHRcdHRoaXMuZGVidWdRdWV1ZS5tYXAoKG1lc2gpID0+IHtcblx0XHRcdGlmICghbWVzaC5yZWFkeSkgcmV0dXJuO1xuXHRcdFx0bWVzaC5iZWZvcmVSZW5kZXIoKTtcblx0XHRcdFJlbmRlclF1ZXVlLmV4Y3V0ZUNvbW1hbmQoXG5cdFx0XHRcdG1lc2guZ2V0RHJhd0NvbW1hbmQocmVwbGFjZU1hdGVyaWFsLCBjb21tYW5kU3ViVHlwZSksXG5cdFx0XHRcdGNvbnRleHQsXG5cdFx0XHRcdHBhc3NFbmNvZGVyLFxuXHRcdFx0XHRjYW1lcmFcblx0XHRcdCk7XG5cdFx0XHRtZXNoLmFmdGVyUmVuZGVyKCk7XG5cdFx0fSk7XG5cdH1cblx0cHJlUmVuZGVyKGNhbWVyYTogQ2FtZXJhLCBjb250ZXh0OiBDb250ZXh0LCBwYXNzRW5jb2Rlcj86IEdQVVJlbmRlclBhc3NFbmNvZGVyLCByZXBsYWNlTWF0ZXJpYWw/OiBNYXRlcmlhbCkge1xuXHRcdHRoaXMucHJlLm1hcCgobWVzaCkgPT4ge1xuXHRcdFx0aWYgKCFtZXNoLnJlYWR5KSByZXR1cm47XG5cdFx0XHRtZXNoLmJlZm9yZVJlbmRlcigpO1xuXHRcdFx0UmVuZGVyUXVldWUuZXhjdXRlQ29tbWFuZChtZXNoLmdldERyYXdDb21tYW5kKCksIGNvbnRleHQsIHBhc3NFbmNvZGVyLCBjYW1lcmEpO1xuXHRcdFx0bWVzaC5hZnRlclJlbmRlcigpO1xuXHRcdH0pO1xuXHR9XG5cdHN0YXRpYyBleGN1dGVDb21tYW5kKGNvbW1hbmQ6IERyYXdDb21tYW5kLCBjb250ZXh0PzogQ29udGV4dCwgcGFzc0VuY29kZXI/OiBHUFVSZW5kZXJQYXNzRW5jb2RlciwgY2FtZXJhPzogQ2FtZXJhKSB7XG5cdFx0Y29tbWFuZC5yZW5kZXIoe1xuXHRcdFx0ZGV2aWNlOiBjb250ZXh0LmRldmljZSxcblx0XHRcdHBhc3NFbmNvZGVyLFxuXHRcdFx0Y2FtZXJhLFxuXHRcdFx0dmlld1BvcnQ6IGNvbnRleHQ/LnZpZXdQb3J0LFxuXHRcdFx0c2Npc3NvclRlc3Q6IGNvbnRleHQ/LnNjaXNzb3JUZXN0XG5cdFx0fSk7XG5cdH1cblx0c3RhdGljIGV4Y3V0ZUNvbXB1dGUoY29tbWFuZDogQ29tcHV0ZUNvbW1hbmQsIGNvbnRleHQ/OiBDb250ZXh0LCBwYXNzRW5jb2Rlcj86IEdQVUNvbXB1dGVQYXNzRW5jb2Rlcikge1xuXHRcdGNvbW1hbmQucmVuZGVyKHsgZGV2aWNlOiBjb250ZXh0LmRldmljZSwgcGFzc0VuY29kZXIgfSk7XG5cdH1cblx0cmVzZXQoKSB7XG5cdFx0dGhpcy5wcmUgPSBbXTtcblx0XHR0aGlzLm9wYXF1ZSA9IFtdO1xuXHRcdHRoaXMudHJhbnNwYXJlbnQgPSBbXTtcblx0XHR0aGlzLmNvbXB1dGVzID0gW107XG5cdFx0dGhpcy5kZWJ1Z1F1ZXVlID0gW107XG5cdH1cblx0c3RhdGljIF9jb21wYXJlRnJvbU5lYXJUb0ZhcihhOiBNZXNoLCBiOiBNZXNoKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gYS5wcmlvcml0eSAtIGIucHJpb3JpdHkgfHwgYS5kaXN0YW5jZVRvQ2FtZXJhIC0gYi5kaXN0YW5jZVRvQ2FtZXJhO1xuXHR9XG5cblx0c3RhdGljIF9jb21wYXJlRnJvbUZhclRvTmVhcihhOiBNZXNoLCBiOiBNZXNoKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gYS5wcmlvcml0eSAtIGIucHJpb3JpdHkgfHwgYi5kaXN0YW5jZVRvQ2FtZXJhIC0gYS5kaXN0YW5jZVRvQ2FtZXJhO1xuXHR9XG5cdC8vIGFjY29yZGluZyB0byBjYW1lcmEgZGlzdGFuY2Vcblx0c3RhdGljIHNvcnQ8VD4oaW5zYXRuY2U6IFRbXSwgZnJvbTogbnVtYmVyLCB0bzogbnVtYmVyLCBjb21wYXJlRnVuYzogRnVuY3Rpb24pOiB2b2lkIHtcblx0XHRSZW5kZXJRdWV1ZS5fcXVpY2tTb3J0KGluc2F0bmNlLCBmcm9tLCB0bywgY29tcGFyZUZ1bmMpO1xuXHR9XG5cdC8vIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL29hc2lzLWVuZ2luZS9lbmdpbmUvYmxvYi9tYWluL3BhY2thZ2VzL2NvcmUvc3JjL1JlbmRlclBpcGVsaW5lL1JlbmRlclF1ZXVlLnRzXG5cdHByaXZhdGUgc3RhdGljIF9xdWlja1NvcnQ8VD4oYTogVFtdLCBmcm9tOiBudW1iZXIsIHRvOiBudW1iZXIsIGNvbXBhcmVGdW5jOiBGdW5jdGlvbik6IHZvaWQge1xuXHRcdHdoaWxlICh0cnVlKSB7XG5cdFx0XHQvLyBJbnNlcnRpb24gc29ydCBpcyBmYXN0ZXIgZm9yIHNob3J0IGFycmF5cy5cblx0XHRcdGlmICh0byAtIGZyb20gPD0gMTApIHtcblx0XHRcdFx0UmVuZGVyUXVldWUuX2luc2VydGlvblNvcnQoYSwgZnJvbSwgdG8sIGNvbXBhcmVGdW5jKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgdGhpcmRfaW5kZXggPSAoZnJvbSArIHRvKSA+PiAxO1xuXHRcdFx0Ly8gRmluZCBhIHBpdm90IGFzIHRoZSBtZWRpYW4gb2YgZmlyc3QsIGxhc3QgYW5kIG1pZGRsZSBlbGVtZW50LlxuXHRcdFx0bGV0IHYwID0gYVtmcm9tXTtcblx0XHRcdGxldCB2MSA9IGFbdG8gLSAxXTtcblx0XHRcdGxldCB2MiA9IGFbdGhpcmRfaW5kZXhdO1xuXHRcdFx0Y29uc3QgYzAxID0gY29tcGFyZUZ1bmModjAsIHYxKTtcblx0XHRcdGlmIChjMDEgPiAwKSB7XG5cdFx0XHRcdC8vIHYxIDwgdjAsIHNvIHN3YXAgdGhlbS5cblx0XHRcdFx0Y29uc3QgdG1wID0gdjA7XG5cdFx0XHRcdHYwID0gdjE7XG5cdFx0XHRcdHYxID0gdG1wO1xuXHRcdFx0fSAvLyB2MCA8PSB2MS5cblx0XHRcdGNvbnN0IGMwMiA9IGNvbXBhcmVGdW5jKHYwLCB2Mik7XG5cdFx0XHRpZiAoYzAyID49IDApIHtcblx0XHRcdFx0Ly8gdjIgPD0gdjAgPD0gdjEuXG5cdFx0XHRcdGNvbnN0IHRtcCA9IHYwO1xuXHRcdFx0XHR2MCA9IHYyO1xuXHRcdFx0XHR2MiA9IHYxO1xuXHRcdFx0XHR2MSA9IHRtcDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIHYwIDw9IHYxICYmIHYwIDwgdjJcblx0XHRcdFx0Y29uc3QgYzEyID0gY29tcGFyZUZ1bmModjEsIHYyKTtcblx0XHRcdFx0aWYgKGMxMiA+IDApIHtcblx0XHRcdFx0XHQvLyB2MCA8PSB2MiA8IHYxXG5cdFx0XHRcdFx0Y29uc3QgdG1wID0gdjE7XG5cdFx0XHRcdFx0djEgPSB2Mjtcblx0XHRcdFx0XHR2MiA9IHRtcDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Ly8gdjAgPD0gdjEgPD0gdjJcblx0XHRcdGFbZnJvbV0gPSB2MDtcblx0XHRcdGFbdG8gLSAxXSA9IHYyO1xuXHRcdFx0Y29uc3QgcGl2b3QgPSB2MTtcblx0XHRcdGxldCBsb3dfZW5kID0gZnJvbSArIDE7IC8vIFVwcGVyIGJvdW5kIG9mIGVsZW1lbnRzIGxvd2VyIHRoYW4gcGl2b3QuXG5cdFx0XHRsZXQgaGlnaF9zdGFydCA9IHRvIC0gMTsgLy8gTG93ZXIgYm91bmQgb2YgZWxlbWVudHMgZ3JlYXRlciB0aGFuIHBpdm90LlxuXHRcdFx0YVt0aGlyZF9pbmRleF0gPSBhW2xvd19lbmRdO1xuXHRcdFx0YVtsb3dfZW5kXSA9IHBpdm90O1xuXG5cdFx0XHQvLyBGcm9tIGxvd19lbmQgdG8gaSBhcmUgZWxlbWVudHMgZXF1YWwgdG8gcGl2b3QuXG5cdFx0XHQvLyBGcm9tIGkgdG8gaGlnaF9zdGFydCBhcmUgZWxlbWVudHMgdGhhdCBoYXZlbid0IGJlZW4gY29tcGFyZWQgeWV0LlxuXHRcdFx0cGFydGl0aW9uOiBmb3IgKGxldCBpID0gbG93X2VuZCArIDE7IGkgPCBoaWdoX3N0YXJ0OyBpKyspIHtcblx0XHRcdFx0bGV0IGVsZW1lbnQgPSBhW2ldO1xuXHRcdFx0XHRsZXQgb3JkZXIgPSBjb21wYXJlRnVuYyhlbGVtZW50LCBwaXZvdCk7XG5cdFx0XHRcdGlmIChvcmRlciA8IDApIHtcblx0XHRcdFx0XHRhW2ldID0gYVtsb3dfZW5kXTtcblx0XHRcdFx0XHRhW2xvd19lbmRdID0gZWxlbWVudDtcblx0XHRcdFx0XHRsb3dfZW5kKys7XG5cdFx0XHRcdH0gZWxzZSBpZiAob3JkZXIgPiAwKSB7XG5cdFx0XHRcdFx0ZG8ge1xuXHRcdFx0XHRcdFx0aGlnaF9zdGFydC0tO1xuXHRcdFx0XHRcdFx0aWYgKGhpZ2hfc3RhcnQgPT0gaSkgYnJlYWsgcGFydGl0aW9uO1xuXHRcdFx0XHRcdFx0Y29uc3QgdG9wX2VsZW0gPSBhW2hpZ2hfc3RhcnRdO1xuXHRcdFx0XHRcdFx0b3JkZXIgPSBjb21wYXJlRnVuYyh0b3BfZWxlbSwgcGl2b3QpO1xuXHRcdFx0XHRcdH0gd2hpbGUgKG9yZGVyID4gMCk7XG5cdFx0XHRcdFx0YVtpXSA9IGFbaGlnaF9zdGFydF07XG5cdFx0XHRcdFx0YVtoaWdoX3N0YXJ0XSA9IGVsZW1lbnQ7XG5cdFx0XHRcdFx0aWYgKG9yZGVyIDwgMCkge1xuXHRcdFx0XHRcdFx0ZWxlbWVudCA9IGFbaV07XG5cdFx0XHRcdFx0XHRhW2ldID0gYVtsb3dfZW5kXTtcblx0XHRcdFx0XHRcdGFbbG93X2VuZF0gPSBlbGVtZW50O1xuXHRcdFx0XHRcdFx0bG93X2VuZCsrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKHRvIC0gaGlnaF9zdGFydCA8IGxvd19lbmQgLSBmcm9tKSB7XG5cdFx0XHRcdHRoaXMuX3F1aWNrU29ydChhLCBoaWdoX3N0YXJ0LCB0bywgY29tcGFyZUZ1bmMpO1xuXHRcdFx0XHR0byA9IGxvd19lbmQ7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLl9xdWlja1NvcnQoYSwgZnJvbSwgbG93X2VuZCwgY29tcGFyZUZ1bmMpO1xuXHRcdFx0XHRmcm9tID0gaGlnaF9zdGFydDtcblx0XHRcdH1cblx0XHR9XG5cdH1cblx0cHJpdmF0ZSBzdGF0aWMgX2luc2VydGlvblNvcnQ8VD4oYTogVFtdLCBmcm9tOiBudW1iZXIsIHRvOiBudW1iZXIsIGNvbXBhcmVGdW5jOiBGdW5jdGlvbik6IHZvaWQge1xuXHRcdGZvciAobGV0IGkgPSBmcm9tICsgMTsgaSA8IHRvOyBpKyspIHtcblx0XHRcdGxldCBqO1xuXHRcdFx0Y29uc3QgZWxlbWVudCA9IGFbaV07XG5cdFx0XHRmb3IgKGogPSBpIC0gMTsgaiA+PSBmcm9tOyBqLS0pIHtcblx0XHRcdFx0Y29uc3QgdG1wID0gYVtqXTtcblx0XHRcdFx0Y29uc3Qgb3JkZXIgPSBjb21wYXJlRnVuYyh0bXAsIGVsZW1lbnQpO1xuXHRcdFx0XHRpZiAob3JkZXIgPiAwKSB7XG5cdFx0XHRcdFx0YVtqICsgMV0gPSB0bXA7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGFbaiArIDFdID0gZWxlbWVudDtcblx0XHR9XG5cdH1cbn1cbiIsImltcG9ydCB7IFNjZW5lIH0gZnJvbSBcIi4uL1NjZW5lXCI7XHJcbmltcG9ydCBDYW1lcmEgZnJvbSBcIi4uL2NhbWVyYS9DYW1lcmFcIjtcclxuaW1wb3J0IENvbG9yIGZyb20gXCIuLi9tYXRoL0NvbG9yXCI7XHJcbmltcG9ydCBQYXNzIGZyb20gXCIuLi9wYXNzL1Bhc3NcIjtcclxuaW1wb3J0IENvbnRleHQgZnJvbSBcIi4uL3JlbmRlci9Db250ZXh0XCI7XHJcbmltcG9ydCBUZXh0dXJlIGZyb20gXCIuLi9yZW5kZXIvVGV4dHVyZVwiO1xyXG5pbXBvcnQgY29tYmluZSBmcm9tIFwiLi4vdXRpbHMvY29tYmluZVwiO1xyXG5pbXBvcnQgQ3VsbGluZ1ZvbHVtZSBmcm9tIFwiLi9DdWxsaW5nVm9sdW1lXCI7XHJcbmltcG9ydCBMaWdodE1hbmdlciBmcm9tIFwiLi9MaWdodE1hbmdlclwiO1xyXG5pbXBvcnQgUmVuZGVyUXVldWUgZnJvbSBcIi4vUmVuZGVyUXVldWVcIjtcclxuXHJcbmludGVyZmFjZSBGcmFtZVN0YXRlT3B0aW9ucyB7XHJcblx0YmFja2dyb3VuZD86IEJhY2tncm91bmQ7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQmFja2dyb3VuZCB7XHJcblx0dmFsdWU6IENvbG9yIHwgVGV4dHVyZTtcclxuXHRvcGFjaXR5OiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBGcmFtZVN0YXRlIHtcclxuXHRwdWJsaWMgYmFja2dyb3VuZDogQmFja2dyb3VuZDtcclxuXHRwdWJsaWMgcGFzczogUGFzcztcclxuXHRwdWJsaWMgcmVuZGVyUXVldWU6IFJlbmRlclF1ZXVlO1xyXG5cdHB1YmxpYyBkcmF3Q2FsbG51bXM6IG51bWJlcjtcclxuXHRwdWJsaWMgZ2VvbWV0cnlNZW1vcnk6IG51bWJlcjtcclxuXHRwdWJsaWMgdGV4dHVyZU1lbW9yeTogbnVtYmVyO1xyXG5cdHB1YmxpYyBmcmFtZU51bWJlcjogbnVtYmVyO1xyXG5cdHB1YmxpYyBjdWxsaW5nVm9sdW1lOiBDdWxsaW5nVm9sdW1lO1xyXG5cdHB1YmxpYyBkZWZpbmVzRGlydHk6IGJvb2xlYW47XHJcblx0cHJpdmF0ZSBfZGVmaW5lczogb2JqZWN0O1xyXG5cdGNvbnN0cnVjdG9yKHB1YmxpYyBjb250ZXh0OiBDb250ZXh0LCBwdWJsaWMgbGlnaHRNYW5nZXI/OiBMaWdodE1hbmdlciwgb3B0aW9uczogRnJhbWVTdGF0ZU9wdGlvbnMgPSB7fSkge1xyXG5cdFx0dGhpcy5iYWNrZ3JvdW5kID0gb3B0aW9ucy5iYWNrZ3JvdW5kO1xyXG5cdFx0dGhpcy5yZW5kZXJRdWV1ZSA9IG5ldyBSZW5kZXJRdWV1ZSgpO1xyXG5cdFx0dGhpcy5nZW9tZXRyeU1lbW9yeSA9IDA7XHJcblx0XHR0aGlzLnRleHR1cmVNZW1vcnkgPSAwO1xyXG5cdFx0dGhpcy5mcmFtZU51bWJlciA9IDA7XHJcblx0XHR0aGlzLl9kZWZpbmVzID0ge307XHJcblx0XHR0aGlzLmRlZmluZXNEaXJ0eSA9IHRydWU7XHJcblx0fVxyXG5cdGdldCBkZWZpbmVzKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuX2RlZmluZXM7XHJcblx0fVxyXG5cdHNldCBkZWZpbmVzKHZhbHVlKSB7XHJcblx0XHR0aGlzLmRlZmluZXNEaXJ0eSA9IHRydWU7XHJcblx0XHR0aGlzLl9kZWZpbmVzID0gY29tYmluZSh2YWx1ZSwgdGhpcy5fZGVmaW5lcywgZmFsc2UpO1xyXG5cdH1cclxuXHR1cGRhdGUoY2FtZXJhOiBDYW1lcmEsIG9wdGlvbnM6IEZyYW1lU3RhdGVPcHRpb25zID0ge30pIHtcclxuXHRcdHRoaXMuYmFja2dyb3VuZCA9IG9wdGlvbnMuYmFja2dyb3VuZDtcclxuXHJcblx0XHR0aGlzLnJlbmRlclF1ZXVlLnJlc2V0KCk7XHJcblx0XHR0aGlzPy5saWdodE1hbmdlcj8udXBkYXRlPy4odGhpcywgY2FtZXJhKTtcclxuXHRcdHRoaXMuY3VsbGluZ1ZvbHVtZSA9IGNhbWVyYS5nZXRDdWxsaW5nVm9sdW1lKCk7XHJcblx0XHR0aGlzLmZyYW1lTnVtYmVyICs9IDE7XHJcblx0fVxyXG5cclxuXHRyZXNldEN1bGxpbmdWb2x1bWUoY2FtZXJhOiBDYW1lcmEpIHtcclxuXHRcdHRoaXMuY3VsbGluZ1ZvbHVtZSA9IGNhbWVyYS5nZXRDdWxsaW5nVm9sdW1lKCk7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZ2V0RnJhbWVTdGF0ZU9wdGlvbnNCeVNjZW5lKHNjZW5lSW5zdGFuY2U6IFNjZW5lKSB7XHJcblx0XHRyZXR1cm4ge1xyXG5cdFx0XHRiYWNrZ3JvdW5kOiBzY2VuZUluc3RhbmNlLmJhY2tncm91bmRcclxuXHRcdH07XHJcblx0fVxyXG59XHJcbiIsImltcG9ydCB7IExpZ2h0VHlwZSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XHJcbmltcG9ydCBWZWN0b3IzIGZyb20gXCIuLi9tYXRoL1ZlY3RvcjNcIjtcclxuaW1wb3J0IFZlY3RvcjQgZnJvbSBcIi4uL21hdGgvVmVjdG9yNFwiO1xyXG5pbXBvcnQgeyBMaWdodCB9IGZyb20gXCIuL0xpZ2h0XCI7XHJcblxyXG5leHBvcnQgY2xhc3MgQW1iaWVudExpZ2h0IGV4dGVuZHMgTGlnaHQge1xyXG5cdHByaXZhdGUgX2NvbG9yQW5kSW50ZW5zaXR5OiBWZWN0b3I0O1xyXG5cdGNvbnN0cnVjdG9yKGNvbG9yOiBWZWN0b3IzLCBpbnRlbnNpdHk6IG51bWJlcikge1xyXG5cdFx0c3VwZXIoY29sb3IsIGludGVuc2l0eSk7XHJcblx0XHR0aGlzLmxpZ2h0VHlwZSA9IExpZ2h0VHlwZS5BbWJpZW50TGlnaHQ7XHJcblx0XHR0aGlzLl9jb2xvckFuZEludGVuc2l0eSA9IG5ldyBWZWN0b3I0KGNvbG9yLngsIGNvbG9yLnksIGNvbG9yLnosIGludGVuc2l0eSk7XHJcblx0fVxyXG5cdGdldCBDb2xvckFuZEludGVuc2l0eSgpIHtcclxuXHRcdHRoaXMuX2NvbG9yQW5kSW50ZW5zaXR5LnNldCh0aGlzLmNvbG9yLngsIHRoaXMuY29sb3IueSwgdGhpcy5jb2xvci56LCB0aGlzLmludGVuc2l0eSk7XHJcblx0XHRyZXR1cm4gdGhpcy5fY29sb3JBbmRJbnRlbnNpdHk7XHJcblx0fVxyXG59XHJcbi8vIGxpZ2h0LmNvbG9yICkubXVsdGlwbHlTY2FsYXIoIGxpZ2h0LmludGVuc2l0eSAqIHNjYWxlRmFjdG9yICk7XHJcbiIsImltcG9ydCBDYW1lcmEgZnJvbSBcIi4uL2NhbWVyYS9DYW1lcmFcIjtcbmltcG9ydCB7IExpZ2h0TWFuZ2VyT3B0aW9ucywgTGlnaHRUeXBlLCBVbmlmb3JtRW51bSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XG5pbXBvcnQgeyBBbWJpZW50TGlnaHQgfSBmcm9tIFwiLi4vbGlnaHQvQW1iaWVudExpZ2h0XCI7XG5pbXBvcnQgeyBEaXJlY3Rpb25hbExpZ2h0IH0gZnJvbSBcIi4uL2xpZ2h0L0RpcmVjdGlvbmFsTGlnaHRcIjtcbmltcG9ydCB7IExpZ2h0IH0gZnJvbSBcIi4uL2xpZ2h0L0xpZ2h0XCI7XG5pbXBvcnQgeyBQb2ludExpZ2h0IH0gZnJvbSBcIi4uL2xpZ2h0L1BvaW50TGlnaHRcIjtcbmltcG9ydCB7IFNwb3RMaWdodCB9IGZyb20gXCIuLi9saWdodC9TcG90TGlnaHRcIjtcbmltcG9ydCBWZWN0b3IzIGZyb20gXCIuLi9tYXRoL1ZlY3RvcjNcIjtcbmltcG9ydCBTYW1wbGVyIGZyb20gXCIuLi9yZW5kZXIvU2FtcGxlclwiO1xuaW1wb3J0IFNoYWRlckRhdGEgZnJvbSBcIi4uL3JlbmRlci9TaGFkZXJEYXRhXCI7XG5pbXBvcnQgVGV4dHVyZSBmcm9tIFwiLi4vcmVuZGVyL1RleHR1cmVcIjtcbmltcG9ydCBVbmlmb3JtQnVmZmVyIGZyb20gXCIuLi9yZW5kZXIvVW5pZm9ybUJ1ZmZlclwiO1xuaW1wb3J0IHsgRnJhbWVTdGF0ZSB9IGZyb20gXCIuL0ZyYW1lU3RhdGVcIjtcbmltcG9ydCB7XG5cdFRleHR1cmVVc2FnZSxcblx0QnVmZmVyVXNhZ2UsXG5cdFRleHR1cmVGb3JtYXQsXG5cdENvbXBhcmVGdW5jdGlvbixcblx0U2FtcGxlckJpbmRpbmdUeXBlLFxuXHRUZXh0dXJlU2FtcGxlVHlwZSxcblx0VGV4dHVyZVZpZXdEaW1lbnNpb24sXG5cdEJ1ZmZlckJpbmRpbmdUeXBlXG59IGZyb20gXCIuL1dlYkdQVUNvbnN0YW50XCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpZ2h0TWFuZ2VyIHtcblx0bGlnaHRVbmlmb3JtQnVmZmVyOiBVbmlmb3JtQnVmZmVyO1xuXHRzaGFkb3dVbmlmb3JtQnVmZmVyOiBVbmlmb3JtQnVmZmVyO1xuXHRwb2ludExpZ2h0czogUG9pbnRMaWdodFtdO1xuXG5cdHNwb3RMaWdodHM6IFNwb3RMaWdodFtdO1xuXG5cdGRpcmVjdExpZ2h0czogRGlyZWN0aW9uYWxMaWdodFtdO1xuXG5cdGFtYmllbnRMaWdodDogQW1iaWVudExpZ2h0O1xuXG5cdGxpZ2h0U2hhZGVyRGF0YTogU2hhZGVyRGF0YTtcblxuXHRsaWdodENvdW50RGlydHk6IGJvb2xlYW47XG5cblx0cHJpdmF0ZSBvcGVuU2hhZG93OiBib29sZWFuO1xuXHRzcG90TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXk6IFRleHR1cmU7XG5cdHBvaW50TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXk6IFRleHR1cmU7XG5cdGRpcmVjdExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5OiBUZXh0dXJlO1xuXHRfdGVzdFRleHR1cmU6IFRleHR1cmU7XG5cblx0Y29uc3RydWN0b3Iob3B0aW9uczogTGlnaHRNYW5nZXJPcHRpb25zKSB7XG5cdFx0dGhpcy5zcG90TGlnaHRzID0gW107XG5cdFx0dGhpcy5wb2ludExpZ2h0cyA9IFtdO1xuXHRcdHRoaXMuZGlyZWN0TGlnaHRzID0gW107XG5cdFx0dGhpcy5hbWJpZW50TGlnaHQgPSBuZXcgQW1iaWVudExpZ2h0KG5ldyBWZWN0b3IzKDEuMCwgMS4wLCAxLjApLCAwLjIpO1xuXHRcdHRoaXMubGlnaHRDb3VudERpcnR5ID0gdHJ1ZTtcblx0XHR0aGlzLm9wZW5TaGFkb3cgPSBvcHRpb25zLm9wZW5TaGFkb3c7XG5cdH1cblx0dXBkYXRlKGZyYW1lU3RhdGU6IEZyYW1lU3RhdGUsIGNhbWVyYTogQ2FtZXJhKSB7XG5cdFx0dGhpcy5jaGVja0xpZ2h0U2hhZG93U3RhdGUoKTtcblx0XHR0aGlzLnVwZGF0ZUxpZ2h0KGNhbWVyYSk7XG5cdH1cblx0YWRkKGxpZ2h0OiBMaWdodCkge1xuXHRcdHRoaXMubGlnaHRDb3VudERpcnR5ID0gdHJ1ZTtcblx0XHRpZiAobGlnaHQubGlnaHRUeXBlID09IExpZ2h0VHlwZS5BbWJpZW50TGlnaHQpIHtcblx0XHRcdHRoaXMuYW1iaWVudExpZ2h0ID0gPEFtYmllbnRMaWdodD5saWdodDtcblx0XHR9IGVsc2UgaWYgKGxpZ2h0LmxpZ2h0VHlwZSA9PSBMaWdodFR5cGUuRGlyZWN0aW9uYWxMaWdodCkge1xuXHRcdFx0dGhpcy5kaXJlY3RMaWdodHMucHVzaCg8RGlyZWN0aW9uYWxMaWdodD5saWdodCk7XG5cdFx0fSBlbHNlIGlmIChsaWdodC5saWdodFR5cGUgPT0gTGlnaHRUeXBlLlBvaW50TGlnaHQpIHtcblx0XHRcdHRoaXMucG9pbnRMaWdodHMucHVzaCg8UG9pbnRMaWdodD5saWdodCk7XG5cdFx0fSBlbHNlIGlmIChsaWdodC5saWdodFR5cGUgPT0gTGlnaHRUeXBlLlNwb3RMaWdodCkge1xuXHRcdFx0dGhpcy5zcG90TGlnaHRzLnB1c2goPFNwb3RMaWdodD5saWdodCk7XG5cdFx0fVxuXHR9XG5cdHJlbW92ZShsaWdodDogTGlnaHQpIHtcblx0XHR0aGlzLmxpZ2h0Q291bnREaXJ0eSA9IHRydWU7XG5cdFx0aWYgKGxpZ2h0LmxpZ2h0VHlwZSA9PSBMaWdodFR5cGUuQW1iaWVudExpZ2h0KSB7XG5cdFx0XHR0aGlzLmFtYmllbnRMaWdodCA9IG5ldyBBbWJpZW50TGlnaHQobmV3IFZlY3RvcjMoMS4wLCAxLjAsIDEuMCksIDEuMCk7XG5cdFx0fSBlbHNlIGlmIChsaWdodC5saWdodFR5cGUgPT0gTGlnaHRUeXBlLkRpcmVjdGlvbmFsTGlnaHQpIHtcblx0XHRcdHRoaXMuZGlyZWN0TGlnaHRzLnNwbGljZSh0aGlzLmRpcmVjdExpZ2h0cy5pbmRleE9mKDxEaXJlY3Rpb25hbExpZ2h0PmxpZ2h0KSwgMSk7XG5cdFx0fSBlbHNlIGlmIChsaWdodC5saWdodFR5cGUgPT0gTGlnaHRUeXBlLlBvaW50TGlnaHQpIHtcblx0XHRcdHRoaXMucG9pbnRMaWdodHMuc3BsaWNlKHRoaXMucG9pbnRMaWdodHMuaW5kZXhPZig8UG9pbnRMaWdodD5saWdodCksIDEpO1xuXHRcdH0gZWxzZSBpZiAobGlnaHQubGlnaHRUeXBlID09IExpZ2h0VHlwZS5TcG90TGlnaHQpIHtcblx0XHRcdHRoaXMuc3BvdExpZ2h0cy5zcGxpY2UodGhpcy5zcG90TGlnaHRzLmluZGV4T2YoPFNwb3RMaWdodD5saWdodCksIDEpO1xuXHRcdH1cblx0fVxuXHRjaGVja0xpZ2h0U2hhZG93U3RhdGUoKSB7XG5cdFx0Y29uc3QgbGlnaHRzID0gdGhpcy5nZXRBbGxMaWdodHMoKTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGxpZ2h0cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3QgbGlnaHQgPSBsaWdodHNbaV07XG5cdFx0XHRpZiAobGlnaHQuc2hhZG93RGlydHkpIHtcblx0XHRcdFx0bGlnaHQuc2hhZG93RGlydHkgPSBmYWxzZTtcblx0XHRcdFx0dGhpcy5saWdodENvdW50RGlydHkgPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHVwZGF0ZUxpZ2h0U2hhZG93KCkge1xuXHRcdGlmICh0aGlzLnNwb3RMaWdodFNoYWRvd01hcFRleHR1cmVBcnJheSkgdGhpcy5zcG90TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXkuZGlydHkgPSB0cnVlO1xuXG5cdFx0aWYgKHRoaXMucG9pbnRMaWdodFNoYWRvd01hcFRleHR1cmVBcnJheSkgdGhpcy5wb2ludExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5LmRpcnR5ID0gdHJ1ZTtcblxuXHRcdGlmICh0aGlzLmRpcmVjdExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5KSB0aGlzLmRpcmVjdExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5LmRpcnR5ID0gdHJ1ZTtcblx0fVxuXG5cdHByaXZhdGUgdXBkYXRlTGlnaHQoY2FtZXJhOiBDYW1lcmEpIHtcblx0XHRpZiAodGhpcy5saWdodENvdW50RGlydHkpIHtcblx0XHRcdHRoaXMubGlnaHRDb3VudERpcnR5ID0gZmFsc2U7XG5cdFx0XHRpZiAodGhpcy5saWdodFNoYWRlckRhdGEpIHRoaXMubGlnaHRTaGFkZXJEYXRhLmRlc3Ryb3koKTtcblx0XHRcdHRoaXMuY3JlYXRlTGlnaHRTaGFkZXJEYXRhKCk7XG5cdFx0fVxuXHR9XG5cdHByaXZhdGUgY3JlYXRlTGlnaHRTaGFkZXJEYXRhKCkge1xuXHRcdHRoaXMubGlnaHRTaGFkZXJEYXRhID0gbmV3IFNoYWRlckRhdGEoXCJsaWdodFwiLCAwLCAyLCAyKTtcblx0XHR0aGlzLmxpZ2h0VW5pZm9ybUJ1ZmZlciA9IG5ldyBVbmlmb3JtQnVmZmVyKHtcblx0XHRcdGxhYmVsOiBcImxpZ2h0XCIsXG5cdFx0XHR0eXBlOiBCdWZmZXJCaW5kaW5nVHlwZS5SZWFkT25seVN0b3JhZ2UsXG5cdFx0XHR1c2FnZTogQnVmZmVyVXNhZ2UuU3RvcmFnZSB8IEJ1ZmZlclVzYWdlLkNvcHlEc3Rcblx0XHR9KTtcblxuXHRcdHRoaXMubGlnaHRTaGFkZXJEYXRhLnNldERlZmluZShcInNwb3RMaWdodHNDb3VudFwiLCB0aGlzLnNwb3RMaWdodHMubGVuZ3RoKTtcblx0XHR0aGlzLmxpZ2h0U2hhZGVyRGF0YS5zZXREZWZpbmUoXCJwb2ludExpZ2h0c0NvdW50XCIsIHRoaXMucG9pbnRMaWdodHMubGVuZ3RoKTtcblx0XHR0aGlzLmxpZ2h0U2hhZGVyRGF0YS5zZXREZWZpbmUoXCJkaXJ0ZWN0TGlnaHRzQ291bnRcIiwgdGhpcy5kaXJlY3RMaWdodHMubGVuZ3RoKTtcblx0XHR0aGlzLmxpZ2h0U2hhZGVyRGF0YS5zZXREZWZpbmUoXCJhbWJpZW50TGlnaHRDb3VudFwiLCAxKTtcblx0XHRpZiAodGhpcy5hbWJpZW50TGlnaHQpXG5cdFx0XHR0aGlzLmxpZ2h0VW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XHRcImFtYmllbnRMaWdodFwiLFxuXHRcdFx0XHQoKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMuYW1iaWVudExpZ2h0LkNvbG9yQW5kSW50ZW5zaXR5O1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRVbmlmb3JtRW51bS5GbG9hdFZlYzRcblx0XHRcdCk7XG5cdFx0aWYgKHRoaXMuc3BvdExpZ2h0cy5sZW5ndGgpIHtcblx0XHRcdC8vIOWIneWni+WMluiBmuWFieeBr1xuXHRcdFx0dGhpcy5saWdodFVuaWZvcm1CdWZmZXIuc2V0VW5pZm9ybShcblx0XHRcdFx0XCJzcG90TGlnaHRzXCIsXG5cdFx0XHRcdCgpID0+IHtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5zcG90TGlnaHRzO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRVbmlmb3JtRW51bS5TcG90TGlnaHRzLFxuXHRcdFx0XHR0aGlzLnNwb3RMaWdodHMubGVuZ3RoXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRpZiAodGhpcy5wb2ludExpZ2h0cy5sZW5ndGgpIHtcblx0XHRcdC8vIOeCueWFiea6kFxuXHRcdFx0dGhpcy5saWdodFVuaWZvcm1CdWZmZXIuc2V0VW5pZm9ybShcblx0XHRcdFx0XCJwb2ludExpZ2h0c1wiLFxuXHRcdFx0XHQoKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMucG9pbnRMaWdodHM7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdFVuaWZvcm1FbnVtLlBvaW50TGlnaHRzLFxuXHRcdFx0XHR0aGlzLnBvaW50TGlnaHRzLmxlbmd0aFxuXHRcdFx0KTtcblx0XHR9XG5cdFx0aWYgKHRoaXMuZGlyZWN0TGlnaHRzLmxlbmd0aCkge1xuXHRcdFx0Ly8g5pa55ZCR5YWJXG5cdFx0XHR0aGlzLmxpZ2h0VW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XHRcImRpcmVjdExpZ2h0c1wiLFxuXHRcdFx0XHQoKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMuZGlyZWN0TGlnaHRzO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRVbmlmb3JtRW51bS5EaXJ0ZWN0TGlnaHRzLFxuXHRcdFx0XHR0aGlzLmRpcmVjdExpZ2h0cy5sZW5ndGhcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0c2hhZG93U2hhZGVyRGF0YToge1xuXHRcdFx0aWYgKHRoaXMub3BlblNoYWRvdykge1xuXHRcdFx0XHRjb25zdCBzcG90TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXkgPSAodGhpcy5zcG90TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXkgPVxuXHRcdFx0XHRcdHRoaXMuY3JlYXRlU2hhZG93TWFwVGV4dHVyZUFycmF5KHRoaXMuc3BvdExpZ2h0cykpO1xuXHRcdFx0XHRjb25zdCBwb2ludExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5ID0gKHRoaXMucG9pbnRMaWdodFNoYWRvd01hcFRleHR1cmVBcnJheSA9XG5cdFx0XHRcdFx0dGhpcy5jcmVhdGVTaGFkb3dNYXBUZXh0dXJlQXJyYXkodGhpcy5wb2ludExpZ2h0cykpO1xuXHRcdFx0XHRjb25zdCBkaXJlY3RMaWdodFNoYWRvd01hcFRleHR1cmVBcnJheSA9ICh0aGlzLmRpcmVjdExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5ID1cblx0XHRcdFx0XHR0aGlzLmNyZWF0ZVNoYWRvd01hcFRleHR1cmVBcnJheSh0aGlzLmRpcmVjdExpZ2h0cykpO1xuXHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0IXNwb3RMaWdodFNoYWRvd01hcFRleHR1cmVBcnJheSAmJlxuXHRcdFx0XHRcdCFwb2ludExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5ICYmXG5cdFx0XHRcdFx0IWRpcmVjdExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5XG5cdFx0XHRcdClcblx0XHRcdFx0XHRicmVhayBzaGFkb3dTaGFkZXJEYXRhO1xuXG5cdFx0XHRcdC8vIGRlZmluZVxuXHRcdFx0XHR0aGlzLmxpZ2h0U2hhZGVyRGF0YS5zZXREZWZpbmUoXCJvcGVuU2hhZG93XCIsIHRoaXMub3BlblNoYWRvdyk7XG5cblx0XHRcdFx0Ly8gc2hhZG93VW5pZm9ybUJ1ZmZlclxuXHRcdFx0XHR0aGlzLnNoYWRvd1VuaWZvcm1CdWZmZXIgPSBuZXcgVW5pZm9ybUJ1ZmZlcih7XG5cdFx0XHRcdFx0bGFiZWw6IFwic2hhZG93XCIsXG5cdFx0XHRcdFx0dHlwZTogQnVmZmVyQmluZGluZ1R5cGUuUmVhZE9ubHlTdG9yYWdlLFxuXHRcdFx0XHRcdHVzYWdlOiBCdWZmZXJVc2FnZS5TdG9yYWdlIHwgQnVmZmVyVXNhZ2UuQ29weURzdFxuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHQvLyBtYXRyaXgsbmVhcixmYXIuLi5cblx0XHRcdFx0Y29uc3Qgc3BvdExpZ2h0V2l0aFNoYWRvd0NvdW50ID0gdGhpcy5zZXRTaGFkb3dVbmlmb3JtKFxuXHRcdFx0XHRcdFwic3BvdExpZ2h0U2hhZG93c1wiLFxuXHRcdFx0XHRcdHRoaXMuc3BvdExpZ2h0cyxcblx0XHRcdFx0XHRVbmlmb3JtRW51bS5TcG90TGlnaHRTaGFkb3dzXG5cdFx0XHRcdCk7XG5cdFx0XHRcdGNvbnN0IHBvaW50TGlnaHRXaXRoU2hhZG93Q291bnQgPSB0aGlzLnNldFNoYWRvd1VuaWZvcm0oXG5cdFx0XHRcdFx0XCJwb2ludExpZ2h0U2hhZG93c1wiLFxuXHRcdFx0XHRcdHRoaXMucG9pbnRMaWdodHMsXG5cdFx0XHRcdFx0VW5pZm9ybUVudW0uUG9pbnRMaWdodFNoYWRvd3Ncblx0XHRcdFx0KTtcblx0XHRcdFx0Y29uc3QgZGlyZWN0TGlnaHRXaXRoU2hhZG93Q291bnQgPSB0aGlzLnNldFNoYWRvd1VuaWZvcm0oXG5cdFx0XHRcdFx0XCJkaXJlY3RMaWdodFNoYWRvd3NcIixcblx0XHRcdFx0XHR0aGlzLmRpcmVjdExpZ2h0cyxcblx0XHRcdFx0XHRVbmlmb3JtRW51bS5EaXJ0ZWN0TGlnaHRTaGFkb3dzXG5cdFx0XHRcdCk7XG5cdFx0XHRcdHRoaXMubGlnaHRTaGFkZXJEYXRhLnNldFVuaWZvcm1CdWZmZXIoXCJzaGFkb3dcIiwgdGhpcy5zaGFkb3dVbmlmb3JtQnVmZmVyKTtcblxuXHRcdFx0XHR0aGlzLmxpZ2h0U2hhZGVyRGF0YS5zZXREZWZpbmUoXCJzcG90TGlnaHRTaGFkb3dNYXBzQ291bnRcIiwgc3BvdExpZ2h0V2l0aFNoYWRvd0NvdW50KTtcblx0XHRcdFx0dGhpcy5saWdodFNoYWRlckRhdGEuc2V0RGVmaW5lKFwicG9pbnRMaWdodFNoYWRvd01hcHNDb3VudFwiLCBwb2ludExpZ2h0V2l0aFNoYWRvd0NvdW50KTtcblx0XHRcdFx0dGhpcy5saWdodFNoYWRlckRhdGEuc2V0RGVmaW5lKFwiZGlyZWN0TGlnaHRTaGFkb3dNYXBzQ291bnRcIiwgZGlyZWN0TGlnaHRXaXRoU2hhZG93Q291bnQpO1xuXG5cdFx0XHRcdC8vIHRleHR1cmUsc2FtcGxlXG5cdFx0XHRcdGlmIChzcG90TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXkgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdGlmIChzcG90TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXkudGV4dHVyZVByb3Auc2l6ZS5kZXB0aCAhPSBzcG90TGlnaHRXaXRoU2hhZG93Q291bnQpXG5cdFx0XHRcdFx0XHRjb25zb2xlLndhcm4oXCJzcG90TGlnaHRTaGFkb3dNYXAgYWxpZ24gaGFzIHByb2JsZW1cIik7XG5cdFx0XHRcdFx0dGhpcy5saWdodFNoYWRlckRhdGEuc2V0VGV4dHVyZShcInNwb3RMaWdodFNoYWRvd01hcFRleHR1cmVBcnJheVwiLCBzcG90TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXkpO1xuXHRcdFx0XHRcdC8vIHRoaXMuX3Rlc3RUZXh0dXJlID0gc3BvdExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKHBvaW50TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXkgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdGlmIChwb2ludExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5LnRleHR1cmVQcm9wLnNpemUuZGVwdGggIT0gcG9pbnRMaWdodFdpdGhTaGFkb3dDb3VudClcblx0XHRcdFx0XHRcdGNvbnNvbGUud2FybihcInBvaW50TGlnaHRTaGFkb3dNYXAgYWxpZ24gaGFzIHByb2JsZW1cIik7XG5cdFx0XHRcdFx0dGhpcy5saWdodFNoYWRlckRhdGEuc2V0VGV4dHVyZShcInBvaW50TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXlcIiwgcG9pbnRMaWdodFNoYWRvd01hcFRleHR1cmVBcnJheSk7XG5cdFx0XHRcdFx0Ly8gdGhpcy5fdGVzdFRleHR1cmUgPSBwb2ludExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5O1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChkaXJlY3RMaWdodFNoYWRvd01hcFRleHR1cmVBcnJheSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdFx0aWYgKGRpcmVjdExpZ2h0U2hhZG93TWFwVGV4dHVyZUFycmF5LnRleHR1cmVQcm9wLnNpemUuZGVwdGggIT0gZGlyZWN0TGlnaHRXaXRoU2hhZG93Q291bnQpXG5cdFx0XHRcdFx0XHRjb25zb2xlLndhcm4oXCJkaXJlY3RMaWdodFNoYWRvd01hcCBhbGlnbiBoYXMgcHJvYmxlbVwiKTtcblx0XHRcdFx0XHR0aGlzLmxpZ2h0U2hhZGVyRGF0YS5zZXRUZXh0dXJlKFxuXHRcdFx0XHRcdFx0XCJkaXJlY3RMaWdodFNoYWRvd01hcFRleHR1cmVBcnJheVwiLFxuXHRcdFx0XHRcdFx0ZGlyZWN0TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXlcblx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdC8vIHRoaXMuX3Rlc3RUZXh0dXJlID0gZGlyZWN0TGlnaHRTaGFkb3dNYXBUZXh0dXJlQXJyYXlcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLmxpZ2h0U2hhZGVyRGF0YS5zZXRTYW1wbGVyKFxuXHRcdFx0XHRcdFwic2hhZG93U2FtcGxlclwiLFxuXHRcdFx0XHRcdG5ldyBTYW1wbGVyKHsgY29tcGFyZTogQ29tcGFyZUZ1bmN0aW9uLkxlc3MgfSwgeyB0eXBlOiBTYW1wbGVyQmluZGluZ1R5cGUuQ29tcGFyaXNvbiB9KVxuXHRcdFx0XHQpO1xuXHRcdFx0XHQvLyB0aGlzLmxpZ2h0U2hhZGVyRGF0YS5zZXRTYW1wbGVyKFwic2hhZG93U2FtcGxlclwiLCBuZXcgU2FtcGxlcigpKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzLmxpZ2h0U2hhZGVyRGF0YS5zZXRVbmlmb3JtQnVmZmVyKFwibGlnaHRcIiwgdGhpcy5saWdodFVuaWZvcm1CdWZmZXIpO1xuXHR9XG5cblx0cHVibGljIGdldEFsbExpZ2h0cygpOiBBcnJheTxMaWdodD4ge1xuXHRcdGNvbnN0IHJlc3VsdCA9IFtdO1xuXHRcdHJldHVybiByZXN1bHQuY29uY2F0KHRoaXMuc3BvdExpZ2h0cywgdGhpcy5wb2ludExpZ2h0cywgdGhpcy5kaXJlY3RMaWdodHMpO1xuXHR9XG5cblx0ZGVzdHJveSgpIHtcblx0XHR0aGlzLmxpZ2h0U2hhZGVyRGF0YS5kZXN0cm95KCk7XG5cdFx0dGhpcy5saWdodFVuaWZvcm1CdWZmZXIuZGVzdHJveSgpO1xuXHR9XG5cblx0Y3JlYXRlU2hhZG93TWFwVGV4dHVyZUFycmF5KGxpZ2h0czogQXJyYXk8TGlnaHQ+KSB7XG5cdFx0aWYgKGxpZ2h0cy5sZW5ndGggPD0gMCkgcmV0dXJuIHVuZGVmaW5lZDtcblx0XHRjb25zdCBzaGFkb3dNYXBTb3VyY2VzID0gW107XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBsaWdodHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IGxpZ2h0ID0gbGlnaHRzW2ldO1xuXHRcdFx0aWYgKGxpZ2h0LnNoYWRvdykge1xuXHRcdFx0XHRjb25zdCBzaGFkb3dNYXBUZXh0dXJlID0gbGlnaHQuc2hhZG93LmdldFNoYWRvd01hcFRleHR1cmUoKTtcblx0XHRcdFx0Y29uc3Qgc2hhZG93TWFwU291cmNlID0ge1xuXHRcdFx0XHRcdHNvdXJjZTogc2hhZG93TWFwVGV4dHVyZSxcblx0XHRcdFx0XHR3aWR0aDogc2hhZG93TWFwVGV4dHVyZS50ZXh0dXJlUHJvcC5zaXplLndpZHRoLFxuXHRcdFx0XHRcdGhlaWdodDogc2hhZG93TWFwVGV4dHVyZS50ZXh0dXJlUHJvcC5zaXplLmhlaWdodCxcblx0XHRcdFx0XHRkZXB0aDogMSxcblx0XHRcdFx0XHR4OiAwLFxuXHRcdFx0XHRcdHk6IDAsXG5cdFx0XHRcdFx0ejogaVxuXHRcdFx0XHR9O1xuXHRcdFx0XHRzaGFkb3dNYXBTb3VyY2VzLnB1c2goc2hhZG93TWFwU291cmNlKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoc2hhZG93TWFwU291cmNlcy5sZW5ndGggPD0gMCkgcmV0dXJuIHVuZGVmaW5lZDtcblxuXHRcdGNvbnN0IHNoYWRvd01hcFRleHR1cmVBcnJheSA9IG5ldyBUZXh0dXJlKHtcblx0XHRcdHNpemU6IHtcblx0XHRcdFx0d2lkdGg6IHNoYWRvd01hcFNvdXJjZXNbMF0ud2lkdGgsXG5cdFx0XHRcdGhlaWdodDogc2hhZG93TWFwU291cmNlc1swXS5oZWlnaHQsXG5cdFx0XHRcdGRlcHRoOiBzaGFkb3dNYXBTb3VyY2VzLmxlbmd0aFxuXHRcdFx0fSxcblx0XHRcdGZpeGVkU2l6ZTogdHJ1ZSxcblx0XHRcdHNhbXBsZVR5cGU6IFRleHR1cmVTYW1wbGVUeXBlLkRlcHRoLFxuXHRcdFx0Zm9ybWF0OiBUZXh0dXJlRm9ybWF0LkRlcHRoMjRQbHVzLFxuXHRcdFx0dXNhZ2U6IFRleHR1cmVVc2FnZS5UZXh0dXJlQmluZGluZyB8IFRleHR1cmVVc2FnZS5Db3B5RHN0LFxuXHRcdFx0ZGF0YTogc2hhZG93TWFwU291cmNlcyxcblx0XHRcdHZpZXdGb3JtYXRzOiBUZXh0dXJlVmlld0RpbWVuc2lvbi5FMmRBcnJheVxuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIHNoYWRvd01hcFRleHR1cmVBcnJheTtcblx0fVxuXG5cdHNldFNoYWRvd1VuaWZvcm0odW5pZm9ybU5hbWU6IHN0cmluZywgbGlnaHRzOiBBcnJheTxMaWdodD4sIHVuaWZvcm1UeXBlOiBVbmlmb3JtRW51bSkge1xuXHRcdGlmIChsaWdodHMubGVuZ3RoKSB7XG5cdFx0XHRjb25zdCBsaWdodFdpdGhTaGFkb3dBcnJheSA9IFtdO1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBsaWdodHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0Y29uc3QgbGlnaHQgPSBsaWdodHNbaV07XG5cdFx0XHRcdGlmICghbGlnaHQuc2hhZG93KSBjb250aW51ZTtcblx0XHRcdFx0bGlnaHRXaXRoU2hhZG93QXJyYXkucHVzaChsaWdodCk7XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuc2hhZG93VW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XHR1bmlmb3JtTmFtZSxcblx0XHRcdFx0KCkgPT4ge1xuXHRcdFx0XHRcdHJldHVybiBsaWdodFdpdGhTaGFkb3dBcnJheTtcblx0XHRcdFx0fSxcblx0XHRcdFx0dW5pZm9ybVR5cGUsXG5cdFx0XHRcdGxpZ2h0V2l0aFNoYWRvd0FycmF5Lmxlbmd0aFxuXHRcdFx0KTtcblxuXHRcdFx0cmV0dXJuIGxpZ2h0V2l0aFNoYWRvd0FycmF5Lmxlbmd0aDtcblx0XHR9XG5cdH1cbn1cbiIsImltcG9ydCBDYW1lcmEgZnJvbSBcIi4uL2NhbWVyYS9DYW1lcmFcIjtcbmltcG9ydCB7IE1lc2ggfSBmcm9tIFwiLi4vbWVzaC9NZXNoXCI7XG5pbXBvcnQgeyBGcmFtZVN0YXRlIH0gZnJvbSBcIi4vRnJhbWVTdGF0ZVwiO1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWVzaE1hbmdlciB7XG5cdHByaXZhdGUgX2xpc3Q6IE1hcDxzdHJpbmcgfCBudW1iZXIsIE1lc2g+O1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHR0aGlzLl9saXN0ID0gbmV3IE1hcCgpO1xuXHR9XG5cdGdldCBsZW5ndGgoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX2xpc3Quc2l6ZTtcblx0fVxuXHR1cGRhdGUoZnJhbWVTdGF0ZTogRnJhbWVTdGF0ZSwgY2FtZXJhOiBDYW1lcmEpOiB2b2lkIHtcblx0XHR0aGlzLl9saXN0LmZvckVhY2goKGluc3RhbmNlKSA9PiB7XG5cdFx0XHRpbnN0YW5jZS51cGRhdGUoZnJhbWVTdGF0ZSwgY2FtZXJhKTtcblx0XHR9KTtcblx0fVxuXHRhZGQoaW5zdGFuY2U6IE1lc2gpOiBNZXNoIHtcblx0XHRpZiAodGhpcy5fbGlzdC5nZXQoaW5zdGFuY2UudWlkKSkgcmV0dXJuIHRoaXMuX2xpc3QuZ2V0KGluc3RhbmNlLnVpZCk7XG5cdFx0dGhpcy5fbGlzdC5zZXQoaW5zdGFuY2UudWlkLCBpbnN0YW5jZSk7XG5cdFx0cmV0dXJuIGluc3RhbmNlO1xuXHR9XG5cdHJlbW92ZShpbnN0YW5jZTogTWVzaCk6IGJvb2xlYW4ge1xuXHRcdGlmICh0aGlzLl9saXN0LmdldChpbnN0YW5jZS51aWQpKSB7XG5cdFx0XHRpbnN0YW5jZS5kZXN0cm95KCk7XG5cdFx0XHR0aGlzLl9saXN0LmRlbGV0ZShpbnN0YW5jZS51aWQpO1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHRjb250YWlucyhpbnN0YW5jZTogTWVzaCkge1xuXHRcdHJldHVybiAhIXRoaXMuX2xpc3QuZ2V0KGluc3RhbmNlLnVpZCk7XG5cdH1cbn1cbiIsImltcG9ydCB7IFRleHR1cmVGb3JtYXQsIFRleHR1cmVVc2FnZSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVUNvbnN0YW50XCI7XG5pbXBvcnQgR2VvbWV0cnkgZnJvbSBcIi4uL2dlb21ldHJ5L0dlb21ldHJ5XCI7XG5pbXBvcnQgU2hhZGVyTWF0ZXJpYWwgZnJvbSBcIi4uL21hdGVyaWFsL1NoYWRlck1hdGVyaWFsXCI7XG5pbXBvcnQgeyBNZXNoIH0gZnJvbSBcIi4uL21lc2gvTWVzaFwiO1xuaW1wb3J0IEF0dGFjaG1lbnQgZnJvbSBcIi4uL3JlbmRlci9BdHRhY2htZW50XCI7XG5pbXBvcnQgeyBGbG9hdDMyQXR0cmlidXRlIH0gZnJvbSBcIi4uL3JlbmRlci9BdHRyaWJ1dGVcIjtcbmltcG9ydCBDb250ZXh0IGZyb20gXCIuLi9yZW5kZXIvQ29udGV4dFwiO1xuaW1wb3J0IFJlbmRlclRhcmdldCBmcm9tIFwiLi4vcmVuZGVyL1JlbmRlclRhcmdldFwiO1xuaW1wb3J0IFNhbXBsZXIgZnJvbSBcIi4uL3JlbmRlci9TYW1wbGVyXCI7XG5pbXBvcnQgVGV4dHVyZSBmcm9tIFwiLi4vcmVuZGVyL1RleHR1cmVcIjtcbmltcG9ydCBnZXRWZXJ0RnJhZyBmcm9tIFwiLi4vc2hhZGVyL1NoYWRlcnNcIjtcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlc29sdmVGcmFtZSB7XG5cdGNhbnZhc1JlbmRlclRhcmdldDogUmVuZGVyVGFyZ2V0O1xuXHRtYXRlcmlhbDogU2hhZGVyTWF0ZXJpYWw7XG5cdGdlb21ldHJ5OiBHZW9tZXRyeTtcblx0cXVhZE1lc2g6IE1lc2g7XG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHRoaXMuZ2VvbWV0cnkgPSBuZXcgR2VvbWV0cnkoe30pO1xuXHRcdHRoaXMuZ2VvbWV0cnkuc2V0QXR0cmlidXRlKFxuXHRcdFx0bmV3IEZsb2F0MzJBdHRyaWJ1dGUoXCJwb3NpdGlvblwiLCBbLTEuMCwgMS4wLCAtMS4wLCAtMS4wLCAxLjAsIC0xLjAsIDEuMCwgLTEuMCwgMS4wLCAxLjAsIC0xLjAsIDEuMF0sIDIpXG5cdFx0KTtcblx0XHR0aGlzLmdlb21ldHJ5LmNvdW50ID0gNjtcblx0XHRjb25zdCBzaGFkZXIgPSBnZXRWZXJ0RnJhZyhcInJlc29sdmVcIiwgeyBwb3NpdGlvbkxvY2F0aW9uOiAwIH0pO1xuXHRcdHRoaXMubWF0ZXJpYWwgPSBuZXcgU2hhZGVyTWF0ZXJpYWwoe1xuXHRcdFx0dHlwZTogXCJyZXNvbHZlXCIsXG5cdFx0XHRmcmFnOiBzaGFkZXIuZnJhZyxcblx0XHRcdHZlcnQ6IHNoYWRlci52ZXJ0LFxuXHRcdFx0dW5pZm9ybXM6IHtcblx0XHRcdFx0dGV4dHVyZToge1xuXHRcdFx0XHRcdHR5cGU6IFwidGV4dHVyZVwiLFxuXHRcdFx0XHRcdHZhbHVlOiB1bmRlZmluZWRcblx0XHRcdFx0fSxcblx0XHRcdFx0c2FtcGxlcjoge1xuXHRcdFx0XHRcdHR5cGU6IFwic2FtcGxlclwiLFxuXHRcdFx0XHRcdHZhbHVlOiBuZXcgU2FtcGxlcih7XG5cdFx0XHRcdFx0XHRtYWdGaWx0ZXI6IFwibGluZWFyXCIsXG5cdFx0XHRcdFx0XHRtaW5GaWx0ZXI6IFwibGluZWFyXCJcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0dGhpcy5xdWFkTWVzaCA9IG5ldyBNZXNoKHRoaXMuZ2VvbWV0cnksIHRoaXMubWF0ZXJpYWwpO1xuXHR9XG5cdHNldFNpemUod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcblx0XHR0aGlzLmNhbnZhc1JlbmRlclRhcmdldC5zZXRTaXplKHdpZHRoLCBoZWlnaHQpO1xuXHRcdHRoaXMubWF0ZXJpYWwuZGlydHkgPSB0cnVlO1xuXHR9XG5cdHJlbmRlcihjb250ZXh0OiBDb250ZXh0LCBjb2xvclRleHR1cmU/OiBUZXh0dXJlKSB7XG5cdFx0aWYgKCF0aGlzLmNhbnZhc1JlbmRlclRhcmdldCkgdGhpcy5pbml0UmVuZGVyVGFyZ2V0KGNvbnRleHQpO1xuXHRcdC8vIHRoaXMubWF0ZXJpYWxcblx0XHR0aGlzLm1hdGVyaWFsLnVuaWZvcm1zLnRleHR1cmUudmFsdWUgPSBjb2xvclRleHR1cmU7XG5cblx0XHR0aGlzLm1hdGVyaWFsLnVwZGF0ZSh1bmRlZmluZWQsIHRoaXMucXVhZE1lc2gpO1xuXG5cdFx0Y29uc3QgZHJhd0NvbWFuZCA9IHRoaXMucXVhZE1lc2guZ2V0RHJhd0NvbW1hbmQoKTtcblxuXHRcdGNvbnN0IGN1cnJlbnRSZW5kZXJQYXNzRW5jb2RlciA9IHRoaXMuY2FudmFzUmVuZGVyVGFyZ2V0LmJlZ2luUmVuZGVyUGFzcyhjb250ZXh0LmRldmljZSk7XG5cblx0XHRkcmF3Q29tYW5kLnJlbmRlcih7IGRldmljZTogY29udGV4dC5kZXZpY2UsIHBhc3NFbmNvZGVyOiBjdXJyZW50UmVuZGVyUGFzc0VuY29kZXIgfSk7XG5cblx0XHR0aGlzLmNhbnZhc1JlbmRlclRhcmdldC5lbmRSZW5kZXJQYXNzKCk7XG5cdH1cblx0cHJpdmF0ZSBpbml0UmVuZGVyVGFyZ2V0KGNvbnRleHQ6IENvbnRleHQpIHtcblx0XHRjb25zdCB7IHdpZHRoLCBoZWlnaHQsIGRlcHRoIH0gPSBjb250ZXh0LnByZXNlbnRhdGlvblNpemU7XG5cdFx0Y29uc3QgY29sb3JBdHRhY2htZW50ID0gbmV3IEF0dGFjaG1lbnQoXG5cdFx0XHR7IHI6IDAuMCwgZzogMC4wLCBiOiAwLjAsIGE6IDAgfSxcblx0XHRcdHtcblx0XHRcdFx0dGV4dHVyZVZpZXc6ICgpID0+IHtcblx0XHRcdFx0XHRyZXR1cm4gY29udGV4dC5jb250ZXh0LmdldEN1cnJlbnRUZXh0dXJlKCkuY3JlYXRlVmlldygpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0KTtcblx0XHRjb25zdCBkZXB0aFRleHR1cmUgPSBuZXcgVGV4dHVyZSh7XG5cdFx0XHRsYWJlbDogXCJyZXNvbHZlRGVwdGhcIixcblx0XHRcdHNpemU6IHsgd2lkdGgsIGhlaWdodCwgZGVwdGggfSxcblx0XHRcdGZvcm1hdDogVGV4dHVyZUZvcm1hdC5EZXB0aDI0UGx1cyxcblx0XHRcdHVzYWdlOiBUZXh0dXJlVXNhZ2UuUmVuZGVyQXR0YWNobWVudFxuXHRcdH0pO1xuXHRcdGNvbnN0IGRlcHRoQXR0YWNobWVudCA9IG5ldyBBdHRhY2htZW50KDEuMCwgeyB0ZXh0dXJlOiBkZXB0aFRleHR1cmUgfSk7XG5cdFx0dGhpcy5jYW52YXNSZW5kZXJUYXJnZXQgPSBuZXcgUmVuZGVyVGFyZ2V0KFwicmVuZGVyXCIsIFtjb2xvckF0dGFjaG1lbnRdLCBkZXB0aEF0dGFjaG1lbnQpO1xuXHR9XG59XG4iLCJpbXBvcnQgQ29udGV4dCBmcm9tIFwiLi4vcmVuZGVyL0NvbnRleHRcIjtcbmltcG9ydCBUZXh0dXJlIGZyb20gXCIuLi9yZW5kZXIvVGV4dHVyZVwiO1xuaW1wb3J0IFBvc3RFZmZlY3QgZnJvbSBcIi4vUG9zdEVmZmVjdFwiO1xuaW1wb3J0IFJlc29sdmVGcmFtZSBmcm9tIFwiLi9SZXNvbHZlRnJhbWVcIjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUG9zdEVmZmVjdENvbGxlY3Rpb24ge1xuXHRwcml2YXRlIF9wb3N0RWZmZWN0czogTWFwPHN0cmluZywgUG9zdEVmZmVjdD47XG5cdHB1YmxpYyBjdXJyZW50Q29sb3JUZXh0dXJlOiBUZXh0dXJlO1xuXHRwcml2YXRlIHJlc29sdmVGcmFtZTogUmVzb2x2ZUZyYW1lO1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHR0aGlzLl9wb3N0RWZmZWN0cyA9IG5ldyBNYXAoKTtcblx0XHR0aGlzLmN1cnJlbnRDb2xvclRleHR1cmUgPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy5yZXNvbHZlRnJhbWUgPSBuZXcgUmVzb2x2ZUZyYW1lKCk7XG5cdH1cblx0YWRkKHBvc3RFZmZlY3Q6IFBvc3RFZmZlY3QpIHtcblx0XHR0aGlzLl9wb3N0RWZmZWN0cy5zZXQocG9zdEVmZmVjdC5pZCwgcG9zdEVmZmVjdCk7XG5cdH1cblx0cmVtb3ZlKHBvc3RFZmZlY3Q6IFBvc3RFZmZlY3QpIHtcblx0XHR0aGlzLl9wb3N0RWZmZWN0cy5kZWxldGUocG9zdEVmZmVjdC5pZCk7XG5cdFx0cG9zdEVmZmVjdC5kZXN0cm95KCk7XG5cdH1cblx0cmVuZGVyKGNvbnRleHQ6IENvbnRleHQsIGNvbG9yVGV4dHVyZTogVGV4dHVyZSk6IHZvaWQge1xuXHRcdHRoaXMuY3VycmVudENvbG9yVGV4dHVyZSA9IGNvbG9yVGV4dHVyZTtcblx0XHR0aGlzLl9wb3N0RWZmZWN0cy5mb3JFYWNoKChwb3N0RWZmZWN0KSA9PiB7XG5cdFx0XHR0aGlzLmN1cnJlbnRDb2xvclRleHR1cmUgPSBwb3N0RWZmZWN0LnJlbmRlcihjb250ZXh0LCB0aGlzLmN1cnJlbnRDb2xvclRleHR1cmUpO1xuXHRcdH0pO1xuXHRcdHRoaXMucmVzb2x2ZUZyYW1lLnJlbmRlcihjb250ZXh0LCB0aGlzLmN1cnJlbnRDb2xvclRleHR1cmUpO1xuXHR9XG5cdHNldFNpemUod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcblx0XHR0aGlzLl9wb3N0RWZmZWN0cy5mb3JFYWNoKChwb3N0RWZmZWN0KSA9PiBwb3N0RWZmZWN0LnNldFNpemUod2lkdGgsIGhlaWdodCkpO1xuXHRcdHRoaXMucmVzb2x2ZUZyYW1lLnNldFNpemUod2lkdGgsIGhlaWdodCk7XG5cdH1cblx0cHJpdmF0ZSBwb3N0RWZmZWN0c1NvcnQoKSB7XG5cdFx0Ly8gdGhpcy5fcG9zdEVmZmVjdHMuc29ydCgpXG5cdH1cbn1cbiIsImltcG9ydCB7IEZyYW1lU3RhdGUgfSBmcm9tIFwiLi4vY29yZS9GcmFtZVN0YXRlLmpzXCI7XG5pbXBvcnQgeyBNYXRlcmlhbCB9IGZyb20gXCIuLi9tYXRlcmlhbC9NYXRlcmlhbC5qc1wiO1xuaW1wb3J0IENvbnRleHQgZnJvbSBcIi4uL3JlbmRlci9Db250ZXh0LmpzXCI7XG5pbXBvcnQgeyBUYXJnZXQgfSBmcm9tIFwiLi4vcmVuZGVyL1JlbmRlclN0YXRlXCI7XG5pbXBvcnQgUmVuZGVyVGFyZ2V0IGZyb20gXCIuLi9yZW5kZXIvUmVuZGVyVGFyZ2V0LmpzXCI7XG5pbXBvcnQgVGV4dHVyZSBmcm9tIFwiLi4vcmVuZGVyL1RleHR1cmUuanNcIjtcblxuY2xhc3MgUGFzcyB7XG5cdHB1YmxpYyByZW5kZXJUYXJnZXQ6IFJlbmRlclRhcmdldDtcblx0cHVibGljIGNvbXB1dGVUYXJnZXQ6IFJlbmRlclRhcmdldDtcblx0cHVibGljIGNvbnRleHQ6IENvbnRleHQ7XG5cdHB1YmxpYyBvdmVycmlkZU1hdGVyaWFsPzogTWF0ZXJpYWw7XG5cdHB1YmxpYyBjb2xvclRhcmdldHM/OiBBcnJheTxUYXJnZXQ+O1xuXHRwdWJsaWMgcGFzc1JlbmRlckVuY29kZXI6IEdQVVJlbmRlclBhc3NFbmNvZGVyIHwgbnVsbDtcblx0cHVibGljIHBhc3NDb21wdXRlRW5jb2RlcjogR1BVQ29tcHV0ZVBhc3NFbmNvZGVyO1xuXHRjb25zdHJ1Y3Rvcihjb250ZXh0OiBDb250ZXh0KSB7XG5cdFx0dGhpcy5jb250ZXh0ID0gY29udGV4dDtcblx0fVxuXHR1cGRhdGUoZnJhbWVTdGF0ZTogRnJhbWVTdGF0ZSk6IHZvaWQge1xuXHRcdC8vIHRvZG87XG5cdH1cblx0c2V0U2l6ZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IHZvaWQge1xuXHRcdC8vIHRvZG8gO1xuXHR9XG5cdGJlZm9yZVJlbmRlcihvcHRpb25zPzogYW55KSB7XG5cdFx0dGhpcy5wYXNzUmVuZGVyRW5jb2RlciA9IHRoaXMucmVuZGVyVGFyZ2V0LmJlZ2luUmVuZGVyUGFzcyh0aGlzLmNvbnRleHQuZGV2aWNlKTtcblx0XHRpZiAodGhpcy5jb21wdXRlVGFyZ2V0KVxuXHRcdFx0dGhpcy5wYXNzQ29tcHV0ZUVuY29kZXIgPSB0aGlzLmNvbXB1dGVUYXJnZXQuYmVnaW5Db21wdXRlUGFzc0VuY29kZXIodGhpcy5jb250ZXh0LmRldmljZSk7XG5cdH1cblx0Z2V0Q29sb3JUZXh0dXJlKGluZGV4ID0gMCk6IFRleHR1cmUge1xuXHRcdHJldHVybiB0aGlzLnJlbmRlclRhcmdldC5nZXRDb2xvclRleHR1cmUoaW5kZXgpIGFzIFRleHR1cmU7XG5cdH1cblx0Z2V0RGVwdGhUZXh0dXJlKCk6IFRleHR1cmUgfCB7IGdwdVRleHR1cmU6IEdQVVRleHR1cmUgfSB7XG5cdFx0cmV0dXJuIHRoaXMucmVuZGVyVGFyZ2V0LmdldERlcHRoVGV4dHVyZSgpO1xuXHR9XG5cdGFmdGVyUmVuZGVyKCkge1xuXHRcdHRoaXMucmVuZGVyVGFyZ2V0LmVuZFJlbmRlclBhc3MoKTtcblx0XHRpZiAodGhpcy5jb21wdXRlVGFyZ2V0KSB0aGlzLmNvbXB1dGVUYXJnZXQuZW5kQ29tcHV0ZVBhc3NFbmNvZGVyKCk7XG5cdH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUGFzcztcbiIsImltcG9ydCBDYW1lcmEgZnJvbSBcIi4uL2NhbWVyYS9DYW1lcmFcIjtcbmltcG9ydCB7IEZyYW1lU3RhdGUgfSBmcm9tIFwiLi4vY29yZS9GcmFtZVN0YXRlXCI7XG5pbXBvcnQgeyBUZXh0dXJlRm9ybWF0LCBUZXh0dXJlVXNhZ2UgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVDb25zdGFudFwiO1xuaW1wb3J0IENvbG9yIGZyb20gXCIuLi9tYXRoL0NvbG9yXCI7XG5pbXBvcnQgQXR0YWNobWVudCBmcm9tIFwiLi4vcmVuZGVyL0F0dGFjaG1lbnRcIjtcbmltcG9ydCBDb250ZXh0IGZyb20gXCIuLi9yZW5kZXIvQ29udGV4dFwiO1xuaW1wb3J0IERyYXdDb21tYW5kIGZyb20gXCIuLi9yZW5kZXIvRHJhd0NvbW1hbmRcIjtcbmltcG9ydCBSZW5kZXJUYXJnZXQgZnJvbSBcIi4uL3JlbmRlci9SZW5kZXJUYXJnZXRcIjtcbmltcG9ydCBUZXh0dXJlIGZyb20gXCIuLi9yZW5kZXIvVGV4dHVyZVwiO1xuaW1wb3J0IFBhc3MgZnJvbSBcIi4vUGFzc1wiO1xuXG5leHBvcnQgY2xhc3MgQmFzaWNQYXNzIGV4dGVuZHMgUGFzcyB7XG5cdHNreWJveERyYXdDb21hbmQ6IERyYXdDb21tYW5kO1xuXHRjb25zdHJ1Y3Rvcihjb250ZXh0OiBDb250ZXh0KSB7XG5cdFx0c3VwZXIoY29udGV4dCk7XG5cdFx0dGhpcy5pbml0KGNvbnRleHQpO1xuXHR9XG5cblx0YmVmb3JlUmVuZGVyKGZyYW1lU3RhdGU6IEZyYW1lU3RhdGUpIHtcblx0XHR0aGlzLnVwZGF0ZVJlbmRlclRhcmdldChmcmFtZVN0YXRlKTtcblxuXHRcdHN1cGVyLmJlZm9yZVJlbmRlcigpO1xuXHR9XG5cblx0cmVuZGVyKGZyYW1lU3RhdGU6IEZyYW1lU3RhdGUsIGNhbWVyYT86IENhbWVyYSkge1xuXHRcdGNvbnN0IHsgcmVuZGVyUXVldWUsIGxpZ2h0TWFuZ2VyIH0gPSBmcmFtZVN0YXRlO1xuXG5cdFx0cmVuZGVyUXVldWUuc29ydCgpO1xuXHRcdHJlbmRlclF1ZXVlLnByZVJlbmRlcihjYW1lcmEsIHRoaXMuY29udGV4dCwgdGhpcy5wYXNzUmVuZGVyRW5jb2Rlcik7XG5cdFx0cmVuZGVyUXVldWUudHJhbnNwYXJlbnRSZW5kZXIoY2FtZXJhLCB0aGlzLmNvbnRleHQsIHRoaXMucGFzc1JlbmRlckVuY29kZXIsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBsaWdodE1hbmdlcik7XG5cdFx0cmVuZGVyUXVldWUub3BhcXVlUmVuZGVyKGNhbWVyYSwgdGhpcy5jb250ZXh0LCB0aGlzLnBhc3NSZW5kZXJFbmNvZGVyLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgbGlnaHRNYW5nZXIpO1xuXHRcdHJlbmRlclF1ZXVlLmRlYnVnUXVldWVSZW5kZXIoY2FtZXJhLCB0aGlzLmNvbnRleHQsIHRoaXMucGFzc1JlbmRlckVuY29kZXIpO1xuXHR9XG5cdHByaXZhdGUgaW5pdChjb250ZXh0OiBDb250ZXh0KSB7XG5cdFx0dGhpcy5jcmVhdGVSZW5kZXJUYXJnZXQoY29udGV4dCk7XG5cdH1cblx0cHJpdmF0ZSBjcmVhdGVSZW5kZXJUYXJnZXQoY29udGV4dDogQ29udGV4dCkge1xuXHRcdGNvbnN0IHsgd2lkdGgsIGhlaWdodCwgZGVwdGggfSA9IGNvbnRleHQucHJlc2VudGF0aW9uU2l6ZTtcblx0XHRjb25zdCBjb2xvclRleHR1cmUgPSBuZXcgVGV4dHVyZSh7XG5cdFx0XHRsYWJlbDogXCJiYXNpY1Bhc3NDb2xvclwiLFxuXHRcdFx0c2l6ZTogeyB3aWR0aCwgaGVpZ2h0LCBkZXB0aCB9LFxuXHRcdFx0Zm9ybWF0OiB0aGlzLmNvbnRleHQucHJlc2VudGF0aW9uRm9ybWF0LFxuXHRcdFx0dXNhZ2U6IFRleHR1cmVVc2FnZS5SZW5kZXJBdHRhY2htZW50IHwgVGV4dHVyZVVzYWdlLlRleHR1cmVCaW5kaW5nXG5cdFx0fSk7XG5cdFx0Y29uc3QgZGVwdGhUZXh0dXJlID0gbmV3IFRleHR1cmUoe1xuXHRcdFx0bGFiZWw6IFwiYmFzaWNQYXNzRGVwdGhcIixcblx0XHRcdHNpemU6IHsgd2lkdGgsIGhlaWdodCwgZGVwdGggfSxcblx0XHRcdGZvcm1hdDogVGV4dHVyZUZvcm1hdC5EZXB0aDI0UGx1cyxcblx0XHRcdHVzYWdlOiBUZXh0dXJlVXNhZ2UuUmVuZGVyQXR0YWNobWVudFxuXHRcdH0pO1xuXHRcdGNvbnN0IGNvbG9yQXR0YWNobWVudCA9IG5ldyBBdHRhY2htZW50KHsgcjogMC4wLCBnOiAwLjAsIGI6IDAuMCwgYTogMC4wIH0sIHsgdGV4dHVyZTogY29sb3JUZXh0dXJlIH0pO1xuXHRcdGNvbnN0IGRlcHRoQXR0YWNobWVudCA9IG5ldyBBdHRhY2htZW50KDEuMCwgeyB0ZXh0dXJlOiBkZXB0aFRleHR1cmUgfSk7XG5cdFx0dGhpcy5yZW5kZXJUYXJnZXQgPSBuZXcgUmVuZGVyVGFyZ2V0KFwicmVuZGVyXCIsIFtjb2xvckF0dGFjaG1lbnRdLCBkZXB0aEF0dGFjaG1lbnQpO1xuXHR9XG5cdHB1YmxpYyBzZXRTaXplKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogdm9pZCB7XG5cdFx0dGhpcy5yZW5kZXJUYXJnZXQuc2V0U2l6ZSh3aWR0aCwgaGVpZ2h0LCAxKTtcblx0fVxuXHRwcml2YXRlIHVwZGF0ZVJlbmRlclRhcmdldChmcmFtZVN0YXRlOiBGcmFtZVN0YXRlKSB7XG5cdFx0aWYgKGZyYW1lU3RhdGU/LmJhY2tncm91bmQ/LnZhbHVlIGluc3RhbmNlb2YgQ29sb3IpIHtcblx0XHRcdGNvbnN0IHsgcmVkLCBncmVlbiwgYmx1ZSB9ID0gZnJhbWVTdGF0ZS5iYWNrZ3JvdW5kLnZhbHVlO1xuXHRcdFx0Y29uc3Qgb3BhY2l0eSA9IGZyYW1lU3RhdGUuYmFja2dyb3VuZD8ub3BhY2l0eTtcblx0XHRcdGNvbnN0IGNsZWFyVmFsdWUgPSB7XG5cdFx0XHRcdHI6IHJlZCxcblx0XHRcdFx0ZzogZ3JlZW4sXG5cdFx0XHRcdGI6IGJsdWUsXG5cdFx0XHRcdGE6IG9wYWNpdHkgPz8gMS4wXG5cdFx0XHR9O1xuXHRcdFx0dGhpcy5yZW5kZXJUYXJnZXQuY29sb3JBdHRhY2htZW50c1swXS52YWx1ZSA9IGNsZWFyVmFsdWU7XG5cdFx0fVxuXHR9XG59XG4iLCJpbXBvcnQgZGVmaW5lZCBmcm9tIFwiLi4vdXRpbHMvZGVmaW5lZFwiO1xyXG5pbXBvcnQgR01hdGggZnJvbSBcIi4vTWF0aFwiO1xyXG5pbXBvcnQgTWF0cml4NCBmcm9tIFwiLi9NYXRyaXg0XCI7XHJcbmltcG9ydCBWZWN0b3IzIGZyb20gXCIuL1ZlY3RvcjNcIjtcclxuaW1wb3J0IFZlY3RvcjQgZnJvbSBcIi4vVmVjdG9yNFwiO1xyXG5cclxuLyoqXHJcbiAqIEEgcGxhbmUgaW4gSGVzc2lhbiBOb3JtYWwgRm9ybSBkZWZpbmVkIGJ5XHJcbiAqIDxwcmU+XHJcbiAqIGF4ICsgYnkgKyBjeiArIGQgPSAwXHJcbiAqIDwvcHJlPlxyXG4gKiB3aGVyZSAoYSwgYiwgYykgaXMgdGhlIHBsYW5lJ3MgPGNvZGU+bm9ybWFsPC9jb2RlPiwgZCBpcyB0aGUgc2lnbmVkXHJcbiAqIDxjb2RlPmRpc3RhbmNlPC9jb2RlPiB0byB0aGUgcGxhbmUsIGFuZCAoeCwgeSwgeikgaXMgYW55IHBvaW50IG9uXHJcbiAqIHRoZSBwbGFuZS5cclxuICpcclxuICogQGFsaWFzIFBsYW5lXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKlxyXG4gKiBAcGFyYW0ge1ZlY3RvcjN9IG5vcm1hbCBUaGUgcGxhbmUncyBub3JtYWwgKG5vcm1hbGl6ZWQpLlxyXG4gKiBAcGFyYW0ge051bWJlcn0gZGlzdGFuY2UgVGhlIHNob3J0ZXN0IGRpc3RhbmNlIGZyb20gdGhlIG9yaWdpbiB0byB0aGUgcGxhbmUuICBUaGUgc2lnbiBvZlxyXG4gKiBAZXhhbXBsZVxyXG4gKiAvLyBUaGUgcGxhbmUgeD0wXHJcbiAqIGNvbnN0IHBsYW5lID0gbmV3IFBsYW5lKFZlY3RvcjMuVU5JVF9YLCAwLjApO1xyXG4gKlxyXG4gKiBAZXhjZXB0aW9uIHtEZXZlbG9wZXJFcnJvcn0gTm9ybWFsIG11c3QgYmUgbm9ybWFsaXplZFxyXG4gKi9cclxuY2xhc3MgUGxhbmUge1xyXG5cdG5vcm1hbDogVmVjdG9yMztcclxuXHRkaXN0YW5jZTogbnVtYmVyO1xyXG5cdHB1YmxpYyBzdGF0aWMgT1JJR0lOX1hZX1BMQU5FID0gT2JqZWN0LmZyZWV6ZShuZXcgUGxhbmUoVmVjdG9yMy5VTklUX1osIDAuMCkpO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIE9SSUdJTl9ZWl9QTEFORSA9IE9iamVjdC5mcmVlemUobmV3IFBsYW5lKFZlY3RvcjMuVU5JVF9YLCAwLjApKTtcclxuXHJcblx0cHVibGljIHN0YXRpYyBPUklHSU5fWlhfUExBTkUgPSBPYmplY3QuZnJlZXplKG5ldyBQbGFuZShWZWN0b3IzLlVOSVRfWSwgMC4wKSk7XHJcblx0Y29uc3RydWN0b3Iobm9ybWFsOiBWZWN0b3IzLCBkaXN0YW5jZTogbnVtYmVyKSB7XHJcblx0XHR0aGlzLm5vcm1hbCA9IFZlY3RvcjMuY2xvbmUobm9ybWFsKTtcclxuXHJcblx0XHR0aGlzLmRpc3RhbmNlID0gZGlzdGFuY2U7XHJcblx0fVxyXG5cdG5vcm1hbGl6ZSgpIHtcclxuXHRcdGNvbnN0IGludmVyc2VOb3JtYWxMZW5ndGggPSAxLjAgLyB0aGlzLm5vcm1hbC5sZW5ndGgoKTtcclxuXHRcdHRoaXMubm9ybWFsID0gVmVjdG9yMy5tdWx0aXBseUJ5U2NhbGFyKHRoaXMubm9ybWFsLCBpbnZlcnNlTm9ybWFsTGVuZ3RoLCB0aGlzLm5vcm1hbCk7XHJcblx0XHR0aGlzLmRpc3RhbmNlICo9IGludmVyc2VOb3JtYWxMZW5ndGg7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBmcm9tUG9pbnROb3JtYWwocG9pbnQ6IFZlY3RvcjMsIG5vcm1hbDogVmVjdG9yMywgcmVzdWx0OiBQbGFuZSk6IFBsYW5lIHtcclxuXHRcdGlmICghR01hdGguZXF1YWxzRXBzaWxvbihWZWN0b3IzLm1hZ25pdHVkZShub3JtYWwpLCAxLjAsIEdNYXRoLkVQU0lMT042KSkge1xyXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJub3JtYWwgbXVzdCBiZSBub3JtYWxpemVkLlwiKTtcclxuXHRcdH1cclxuXHRcdC8vID4+aW5jbHVkZUVuZCgnZGVidWcnKTtcclxuXHJcblx0XHRjb25zdCBkaXN0YW5jZSA9IC1WZWN0b3IzLmRvdChub3JtYWwsIHBvaW50KTtcclxuXHJcblx0XHRpZiAoIWRlZmluZWQocmVzdWx0KSkge1xyXG5cdFx0XHRyZXR1cm4gbmV3IFBsYW5lKG5vcm1hbCwgZGlzdGFuY2UpO1xyXG5cdFx0fVxyXG5cclxuXHRcdFZlY3RvcjMuY2xvbmUobm9ybWFsLCByZXN1bHQubm9ybWFsKTtcclxuXHRcdHJlc3VsdC5kaXN0YW5jZSA9IGRpc3RhbmNlO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBmcm9tVmVjdG9yNChjb2VmZmljaWVudHM6IFZlY3RvcjQsIHJlc3VsdDogUGxhbmUpOiBQbGFuZSB7XHJcblx0XHRjb25zdCBub3JtYWwgPSBWZWN0b3IzLmZyb21WZWN0b3I0KGNvZWZmaWNpZW50cywgc2NyYXRjaE5vcm1hbCk7XHJcblx0XHRjb25zdCBkaXN0YW5jZSA9IGNvZWZmaWNpZW50cy53O1xyXG5cclxuXHRcdC8vID4+aW5jbHVkZVN0YXJ0KCdkZWJ1ZycsIHByYWdtYXMuZGVidWcpO1xyXG5cdFx0aWYgKCFHTWF0aC5lcXVhbHNFcHNpbG9uKFZlY3RvcjMubWFnbml0dWRlKG5vcm1hbCksIDEuMCwgR01hdGguRVBTSUxPTjYpKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIm5vcm1hbCBtdXN0IGJlIG5vcm1hbGl6ZWQuXCIpO1xyXG5cdFx0fVxyXG5cdFx0Ly8gPj5pbmNsdWRlRW5kKCdkZWJ1ZycpO1xyXG5cclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJldHVybiBuZXcgUGxhbmUobm9ybWFsLCBkaXN0YW5jZSk7XHJcblx0XHR9XHJcblx0XHRWZWN0b3IzLmNsb25lKG5vcm1hbCwgcmVzdWx0Lm5vcm1hbCk7XHJcblx0XHRyZXN1bHQuZGlzdGFuY2UgPSBkaXN0YW5jZTtcclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgZ2V0UG9pbnREaXN0YW5jZShwbGFuZTogUGxhbmUsIHBvaW50OiBWZWN0b3IzKTogbnVtYmVyIHtcclxuXHRcdHJldHVybiBWZWN0b3IzLmRvdChwbGFuZS5ub3JtYWwsIHBvaW50KSArIHBsYW5lLmRpc3RhbmNlO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIHByb2plY3RQb2ludE9udG9QbGFuZShwbGFuZTogUGxhbmUsIHBvaW50OiBWZWN0b3IzLCByZXN1bHQ6IFZlY3RvcjMpOiBWZWN0b3IzIHtcclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJlc3VsdCA9IG5ldyBWZWN0b3IzKCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gcHJvamVjdGVkUG9pbnQgPSBwb2ludCAtIChub3JtYWwucG9pbnQgKyBzY2FsZSkgKiBub3JtYWxcclxuXHRcdGNvbnN0IHBvaW50RGlzdGFuY2UgPSBQbGFuZS5nZXRQb2ludERpc3RhbmNlKHBsYW5lLCBwb2ludCk7XHJcblx0XHRjb25zdCBzY2FsZWROb3JtYWwgPSBWZWN0b3IzLm11bHRpcGx5QnlTY2FsYXIocGxhbmUubm9ybWFsLCBwb2ludERpc3RhbmNlLCBzY3JhdGNoQ2FydGVzaWFuKTtcclxuXHJcblx0XHRyZXR1cm4gVmVjdG9yMy5zdWJ0cmFjdChwb2ludCwgc2NhbGVkTm9ybWFsLCByZXN1bHQpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIHRyYW5zZm9ybShwbGFuZTogUGxhbmUsIHRyYW5zZm9ybTogTWF0cml4NCwgcmVzdWx0OiBQbGFuZSk6IFBsYW5lIHtcclxuXHRcdGNvbnN0IG5vcm1hbCA9IHBsYW5lLm5vcm1hbDtcclxuXHRcdGNvbnN0IGRpc3RhbmNlID0gcGxhbmUuZGlzdGFuY2U7XHJcblx0XHRjb25zdCBpbnZlcnNlVHJhbnNwb3NlID0gTWF0cml4NC5pbnZlcnNlVHJhbnNwb3NlKHRyYW5zZm9ybSwgc2NyYXRjaEludmVyc2VUcmFuc3Bvc2UpO1xyXG5cdFx0bGV0IHBsYW5lQXNDYXJ0ZXNpYW40ID0gVmVjdG9yNC5mcm9tRWxlbWVudHMobm9ybWFsLngsIG5vcm1hbC55LCBub3JtYWwueiwgZGlzdGFuY2UsIHNjcmF0Y2hQbGFuZUNhcnRlc2lhbjQpO1xyXG5cdFx0cGxhbmVBc0NhcnRlc2lhbjQgPSBNYXRyaXg0Lm11bHRpcGx5QnlWZWN0b3IoaW52ZXJzZVRyYW5zcG9zZSwgcGxhbmVBc0NhcnRlc2lhbjQsIHBsYW5lQXNDYXJ0ZXNpYW40KTtcclxuXHJcblx0XHQvLyBDb252ZXJ0IHRoZSB0cmFuc2Zvcm1lZCBwbGFuZSB0byBIZXNzaWFuIE5vcm1hbCBGb3JtXHJcblx0XHRjb25zdCB0cmFuc2Zvcm1lZE5vcm1hbCA9IFZlY3RvcjMuZnJvbVZlY3RvcjQocGxhbmVBc0NhcnRlc2lhbjQsIHNjcmF0Y2hUcmFuc2Zvcm1Ob3JtYWwpO1xyXG5cclxuXHRcdHBsYW5lQXNDYXJ0ZXNpYW40ID0gVmVjdG9yNC5kaXZpZGVCeVNjYWxhcihcclxuXHRcdFx0cGxhbmVBc0NhcnRlc2lhbjQsXHJcblx0XHRcdFZlY3RvcjMubWFnbml0dWRlKHRyYW5zZm9ybWVkTm9ybWFsKSxcclxuXHRcdFx0cGxhbmVBc0NhcnRlc2lhbjRcclxuXHRcdCk7XHJcblxyXG5cdFx0cmV0dXJuIFBsYW5lLmZyb21WZWN0b3I0KHBsYW5lQXNDYXJ0ZXNpYW40LCByZXN1bHQpO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGNsb25lKHBsYW5lOiBQbGFuZSwgcmVzdWx0OiBQbGFuZSk6IFBsYW5lIHtcclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJldHVybiBuZXcgUGxhbmUocGxhbmUubm9ybWFsLCBwbGFuZS5kaXN0YW5jZSk7XHJcblx0XHR9XHJcblxyXG5cdFx0VmVjdG9yMy5jbG9uZShwbGFuZS5ub3JtYWwsIHJlc3VsdC5ub3JtYWwpO1xyXG5cdFx0cmVzdWx0LmRpc3RhbmNlID0gcGxhbmUuZGlzdGFuY2U7XHJcblxyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBlcXVhbHMobGVmdDogUGxhbmUsIHJpZ2h0OiBQbGFuZSk6IGJvb2xlYW4ge1xyXG5cdFx0cmV0dXJuIGxlZnQuZGlzdGFuY2UgPT09IHJpZ2h0LmRpc3RhbmNlICYmIFZlY3RvcjMuZXF1YWxzKGxlZnQubm9ybWFsLCByaWdodC5ub3JtYWwpO1xyXG5cdH1cclxufVxyXG5jb25zdCBzY3JhdGNoTm9ybWFsID0gbmV3IFZlY3RvcjMoKTtcclxuY29uc3Qgc2NyYXRjaENhcnRlc2lhbiA9IG5ldyBWZWN0b3IzKCk7XHJcbmNvbnN0IHNjcmF0Y2hJbnZlcnNlVHJhbnNwb3NlID0gbmV3IE1hdHJpeDQoKTtcclxuY29uc3Qgc2NyYXRjaFBsYW5lQ2FydGVzaWFuNCA9IG5ldyBWZWN0b3I0KCk7XHJcbmNvbnN0IHNjcmF0Y2hUcmFuc2Zvcm1Ob3JtYWwgPSBuZXcgVmVjdG9yMygpO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgUGxhbmU7XHJcbiIsImltcG9ydCBWZWN0b3IzIGZyb20gXCIuLi9tYXRoL1ZlY3RvcjNcIjtcclxuaW1wb3J0IFZlY3RvcjQgZnJvbSBcIi4uL21hdGgvVmVjdG9yNFwiO1xyXG5pbXBvcnQgZGVmYXVsdFZhbHVlIGZyb20gXCIuLi91dGlscy9kZWZhdWx0VmFsdWVcIjtcclxuaW1wb3J0IGRlZmluZWQgZnJvbSBcIi4uL3V0aWxzL2RlZmluZWRcIjtcclxuaW1wb3J0IHsgSW50ZXJzZWN0IH0gZnJvbSBcIi4vV2ViR1BVQ29uc3RhbnRcIjtcclxuaW1wb3J0IFBsYW5lIGZyb20gXCIuLi9tYXRoL1BsYW5lXCI7XHJcblxyXG4vKipcclxuICogVGhlIGN1bGxpbmcgdm9sdW1lIGRlZmluZWQgYnkgcGxhbmVzLlxyXG4gKlxyXG4gKiBAYWxpYXMgQ3VsbGluZ1ZvbHVtZVxyXG4gKiBAY29uc3RydWN0b3JcclxuICpcclxuICogQHBhcmFtIHtWZWN0b3I0W119IFtwbGFuZXNdIEFuIGFycmF5IG9mIGNsaXBwaW5nIHBsYW5lcy5cclxuICovXHJcbmNsYXNzIEN1bGxpbmdWb2x1bWUge1xyXG5cdHBsYW5lczogUGxhbmVbXTtcclxuXHJcblx0cHVibGljIHN0YXRpYyBNQVNLX09VVFNJREUgPSAweGZmZmZmZmZmO1xyXG5cclxuXHRwdWJsaWMgc3RhdGljIE1BU0tfSU5TSURFID0gMHgwMDAwMDAwMDtcclxuXHJcblx0cHVibGljIHN0YXRpYyBNQVNLX0lOREVURVJNSU5BVEUgPSAweDdmZmZmZmZmO1xyXG5cclxuXHRjb25zdHJ1Y3RvcihwbGFuZXM/OiBQbGFuZVtdKSB7XHJcblx0XHR0aGlzLnBsYW5lcyA9IGRlZmF1bHRWYWx1ZShwbGFuZXMsIFtcclxuXHRcdFx0bmV3IFBsYW5lKFZlY3RvcjMuVU5JVF9aLCAwLjApLFxyXG5cdFx0XHRuZXcgUGxhbmUoVmVjdG9yMy5VTklUX1osIDAuMCksXHJcblx0XHRcdG5ldyBQbGFuZShWZWN0b3IzLlVOSVRfWiwgMC4wKSxcclxuXHRcdFx0bmV3IFBsYW5lKFZlY3RvcjMuVU5JVF9aLCAwLjApLFxyXG5cdFx0XHRuZXcgUGxhbmUoVmVjdG9yMy5VTklUX1osIDAuMCksXHJcblx0XHRcdG5ldyBQbGFuZShWZWN0b3IzLlVOSVRfWiwgMC4wKVxyXG5cdFx0XSk7XHJcblx0fVxyXG5cdC8qKlxyXG5cdCAqIENvbnN0cnVjdHMgYSBjdWxsaW5nIHZvbHVtZSBmcm9tIGEgYm91bmRpbmcgc3BoZXJlLiBDcmVhdGVzIHNpeCBwbGFuZXMgdGhhdCBjcmVhdGUgYSBib3ggY29udGFpbmluZyB0aGUgc3BoZXJlLlxyXG5cdCAqIFRoZSBwbGFuZXMgYXJlIGFsaWduZWQgdG8gdGhlIHgsIHksIGFuZCB6IGF4ZXMgaW4gd29ybGQgY29vcmRpbmF0ZXMuXHJcblx0ICpcclxuXHQgKiBAcGFyYW0ge0JvdW5kaW5nU3BoZXJlfSBib3VuZGluZ1NwaGVyZSBUaGUgYm91bmRpbmcgc3BoZXJlIHVzZWQgdG8gY3JlYXRlIHRoZSBjdWxsaW5nIHZvbHVtZS5cclxuXHQgKiBAcGFyYW0ge0N1bGxpbmdWb2x1bWV9IFtyZXN1bHRdIFRoZSBvYmplY3Qgb250byB3aGljaCB0byBzdG9yZSB0aGUgcmVzdWx0LlxyXG5cdCAqIEByZXR1cm5zIHtDdWxsaW5nVm9sdW1lfSBUaGUgY3VsbGluZyB2b2x1bWUgY3JlYXRlZCBmcm9tIHRoZSBib3VuZGluZyBzcGhlcmUuXHJcblx0ICovXHJcblx0c3RhdGljIGZyb21Cb3VuZGluZ1NwaGVyZShib3VuZGluZ1NwaGVyZSwgcmVzdWx0KSB7XHJcblx0XHRpZiAoIWRlZmluZWQoYm91bmRpbmdTcGhlcmUpKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcImJvdW5kaW5nU3BoZXJlIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdGlmICghZGVmaW5lZChyZXN1bHQpKSB7XHJcblx0XHRcdHJlc3VsdCA9IG5ldyBDdWxsaW5nVm9sdW1lKCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Y29uc3QgbGVuZ3RoID0gZmFjZXMubGVuZ3RoO1xyXG5cdFx0Y29uc3QgcGxhbmVzID0gcmVzdWx0LnBsYW5lcztcclxuXHRcdHBsYW5lcy5sZW5ndGggPSAyICogbGVuZ3RoO1xyXG5cclxuXHRcdGNvbnN0IGNlbnRlciA9IGJvdW5kaW5nU3BoZXJlLmNlbnRlcjtcclxuXHRcdGNvbnN0IHJhZGl1cyA9IGJvdW5kaW5nU3BoZXJlLnJhZGl1cztcclxuXHJcblx0XHRsZXQgcGxhbmVJbmRleCA9IDA7XHJcblxyXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xyXG5cdFx0XHRjb25zdCBmYWNlTm9ybWFsID0gZmFjZXNbaV07XHJcblxyXG5cdFx0XHRsZXQgcGxhbmUwID0gcGxhbmVzW3BsYW5lSW5kZXhdO1xyXG5cdFx0XHRsZXQgcGxhbmUxID0gcGxhbmVzW3BsYW5lSW5kZXggKyAxXTtcclxuXHJcblx0XHRcdGlmICghZGVmaW5lZChwbGFuZTApKSB7XHJcblx0XHRcdFx0cGxhbmUwID0gcGxhbmVzW3BsYW5lSW5kZXhdID0gbmV3IFZlY3RvcjQoKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAoIWRlZmluZWQocGxhbmUxKSkge1xyXG5cdFx0XHRcdHBsYW5lMSA9IHBsYW5lc1twbGFuZUluZGV4ICsgMV0gPSBuZXcgVmVjdG9yNCgpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRWZWN0b3IzLm11bHRpcGx5QnlTY2FsYXIoZmFjZU5vcm1hbCwgLXJhZGl1cywgc2NyYXRjaFBsYW5lQ2VudGVyKTtcclxuXHRcdFx0VmVjdG9yMy5hZGQoY2VudGVyLCBzY3JhdGNoUGxhbmVDZW50ZXIsIHNjcmF0Y2hQbGFuZUNlbnRlcik7XHJcblxyXG5cdFx0XHRwbGFuZTAueCA9IGZhY2VOb3JtYWwueDtcclxuXHRcdFx0cGxhbmUwLnkgPSBmYWNlTm9ybWFsLnk7XHJcblx0XHRcdHBsYW5lMC56ID0gZmFjZU5vcm1hbC56O1xyXG5cdFx0XHRwbGFuZTAudyA9IC1WZWN0b3IzLmRvdChmYWNlTm9ybWFsLCBzY3JhdGNoUGxhbmVDZW50ZXIpO1xyXG5cclxuXHRcdFx0VmVjdG9yMy5tdWx0aXBseUJ5U2NhbGFyKGZhY2VOb3JtYWwsIHJhZGl1cywgc2NyYXRjaFBsYW5lQ2VudGVyKTtcclxuXHRcdFx0VmVjdG9yMy5hZGQoY2VudGVyLCBzY3JhdGNoUGxhbmVDZW50ZXIsIHNjcmF0Y2hQbGFuZUNlbnRlcik7XHJcblxyXG5cdFx0XHRwbGFuZTEueCA9IC1mYWNlTm9ybWFsLng7XHJcblx0XHRcdHBsYW5lMS55ID0gLWZhY2VOb3JtYWwueTtcclxuXHRcdFx0cGxhbmUxLnogPSAtZmFjZU5vcm1hbC56O1xyXG5cdFx0XHRwbGFuZTEudyA9IC1WZWN0b3IzLmRvdChWZWN0b3IzLm5lZ2F0ZShmYWNlTm9ybWFsLCBzY3JhdGNoUGxhbmVOb3JtYWwpLCBzY3JhdGNoUGxhbmVDZW50ZXIpO1xyXG5cclxuXHRcdFx0cGxhbmVJbmRleCArPSAyO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cdC8qKlxyXG5cdCAqIERldGVybWluZXMgd2hldGhlciBhIGJvdW5kaW5nIHZvbHVtZSBpbnRlcnNlY3RzIHRoZSBjdWxsaW5nIHZvbHVtZS5cclxuXHQgKlxyXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBib3VuZGluZ1ZvbHVtZSBUaGUgYm91bmRpbmcgdm9sdW1lIHdob3NlIGludGVyc2VjdGlvbiB3aXRoIHRoZSBjdWxsaW5nIHZvbHVtZSBpcyB0byBiZSB0ZXN0ZWQuXHJcblx0ICogQHJldHVybnMge0ludGVyc2VjdH0gIEludGVyc2VjdC5PVVRTSURFLCBJbnRlcnNlY3QuSU5URVJTRUNUSU5HLCBvciBJbnRlcnNlY3QuSU5TSURFLlxyXG5cdCAqL1xyXG5cdGNvbXB1dGVWaXNpYmlsaXR5KGJvdW5kaW5nVm9sdW1lKSB7XHJcblx0XHRpZiAoIWRlZmluZWQoYm91bmRpbmdWb2x1bWUpKSB7XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcImJvdW5kaW5nVm9sdW1lIGlzIHJlcXVpcmVkLlwiKTtcclxuXHRcdH1cclxuXHRcdGNvbnN0IHBsYW5lcyA9IHRoaXMucGxhbmVzO1xyXG5cdFx0bGV0IGludGVyc2VjdGluZyA9IGZhbHNlO1xyXG5cdFx0Zm9yIChsZXQgayA9IDAsIGxlbiA9IHBsYW5lcy5sZW5ndGg7IGsgPCBsZW47ICsraykge1xyXG5cdFx0XHRjb25zdCByZXN1bHQgPSBib3VuZGluZ1ZvbHVtZS5pbnRlcnNlY3RQbGFuZShwbGFuZXNba10pO1xyXG5cdFx0XHRpZiAocmVzdWx0ID09PSBJbnRlcnNlY3QuT1VUU0lERSkge1xyXG5cdFx0XHRcdHJldHVybiBJbnRlcnNlY3QuT1VUU0lERTtcclxuXHRcdFx0fSBlbHNlIGlmIChyZXN1bHQgPT09IEludGVyc2VjdC5JTlRFUlNFQ1RJTkcpIHtcclxuXHRcdFx0XHRpbnRlcnNlY3RpbmcgPSB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGludGVyc2VjdGluZyA/IEludGVyc2VjdC5JTlRFUlNFQ1RJTkcgOiBJbnRlcnNlY3QuSU5TSURFO1xyXG5cdH1cclxufVxyXG5cclxuY29uc3QgZmFjZXMgPSBbbmV3IFZlY3RvcjMoKSwgbmV3IFZlY3RvcjMoKSwgbmV3IFZlY3RvcjMoKV07XHJcblZlY3RvcjMuY2xvbmUoVmVjdG9yMy5VTklUX1gsIGZhY2VzWzBdKTtcclxuVmVjdG9yMy5jbG9uZShWZWN0b3IzLlVOSVRfWSwgZmFjZXNbMV0pO1xyXG5WZWN0b3IzLmNsb25lKFZlY3RvcjMuVU5JVF9aLCBmYWNlc1syXSk7XHJcblxyXG5jb25zdCBzY3JhdGNoUGxhbmVDZW50ZXIgPSBuZXcgVmVjdG9yMygpO1xyXG5jb25zdCBzY3JhdGNoUGxhbmVOb3JtYWwgPSBuZXcgVmVjdG9yMygpO1xyXG5jb25zdCBzY3JhdGNoUGxhbmVzID0gbmV3IFZlY3RvcjQoKTtcclxuY29uc3Qgc2NyYXRjaFBsYW5lID0gbmV3IFBsYW5lKG5ldyBWZWN0b3IzKDEuMCwgMC4wLCAwLjApLCAwLjApO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgQ3VsbGluZ1ZvbHVtZTtcclxuIiwiaW1wb3J0IEN1bGxpbmdWb2x1bWUgZnJvbSBcIi4uL2NvcmUvQ3VsbGluZ1ZvbHVtZVwiO1xuaW1wb3J0IFJlbmRlck9iamVjdCBmcm9tIFwiLi4vY29yZS9SZW5kZXJPYmplY3RcIjtcbmltcG9ydCB7IFJlbmRlck9iamVjdFR5cGUsIFVuaWZvcm1FbnVtIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcbmltcG9ydCBNYXRyaXg0IGZyb20gXCIuLi9tYXRoL01hdHJpeDRcIjtcbmltcG9ydCBQbGFuZSBmcm9tIFwiLi4vbWF0aC9QbGFuZVwiO1xuaW1wb3J0IFZlY3RvcjMgZnJvbSBcIi4uL21hdGgvVmVjdG9yM1wiO1xuaW1wb3J0IFNoYWRlckRhdGEgZnJvbSBcIi4uL3JlbmRlci9TaGFkZXJEYXRhXCI7XG5pbXBvcnQgVW5pZm9ybUJ1ZmZlciBmcm9tIFwiLi4vcmVuZGVyL1VuaWZvcm1CdWZmZXJcIjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2FtZXJhIGV4dGVuZHMgUmVuZGVyT2JqZWN0IHtcblx0cHJpdmF0ZSBfdmlld01hdHJpeDogTWF0cml4NDtcblx0cHJvdGVjdGVkIF9wcm9qZWN0aW9uTWF0cml4OiBNYXRyaXg0O1xuXHRwcml2YXRlIF92cE1hdHJpeDogTWF0cml4NDtcblx0Y3VsbGluZ1ZvbHVtZTogQ3VsbGluZ1ZvbHVtZTtcblx0cHJvamVjdE1hdHJpeERpcnR5OiBib29sZWFuO1xuXHRzaGFkZXJEYXRhOiBTaGFkZXJEYXRhO1xuXHRuZWFyOiBudW1iZXI7XG5cdGZhcjogbnVtYmVyO1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXHRcdHRoaXMuX3ZpZXdNYXRyaXggPSB1bmRlZmluZWQ7XG5cdFx0dGhpcy50eXBlID0gUmVuZGVyT2JqZWN0VHlwZS5DYW1lcmE7XG5cdFx0dGhpcy5jdWxsaW5nVm9sdW1lID0gbmV3IEN1bGxpbmdWb2x1bWUoKTtcblx0XHR0aGlzLl92aWV3TWF0cml4ID0gbmV3IE1hdHJpeDQoKTtcblx0XHR0aGlzLl92cE1hdHJpeCA9IG5ldyBNYXRyaXg0KCk7XG5cdFx0dGhpcy5wcm9qZWN0TWF0cml4RGlydHkgPSB0cnVlO1xuXHRcdHRoaXMuY3JlYXRlU2hhZGVyRGF0YSgpO1xuXHR9XG5cdGdldCB2aWV3TWF0cml4KCkge1xuXHRcdHRoaXMudXBkYXRlTWF0cml4KCk7XG5cdFx0TWF0cml4NC5pbnZlcnNlKHRoaXMubW9kZWxNYXRyaXgsIHRoaXMuX3ZpZXdNYXRyaXgpO1xuXHRcdHJldHVybiB0aGlzLl92aWV3TWF0cml4O1xuXHR9XG5cdGdldCBwcm9qZWN0aW9uTWF0cml4KCkge1xuXHRcdHRoaXMudXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpO1xuXHRcdHJldHVybiB0aGlzLl9wcm9qZWN0aW9uTWF0cml4O1xuXHR9XG5cblx0Z2V0IHZwTWF0cml4KCkge1xuXHRcdE1hdHJpeDQubXVsdGlwbHkodGhpcy5wcm9qZWN0aW9uTWF0cml4LCB0aGlzLnZpZXdNYXRyaXgsIHRoaXMuX3ZwTWF0cml4KTtcblx0XHRyZXR1cm4gdGhpcy5fdnBNYXRyaXg7XG5cdH1cblxuXHRnZXQgaW52ZXJzZVZpZXdNYXRyaXgoKSB7XG5cdFx0dGhpcy51cGRhdGVNYXRyaXgoKTtcblx0XHRyZXR1cm4gdGhpcy5tb2RlbE1hdHJpeDtcblx0fVxuXHRwdWJsaWMgdXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpIHt9XG5cdC8qKlxuXHQgKiBnZXQgYSBjdWxsaW5nIHZvbHVtZSBmb3IgdGhpcyBmcnVzdHVtLlxuXHQgKi9cblx0Z2V0Q3VsbGluZ1ZvbHVtZSgpIHtcblx0XHRjb25zdCBjbG9uZVZpZXdNYXRyaXggPSB0aGlzLnZpZXdNYXRyaXguY2xvbmUobmV3IE1hdHJpeDQoKSk7XG5cdFx0Y29uc3QgdnBNYXRyaXggPSBNYXRyaXg0Lm11bHRpcGx5KHRoaXMucHJvamVjdGlvbk1hdHJpeCwgY2xvbmVWaWV3TWF0cml4LCBuZXcgTWF0cml4NCgpKTtcblx0XHRjb25zdCBwbGFuZXMgPSB0aGlzLmN1bGxpbmdWb2x1bWUucGxhbmVzO1xuXHRcdGNvbnN0IG1lID0gdnBNYXRyaXg7XG5cdFx0Y29uc3QgbWUwID0gbWVbMF0sXG5cdFx0XHRtZTEgPSBtZVsxXSxcblx0XHRcdG1lMiA9IG1lWzJdLFxuXHRcdFx0bWUzID0gbWVbM107XG5cdFx0Y29uc3QgbWU0ID0gbWVbNF0sXG5cdFx0XHRtZTUgPSBtZVs1XSxcblx0XHRcdG1lNiA9IG1lWzZdLFxuXHRcdFx0bWU3ID0gbWVbN107XG5cdFx0Y29uc3QgbWU4ID0gbWVbOF0sXG5cdFx0XHRtZTkgPSBtZVs5XSxcblx0XHRcdG1lMTAgPSBtZVsxMF0sXG5cdFx0XHRtZTExID0gbWVbMTFdO1xuXHRcdGNvbnN0IG1lMTIgPSBtZVsxMl0sXG5cdFx0XHRtZTEzID0gbWVbMTNdLFxuXHRcdFx0bWUxNCA9IG1lWzE0XSxcblx0XHRcdG1lMTUgPSBtZVsxNV07XG5cdFx0cGxhbmVzWzBdID0gbmV3IFBsYW5lKG5ldyBWZWN0b3IzKG1lMyAtIG1lMCwgbWU3IC0gbWU0LCBtZTExIC0gbWU4KSwgbWUxNSAtIG1lMTIpO1xuXHRcdHBsYW5lc1swXS5ub3JtYWxpemUoKTtcblx0XHRwbGFuZXNbMV0gPSBuZXcgUGxhbmUobmV3IFZlY3RvcjMobWUzICsgbWUwLCBtZTcgKyBtZTQsIG1lMTEgKyBtZTgpLCBtZTE1ICsgbWUxMik7XG5cdFx0cGxhbmVzWzFdLm5vcm1hbGl6ZSgpO1xuXG5cdFx0cGxhbmVzWzJdID0gbmV3IFBsYW5lKG5ldyBWZWN0b3IzKG1lMyArIG1lMSwgbWU3ICsgbWU1LCBtZTExICsgbWU5KSwgbWUxNSArIG1lMTMpO1xuXHRcdHBsYW5lc1syXS5ub3JtYWxpemUoKTtcblxuXHRcdHBsYW5lc1szXSA9IG5ldyBQbGFuZShuZXcgVmVjdG9yMyhtZTMgLSBtZTEsIG1lNyAtIG1lNSwgbWUxMSAtIG1lOSksIG1lMTUgLSBtZTEzKTtcblx0XHRwbGFuZXNbM10ubm9ybWFsaXplKCk7XG5cblx0XHRwbGFuZXNbNF0gPSBuZXcgUGxhbmUobmV3IFZlY3RvcjMobWUzIC0gbWUyLCBtZTcgLSBtZTYsIG1lMTEgLSBtZTEwKSwgbWUxNSAtIG1lMTQpO1xuXHRcdHBsYW5lc1s0XS5ub3JtYWxpemUoKTtcblxuXHRcdHBsYW5lc1s1XSA9IG5ldyBQbGFuZShuZXcgVmVjdG9yMyhtZTMgKyBtZTIsIG1lNyArIG1lNiwgbWUxMSArIG1lMTApLCBtZTE1ICsgbWUxNCk7XG5cdFx0cGxhbmVzWzVdLm5vcm1hbGl6ZSgpO1xuXG5cdFx0cmV0dXJuIHRoaXMuY3VsbGluZ1ZvbHVtZTtcblx0fVxuXG5cdGNyZWF0ZVNoYWRlckRhdGEoKSB7XG5cdFx0dGhpcy5zaGFkZXJEYXRhID0gbmV3IFNoYWRlckRhdGEoXCJjYW1lcmFcIiwgMCwgMSwgMSk7XG5cdFx0Y29uc3QgdW5pZm9ybUJ1ZmZlciA9IG5ldyBVbmlmb3JtQnVmZmVyKHsgbGFiZWw6IFwiY2FtZXJhXCIgfSk7XG5cdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XCJwcm9qZWN0aW9uTWF0cml4XCIsXG5cdFx0XHQoKSA9PiB7XG5cdFx0XHRcdHJldHVybiB0aGlzLnByb2plY3Rpb25NYXRyaXg7XG5cdFx0XHR9LFxuXHRcdFx0VW5pZm9ybUVudW0uTWF0NFxuXHRcdCk7XG5cdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XCJ2aWV3TWF0cml4XCIsXG5cdFx0XHQoKSA9PiB7XG5cdFx0XHRcdHJldHVybiB0aGlzLnZpZXdNYXRyaXg7XG5cdFx0XHR9LFxuXHRcdFx0VW5pZm9ybUVudW0uTWF0NFxuXHRcdCk7XG5cdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XCJpbnZlcnNlVmlld01hdHJpeFwiLFxuXHRcdFx0KCkgPT4ge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5pbnZlcnNlVmlld01hdHJpeDtcblx0XHRcdH0sXG5cdFx0XHRVbmlmb3JtRW51bS5NYXQ0XG5cdFx0KTtcblx0XHR1bmlmb3JtQnVmZmVyLnNldFVuaWZvcm0oXG5cdFx0XHRcInBvc2l0aW9uXCIsXG5cdFx0XHQoKSA9PiB7XG5cdFx0XHRcdHJldHVybiB0aGlzLnBvc2l0aW9uO1xuXHRcdFx0fSxcblx0XHRcdFVuaWZvcm1FbnVtLkZsb2F0VmVjM1xuXHRcdCk7XG5cdFx0dGhpcy5zaGFkZXJEYXRhLnNldFVuaWZvcm1CdWZmZXIoXCJjYW1lcmFcIiwgdW5pZm9ybUJ1ZmZlcik7XG5cdH1cbn1cbiIsImltcG9ydCBDdWxsaW5nVm9sdW1lIGZyb20gXCIuLi9jb3JlL0N1bGxpbmdWb2x1bWVcIjtcclxuaW1wb3J0IEdNYXRoIGZyb20gXCIuLi9tYXRoL01hdGhcIjtcclxuaW1wb3J0IE1hdHJpeDQgZnJvbSBcIi4uL21hdGgvTWF0cml4NFwiO1xyXG5pbXBvcnQgQ2FtZXJhIGZyb20gXCIuL0NhbWVyYVwiO1xyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQZXJzcGVjdGl2ZUNhbWVyYSBleHRlbmRzIENhbWVyYSB7XHJcblx0eE9mZnNldDogbnVtYmVyO1xyXG5cdHlPZmZzZXQ6IG51bWJlcjtcclxuXHRjdWxsaW5nVm9sdW1lOiBDdWxsaW5nVm9sdW1lO1xyXG5cdHByaXZhdGUgX2FzcGVjdDogbnVtYmVyO1xyXG5cdHByaXZhdGUgX2ZvdjogbnVtYmVyO1xyXG5cdGhlaWdodDogbnVtYmVyO1xyXG5cdHdpZHRoOiBudW1iZXI7XHJcblx0aXNQZXJzcGVjdGl2ZUNhbWVyYTogYm9vbGVhbjtcclxuXHRuZWFyOiBudW1iZXI7XHJcblx0ZmFyOiBudW1iZXI7XHJcblx0dG9wOiBudW1iZXI7XHJcblx0bGVmdDogbnVtYmVyO1xyXG5cdGNvbnN0cnVjdG9yKGZvdiA9IDUwLCBhc3BlY3QgPSAxLCBuZWFyID0gMC4xLCBmYXIgPSAyMDAwKSB7XHJcblx0XHRzdXBlcigpO1xyXG5cdFx0dGhpcy5fYXNwZWN0ID0gYXNwZWN0O1xyXG5cdFx0dGhpcy5mb3YgPSBmb3Y7XHJcblx0XHR0aGlzLm5lYXIgPSBuZWFyO1xyXG5cdFx0dGhpcy5mYXIgPSBmYXI7XHJcblx0XHR0aGlzLnhPZmZzZXQgPSAwO1xyXG5cdFx0dGhpcy55T2Zmc2V0ID0gMDtcclxuXHRcdHRoaXMucHJvamVjdE1hdHJpeERpcnR5ID0gdHJ1ZTtcclxuXHRcdHRoaXMudXBkYXRlQ2FtZXJhUGFybXMoKTtcclxuXHRcdHRoaXMuY3VsbGluZ1ZvbHVtZSA9IG5ldyBDdWxsaW5nVm9sdW1lKCk7XHJcblx0XHR0aGlzLmlzUGVyc3BlY3RpdmVDYW1lcmEgPSB0cnVlO1xyXG5cdH1cclxuXHRnZXQgYXNwZWN0KCk6IG51bWJlciB7XHJcblx0XHRyZXR1cm4gdGhpcy5fYXNwZWN0O1xyXG5cdH1cclxuXHJcblx0c2V0IGFzcGVjdCh2OiBudW1iZXIpIHtcclxuXHRcdHRoaXMucHJvamVjdE1hdHJpeERpcnR5ID0gdHJ1ZTtcclxuXHRcdHRoaXMuX2FzcGVjdCA9IHY7XHJcblx0fVxyXG5cdGdldCBmb3YoKTogbnVtYmVyIHtcclxuXHRcdHJldHVybiB0aGlzLl9mb3Y7XHJcblx0fVxyXG5cclxuXHRzZXQgZm92KHY6IG51bWJlcikge1xyXG5cdFx0dGhpcy5wcm9qZWN0TWF0cml4RGlydHkgPSB0cnVlO1xyXG5cdFx0dGhpcy5fZm92ID0gdjtcclxuXHR9XHJcblx0cHJpdmF0ZSB1cGRhdGVDYW1lcmFQYXJtcygpIHtcclxuXHRcdHRoaXMudG9wID0gdGhpcy5uZWFyICogTWF0aC50YW4oMC41ICogR01hdGguUkFESUFOU19QRVJfREVHUkVFICogdGhpcy5mb3YpO1xyXG5cdFx0dGhpcy5oZWlnaHQgPSAyICogdGhpcy50b3A7XHJcblx0XHR0aGlzLndpZHRoID0gdGhpcy5hc3BlY3QgKiB0aGlzLmhlaWdodDtcclxuXHRcdHRoaXMubGVmdCA9IC0wLjUgKiB0aGlzLndpZHRoO1xyXG5cdH1cclxuXHRwdWJsaWMgdXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpIHtcclxuXHRcdGlmICh0aGlzLnByb2plY3RNYXRyaXhEaXJ0eSkge1xyXG5cdFx0XHR0aGlzLnVwZGF0ZUNhbWVyYVBhcm1zKCk7XHJcblx0XHRcdHRoaXMuX3Byb2plY3Rpb25NYXRyaXggPSBNYXRyaXg0Lm1ha2VQZXJzcGVjdGl2ZShcclxuXHRcdFx0XHR0aGlzLmxlZnQsXHJcblx0XHRcdFx0dGhpcy5sZWZ0ICsgdGhpcy53aWR0aCxcclxuXHRcdFx0XHR0aGlzLnRvcCxcclxuXHRcdFx0XHR0aGlzLnRvcCAtIHRoaXMuaGVpZ2h0LFxyXG5cdFx0XHRcdHRoaXMubmVhcixcclxuXHRcdFx0XHR0aGlzLmZhclxyXG5cdFx0XHQpO1xyXG5cdFx0XHR0aGlzLnByb2plY3RNYXRyaXhEaXJ0eSA9IGZhbHNlO1xyXG5cdFx0fVxyXG5cdH1cclxufVxyXG4iLCJpbXBvcnQgeyBCdWZmZXJVc2FnZSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVUNvbnN0YW50XCI7XG5pbXBvcnQgeyBVbmlmb3JtRW51bSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XG5pbXBvcnQgTWF0cml4NCBmcm9tIFwiLi4vbWF0aC9NYXRyaXg0XCI7XG5pbXBvcnQgU2hhZGVyRGF0YSBmcm9tIFwiLi4vcmVuZGVyL1NoYWRlckRhdGFcIjtcbmltcG9ydCBVbmlmb3JtQnVmZmVyIGZyb20gXCIuLi9yZW5kZXIvVW5pZm9ybUJ1ZmZlclwiO1xuaW1wb3J0IFBlcnNwZWN0aXZlQ2FtZXJhIGZyb20gXCIuL1BlcnNwZWN0aXZlQ2FtZXJhXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBvaW50TGlnaHRTaGFkb3dDYW1lcmEgZXh0ZW5kcyBQZXJzcGVjdGl2ZUNhbWVyYSB7XG5cdHB1YmxpYyB2cE1hdHJpeEFycmF5OiBBcnJheTxNYXRyaXg0Pjtcblx0cHVibGljIHZwTWF0cml4SW5kZXhBcnJheTogQXJyYXk8bnVtYmVyPjtcblxuXHRjb25zdHJ1Y3Rvcihmb3YgPSA1MCwgYXNwZWN0ID0gMSwgbmVhciA9IDAuMSwgZmFyID0gMjAwMCkge1xuXHRcdHN1cGVyKGZvdiwgYXNwZWN0LCBuZWFyLCBmYXIpO1xuXHRcdHRoaXMudnBNYXRyaXhBcnJheSA9IFtuZXcgTWF0cml4NCgpLCBuZXcgTWF0cml4NCgpLCBuZXcgTWF0cml4NCgpLCBuZXcgTWF0cml4NCgpLCBuZXcgTWF0cml4NCgpLCBuZXcgTWF0cml4NCgpXTtcblx0fVxuXG5cdC8vIGNyZWF0ZVNoYWRlckRhdGEoKSB7XG5cdC8vIFx0dGhpcy5zaGFkZXJEYXRhID0gbmV3IFNoYWRlckRhdGEoXCJjYW1lcmFcIiwgMCwgMSwgMSk7XG5cblx0Ly8gXHRjb25zdCB1bmlmb3JtQnVmZmVyID0gbmV3IFVuaWZvcm1CdWZmZXIoe1xuXHQvLyBcdFx0bGFiZWw6IFwicG9pbnRMaWdodFNoYWRvd0NhbWVyYVwiLFxuXHQvLyBcdFx0dHlwZTogXCJyZWFkLW9ubHktc3RvcmFnZVwiLFxuXHQvLyBcdFx0dXNhZ2U6IEJ1ZmZlclVzYWdlLlN0b3JhZ2UgfCBCdWZmZXJVc2FnZS5Db3B5RHN0LFxuXHQvLyBcdFx0aGFzRHluYW1pY09mZnNldDogdHJ1ZSxcblx0Ly8gXHRcdG1pbkJpbmRpbmdTaXplOiA2NCxcblx0Ly8gXHRcdG1heE9mZnNldDogNixcblx0Ly8gXHRcdHNpemU6IDI1NiAqIDZcblx0Ly8gXHR9KTtcblx0Ly8gXHR1bmlmb3JtQnVmZmVyLnNldE1hdHJpeDRBcnJheShcblx0Ly8gXHRcdFwidnBNYXRyaXhBcnJheVwiLFxuXHQvLyBcdFx0KCkgPT4ge1xuXHQvLyBcdFx0XHRpZiAodGhpcy52cE1hdHJpeEFycmF5Lmxlbmd0aCAhPSA2KSB0aHJvdyBuZXcgRXJyb3IoXCJwb2ludExpZ2h0U2hhZG93Q2FtZXJhIHVuaWZvcm1CdWZmZXIgaGFzIEVycm9yXCIpO1xuXG5cdC8vIFx0XHRcdHJldHVybiB0aGlzLnZwTWF0cml4QXJyYXk7XG5cdC8vIFx0XHR9LFxuXHQvLyBcdFx0Nixcblx0Ly8gXHRcdDI1NlxuXHQvLyBcdCk7XG5cblx0Ly8gXHR0aGlzLnNoYWRlckRhdGEuc2V0VW5pZm9ybUJ1ZmZlcihcInBvaW50TGlnaHRTaGFkb3dDYW1lcmFcIiwgdW5pZm9ybUJ1ZmZlcik7XG5cdC8vIFx0dGhpcy5zaGFkZXJEYXRhLnNldERlZmluZShcImlzUG9pbnRMaWdodFNoYWRvd01hcFwiLCB0cnVlKTtcblx0Ly8gfVxuXG5cdGNyZWF0ZVNoYWRlckRhdGEoKSB7XG5cdFx0dGhpcy5zaGFkZXJEYXRhID0gbmV3IFNoYWRlckRhdGEoXCJjYW1lcmFcIiwgMCwgMSwgMSk7XG5cblx0XHRjb25zdCB1bmlmb3JtQnVmZmVyID0gbmV3IFVuaWZvcm1CdWZmZXIoe1xuXHRcdFx0bGFiZWw6IFwicG9pbnRMaWdodFNoYWRvd0NhbWVyYVwiLFxuXHRcdFx0dHlwZTogXCJyZWFkLW9ubHktc3RvcmFnZVwiLFxuXHRcdFx0dXNhZ2U6IEJ1ZmZlclVzYWdlLlN0b3JhZ2UgfCBCdWZmZXJVc2FnZS5Db3B5RHN0XG5cdFx0fSk7XG5cdFx0dW5pZm9ybUJ1ZmZlci5zZXRVbmlmb3JtKFxuXHRcdFx0XCJ2cE1hdHJpeFwiLFxuXHRcdFx0KCkgPT4ge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy52cE1hdHJpeDtcblx0XHRcdH0sXG5cdFx0XHRVbmlmb3JtRW51bS5NYXQ0XG5cdFx0KTtcblxuXHRcdHRoaXMuc2hhZGVyRGF0YS5zZXRVbmlmb3JtQnVmZmVyKFwicG9pbnRMaWdodFNoYWRvd0NhbWVyYVwiLCB1bmlmb3JtQnVmZmVyKTtcblx0XHR0aGlzLnNoYWRlckRhdGEuc2V0RGVmaW5lKFwiaXNQb2ludExpZ2h0U2hhZG93TWFwXCIsIHRydWUpO1xuXHR9XG5cblx0dXBkYXRlVnBNYXRyaXhBcnJheUFuZEluZGV4KGluZGV4OiBudW1iZXIpIHtcblx0XHRNYXRyaXg0LmNsb25lKHRoaXMudnBNYXRyaXgsIHRoaXMudnBNYXRyaXhBcnJheVtpbmRleF0pO1xuXHR9XG59XG4iLCJpbXBvcnQgQ2FtZXJhIGZyb20gXCIuLi8uLi9jYW1lcmEvQ2FtZXJhXCI7XHJcbmltcG9ydCB7IFRleHR1cmVGb3JtYXQsIFRleHR1cmVTYW1wbGVUeXBlLCBUZXh0dXJlVXNhZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS9XZWJHUFVDb25zdGFudFwiO1xyXG5pbXBvcnQgVmVjdG9yMiBmcm9tIFwiLi4vLi4vbWF0aC9WZWN0b3IyXCI7XHJcbmltcG9ydCBWZWN0b3I0IGZyb20gXCIuLi8uLi9tYXRoL1ZlY3RvcjRcIjtcclxuaW1wb3J0IFRleHR1cmUgZnJvbSBcIi4uLy4uL3JlbmRlci9UZXh0dXJlXCI7XHJcbmltcG9ydCB7IExpZ2h0IH0gZnJvbSBcIi4uL0xpZ2h0XCI7XHJcbmV4cG9ydCBjbGFzcyBCYXNlU2hhZG93IHtcclxuXHRwcm90ZWN0ZWQgX3NoYWRvd01hcFNpemU6IFZlY3RvcjI7XHJcblx0cHJvdGVjdGVkIF9jYW1lcmE6IENhbWVyYTtcclxuXHRwcm90ZWN0ZWQgX3NoYWRvd01hcDogVGV4dHVyZTtcclxuXHRwdWJsaWMgdHlwZTogc3RyaW5nO1xyXG5cdHB1YmxpYyBfdmlld3BvcnRzOiBBcnJheTxWZWN0b3I0PjtcclxuXHRwdWJsaWMgdmlld3BvcnRTaXplOiBWZWN0b3IyO1xyXG5cdHB1YmxpYyBjdXJyZW50Vmlld3BvcnRJbmRleDogbnVtYmVyO1xyXG5cdHB1YmxpYyB2aWV3UG9ydERpcnR5OiBib29sZWFuO1xyXG5cdHB1YmxpYyB2cE1hdHJpeERpcnR5OiBib29sZWFuO1xyXG5cclxuXHRjb25zdHJ1Y3RvcihzaGFkb3dNYXBTaXplOiBWZWN0b3IyLCBjYW1lcmE6IENhbWVyYSkge1xyXG5cdFx0dGhpcy5fc2hhZG93TWFwU2l6ZSA9IHNoYWRvd01hcFNpemU7XHJcblx0XHR0aGlzLl9jYW1lcmEgPSBjYW1lcmE7XHJcblx0XHR0aGlzLnZpZXdQb3J0RGlydHkgPSB0cnVlO1xyXG5cdFx0dGhpcy52cE1hdHJpeERpcnR5ID0gdHJ1ZTtcclxuXHJcblx0XHR0aGlzLl9pbml0KCk7XHJcblx0fVxyXG5cclxuXHRnZXQgY2FtZXJhKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuX2NhbWVyYTtcclxuXHR9XHJcblxyXG5cdGdldCBzaGFkb3dNYXBTaXplKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuX3NoYWRvd01hcFNpemU7XHJcblx0fVxyXG5cclxuXHRnZXQgdmlld3BvcnRzKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuX3ZpZXdwb3J0cztcclxuXHR9XHJcblxyXG5cdHB1YmxpYyBnZXRTaGFkb3dNYXBUZXh0dXJlKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuX3NoYWRvd01hcDtcclxuXHR9XHJcblxyXG5cdHByb3RlY3RlZCBfaW5pdCgpIHtcclxuXHRcdHRoaXMuX2luaXRTaGFkb3dNYXBUZXh0dXJlKCk7XHJcblx0fVxyXG5cclxuXHRwcm90ZWN0ZWQgX2luaXRTaGFkb3dNYXBUZXh0dXJlKCkge1xyXG5cdFx0dGhpcy5fY3JlYXRlU2hhZG93TWFwVGV4dHVyZSgpO1xyXG5cdH1cclxuXHJcblx0cHJvdGVjdGVkIF9jcmVhdGVTaGFkb3dNYXBUZXh0dXJlKCkge1xyXG5cdFx0dGhpcy5fc2hhZG93TWFwID0gbmV3IFRleHR1cmUoe1xyXG5cdFx0XHRzaXplOiB7XHJcblx0XHRcdFx0d2lkdGg6IHRoaXMuX3NoYWRvd01hcFNpemUueCxcclxuXHRcdFx0XHRoZWlnaHQ6IHRoaXMuX3NoYWRvd01hcFNpemUueSxcclxuXHRcdFx0XHRkZXB0aDogMVxyXG5cdFx0XHR9LFxyXG5cdFx0XHRmaXhlZFNpemU6IHRydWUsXHJcblx0XHRcdHNhbXBsZVR5cGU6IFRleHR1cmVTYW1wbGVUeXBlLkRlcHRoLFxyXG5cdFx0XHRmb3JtYXQ6IFRleHR1cmVGb3JtYXQuRGVwdGgyNFBsdXMsXHJcblx0XHRcdHVzYWdlOiBUZXh0dXJlVXNhZ2UuUmVuZGVyQXR0YWNobWVudCB8IFRleHR1cmVVc2FnZS5UZXh0dXJlQmluZGluZyB8IFRleHR1cmVVc2FnZS5Db3B5U3JjXHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdHB1YmxpYyB1cGRhdGUobGlnaHQ6IExpZ2h0KSB7fVxyXG59XHJcbiIsImltcG9ydCBQb2ludExpZ2h0U2hhZG93Q2FtZXJhIGZyb20gXCIuLi8uLi9jYW1lcmEvUG9pbnRMaWdodFNoYWRvd0NhbWVyYVwiO1xyXG5pbXBvcnQgVmVjdG9yMiBmcm9tIFwiLi4vLi4vbWF0aC9WZWN0b3IyXCI7XHJcbmltcG9ydCBWZWN0b3IzIGZyb20gXCIuLi8uLi9tYXRoL1ZlY3RvcjNcIjtcclxuaW1wb3J0IFZlY3RvcjQgZnJvbSBcIi4uLy4uL21hdGgvVmVjdG9yNFwiO1xyXG5pbXBvcnQgeyBQb2ludExpZ2h0IH0gZnJvbSBcIi4uL1BvaW50TGlnaHRcIjtcclxuaW1wb3J0IHsgQmFzZVNoYWRvdyB9IGZyb20gXCIuL0Jhc2VTaGFkb3dcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBQb2ludExpZ2h0U2hhZG93IGV4dGVuZHMgQmFzZVNoYWRvdyB7XHJcblx0cHVibGljIHR5cGU6IHN0cmluZztcclxuXHRwcml2YXRlIF9wb2ludExpZ2h0U2hhZG93TG9va0RpcmVjdGlvbnM6IEFycmF5PFZlY3RvcjM+O1xyXG5cdHByaXZhdGUgX3BvaW50TGlnaHRTaGFkb3dVcHM6IEFycmF5PFZlY3RvcjM+O1xyXG5cdHZwTWF0cml4QXJyYXlEaXJ0eTogYm9vbGVhbjtcclxuXHJcblx0Z2V0IGNhbWVyYSgpOiBQb2ludExpZ2h0U2hhZG93Q2FtZXJhIHtcclxuXHRcdHJldHVybiB0aGlzLl9jYW1lcmEgYXMgUG9pbnRMaWdodFNoYWRvd0NhbWVyYTtcclxuXHR9XHJcblxyXG5cdGNvbnN0cnVjdG9yKCkge1xyXG5cdFx0Y29uc3QgY2FtZXJhID0gbmV3IFBvaW50TGlnaHRTaGFkb3dDYW1lcmEoOTAsIDEsIDAuMSwgNTAwKTtcclxuXHRcdHN1cGVyKG5ldyBWZWN0b3IyKDE1MzYsIDEwMjQpLCBjYW1lcmEpO1xyXG5cdFx0dGhpcy52aWV3cG9ydFNpemUgPSBuZXcgVmVjdG9yMig1MTIsIDUxMik7XHJcblx0XHR0aGlzLmN1cnJlbnRWaWV3cG9ydEluZGV4ID0gMDtcclxuXHRcdHRoaXMudHlwZSA9IFwicG9pbnRMaWdodFNoYWRvd1wiO1xyXG5cdFx0dGhpcy52cE1hdHJpeEFycmF5RGlydHkgPSB0cnVlO1xyXG5cclxuXHRcdHRoaXMuX3ZpZXdwb3J0cyA9IFtcclxuXHRcdFx0Ly8gcG9zaXRpdmUgWCAwXHJcblx0XHRcdG5ldyBWZWN0b3I0KDAsIDAsIDEgLyAzLCAxIC8gMiksXHJcblx0XHRcdC8vIG5lZ2F0aXZlIFggMVxyXG5cdFx0XHRuZXcgVmVjdG9yNCgxLCAwLCAxIC8gMywgMSAvIDIpLFxyXG5cdFx0XHQvLyBwb3NpdGl2ZSBaIDJcclxuXHRcdFx0bmV3IFZlY3RvcjQoMiwgMCwgMSAvIDMsIDEgLyAyKSxcclxuXHRcdFx0Ly8gbmVnYXRpdmUgWiAzXHJcblx0XHRcdG5ldyBWZWN0b3I0KDAsIDEsIDEgLyAzLCAxIC8gMiksXHJcblx0XHRcdC8vIHBvc2l0aXZlIFkgNFxyXG5cdFx0XHRuZXcgVmVjdG9yNCgxLCAxLCAxIC8gMywgMSAvIDIpLFxyXG5cdFx0XHQvLyBuZWdhdGl2ZSBZIDVcclxuXHRcdFx0bmV3IFZlY3RvcjQoMiwgMSwgMSAvIDMsIDEgLyAyKVxyXG5cdFx0XTtcclxuXHJcblx0XHR0aGlzLl9wb2ludExpZ2h0U2hhZG93TG9va0RpcmVjdGlvbnMgPSBbXHJcblx0XHRcdG5ldyBWZWN0b3IzKDEsIDAsIDApLFxyXG5cdFx0XHRuZXcgVmVjdG9yMygtMSwgMCwgMCksXHJcblx0XHRcdG5ldyBWZWN0b3IzKDAsIDAsIDEpLFxyXG5cdFx0XHRuZXcgVmVjdG9yMygwLCAwLCAtMSksXHJcblx0XHRcdG5ldyBWZWN0b3IzKDAsIDEsIDApLFxyXG5cdFx0XHRuZXcgVmVjdG9yMygwLCAtMSwgMClcclxuXHRcdF07XHJcblxyXG5cdFx0dGhpcy5fcG9pbnRMaWdodFNoYWRvd1VwcyA9IFtcclxuXHRcdFx0bmV3IFZlY3RvcjMoMCwgMSwgMCksXHJcblx0XHRcdG5ldyBWZWN0b3IzKDAsIDEsIDApLFxyXG5cdFx0XHRuZXcgVmVjdG9yMygwLCAxLCAwKSxcclxuXHRcdFx0bmV3IFZlY3RvcjMoMCwgMSwgMCksXHJcblx0XHRcdG5ldyBWZWN0b3IzKDAsIDAsIDEpLFxyXG5cdFx0XHRuZXcgVmVjdG9yMygwLCAwLCAtMSlcclxuXHRcdF07XHJcblx0fVxyXG5cclxuXHRwdWJsaWMgdXBkYXRlKGxpZ2h0OiBQb2ludExpZ2h0KSB7XHJcblx0XHR0aGlzLnVwZGF0ZU1hdHJpY2VzKGxpZ2h0KTtcclxuXHR9XHJcblxyXG5cdHVwZGF0ZU1hdHJpY2VzKGxpZ2h0OiBQb2ludExpZ2h0KSB7XHJcblx0XHRpZiAodGhpcy5jYW1lcmEgaW5zdGFuY2VvZiBQb2ludExpZ2h0U2hhZG93Q2FtZXJhKSB7XHJcblx0XHRcdHRoaXMuY2FtZXJhLnBvc2l0aW9uLmNvcHkobGlnaHQucG9zaXRpb24pO1xyXG5cdFx0XHRjb25zdCB0YXJnZXQgPSBWZWN0b3IzLmNsb25lKGxpZ2h0LnBvc2l0aW9uKTtcclxuXHRcdFx0dGFyZ2V0LmFkZCh0aGlzLl9wb2ludExpZ2h0U2hhZG93TG9va0RpcmVjdGlvbnNbdGhpcy5jdXJyZW50Vmlld3BvcnRJbmRleF0pO1xyXG5cdFx0XHR0aGlzLmNhbWVyYS51cC5jb3B5KHRoaXMuX3BvaW50TGlnaHRTaGFkb3dVcHNbdGhpcy5jdXJyZW50Vmlld3BvcnRJbmRleF0pO1xyXG5cdFx0XHRjb25zdCB7IHgsIHksIHogfSA9IHRhcmdldDtcclxuXHRcdFx0dGhpcy5jYW1lcmEubG9va0F0KHgsIHksIHopO1xyXG5cdFx0XHR0aGlzLmNhbWVyYS51cGRhdGVNYXRyaXgoKTtcclxuXHRcdFx0dGhpcy5jYW1lcmEudXBkYXRlVnBNYXRyaXhBcnJheUFuZEluZGV4KHRoaXMuY3VycmVudFZpZXdwb3J0SW5kZXgpO1xyXG5cdFx0XHRpZiAodGhpcy5jdXJyZW50Vmlld3BvcnRJbmRleCA9PSA1KSB0aGlzLnZwTWF0cml4QXJyYXlEaXJ0eSA9IHRydWU7XHJcblx0XHR9XHJcblx0fVxyXG59XHJcbiIsImltcG9ydCB7IExpZ2h0VHlwZSB9IGZyb20gXCIuLi9jb3JlL1dlYkdQVVR5cGVzXCI7XHJcbmltcG9ydCBWZWN0b3IzIGZyb20gXCIuLi9tYXRoL1ZlY3RvcjNcIjtcclxuaW1wb3J0IHsgTGlnaHQgfSBmcm9tIFwiLi9MaWdodFwiO1xyXG5pbXBvcnQgeyBQb2ludExpZ2h0U2hhZG93IH0gZnJvbSBcIi4vc2hhZG93cy9Qb2ludExpZ2h0U2hhZG93XCI7XHJcblxyXG5leHBvcnQgY2xhc3MgUG9pbnRMaWdodCBleHRlbmRzIExpZ2h0IHtcclxuXHRwcml2YXRlIF9kaXN0YW5jZTogbnVtYmVyO1xyXG5cdHByaXZhdGUgX2RlY2F5OiBudW1iZXI7XHJcblx0ZGlzdGFuY2VEaXJ0eTogYm9vbGVhbjtcclxuXHRkZWNheURpcnR5OiBib29sZWFuO1xyXG5cclxuXHRnZXQgc2hhZG93KCk6IFBvaW50TGlnaHRTaGFkb3cge1xyXG5cdFx0cmV0dXJuIHRoaXMuX3NoYWRvdyBhcyBQb2ludExpZ2h0U2hhZG93O1xyXG5cdH1cclxuXHJcblx0c2V0IHNoYWRvdyh2YWx1ZTogUG9pbnRMaWdodFNoYWRvdykge1xyXG5cdFx0dGhpcy5zaGFkb3dEaXJ0eSA9IHRydWU7XHJcblx0XHR0aGlzLl9zaGFkb3cgPSB2YWx1ZTtcclxuXHR9XHJcblxyXG5cdGNvbnN0cnVjdG9yKGNvbG9yOiBWZWN0b3IzLCBpbnRlbnNpdHk6IG51bWJlciwgZGlzdGFuY2UgPSAwLCBkZWNheSA9IDQsIG9wZW5TaGFkb3cgPSB0cnVlKSB7XHJcblx0XHRzdXBlcihjb2xvciwgaW50ZW5zaXR5KTtcclxuXHRcdHRoaXMuX2Rpc3RhbmNlID0gZGlzdGFuY2U7XHJcblx0XHR0aGlzLl9kZWNheSA9IGRlY2F5O1xyXG5cdFx0dGhpcy5kaXN0YW5jZURpcnR5ID0gdHJ1ZTtcclxuXHRcdHRoaXMuZGVjYXlEaXJ0eSA9IHRydWU7XHJcblx0XHR0aGlzLmxpZ2h0VHlwZSA9IExpZ2h0VHlwZS5Qb2ludExpZ2h0O1xyXG5cdFx0aWYgKG9wZW5TaGFkb3cpIHRoaXMuc2hhZG93ID0gbmV3IFBvaW50TGlnaHRTaGFkb3coKTtcclxuXHR9XHJcblx0c2V0IGRpc3RhbmNlKHZhbHVlKSB7XHJcblx0XHR0aGlzLmRpc3RhbmNlRGlydHkgPSB0cnVlO1xyXG5cdFx0dGhpcy5fZGlzdGFuY2UgPSB2YWx1ZTtcclxuXHR9XHJcblx0Z2V0IGRpc3RhbmNlKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuX2Rpc3RhbmNlO1xyXG5cdH1cclxuXHRzZXQgZGVjYXkodmFsdWUpIHtcclxuXHRcdHRoaXMuZGVjYXlEaXJ0eSA9IHRydWU7XHJcblx0XHR0aGlzLl9kZWNheSA9IHZhbHVlO1xyXG5cdH1cclxuXHRnZXQgZGVjYXkoKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5fZGVjYXk7XHJcblx0fVxyXG59XHJcbi8vIHVuaWZvcm1cclxuLy8gY29sb3I6IHt9LFxyXG4vLyBwb3NpdGlvbjoge30sXHJcbi8vIGRlY2F5OiB7fSxcclxuLy8gZGlzdGFuY2U6IHt9XHJcbiIsImltcG9ydCBDYW1lcmEgZnJvbSBcIi4uL2NhbWVyYS9DYW1lcmFcIjtcbmltcG9ydCB7IEZyYW1lU3RhdGUgfSBmcm9tIFwiLi4vY29yZS9GcmFtZVN0YXRlXCI7XG5pbXBvcnQgTGlnaHRNYW5nZXIgZnJvbSBcIi4uL2NvcmUvTGlnaHRNYW5nZXJcIjtcbmltcG9ydCBSZW5kZXJRdWV1ZSBmcm9tIFwiLi4vY29yZS9SZW5kZXJRdWV1ZVwiO1xuaW1wb3J0IHsgQ29tbWFuZFN1YlR5cGUgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVDb25zdGFudFwiO1xuaW1wb3J0IHsgTGlnaHQgfSBmcm9tIFwiLi4vbGlnaHQvTGlnaHRcIjtcbmltcG9ydCB7IFBvaW50TGlnaHQgfSBmcm9tIFwiLi4vbGlnaHQvUG9pbnRMaWdodFwiO1xuaW1wb3J0IHsgQmFzZVNoYWRvdyB9IGZyb20gXCIuLi9saWdodC9zaGFkb3dzL0Jhc2VTaGFkb3dcIjtcbmltcG9ydCB7IFBvaW50TGlnaHRTaGFkb3cgfSBmcm9tIFwiLi4vbGlnaHQvc2hhZG93cy9Qb2ludExpZ2h0U2hhZG93XCI7XG5pbXBvcnQgU2hhZGVyTWF0ZXJpYWwgZnJvbSBcIi4uL21hdGVyaWFsL1NoYWRlck1hdGVyaWFsXCI7XG5pbXBvcnQgQXR0YWNobWVudCBmcm9tIFwiLi4vcmVuZGVyL0F0dGFjaG1lbnRcIjtcbmltcG9ydCBDb250ZXh0IGZyb20gXCIuLi9yZW5kZXIvQ29udGV4dFwiO1xuaW1wb3J0IFJlbmRlclRhcmdldCBmcm9tIFwiLi4vcmVuZGVyL1JlbmRlclRhcmdldFwiO1xuaW1wb3J0IFRleHR1cmUgZnJvbSBcIi4uL3JlbmRlci9UZXh0dXJlXCI7XG5pbXBvcnQgZ2V0VmVydEZyYWcgZnJvbSBcIi4uL3NoYWRlci9TaGFkZXJzXCI7XG5pbXBvcnQgUGFzcyBmcm9tIFwiLi9QYXNzXCI7XG5leHBvcnQgY2xhc3MgU2hhZG93UGFzcyBleHRlbmRzIFBhc3Mge1xuXHRwdWJsaWMgc2hhZG93TWF0ZXJpYWw6IFNoYWRlck1hdGVyaWFsO1xuXHRfdGVzdFRleHR1cmU6IFRleHR1cmU7XG5cdGNvbnN0cnVjdG9yKGNvbnRleHQ6IENvbnRleHQpIHtcblx0XHRzdXBlcihjb250ZXh0KTtcblx0XHR0aGlzLmluaXQoY29udGV4dCk7XG5cdH1cblx0cmVuZGVyKGZyYW1lU3RhdGU6IEZyYW1lU3RhdGUsIGNhbWVyYT86IENhbWVyYSkge1xuXHRcdGNvbnN0IHsgcmVuZGVyUXVldWUsIGNvbnRleHQsIGxpZ2h0TWFuZ2VyIH0gPSBmcmFtZVN0YXRlO1xuXHRcdGNvbnN0IGxpZ2h0cyA9IGxpZ2h0TWFuZ2VyLmdldEFsbExpZ2h0cygpO1xuXHRcdGlmIChsaWdodHMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGxpZ2h0cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3QgbGlnaHQ6IFBvaW50TGlnaHQgfCBMaWdodCA9IGxpZ2h0c1tpXTtcblx0XHRcdGNvbnN0IHNoYWRvdyA9IGxpZ2h0LnNoYWRvdztcblx0XHRcdGlmICghc2hhZG93KSBjb250aW51ZTtcblx0XHRcdC8vIHRoaXMuX3Rlc3RUZXh0dXJlID0gY29udGV4dC5saWdodE1hbmdlci5fdGVzdFRleHR1cmVcblx0XHRcdC8vIHRoaXMuYmVmb3JlUmVuZGVyKHsgc2hhZG93IH0pO1xuXHRcdFx0aWYgKHNoYWRvdyBpbnN0YW5jZW9mIFBvaW50TGlnaHRTaGFkb3cgJiYgbGlnaHQgaW5zdGFuY2VvZiBQb2ludExpZ2h0KSB7XG5cdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgc2hhZG93LnZpZXdwb3J0cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdC8vIOWKqOaAgWJ1ZmZlcuaaguacquiwg+mAmu+8jOWFiOS7peatpOenjeaWueW8j+ino+WGs1xuXHRcdFx0XHRcdHN3aXRjaCAoaSkge1xuXHRcdFx0XHRcdFx0Y2FzZSAwOlxuXHRcdFx0XHRcdFx0XHR0aGlzLnJlbmRlclRhcmdldC5kZXB0aEF0dGFjaG1lbnQub3AgPSBcImNsZWFyXCI7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXG5cdFx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0XHR0aGlzLnJlbmRlclRhcmdldC5kZXB0aEF0dGFjaG1lbnQub3AgPSBcImxvYWRcIjtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHRoaXMuYmVmb3JlUmVuZGVyKHsgc2hhZG93IH0pO1xuXG5cdFx0XHRcdFx0Y29uc3Qgdmlld3BvcnQgPSBzaGFkb3cudmlld3BvcnRzW2ldO1xuXHRcdFx0XHRcdGNvbnN0IHZpZXdwb3J0U2l6ZSA9IHNoYWRvdy52aWV3cG9ydFNpemU7XG5cdFx0XHRcdFx0c2hhZG93LmN1cnJlbnRWaWV3cG9ydEluZGV4ID0gaTtcblx0XHRcdFx0XHRzaGFkb3cudXBkYXRlKGxpZ2h0KTtcblx0XHRcdFx0XHQvLyBsaWdodC5mb3JjZVVwZGF0ZSA9IHRydWU7XG5cdFx0XHRcdFx0Y29udGV4dC5zZXRWaWV3UG9ydChcblx0XHRcdFx0XHRcdHZpZXdwb3J0LnggKiB2aWV3cG9ydFNpemUueCxcblx0XHRcdFx0XHRcdHZpZXdwb3J0LnkgKiB2aWV3cG9ydFNpemUueSxcblx0XHRcdFx0XHRcdHZpZXdwb3J0U2l6ZS54LFxuXHRcdFx0XHRcdFx0dmlld3BvcnRTaXplLnlcblx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdGNvbnRleHQuc2V0U2Npc3NvclRlc3QoXG5cdFx0XHRcdFx0XHR2aWV3cG9ydC54ICogdmlld3BvcnRTaXplLngsXG5cdFx0XHRcdFx0XHR2aWV3cG9ydC55ICogdmlld3BvcnRTaXplLnksXG5cdFx0XHRcdFx0XHR2aWV3cG9ydFNpemUueCxcblx0XHRcdFx0XHRcdHZpZXdwb3J0U2l6ZS55XG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR0aGlzLnN1YlJlbmRlcihyZW5kZXJRdWV1ZSwgc2hhZG93LCBsaWdodE1hbmdlcik7XG5cdFx0XHRcdFx0c3VwZXIuYWZ0ZXJSZW5kZXIoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5yZW5kZXJUYXJnZXQuZGVwdGhBdHRhY2htZW50Lm9wID0gXCJjbGVhclwiO1xuXHRcdFx0XHR0aGlzLmJlZm9yZVJlbmRlcih7IHNoYWRvdyB9KTtcblx0XHRcdFx0c2hhZG93LnVwZGF0ZShsaWdodCk7XG5cdFx0XHRcdGNvbnRleHQuc2V0Vmlld1BvcnQoMCwgMCwgc2hhZG93LnNoYWRvd01hcFNpemUueCwgc2hhZG93LnNoYWRvd01hcFNpemUueSk7XG5cdFx0XHRcdGNvbnRleHQuc2V0U2Npc3NvclRlc3QoMCwgMCwgc2hhZG93LnNoYWRvd01hcFNpemUueCwgc2hhZG93LnNoYWRvd01hcFNpemUueSk7XG5cdFx0XHRcdHRoaXMuc3ViUmVuZGVyKHJlbmRlclF1ZXVlLCBzaGFkb3csIGxpZ2h0TWFuZ2VyKTtcblx0XHRcdFx0c3VwZXIuYWZ0ZXJSZW5kZXIoKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Ly8gc3VwZXIuYWZ0ZXJSZW5kZXIoKTtcblx0XHRsaWdodE1hbmdlci51cGRhdGVMaWdodFNoYWRvdygpO1xuXHRcdGNvbnRleHQucmVzZXRWaWV3UG9ydFRvRnVsbENhbnZhcygpO1xuXHR9XG5cblx0c3ViUmVuZGVyKHJlbmRlclF1ZXVlOiBSZW5kZXJRdWV1ZSwgc2hhZG93OiBCYXNlU2hhZG93LCBsaWdodE1hbmdlcjogTGlnaHRNYW5nZXIpIHtcblx0XHRyZW5kZXJRdWV1ZS5zb3J0KCk7XG5cdFx0Ly8gcmVuZGVyUXVldWUucHJlUmVuZGVyKHNoYWRvdy5jYW1lcmEsIHRoaXMuY29udGV4dCwgdGhpcy5wYXNzUmVuZGVyRW5jb2Rlcik7XG5cdFx0cmVuZGVyUXVldWUudHJhbnNwYXJlbnRSZW5kZXIoXG5cdFx0XHRzaGFkb3cuY2FtZXJhLFxuXHRcdFx0dGhpcy5jb250ZXh0LFxuXHRcdFx0dGhpcy5wYXNzUmVuZGVyRW5jb2Rlcixcblx0XHRcdHRoaXMuc2hhZG93TWF0ZXJpYWwsXG5cdFx0XHRDb21tYW5kU3ViVHlwZS5TaGFkb3csXG5cdFx0XHRsaWdodE1hbmdlclxuXHRcdCk7XG5cdFx0cmVuZGVyUXVldWUub3BhcXVlUmVuZGVyKFxuXHRcdFx0c2hhZG93LmNhbWVyYSxcblx0XHRcdHRoaXMuY29udGV4dCxcblx0XHRcdHRoaXMucGFzc1JlbmRlckVuY29kZXIsXG5cdFx0XHR0aGlzLnNoYWRvd01hdGVyaWFsLFxuXHRcdFx0Q29tbWFuZFN1YlR5cGUuU2hhZG93LFxuXHRcdFx0bGlnaHRNYW5nZXJcblx0XHQpO1xuXHR9XG5cblx0Ly8gZ2V0RGVwdGhUZXh0dXJlKCk6IFRleHR1cmUge1xuXHQvLyBcdHJldHVybiB0aGlzLl90ZXN0VGV4dHVyZTtcblx0Ly8gfVxuXHRiZWZvcmVSZW5kZXIob3B0aW9uczogeyBzaGFkb3c6IEJhc2VTaGFkb3cgfSkge1xuXHRcdGNvbnN0IHsgc2hhZG93IH0gPSBvcHRpb25zO1xuXHRcdHRoaXMuc2V0UmVuZGVyVGFyZ2V0KHNoYWRvdyk7XG5cdFx0c3VwZXIuYmVmb3JlUmVuZGVyKCk7XG5cdH1cblx0cHVibGljIHNldFNpemUod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiB2b2lkIHtcblx0XHR0aGlzLnJlbmRlclRhcmdldC5zZXRTaXplKHdpZHRoLCBoZWlnaHQsIDEpO1xuXHR9XG5cdHByaXZhdGUgc2V0UmVuZGVyVGFyZ2V0KHNoYWRvdzogQmFzZVNoYWRvdykge1xuXHRcdHRoaXMucmVuZGVyVGFyZ2V0LmRlcHRoQXR0YWNobWVudC50ZXh0dXJlID0gc2hhZG93LmdldFNoYWRvd01hcFRleHR1cmUoKTtcblx0fVxuXG5cdHByaXZhdGUgaW5pdChjb250ZXh0OiBDb250ZXh0KSB7XG5cdFx0dGhpcy5jcmVhdGVSZW5kZXJUYXJnZXQoY29udGV4dCk7XG5cdFx0dGhpcy5jcmVhdGVTaGFkb3dNYXRlcmlhbCgpO1xuXHR9XG5cdHByaXZhdGUgY3JlYXRlUmVuZGVyVGFyZ2V0KGNvbnRleHQ6IENvbnRleHQpIHtcblx0XHRjb25zdCBkZXB0aEF0dGFjaG1lbnQgPSBuZXcgQXR0YWNobWVudCgxLjAsIHsgdGV4dHVyZTogdW5kZWZpbmVkIH0pO1xuXHRcdHRoaXMucmVuZGVyVGFyZ2V0ID0gbmV3IFJlbmRlclRhcmdldChcInJlbmRlclwiLCBbXSwgZGVwdGhBdHRhY2htZW50KTtcblx0fVxuXG5cdHByaXZhdGUgY3JlYXRlU2hhZG93TWF0ZXJpYWwoKSB7XG5cdFx0Y29uc3Qgc2hhZG93TWFwU2hhZGVyRnVuY3Rpb24gPSAoZGVmaW5lcyA9IHt9KSA9PiB7XG5cdFx0XHRjb25zdCBmaW5hbERlZmluZXMgPSBPYmplY3QuYXNzaWduKFxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0c2VsZkJpbmRpbmc6IDAsXG5cdFx0XHRcdFx0Y2FtZXJhQmluZGluZzogMCxcblx0XHRcdFx0XHRwb3NpdGlvbkxvY2F0aW9uOiAwXG5cdFx0XHRcdH0sXG5cdFx0XHRcdGRlZmluZXNcblx0XHRcdCk7XG5cdFx0XHRyZXR1cm4gZ2V0VmVydEZyYWcoXCJzaGFkb3dNYXBcIiwgZmluYWxEZWZpbmVzKS52ZXJ0O1xuXHRcdH07XG5cblx0XHR0aGlzLnNoYWRvd01hdGVyaWFsID0gbmV3IFNoYWRlck1hdGVyaWFsKHtcblx0XHRcdHR5cGU6IFwic2hhZG93TWF0ZXJpYWxcIixcblx0XHRcdHVuaWZvcm1zOiB7XG5cdFx0XHRcdG1vZGVsTWF0cml4OiB7IHR5cGU6IFwibWF0NHg0PGYzMj5cIiwgdmFsdWU6IG51bGwgfVxuXHRcdFx0fSxcblx0XHRcdHZlcnQ6IHNoYWRvd01hcFNoYWRlckZ1bmN0aW9uLFxuXHRcdFx0ZnJhZzogdW5kZWZpbmVkLFxuXHRcdFx0bGlnaHQ6IGZhbHNlIC8vIFRPRE865YWIdHJ1Ze+8jGZhbHNl5pyJ5pi+56S6YnVnXG5cdFx0fSk7XG5cdH1cbn1cbiIsImltcG9ydCBDYW1lcmEgZnJvbSBcIi4uL2NhbWVyYS9DYW1lcmFcIjtcbmltcG9ydCB7IEZyYW1lU3RhdGUgfSBmcm9tIFwiLi4vY29yZS9GcmFtZVN0YXRlXCI7XG5pbXBvcnQgeyBCYXNpY1Bhc3MgfSBmcm9tIFwiLi4vcGFzcy9CYXNpY1Bhc3NcIjtcbmltcG9ydCB7IFNoYWRvd1Bhc3MgfSBmcm9tIFwiLi4vcGFzcy9TaGFkb3dQYXNzXCI7XG5pbXBvcnQgQ29udGV4dCBmcm9tIFwiLi4vcmVuZGVyL0NvbnRleHRcIjtcbmltcG9ydCBUZXh0dXJlIGZyb20gXCIuLi9yZW5kZXIvVGV4dHVyZVwiO1xuaW1wb3J0IElCYXNlUmVuZGVyTGluZSBmcm9tIFwiLi9JQmFzZVJlbmRlckxpbmVcIjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRm9yd2FyZFJlbmRlckxpbmUgaW1wbGVtZW50cyBJQmFzZVJlbmRlckxpbmUge1xuXHRwcml2YXRlIGJhc2ljUGFzczogQmFzaWNQYXNzO1xuXHRwcm90ZWN0ZWQgc2hhZG93UGFzczogU2hhZG93UGFzcztcblx0Y29uc3RydWN0b3IocHVibGljIGNvbnRleHQ6IENvbnRleHQpIHtcblx0XHR0aGlzLmJhc2ljUGFzcyA9IG5ldyBCYXNpY1Bhc3MoY29udGV4dCk7XG5cdFx0dGhpcy5zaGFkb3dQYXNzID0gbmV3IFNoYWRvd1Bhc3MoY29udGV4dCk7XG5cdH1cblx0Z2V0T3V0cHV0VGV4dHVyZSgpOiBUZXh0dXJlIHtcblx0XHRyZXR1cm4gdGhpcy5iYXNpY1Bhc3MuZ2V0Q29sb3JUZXh0dXJlKDApO1xuXHRcdC8vIHJldHVybiB0aGlzLnNoYWRvd1Bhc3MuZ2V0RGVwdGhUZXh0dXJlKClcblx0fVxuXHRyZW5kZXIoZnJhbWVTdGF0ZTogRnJhbWVTdGF0ZSwgY2FtZXJhPzogQ2FtZXJhKSB7XG5cdFx0dGhpcy5zaGFkb3dQYXNzLnJlbmRlcihmcmFtZVN0YXRlLCBjYW1lcmEpO1xuXG5cdFx0dGhpcy5iYXNpY1Bhc3MuYmVmb3JlUmVuZGVyKGZyYW1lU3RhdGUpO1xuXHRcdHRoaXMuYmFzaWNQYXNzLnJlbmRlcihmcmFtZVN0YXRlLCBjYW1lcmEpO1xuXHRcdHRoaXMuYmFzaWNQYXNzLmFmdGVyUmVuZGVyKCk7XG5cdH1cblx0c2V0U2l6ZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcikge1xuXHRcdHRoaXMuYmFzaWNQYXNzLnNldFNpemUod2lkdGgsIGhlaWdodCk7XG5cdFx0dGhpcy5zaGFkb3dQYXNzLnNldFNpemUod2lkdGgsIGhlaWdodCk7XG5cdH1cblx0ZGVzdHJveSgpIHtcblx0XHR0aGlzLmJhc2ljUGFzcyA9IHVuZGVmaW5lZDtcblx0fVxufVxuIiwiaW1wb3J0IENhbWVyYSBmcm9tIFwiLi9jYW1lcmEvQ2FtZXJhXCI7XG5pbXBvcnQgUGVyc3BlY3RpdmVDYW1lcmEgZnJvbSBcIi4vY2FtZXJhL1BlcnNwZWN0aXZlQ2FtZXJhXCI7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tIFwiLi9jb3JlL0V2ZW50RGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgRnJhbWVTdGF0ZSwgQmFja2dyb3VuZCB9IGZyb20gXCIuL2NvcmUvRnJhbWVTdGF0ZVwiO1xuaW1wb3J0IExpZ2h0TWFuZ2VyIGZyb20gXCIuL2NvcmUvTGlnaHRNYW5nZXJcIjtcbmltcG9ydCBNZXNoTWFuZ2VyIGZyb20gXCIuL2NvcmUvTWVzaE1hbmdlclwiO1xuaW1wb3J0IHRleHR1cmVDYWNoZSBmcm9tIFwiLi9jb3JlL1RleHR1cmVDYWNoZVwiO1xuaW1wb3J0IHsgSW5zdGFuY2UsIFJlbmRlck9iamVjdFR5cGUgfSBmcm9tIFwiLi9jb3JlL1dlYkdQVVR5cGVzXCI7XG5pbXBvcnQgeyBMaWdodCB9IGZyb20gXCIuL2xpZ2h0L0xpZ2h0XCI7XG5pbXBvcnQgeyBNZXNoIH0gZnJvbSBcIi4vbWVzaC9NZXNoXCI7XG5pbXBvcnQgTm9kZSBmcm9tIFwiLi9tZXNoL05vZGVcIjtcbmltcG9ydCBQb3N0RWZmZWN0IGZyb20gXCIuL3Bvc3QtcHJvY2Vzcy9Qb3N0RWZmZWN0XCI7XG5pbXBvcnQgUG9zdEVmZmVjdENvbGxlY3Rpb24gZnJvbSBcIi4vcG9zdC1wcm9jZXNzL1Bvc3RFZmZlY3RDb2xsZWN0aW9uXCI7XG5pbXBvcnQgQ29udGV4dCBmcm9tIFwiLi9yZW5kZXIvQ29udGV4dFwiO1xuaW1wb3J0IHsgVmlld1BvcnQgfSBmcm9tIFwiLi9yZW5kZXIvUmVuZGVyU3RhdGVcIjtcbmltcG9ydCBGb3J3YXJkUmVuZGVyTGluZSBmcm9tIFwiLi9yZW5kZXJwaXBlbGluZS9Gb3J3YXJkUmVuZGVyTGluZVwiO1xuaW1wb3J0IElCYXNlUmVuZGVyTGluZSBmcm9tIFwiLi9yZW5kZXJwaXBlbGluZS9JQmFzZVJlbmRlckxpbmVcIjtcblxuZXhwb3J0IGNsYXNzIFNjZW5lIGV4dGVuZHMgRXZlbnREaXNwYXRjaGVyIHtcblx0Y2FtZXJhOiBQZXJzcGVjdGl2ZUNhbWVyYTtcblx0Y29udGV4dDogQ29udGV4dDtcblx0cmVxdWVzdEFkYXB0ZXI6IG9iamVjdDtcblx0ZGV2aWNlRGVzY3JpcHRvcjogb2JqZWN0O1xuXHRwcmVzZW50YXRpb25Db250ZXh0RGVzY3JpcHRvcjogb2JqZWN0O1xuXHRjb250YWluZXI6IEhUTUxEaXZFbGVtZW50O1xuXHRmcmFtZVN0YXRlOiBGcmFtZVN0YXRlO1xuXHRjdXJyZW50UmVuZGVyUGlwZWxpbmU6IElCYXNlUmVuZGVyTGluZTtcblx0dmlld3BvcnQ6IFZpZXdQb3J0O1xuXHRiYWNrZ3JvdW5kOiBCYWNrZ3JvdW5kO1xuXHRwcml2YXRlIHJlYWR5OiBib29sZWFuO1xuXHRwcml2YXRlIGluaXRlZDogYm9vbGVhbjtcblx0cHJpdmF0ZSBtZXNoTWFuZ2VyOiBNZXNoTWFuZ2VyO1xuXHRwcml2YXRlIHBvc3RFZmZlY3RDb2xsZWN0aW9uOiBQb3N0RWZmZWN0Q29sbGVjdGlvbjtcblx0cHJpdmF0ZSBsaWdodE1hbmdlcjogTGlnaHRNYW5nZXI7XG5cdGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcblx0XHRzdXBlcigpO1xuXHRcdHRoaXMuY29udGFpbmVyID1cblx0XHRcdG9wdGlvbnMuY29udGFpbmVyIGluc3RhbmNlb2YgSFRNTERpdkVsZW1lbnRcblx0XHRcdFx0PyBvcHRpb25zLmNvbnRhaW5lclxuXHRcdFx0XHQ6IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG9wdGlvbnMuY29udGFpbmVyKTtcblx0XHR0aGlzLm1lc2hNYW5nZXIgPSBuZXcgTWVzaE1hbmdlcigpO1xuXHRcdHRoaXMucG9zdEVmZmVjdENvbGxlY3Rpb24gPSBuZXcgUG9zdEVmZmVjdENvbGxlY3Rpb24oKTtcblx0XHR0aGlzLmNvbnRleHQgPSBuZXcgQ29udGV4dCh7XG5cdFx0XHRjYW52YXM6IG51bGwsXG5cdFx0XHRjb250YWluZXI6IHRoaXMuY29udGFpbmVyLFxuXHRcdFx0cGl4ZWxSYXRpbzogMVxuXHRcdH0pO1xuXHRcdHRoaXMucmVxdWVzdEFkYXB0ZXIgPSBvcHRpb25zLnJlcXVlc3RBZGFwdGVyIHx8IHt9O1xuXHRcdHRoaXMuZGV2aWNlRGVzY3JpcHRvciA9IG9wdGlvbnMuZGV2aWNlRGVzY3JpcHRvciB8fCB7fTtcblx0XHR0aGlzLnByZXNlbnRhdGlvbkNvbnRleHREZXNjcmlwdG9yID0gb3B0aW9ucy5wcmVzZW50YXRpb25Db250ZXh0RGVzY3JpcHRvcjtcblx0XHR0aGlzLnJlYWR5ID0gZmFsc2U7XG5cdFx0dGhpcy5pbml0ZWQgPSBmYWxzZTtcblx0XHR0aGlzLmxpZ2h0TWFuZ2VyID0gbmV3IExpZ2h0TWFuZ2VyKHsgb3BlblNoYWRvdzogdHJ1ZSB9KTtcblx0XHR0aGlzLmJhY2tncm91bmQgPSBvcHRpb25zLmJhY2tncm91bmQ7XG5cdH1cblx0cHJpdmF0ZSBhc3luYyBpbml0KCkge1xuXHRcdGF3YWl0IHRoaXMuY29udGV4dC5pbml0KHRoaXMucmVxdWVzdEFkYXB0ZXIsIHRoaXMuZGV2aWNlRGVzY3JpcHRvciwgdGhpcy5wcmVzZW50YXRpb25Db250ZXh0RGVzY3JpcHRvcik7XG5cdFx0dGhpcy5jdXJyZW50UmVuZGVyUGlwZWxpbmUgPSBuZXcgRm9yd2FyZFJlbmRlckxpbmUodGhpcy5jb250ZXh0KTtcblx0XHR0aGlzLmZyYW1lU3RhdGUgPSBuZXcgRnJhbWVTdGF0ZSh0aGlzLmNvbnRleHQsIHRoaXMubGlnaHRNYW5nZXIsIEZyYW1lU3RhdGUuZ2V0RnJhbWVTdGF0ZU9wdGlvbnNCeVNjZW5lKHRoaXMpKTtcblx0XHR0aGlzLnZpZXdwb3J0ID0gbmV3IFZpZXdQb3J0KDAsIDAsIHRoaXMuY29udGV4dC5wcmVzZW50YXRpb25TaXplLndpZHRoLCB0aGlzLmNvbnRleHQucHJlc2VudGF0aW9uU2l6ZS5oZWlnaHQpO1xuXHRcdHRoaXMucmVhZHkgPSB0cnVlO1xuXHR9XG5cdGFkZChpbnN0YW5jZTogSW5zdGFuY2UpIHtcblx0XHRpZiAoXG5cdFx0XHRbUmVuZGVyT2JqZWN0VHlwZS5Ob2RlLCBSZW5kZXJPYmplY3RUeXBlLlNreWJveCwgUmVuZGVyT2JqZWN0VHlwZS5NZXNoLCBSZW5kZXJPYmplY3RUeXBlLkRlYnVnXS5pbmNsdWRlcyhcblx0XHRcdFx0aW5zdGFuY2UudHlwZVxuXHRcdFx0KVxuXHRcdCkge1xuXHRcdFx0dGhpcy5tZXNoTWFuZ2VyLmFkZCg8TWVzaD5pbnN0YW5jZSk7XG5cdFx0fSBlbHNlIGlmIChpbnN0YW5jZS50eXBlID09IFJlbmRlck9iamVjdFR5cGUuTGlnaHQpIHtcblx0XHRcdHRoaXMubGlnaHRNYW5nZXIuYWRkKDxMaWdodD5pbnN0YW5jZSk7XG5cdFx0fSBlbHNlIGlmIChpbnN0YW5jZS50eXBlID09IFJlbmRlck9iamVjdFR5cGUuUG9zdEVmZmVjdCkge1xuXHRcdFx0dGhpcy5wb3N0RWZmZWN0Q29sbGVjdGlvbi5hZGQoPFBvc3RFZmZlY3Q+aW5zdGFuY2UpO1xuXHRcdH1cblx0fVxuXHRyZW1vdmUoaW5zdGFuY2U6IEluc3RhbmNlKSB7XG5cdFx0aWYgKFtSZW5kZXJPYmplY3RUeXBlLk5vZGUsIFJlbmRlck9iamVjdFR5cGUuU2t5Ym94LCBSZW5kZXJPYmplY3RUeXBlLk1lc2hdLmluY2x1ZGVzKGluc3RhbmNlLnR5cGUpKSB7XG5cdFx0XHR0aGlzLm1lc2hNYW5nZXIucmVtb3ZlKDxNZXNoPmluc3RhbmNlKTtcblx0XHR9IGVsc2UgaWYgKGluc3RhbmNlLnR5cGUgPT0gUmVuZGVyT2JqZWN0VHlwZS5MaWdodCkge1xuXHRcdFx0dGhpcy5saWdodE1hbmdlci5yZW1vdmUoPExpZ2h0Pmluc3RhbmNlKTtcblx0XHR9IGVsc2UgaWYgKGluc3RhbmNlLnR5cGUgPT0gUmVuZGVyT2JqZWN0VHlwZS5Qb3N0RWZmZWN0KSB7XG5cdFx0XHR0aGlzLnBvc3RFZmZlY3RDb2xsZWN0aW9uLnJlbW92ZSg8UG9zdEVmZmVjdD5pbnN0YW5jZSk7XG5cdFx0fVxuXHR9XG5cdHNldENhbWVyYShjYW1lcmEpIHtcblx0XHR0aGlzLmNhbWVyYSA9IGNhbWVyYTtcblx0fVxuXHRyZXNpemUod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcblx0XHR0aGlzLmNvbnRleHQucmVzaXplKHdpZHRoLCBoZWlnaHQpO1xuXHRcdHRoaXM/LmN1cnJlbnRSZW5kZXJQaXBlbGluZT8uc2V0U2l6ZSh3aWR0aCwgaGVpZ2h0KTtcblx0XHR0aGlzPy5wb3N0RWZmZWN0Q29sbGVjdGlvbj8uc2V0U2l6ZSh3aWR0aCwgaGVpZ2h0KTtcblx0fVxuXHRhc3luYyByZW5kZXIobm9kZT86IE5vZGUsIGNhbWVyYT86IENhbWVyYSkge1xuXHRcdGlmICghdGhpcy5pbml0ZWQpIHtcblx0XHRcdHRoaXMuaW5pdGVkID0gdHJ1ZTtcblx0XHRcdGF3YWl0IHRoaXMuaW5pdCgpO1xuXHRcdFx0dGhpcy51cGRhdGUobm9kZSwgY2FtZXJhKTtcblx0XHRcdHRoaXMuYWZ0ZXJSZW5kZXIoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy51cGRhdGUobm9kZSwgY2FtZXJhKTtcblx0XHRcdHRoaXMuYWZ0ZXJSZW5kZXIoKTtcblx0XHR9XG5cdH1cblxuXHRhZnRlclJlbmRlcigpIHtcblx0XHQvLyBUT0RPXG5cdH1cblxuXHRwdWJsaWMgc2V0Vmlld1BvcnQoeDogbnVtYmVyLCB5OiBudW1iZXIsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogYm9vbGVhbiB7XG5cdFx0aWYgKCF0aGlzLnJlYWR5KSByZXR1cm4gZmFsc2U7XG5cdFx0dGhpcy5jb250ZXh0LnNldFZpZXdQb3J0KHgsIHksIHdpZHRoLCBoZWlnaHQpO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHB1YmxpYyBzZXRTY2lzc29yVGVzdCh4OiBudW1iZXIsIHk6IG51bWJlciwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiBib29sZWFuIHtcblx0XHRpZiAoIXRoaXMucmVhZHkpIHJldHVybiBmYWxzZTtcblx0XHR0aGlzLmNvbnRleHQuc2V0U2Npc3NvclRlc3QoeCwgeSwgd2lkdGgsIGhlaWdodCk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblx0cHJpdmF0ZSB1cGRhdGUobm9kZT86IE5vZGUsIGNhbWVyYT86IENhbWVyYSkge1xuXHRcdGlmICghdGhpcy5yZWFkeSkgcmV0dXJuO1xuXHRcdC8vIOmHiuaUvue6ueeQhlxuXHRcdHRleHR1cmVDYWNoZS5yZWxlYXNlZFRleHR1cmVzKCk7XG5cdFx0Ly8g5pu05pawRnJhbWVTdGF0ZVxuXHRcdHRoaXMuZnJhbWVTdGF0ZS51cGRhdGUoY2FtZXJhID8/IHRoaXMuY2FtZXJhLCBGcmFtZVN0YXRlLmdldEZyYW1lU3RhdGVPcHRpb25zQnlTY2VuZSh0aGlzKSk7XG5cdFx0Ly8gdXBkYXRlIHByaW1pdGl2ZSBhbmQgc2VsZWN0XG5cdFx0KG5vZGUgPz8gdGhpcy5tZXNoTWFuZ2VyKS51cGRhdGUodGhpcy5mcmFtZVN0YXRlLCBjYW1lcmEgPz8gdGhpcy5jYW1lcmEpO1xuXHRcdC8vIHNlbGN0IHJlbmRlclBpcGVsaW5lXG5cdFx0dGhpcy5jdXJyZW50UmVuZGVyUGlwZWxpbmUucmVuZGVyKHRoaXMuZnJhbWVTdGF0ZSwgY2FtZXJhID8/IHRoaXMuY2FtZXJhKTtcblx0XHQvLyDlkI7lpITnkIZcblx0XHR0aGlzLnBvc3RFZmZlY3RDb2xsZWN0aW9uLnJlbmRlcih0aGlzLmNvbnRleHQsIHRoaXMuY3VycmVudFJlbmRlclBpcGVsaW5lLmdldE91dHB1dFRleHR1cmUoKSk7XG5cdH1cbn1cbiIsImltcG9ydCBJQ2xvbmUgZnJvbSBcIi4uL2NvcmUvSUNsb25lXCI7XG5pbXBvcnQgeyBSZW5kZXJPYmplY3RUeXBlIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcbmltcG9ydCBHZW9tZXRyeSBmcm9tIFwiLi4vZ2VvbWV0cnkvR2VvbWV0cnlcIjtcbmltcG9ydCB7IE1lc2ggfSBmcm9tIFwiLi4vbWVzaC9NZXNoXCI7XG5pbXBvcnQgeyBGbG9hdDMyQXR0cmlidXRlIH0gZnJvbSBcIi4uL3JlbmRlci9BdHRyaWJ1dGVcIjtcbmltcG9ydCBDb250ZXh0IGZyb20gXCIuLi9yZW5kZXIvQ29udGV4dFwiO1xuaW1wb3J0IHsgUHJpbWl0aXZlLCBSZW5kZXJTdGF0ZSwgVGFyZ2V0IH0gZnJvbSBcIi4uL3JlbmRlci9SZW5kZXJTdGF0ZVwiO1xuaW1wb3J0IFJlbmRlclRhcmdldCBmcm9tIFwiLi4vcmVuZGVyL1JlbmRlclRhcmdldFwiO1xuaW1wb3J0IFNhbXBsZXIgZnJvbSBcIi4uL3JlbmRlci9TYW1wbGVyXCI7XG5pbXBvcnQgVGV4dHVyZSBmcm9tIFwiLi4vcmVuZGVyL1RleHR1cmVcIjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUG9zdEVmZmVjdCBpbXBsZW1lbnRzIElDbG9uZSB7XG5cdHdpZHRoOiBudW1iZXI7XG5cblx0aGVpZ2h0OiBudW1iZXI7XG5cblx0ZGVmYXVsdFNhbXBsZXI6IFNhbXBsZXI7XG5cblx0cmVzb2x2ZVRvQ2FudmFzOiBib29sZWFuO1xuXG5cdGN1cnJlbnRSZW5kZXJUYXJnZXQ6IFJlbmRlclRhcmdldDtcblxuXHRmdWxsU2NyZWVuUXVhZDogTWVzaDtcblxuXHRyZW5kZXJTdGF0ZTogUmVuZGVyU3RhdGU7XG5cblx0aWQ6IHN0cmluZztcblxuXHRwcmlvcml0eTogbnVtYmVyO1xuXG5cdGlzUG9zdEVmZmVjdDogYm9vbGVhbjtcblxuXHR0eXBlOiBSZW5kZXJPYmplY3RUeXBlO1xuXG5cdGNvbnN0cnVjdG9yKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBpZDogc3RyaW5nKSB7XG5cdFx0dGhpcy53aWR0aCA9IHdpZHRoO1xuXHRcdHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xuXHRcdHRoaXMuaW5pdERlZmF1bHRQYXJtcygpO1xuXHRcdHRoaXMuaWQgPSBpZDtcblx0XHR0aGlzLnByaW9yaXR5ID0gMDtcblx0XHR0aGlzLmlzUG9zdEVmZmVjdCA9IHRydWU7XG5cdFx0dGhpcy50eXBlID0gUmVuZGVyT2JqZWN0VHlwZS5Qb3N0RWZmZWN0O1xuXHR9XG5cdHJlbmRlcihjb250ZXh0OiBDb250ZXh0LCBjb2xvclRleHR1cmU6IFRleHR1cmUpOiBUZXh0dXJlIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXHRzZXRTaXplKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogdm9pZCB7XG5cdFx0Ly8gdG9kbyA7XG5cdH1cblx0ZGVzdHJveSgpIHtcblx0XHR0aGlzPy5jdXJyZW50UmVuZGVyVGFyZ2V0Py5kZXN0cm95KCk7XG5cdH1cblx0cHJvdGVjdGVkIHJlbmRlck1lc2goY29udGV4dDogQ29udGV4dCkge1xuXHRcdHRoaXMuZnVsbFNjcmVlblF1YWQubWF0ZXJpYWwuZGlydHkgPSB0cnVlO1xuXHRcdHRoaXMuZnVsbFNjcmVlblF1YWQubWF0ZXJpYWwudXBkYXRlKCk7XG5cdFx0Y29uc3QgZHJhd0NvbWFuZCA9IHRoaXMuZnVsbFNjcmVlblF1YWQuZ2V0RHJhd0NvbW1hbmQoKTtcblx0XHRjb25zdCBjdXJyZW50UmVuZGVyUGFzc0VuY29kZXIgPSB0aGlzLmN1cnJlbnRSZW5kZXJUYXJnZXQuYmVnaW5SZW5kZXJQYXNzKGNvbnRleHQuZGV2aWNlKTtcblx0XHRkcmF3Q29tYW5kLnJlbmRlcih7IGRldmljZTogY29udGV4dC5kZXZpY2UsIHBhc3NFbmNvZGVyOiBjdXJyZW50UmVuZGVyUGFzc0VuY29kZXIgfSk7XG5cdFx0dGhpcy5jdXJyZW50UmVuZGVyVGFyZ2V0LmVuZFJlbmRlclBhc3MoKTtcblx0fVxuXHRwcml2YXRlIGluaXREZWZhdWx0UGFybXMoKSB7XG5cdFx0Y29uc3QgZ2VvbWV0cnkgPSBuZXcgR2VvbWV0cnkoe30pO1xuXHRcdGdlb21ldHJ5LnNldEF0dHJpYnV0ZShcblx0XHRcdG5ldyBGbG9hdDMyQXR0cmlidXRlKFwicG9zaXRpb25cIiwgWy0xLjAsIDEuMCwgLTEuMCwgLTEuMCwgMS4wLCAtMS4wLCAxLjAsIC0xLjAsIDEuMCwgMS4wLCAtMS4wLCAxLjBdLCAyKVxuXHRcdCk7XG5cdFx0Z2VvbWV0cnkuY291bnQgPSA2O1xuXHRcdC8vIHJzXG5cdFx0Y29uc3QgcHJpbWl0aXZlID0gbmV3IFByaW1pdGl2ZSgpO1xuXHRcdGNvbnN0IHRhcmdldCA9IG5ldyBUYXJnZXQoKTtcblx0XHQvLyB0YXJnZXQuZm9ybWF0PVRleHR1cmVGb3JtYXQuUkdCQThVbm9ybVxuXHRcdGNvbnN0IHJlbmRlclN0YXRlID0gbmV3IFJlbmRlclN0YXRlKCk7XG5cdFx0cmVuZGVyU3RhdGUucHJpbWl0aXZlID0gcHJpbWl0aXZlO1xuXHRcdHJlbmRlclN0YXRlLnRhcmdldHMgPSBbdGFyZ2V0XTtcblx0XHR0aGlzLnJlbmRlclN0YXRlID0gcmVuZGVyU3RhdGU7XG5cdFx0dGhpcy5mdWxsU2NyZWVuUXVhZCA9IG5ldyBNZXNoKGdlb21ldHJ5KTtcblxuXHRcdHRoaXMuZGVmYXVsdFNhbXBsZXIgPSBuZXcgU2FtcGxlcigpO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBUZXh0dXJlRm9ybWF0LCBUZXh0dXJlVXNhZ2UgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVDb25zdGFudFwiO1xuaW1wb3J0IHsgVW5pZm9ybXMgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVUeXBlc1wiO1xuaW1wb3J0IFNoYWRlck1hdGVyaWFsIGZyb20gXCIuLi9tYXRlcmlhbC9TaGFkZXJNYXRlcmlhbFwiO1xuaW1wb3J0IENvbG9yIGZyb20gXCIuLi9tYXRoL0NvbG9yXCI7XG5pbXBvcnQgVmVjdG9yMiBmcm9tIFwiLi4vbWF0aC9WZWN0b3IyXCI7XG5pbXBvcnQgVmVjdG9yMyBmcm9tIFwiLi4vbWF0aC9WZWN0b3IzXCI7XG5pbXBvcnQgQXR0YWNobWVudCBmcm9tIFwiLi4vcmVuZGVyL0F0dGFjaG1lbnRcIjtcbmltcG9ydCBDb250ZXh0IGZyb20gXCIuLi9yZW5kZXIvQ29udGV4dFwiO1xuaW1wb3J0IFJlbmRlclRhcmdldCBmcm9tIFwiLi4vcmVuZGVyL1JlbmRlclRhcmdldFwiO1xuaW1wb3J0IFRleHR1cmUgZnJvbSBcIi4uL3JlbmRlci9UZXh0dXJlXCI7XG5pbXBvcnQgZ2V0VmVydEZyYWcgZnJvbSBcIi4uL3NoYWRlci9TaGFkZXJzXCI7XG5pbXBvcnQgUG9zdEVmZmVjdCBmcm9tIFwiLi9Qb3N0RWZmZWN0XCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJsb29tUG9zdEVmZmVjdCBleHRlbmRzIFBvc3RFZmZlY3Qge1xuXHRzdGF0aWMgQmx1ckRpcmVjdGlvblggPSBuZXcgVmVjdG9yMigxLjAsIDAuMCk7XG5cdHN0YXRpYyBCbHVyRGlyZWN0aW9uWSA9IG5ldyBWZWN0b3IyKDAuMCwgMS4wKTtcblx0c3RyZW5ndGg6IG51bWJlcjtcblx0cmFkaXVzOiBudW1iZXI7XG5cdHRocmVzaG9sZDogbnVtYmVyO1xuXHRyZW5kZXJUYXJnZXRzSG9yaXpvbnRhbDogUmVuZGVyVGFyZ2V0W107XG5cdHJlbmRlclRhcmdldHNWZXJ0aWNhbDogUmVuZGVyVGFyZ2V0W107XG5cdG5NaXBzOiBudW1iZXI7XG5cdHJlbmRlclRhcmdldEJyaWdodDogUmVuZGVyVGFyZ2V0O1xuXHRtYXRlcmlhbEhpZ2hQYXNzRmlsdGVyOiBTaGFkZXJNYXRlcmlhbDtcblx0aGlnaFBhc3NVbmlmb3JtczogVW5pZm9ybXM7XG5cdGNvbXBvc2l0ZU1hdGVyaWFsOiBTaGFkZXJNYXRlcmlhbDtcblx0c2VwYXJhYmxlQmx1ck1hdGVyaWFsczogU2hhZGVyTWF0ZXJpYWxbXTtcblx0c2VwYXJhYmxlQmx1cllNYXRlcmlhbHM6IFNoYWRlck1hdGVyaWFsW107XG5cdGJsZW5kVW5pZm9ybXM6IFVuaWZvcm1zO1xuXHRibGVuZE1hdGVyaWFsOiBTaGFkZXJNYXRlcmlhbDtcblx0YmxlbmRUYXJnZXQ6IFJlbmRlclRhcmdldDtcblxuXHRjb25zdHJ1Y3RvcihvcHRpb25zOiBCbG9vbVBvc3RFZmZlY3RQcm9wcykge1xuXHRcdHN1cGVyKG9wdGlvbnMud2lkdGgsIG9wdGlvbnMuaGVpZ2h0LCBcImJsb29tXCIpO1xuXHRcdHRoaXMuc3RyZW5ndGggPSBvcHRpb25zLnN0cmVuZ3RoO1xuXHRcdHRoaXMucmFkaXVzID0gb3B0aW9ucy5yYWRpdXM7XG5cdFx0dGhpcy50aHJlc2hvbGQgPSBvcHRpb25zLnRocmVzaG9sZDtcblx0XHR0aGlzLmluaXQoKTtcblx0fVxuXHRkZXN0cm95KCkge1xuXHRcdHRoaXMucmVuZGVyVGFyZ2V0QnJpZ2h0LmRlc3Ryb3koKTtcblx0fVxuXHRyZW5kZXIoY29udGV4dDogQ29udGV4dCwgY29sb3JUZXh0dXJlOiBUZXh0dXJlKTogVGV4dHVyZSB7XG5cdFx0Ly8gMS4gRXh0cmFjdCBCcmlnaHQgQXJlYXNcblx0XHR0aGlzLmN1cnJlbnRSZW5kZXJUYXJnZXQgPSB0aGlzLnJlbmRlclRhcmdldEJyaWdodDtcblx0XHR0aGlzLmhpZ2hQYXNzVW5pZm9ybXMudERpZmZ1c2UudmFsdWUgPSBjb2xvclRleHR1cmU7XG5cdFx0dGhpcy5mdWxsU2NyZWVuUXVhZC5tYXRlcmlhbCA9IHRoaXMubWF0ZXJpYWxIaWdoUGFzc0ZpbHRlcjtcblx0XHR0aGlzLnJlbmRlck1lc2goY29udGV4dCk7XG5cdFx0Ly8gMi4gQmx1ciBBbGwgdGhlIG1pcHMgcHJvZ3Jlc3NpdmVseVxuXHRcdGxldCBpbnB1dFJlbmRlclRhcmdldCA9IHRoaXMucmVuZGVyVGFyZ2V0QnJpZ2h0O1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uTWlwczsgaSsrKSB7XG5cdFx0XHR0aGlzLmZ1bGxTY3JlZW5RdWFkLm1hdGVyaWFsID0gdGhpcy5zZXBhcmFibGVCbHVyTWF0ZXJpYWxzW2ldO1xuXG5cdFx0XHR0aGlzLnNlcGFyYWJsZUJsdXJNYXRlcmlhbHNbaV0udW5pZm9ybXMudERpZmZ1c2UudmFsdWUgPSBpbnB1dFJlbmRlclRhcmdldC5nZXRDb2xvclRleHR1cmUoKTtcblx0XHRcdHRoaXMuc2VwYXJhYmxlQmx1ck1hdGVyaWFsc1tpXS51bmlmb3Jtcy5kaXJlY3Rpb24udmFsdWUgPSBCbG9vbVBvc3RFZmZlY3QuQmx1ckRpcmVjdGlvblg7XG5cdFx0XHR0aGlzLmN1cnJlbnRSZW5kZXJUYXJnZXQgPSB0aGlzLnJlbmRlclRhcmdldHNIb3Jpem9udGFsW2ldO1xuXG5cdFx0XHR0aGlzLnJlbmRlck1lc2goY29udGV4dCk7XG5cdFx0XHR0aGlzLmZ1bGxTY3JlZW5RdWFkLm1hdGVyaWFsID0gdGhpcy5zZXBhcmFibGVCbHVyWU1hdGVyaWFsc1tpXTtcblx0XHRcdHRoaXMuc2VwYXJhYmxlQmx1cllNYXRlcmlhbHNbaV0udW5pZm9ybXMudERpZmZ1c2UudmFsdWUgPSB0aGlzLnJlbmRlclRhcmdldHNIb3Jpem9udGFsW2ldLmdldENvbG9yVGV4dHVyZSgpO1xuXHRcdFx0dGhpcy5zZXBhcmFibGVCbHVyWU1hdGVyaWFsc1tpXS51bmlmb3Jtcy5kaXJlY3Rpb24udmFsdWUgPSBCbG9vbVBvc3RFZmZlY3QuQmx1ckRpcmVjdGlvblk7XG5cdFx0XHR0aGlzLmN1cnJlbnRSZW5kZXJUYXJnZXQgPSB0aGlzLnJlbmRlclRhcmdldHNWZXJ0aWNhbFtpXTtcblxuXHRcdFx0dGhpcy5yZW5kZXJNZXNoKGNvbnRleHQpO1xuXG5cdFx0XHRpbnB1dFJlbmRlclRhcmdldCA9IHRoaXMucmVuZGVyVGFyZ2V0c1ZlcnRpY2FsW2ldO1xuXHRcdH1cblx0XHQvLyBDb21wb3NpdGUgQWxsIHRoZSBtaXBzXG5cdFx0dGhpcy5mdWxsU2NyZWVuUXVhZC5tYXRlcmlhbCA9IHRoaXMuY29tcG9zaXRlTWF0ZXJpYWw7XG5cdFx0dGhpcy5jdXJyZW50UmVuZGVyVGFyZ2V0ID0gdGhpcy5yZW5kZXJUYXJnZXRzSG9yaXpvbnRhbFswXTtcblx0XHR0aGlzLnJlbmRlck1lc2goY29udGV4dCk7XG5cdFx0Ly8gYmxlbmRcblx0XHR0aGlzLmJsZW5kVW5pZm9ybXMuYmFzZUNvbG9yVGV4dHVyZS52YWx1ZSA9IGNvbG9yVGV4dHVyZTtcblx0XHR0aGlzLmZ1bGxTY3JlZW5RdWFkLm1hdGVyaWFsID0gdGhpcy5ibGVuZE1hdGVyaWFsO1xuXHRcdHRoaXMuY3VycmVudFJlbmRlclRhcmdldCA9IHRoaXMuYmxlbmRUYXJnZXQ7XG5cdFx0dGhpcy5yZW5kZXJNZXNoKGNvbnRleHQpO1xuXHRcdHJldHVybiB0aGlzLmN1cnJlbnRSZW5kZXJUYXJnZXQuZ2V0Q29sb3JUZXh0dXJlKCk7XG5cdH1cblx0c2V0U2l6ZSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IHZvaWQge1xuXHRcdHRoaXM/LnJlbmRlclRhcmdldHNIb3Jpem9udGFsPy5mb3JFYWNoKChyZW5kZXJUYXJnZXQpID0+IHJlbmRlclRhcmdldC5zZXRTaXplKHdpZHRoLCBoZWlnaHQsIDEpKTtcblx0XHR0aGlzPy5yZW5kZXJUYXJnZXRzVmVydGljYWw/LmZvckVhY2goKHJlbmRlclRhcmdldCkgPT4gcmVuZGVyVGFyZ2V0LnNldFNpemUod2lkdGgsIGhlaWdodCwgMSkpO1xuXHRcdHRoaXM/LnJlbmRlclRhcmdldEJyaWdodD8uc2V0U2l6ZT8uKHdpZHRoLCBoZWlnaHQsIDEpO1xuXHRcdHRoaXM/LmJsZW5kVGFyZ2V0Py5zZXRTaXplPy4od2lkdGgsIGhlaWdodCwgMSk7XG5cdH1cblx0cHJpdmF0ZSBpbml0KCkge1xuXHRcdHRoaXMucmVuZGVyVGFyZ2V0c0hvcml6b250YWwgPSBbXTtcblx0XHR0aGlzLnJlbmRlclRhcmdldHNWZXJ0aWNhbCA9IFtdO1xuXHRcdHRoaXMubk1pcHMgPSA1O1xuXHRcdGxldCByZXN4ID0gTWF0aC5yb3VuZCh0aGlzLndpZHRoIC8gMik7XG5cdFx0bGV0IHJlc3kgPSBNYXRoLnJvdW5kKHRoaXMuaGVpZ2h0IC8gMik7XG5cblx0XHR0aGlzLnJlbmRlclRhcmdldEJyaWdodCA9IG5ldyBSZW5kZXJUYXJnZXQoXCJyZW5kZXJcIiwgW3RoaXMuY3JlYXRlQ29sb3JBdHRhY2htZW50KHJlc3gsIHJlc3kpXSk7XG5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubk1pcHM7IGkrKykge1xuXHRcdFx0Y29uc3QgcmVuZGVyVGFyZ2V0SG9yaXpvbmFsID0gbmV3IFJlbmRlclRhcmdldChcInJlbmRlclwiLCBbdGhpcy5jcmVhdGVDb2xvckF0dGFjaG1lbnQocmVzeCwgcmVzeSldKTtcblx0XHRcdHRoaXMucmVuZGVyVGFyZ2V0c0hvcml6b250YWwucHVzaChyZW5kZXJUYXJnZXRIb3Jpem9uYWwpO1xuXHRcdFx0Y29uc3QgcmVuZGVyVGFyZ2V0VmVydGljYWwgPSBuZXcgUmVuZGVyVGFyZ2V0KFwicmVuZGVyXCIsIFt0aGlzLmNyZWF0ZUNvbG9yQXR0YWNobWVudChyZXN4LCByZXN5KV0pO1xuXHRcdFx0dGhpcy5yZW5kZXJUYXJnZXRzVmVydGljYWwucHVzaChyZW5kZXJUYXJnZXRWZXJ0aWNhbCk7XG5cdFx0XHRyZXN4ID0gTWF0aC5yb3VuZChyZXN4IC8gMik7XG5cdFx0XHRyZXN5ID0gTWF0aC5yb3VuZChyZXN5IC8gMik7XG5cdFx0fVxuXHRcdC8vIGx1bWlub3NpdHkgaGlnaCBwYXNzIG1hdGVyaWFsXG5cdFx0dGhpcy5oaWdoUGFzc1VuaWZvcm1zID0ge1xuXHRcdFx0dERpZmZ1c2U6IHsgdHlwZTogXCJ0ZXh0dXJlXCIsIHZhbHVlOiBudWxsIH0sXG5cdFx0XHR0U2FtcGxlcjoge1xuXHRcdFx0XHR0eXBlOiBcInNhbXBsZXJcIixcblx0XHRcdFx0dmFsdWU6IHRoaXMuZGVmYXVsdFNhbXBsZXJcblx0XHRcdH0sXG5cdFx0XHRsdW1pbm9zaXR5VGhyZXNob2w6IHsgdHlwZTogXCJmbG9hdFwiLCB2YWx1ZTogdGhpcy50aHJlc2hvbGQgfSxcblx0XHRcdHNtb290aFdpZHRoOiB7IHR5cGU6IFwiZmxvYXRcIiwgdmFsdWU6IDAuMDEgfSxcblx0XHRcdGRlZmF1bHRDb2xvcjogeyB0eXBlOiBcImNvbG9yXCIsIHZhbHVlOiBuZXcgQ29sb3IoMC4wLCAwLCAwKSB9LFxuXHRcdFx0ZGVmYXVsdE9wYWNpdHk6IHsgdHlwZTogXCJmbG9hdFwiLCB2YWx1ZTogMS4wIH1cblx0XHR9O1xuXHRcdGNvbnN0IHNoYWRlciA9IGdldFZlcnRGcmFnKFwibHVtaW5vc2l0eUhpZ2hcIiwgeyBwb3NpdGlvbkxvY2F0aW9uOiAwIH0pO1xuXHRcdHRoaXMubWF0ZXJpYWxIaWdoUGFzc0ZpbHRlciA9IG5ldyBTaGFkZXJNYXRlcmlhbCh7XG5cdFx0XHR0eXBlOiBcImJsb29tXCIsXG5cdFx0XHR1bmlmb3JtczogdGhpcy5oaWdoUGFzc1VuaWZvcm1zLFxuXHRcdFx0dmVydDogc2hhZGVyLnZlcnQsXG5cdFx0XHRmcmFnOiBzaGFkZXIuZnJhZ1xuXHRcdH0pO1xuXHRcdC8vIEdhdXNzaWFuIEJsdXIgTWF0ZXJpYWxzXG5cdFx0dGhpcy5tYXRlcmlhbEhpZ2hQYXNzRmlsdGVyLnJlbmRlclN0YXRlID0gdGhpcy5yZW5kZXJTdGF0ZTtcblx0XHR0aGlzLnNlcGFyYWJsZUJsdXJNYXRlcmlhbHMgPSBbXTtcblx0XHR0aGlzLnNlcGFyYWJsZUJsdXJZTWF0ZXJpYWxzID0gW107XG5cdFx0Y29uc3Qga2VybmVsU2l6ZUFycmF5ID0gWzMsIDUsIDcsIDksIDExXTtcblx0XHRyZXN4ID0gTWF0aC5yb3VuZCh0aGlzLndpZHRoIC8gMik7XG5cdFx0cmVzeSA9IE1hdGgucm91bmQodGhpcy5oZWlnaHQgLyAyKTtcblxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uTWlwczsgaSsrKSB7XG5cdFx0XHR0aGlzLnNlcGFyYWJsZUJsdXJNYXRlcmlhbHMucHVzaCh0aGlzLmdldFNlcGVyYWJsZUJsdXJNYXRlcmlhbChrZXJuZWxTaXplQXJyYXlbaV0sIFwiQmx1ck1hdGVyaWFsXCIgKyBpKSk7XG5cdFx0XHR0aGlzLnNlcGFyYWJsZUJsdXJZTWF0ZXJpYWxzLnB1c2godGhpcy5nZXRTZXBlcmFibGVCbHVyTWF0ZXJpYWwoa2VybmVsU2l6ZUFycmF5W2ldLCBcIkJsdXJNYXRlcmlhbFlcIiArIGkpKTtcblx0XHRcdHJlc3ggPSBNYXRoLnJvdW5kKHJlc3ggLyAyKTtcblxuXHRcdFx0cmVzeSA9IE1hdGgucm91bmQocmVzeSAvIDIpO1xuXHRcdH1cblx0XHQvLyBDb21wb3NpdGUgbWF0ZXJpYWxcblx0XHR0aGlzLmNvbXBvc2l0ZU1hdGVyaWFsID0gdGhpcy5nZXRDb21wb3NpdGVNYXRlcmlhbCh0aGlzLm5NaXBzLCBcImNvbXBvc2l0ZU1hdGVyaWFsXCIpO1xuXHRcdHRoaXMuY29tcG9zaXRlTWF0ZXJpYWwucmVuZGVyU3RhdGUgPSB0aGlzLnJlbmRlclN0YXRlO1xuXHRcdHRoaXMuYmxlbmRVbmlmb3JtcyA9IHtcblx0XHRcdHREaWZmdXNlOiB7IHR5cGU6IFwidGV4dHVyZVwiLCB2YWx1ZTogdGhpcy5yZW5kZXJUYXJnZXRzSG9yaXpvbnRhbFswXS5nZXRDb2xvclRleHR1cmUoKSB9LFxuXHRcdFx0YmFzZUNvbG9yVGV4dHVyZTogeyB0eXBlOiBcInRleHR1cmVcIiwgdmFsdWU6IG51bGwgfSxcblx0XHRcdHRTYW1wbGVyOiB7XG5cdFx0XHRcdHR5cGU6IFwic2FtcGxlclwiLFxuXHRcdFx0XHR2YWx1ZTogdGhpcy5kZWZhdWx0U2FtcGxlclxuXHRcdFx0fVxuXHRcdH07XG5cdFx0Y29uc3QgYmxlbmRTaGFkZXIgPSBnZXRWZXJ0RnJhZyhcImJsZW5kXCIsIHsgcG9zaXRpb25Mb2NhdGlvbjogMCB9KTtcblx0XHR0aGlzLmJsZW5kTWF0ZXJpYWwgPSBuZXcgU2hhZGVyTWF0ZXJpYWwoe1xuXHRcdFx0dHlwZTogXCJwb3N0QmxlbmRcIixcblx0XHRcdHVuaWZvcm1zOiB0aGlzLmJsZW5kVW5pZm9ybXMsXG5cdFx0XHR2ZXJ0OiBibGVuZFNoYWRlci52ZXJ0LFxuXHRcdFx0ZnJhZzogYmxlbmRTaGFkZXIuZnJhZ1xuXHRcdH0pO1xuXHRcdHRoaXMuYmxlbmRNYXRlcmlhbC5yZW5kZXJTdGF0ZSA9IHRoaXMucmVuZGVyU3RhdGU7XG5cdFx0dGhpcy5ibGVuZFRhcmdldCA9IG5ldyBSZW5kZXJUYXJnZXQoXCJyZW5kZXJcIiwgW3RoaXMuY3JlYXRlQ29sb3JBdHRhY2htZW50KHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KV0pO1xuXHR9XG5cdHByaXZhdGUgY3JlYXRlQ29sb3JBdHRhY2htZW50KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogQXR0YWNobWVudCB7XG5cdFx0Y29uc3QgY29sb3JUZXh0dXJlID0gbmV3IFRleHR1cmUoe1xuXHRcdFx0c2l6ZTogeyB3aWR0aCwgaGVpZ2h0LCBkZXB0aDogMSB9LFxuXHRcdFx0Zm9ybWF0OiBUZXh0dXJlRm9ybWF0LkJHUkE4VW5vcm0sXG5cdFx0XHR1c2FnZTogVGV4dHVyZVVzYWdlLlJlbmRlckF0dGFjaG1lbnQgfCBUZXh0dXJlVXNhZ2UuVGV4dHVyZUJpbmRpbmdcblx0XHR9KTtcblx0XHRjb25zdCBjb2xvckF0dGFjaG1lbnQgPSBuZXcgQXR0YWNobWVudCh7IHI6IDAuMCwgZzogMC4wLCBiOiAwLjAsIGE6IDAuMCB9LCB7IHRleHR1cmU6IGNvbG9yVGV4dHVyZSB9KTtcblx0XHRyZXR1cm4gY29sb3JBdHRhY2htZW50O1xuXHR9XG5cdHByaXZhdGUgZ2V0Q29tcG9zaXRlTWF0ZXJpYWwobk1pcHM6IG51bWJlciwgdHlwZSk6IFNoYWRlck1hdGVyaWFsIHtcblx0XHRyZXR1cm4gbmV3IFNoYWRlck1hdGVyaWFsKHtcblx0XHRcdHR5cGUsXG5cdFx0XHR1bmlmb3Jtczoge1xuXHRcdFx0XHRibHVyVGV4dHVyZTE6IHsgdHlwZTogXCJ0ZXh0dXJlXCIsIHZhbHVlOiB0aGlzLnJlbmRlclRhcmdldHNWZXJ0aWNhbFswXS5nZXRDb2xvclRleHR1cmUoKSB9LFxuXHRcdFx0XHRibHVyVGV4dHVyZTI6IHsgdHlwZTogXCJ0ZXh0dXJlXCIsIHZhbHVlOiB0aGlzLnJlbmRlclRhcmdldHNWZXJ0aWNhbFsxXS5nZXRDb2xvclRleHR1cmUoKSB9LFxuXHRcdFx0XHRibHVyVGV4dHVyZTM6IHsgdHlwZTogXCJ0ZXh0dXJlXCIsIHZhbHVlOiB0aGlzLnJlbmRlclRhcmdldHNWZXJ0aWNhbFsyXS5nZXRDb2xvclRleHR1cmUoKSB9LFxuXHRcdFx0XHRibHVyVGV4dHVyZTQ6IHsgdHlwZTogXCJ0ZXh0dXJlXCIsIHZhbHVlOiB0aGlzLnJlbmRlclRhcmdldHNWZXJ0aWNhbFszXS5nZXRDb2xvclRleHR1cmUoKSB9LFxuXHRcdFx0XHRibHVyVGV4dHVyZTU6IHsgdHlwZTogXCJ0ZXh0dXJlXCIsIHZhbHVlOiB0aGlzLnJlbmRlclRhcmdldHNWZXJ0aWNhbFs0XS5nZXRDb2xvclRleHR1cmUoKSB9LFxuXHRcdFx0XHR0U2FtcGxlcjoge1xuXHRcdFx0XHRcdHR5cGU6IFwic2FtcGxlclwiLFxuXHRcdFx0XHRcdHZhbHVlOiB0aGlzLmRlZmF1bHRTYW1wbGVyXG5cdFx0XHRcdH0sXG5cdFx0XHRcdGJsb29tU3RyZW5ndGg6IHsgdHlwZTogXCJmMzJcIiwgdmFsdWU6IHRoaXMuc3RyZW5ndGggfSxcblx0XHRcdFx0Ymxvb21SYWRpdXM6IHsgdHlwZTogXCJmMzJcIiwgdmFsdWU6IHRoaXMucmFkaXVzIH0sXG5cdFx0XHRcdGJsb29tRmFjdG9yczogeyB0eXBlOiBcImFycmF5PGYzMj5cIiwgdmFsdWU6IFsxLjAsIDAuOCwgMC42LCAwLjQsIDAuMl0gfSxcblx0XHRcdFx0Ymxvb21UaW50Q29sb3JzOiB7XG5cdFx0XHRcdFx0dHlwZTogXCJhcnJheTxmMzI+XCIsXG5cdFx0XHRcdFx0dmFsdWU6IFtcblx0XHRcdFx0XHRcdG5ldyBWZWN0b3IzKDEsIDEsIDEpLFxuXHRcdFx0XHRcdFx0bmV3IFZlY3RvcjMoMSwgMSwgMSksXG5cdFx0XHRcdFx0XHRuZXcgVmVjdG9yMygxLCAxLCAxKSxcblx0XHRcdFx0XHRcdG5ldyBWZWN0b3IzKDEsIDEsIDEpLFxuXHRcdFx0XHRcdFx0bmV3IFZlY3RvcjMoMSwgMSwgMSlcblx0XHRcdFx0XHRdXG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cblx0XHRcdHZlcnQ6ICgpID0+IHtcblx0XHRcdFx0cmV0dXJuIGBcbiAgICAgICAgICAgICAgc3RydWN0IFZlcnRleElucHV0IHtcbiAgICAgICAgICAgICAgICAgICAgQGxvY2F0aW9uKDApIHBvc2l0aW9uOiB2ZWMyPGYzMj4sICAgICAgIFxuICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgc3RydWN0IFZlcnRleE91dHB1dCB7XG4gICAgICAgICAgICAgICAgICAgIEBidWlsdGluKHBvc2l0aW9uKSBwb3NpdGlvbjogdmVjNDxmMzI+LFxuICAgICAgICAgICAgICAgICAgICBAbG9jYXRpb24oMCkgdXY6IHZlYzI8ZjMyPixcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgQHZlcnRleFxuICAgICAgICAgICAgICAgZm4gbWFpbihpbnB1dDogVmVydGV4SW5wdXQpIC0+IFZlcnRleE91dHB1dCB7XG4gICAgICAgICAgICAgICAgdmFyIG91dHB1dDpWZXJ0ZXhPdXRwdXQ7XG4gICAgICAgICAgICAgICAgb3V0cHV0LnV2ID0gaW5wdXQucG9zaXRpb24gKiAwLjUgKyAwLjU7XG4gICAgICAgICAgICAgICAgb3V0cHV0LnBvc2l0aW9uID0gdmVjNDxmMzI+KGlucHV0LnBvc2l0aW9uLCAwLjAsIDEuMCk7O1xuICAgICAgICAgICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYDtcblx0XHRcdH0sXG5cblx0XHRcdGZyYWc6IChkZWZpbmVzKSA9PiB7XG5cdFx0XHRcdHJldHVybiBgXG4gICAgICAgICAgICAgICAgc3RydWN0IEZyYWdJbnB1dCB7XG4gICAgICAgICAgICAgICAgICAgIEBsb2NhdGlvbigwKSB1djogdmVjMjxmMzI+LFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgc3RydWN0IEJsb29tVW5pZm9ybXN7XG4gICAgICAgICAgICAgICAgICAgIGJsb29tU3RyZW5ndGg6ZjMyLFxuICAgICAgICAgICAgICAgICAgICBibG9vbVJhZGl1czpmMzIsXG4gICAgICAgICAgICAgICAgICAgIGJsb29tRmFjdG9ycyA6IGFycmF5PGYzMiw1PixcbiAgICAgICAgICAgICAgICAgICAgYmxvb21UaW50Q29sb3JzIDogYXJyYXk8dmVjMzxmMzI+LDU+XG4gICAgICAgICAgICAgICAgfSAgXG4gICAgICAgICAgICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKDApICB2YXI8c3RvcmFnZSwgcmVhZD4gYmxvb21Vbmlmb3JtcyA6IEJsb29tVW5pZm9ybXM7XG5cbiAgICAgICAgICAgICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLmJsdXJUZXh0dXJlMUJpbmRpbmd9KSB2YXIgYmx1clRleHR1cmUxOiB0ZXh0dXJlXzJkPGYzMj47XG4gICAgICAgICAgICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKCR7ZGVmaW5lcy5ibHVyVGV4dHVyZTJCaW5kaW5nfSkgdmFyIGJsdXJUZXh0dXJlMjogdGV4dHVyZV8yZDxmMzI+O1xuICAgICAgICAgICAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMuYmx1clRleHR1cmUzQmluZGluZ30pIHZhciBibHVyVGV4dHVyZTM6IHRleHR1cmVfMmQ8ZjMyPjtcbiAgICAgICAgICAgICAgICBAZ3JvdXAoMCkgQGJpbmRpbmcoJHtkZWZpbmVzLmJsdXJUZXh0dXJlNEJpbmRpbmd9KSB2YXIgYmx1clRleHR1cmU0OiB0ZXh0dXJlXzJkPGYzMj47XG4gICAgICAgICAgICAgICAgQGdyb3VwKDApIEBiaW5kaW5nKCR7ZGVmaW5lcy5ibHVyVGV4dHVyZTVCaW5kaW5nfSkgdmFyIGJsdXJUZXh0dXJlNTogdGV4dHVyZV8yZDxmMzI+O1xuICAgICAgICAgICAgICAgIEBncm91cCgwKSBAYmluZGluZygke2RlZmluZXMudFNhbXBsZXJCaW5kaW5nfX0pIHZhciB0U2FtcGxlcjogc2FtcGxlcjtcblxuXHRcdFx0XHRmbiBsZXJwQmxvb21GYWN0b3IoZmFjdG9yOmYzMiktPmYzMiB7XG5cdFx0XHRcdFx0bGV0IG1pcnJvckZhY3RvcjpmMzIgPSAxLjIgLSBmYWN0b3I7XG5cdFx0XHRcdFx0cmV0dXJuIG1peChmYWN0b3IsIG1pcnJvckZhY3RvciwgYmxvb21Vbmlmb3Jtcy5ibG9vbVJhZGl1cyk7XG5cdFx0XHRcdH1cbiAgICAgICAgICAgICAgICBAZnJhZ21lbnRcblx0XHRcdFx0Zm4gbWFpbihpbnB1dDpGcmFnSW5wdXQpLT4gQGxvY2F0aW9uKDApIHZlYzQ8ZjMyPiAge1xuXHRcdFx0XHRcdHJldHVybiBibG9vbVVuaWZvcm1zLmJsb29tU3RyZW5ndGggKiAoIGxlcnBCbG9vbUZhY3RvcihibG9vbVVuaWZvcm1zLmJsb29tRmFjdG9yc1swXSkgKiB2ZWM0KGJsb29tVW5pZm9ybXMuYmxvb21UaW50Q29sb3JzWzBdLCAxLjApICogdGV4dHVyZVNhbXBsZShibHVyVGV4dHVyZTEsIHRTYW1wbGVyLCBpbnB1dC51dikgK1xuXHRcdFx0XHRcdFx0bGVycEJsb29tRmFjdG9yKGJsb29tVW5pZm9ybXMuYmxvb21GYWN0b3JzWzFdKSAqIHZlYzQ8ZjMyPihibG9vbVVuaWZvcm1zLmJsb29tVGludENvbG9yc1sxXSwgMS4wKSAqIHRleHR1cmVTYW1wbGUoYmx1clRleHR1cmUyLCB0U2FtcGxlciwgaW5wdXQudXYpICtcblx0XHRcdFx0XHRcdGxlcnBCbG9vbUZhY3RvcihibG9vbVVuaWZvcm1zLmJsb29tRmFjdG9yc1syXSkgKiB2ZWM0PGYzMj4oYmxvb21Vbmlmb3Jtcy5ibG9vbVRpbnRDb2xvcnNbMl0sIDEuMCkgKiB0ZXh0dXJlU2FtcGxlKGJsdXJUZXh0dXJlMywgdFNhbXBsZXIsIGlucHV0LnV2KSArXG5cdFx0XHRcdFx0XHRsZXJwQmxvb21GYWN0b3IoYmxvb21Vbmlmb3Jtcy5ibG9vbUZhY3RvcnNbM10pICogdmVjNDxmMzI+KGJsb29tVW5pZm9ybXMuYmxvb21UaW50Q29sb3JzWzNdLCAxLjApICogdGV4dHVyZVNhbXBsZShibHVyVGV4dHVyZTQsIHRTYW1wbGVyLCBpbnB1dC51dikgK1xuXHRcdFx0XHRcdFx0bGVycEJsb29tRmFjdG9yKGJsb29tVW5pZm9ybXMuYmxvb21GYWN0b3JzWzRdKSAqIHZlYzQ8ZjMyPihibG9vbVVuaWZvcm1zLmJsb29tVGludENvbG9yc1s0XSwgMS4wKSAqIHRleHR1cmVTYW1wbGUoYmx1clRleHR1cmU1LCB0U2FtcGxlciwgaW5wdXQudXYpICk7XG5cdFx0XHRcdH1gO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cdHByaXZhdGUgZ2V0U2VwZXJhYmxlQmx1ck1hdGVyaWFsKGtlcm5lbFJhZGl1cywgdHlwZSkge1xuXHRcdGNvbnN0IHNoYWRlciA9IGdldFZlcnRGcmFnKFwiYmx1clwiLCB7XG5cdFx0XHRLRVJORUxfUkFESVVTOiBrZXJuZWxSYWRpdXMsXG5cdFx0XHRTSUdNQToga2VybmVsUmFkaXVzLFxuXHRcdFx0cG9zaXRpb25Mb2NhdGlvbjogMFxuXHRcdH0pO1xuXHRcdGNvbnN0IG1hdCA9IG5ldyBTaGFkZXJNYXRlcmlhbCh7XG5cdFx0XHR0eXBlLFxuXHRcdFx0dW5pZm9ybXM6IHtcblx0XHRcdFx0dERpZmZ1c2U6IHsgdHlwZTogXCJ0ZXh0dXJlXCIsIHZhbHVlOiBudWxsIH0sXG5cdFx0XHRcdGRpcmVjdGlvbjogeyB0eXBlOiBcInZlYzI8ZjMyPlwiLCB2YWx1ZTogbmV3IFZlY3RvcjIoMC4wLCAwLjApIH0sXG5cdFx0XHRcdHRTYW1wbGVyOiB7XG5cdFx0XHRcdFx0dHlwZTogXCJzYW1wbGVyXCIsXG5cdFx0XHRcdFx0dmFsdWU6IHRoaXMuZGVmYXVsdFNhbXBsZXJcblx0XHRcdFx0fVxuXHRcdFx0fSxcblxuXHRcdFx0dmVydDogc2hhZGVyLnZlcnQsXG5cblx0XHRcdGZyYWc6IHNoYWRlci5mcmFnXG5cdFx0fSk7XG5cdFx0bWF0LnJlbmRlclN0YXRlID0gdGhpcy5yZW5kZXJTdGF0ZTtcblx0XHRyZXR1cm4gbWF0O1xuXHR9XG59XG5cbnR5cGUgQmxvb21Qb3N0RWZmZWN0UHJvcHMgPSB7XG5cdHdpZHRoOiBudW1iZXI7XG5cdGhlaWdodDogbnVtYmVyO1xuXHRzdHJlbmd0aDogbnVtYmVyO1xuXHRyYWRpdXM6IG51bWJlcjtcblx0dGhyZXNob2xkOiBudW1iZXI7XG59O1xuIiwiaW1wb3J0IE1hdHJpeDQgZnJvbSBcIi4uL21hdGgvTWF0cml4NFwiO1xyXG5pbXBvcnQgQ2FtZXJhIGZyb20gXCIuL0NhbWVyYVwiO1xyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBPcnRob2dyYXBoaWNDYW1lcmEgZXh0ZW5kcyBDYW1lcmEge1xyXG5cdHJpZ2h0OiBudW1iZXI7XHJcblx0aXNPcnRob2dyYXBoaWNDYW1lcmE6IGJvb2xlYW47XHJcblx0Ym90dG9tOiBudW1iZXI7XHJcblx0bGVmdDogbnVtYmVyO1xyXG5cdG5lYXI6IG51bWJlcjtcclxuXHRmYXI6IG51bWJlcjtcclxuXHR0b3A6IG51bWJlcjtcclxuXHRjb25zdHJ1Y3RvcihsZWZ0ID0gLTEsIHJpZ2h0ID0gMSwgdG9wID0gMSwgYm90dG9tID0gLTEsIG5lYXIgPSAwLjEsIGZhciA9IDIwMDApIHtcclxuXHRcdHN1cGVyKCk7XHJcblx0XHR0aGlzLm5lYXIgPSBuZWFyO1xyXG5cdFx0dGhpcy5mYXIgPSBmYXI7XHJcblx0XHR0aGlzLmxlZnQgPSBsZWZ0O1xyXG5cdFx0dGhpcy50b3AgPSB0b3A7XHJcblx0XHR0aGlzLmJvdHRvbSA9IGJvdHRvbTtcclxuXHRcdHRoaXMucmlnaHQgPSByaWdodDtcclxuXHRcdHRoaXMuaXNPcnRob2dyYXBoaWNDYW1lcmEgPSB0cnVlO1xyXG5cdH1cclxuXHRwcml2YXRlIHVwZGF0ZUNhbWVyYVBhcm1zKCkge1xyXG5cdFx0Y29uc3QgZHggPSAodGhpcy5yaWdodCAtIHRoaXMubGVmdCkgLyAyO1xyXG5cdFx0Y29uc3QgZHkgPSAodGhpcy50b3AgLSB0aGlzLmJvdHRvbSkgLyAyO1xyXG5cdFx0Y29uc3QgY3ggPSAodGhpcy5yaWdodCArIHRoaXMubGVmdCkgLyAyO1xyXG5cdFx0Y29uc3QgY3kgPSAodGhpcy50b3AgKyB0aGlzLmJvdHRvbSkgLyAyO1xyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0bGVmdDogY3ggLSBkeCxcclxuXHRcdFx0cmlnaHQ6IGN4ICsgZHgsXHJcblx0XHRcdHRvcDogY3kgKyBkeSxcclxuXHRcdFx0Ym90dG9tOiBjeSAtIGR5XHJcblx0XHR9O1xyXG5cdH1cclxuXHRwdWJsaWMgdXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpIHtcclxuXHRcdGlmICh0aGlzLnByb2plY3RNYXRyaXhEaXJ0eSkge1xyXG5cdFx0XHRjb25zdCB7IGxlZnQsIHJpZ2h0LCB0b3AsIGJvdHRvbSB9ID0gdGhpcy51cGRhdGVDYW1lcmFQYXJtcygpO1xyXG5cdFx0XHR0aGlzLl9wcm9qZWN0aW9uTWF0cml4ID0gTWF0cml4NC5tYWtlT3J0aG9ncmFwaGljKGxlZnQsIHJpZ2h0LCB0b3AsIGJvdHRvbSwgdGhpcy5uZWFyLCB0aGlzLmZhcik7XHJcblx0XHRcdHRoaXMucHJvamVjdE1hdHJpeERpcnR5ID0gZmFsc2U7XHJcblx0XHR9XHJcblx0fVxyXG59XHJcbiIsImltcG9ydCBQZXJzcGVjdGl2ZUNhbWVyYSBmcm9tIFwiLi4vLi4vY2FtZXJhL1BlcnNwZWN0aXZlQ2FtZXJhXCI7XG5pbXBvcnQgVmVjdG9yMiBmcm9tIFwiLi4vLi4vbWF0aC9WZWN0b3IyXCI7XG5pbXBvcnQgeyBTcG90TGlnaHQgfSBmcm9tIFwiLi4vU3BvdExpZ2h0XCI7XG5pbXBvcnQgeyBCYXNlU2hhZG93IH0gZnJvbSBcIi4vQmFzZVNoYWRvd1wiO1xuXG5leHBvcnQgY2xhc3MgU3BvdExpZ2h0U2hhZG93IGV4dGVuZHMgQmFzZVNoYWRvdyB7XG5cdHB1YmxpYyB0eXBlOiBzdHJpbmc7XG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdGNvbnN0IGNhbWVyYSA9IG5ldyBQZXJzcGVjdGl2ZUNhbWVyYSg2MCwgMSwgMC4xLCA1MDApO1xuXHRcdHN1cGVyKG5ldyBWZWN0b3IyKDEwMjQsIDEwMjQpLCBjYW1lcmEpO1xuXHRcdHRoaXMudHlwZSA9IFwic3BvdExpZ2h0U2hhZG93XCI7XG5cdH1cblxuXHRwdWJsaWMgdXBkYXRlKGxpZ2h0OiBTcG90TGlnaHQpIHtcblx0XHR0aGlzLnVwZGF0ZU1hdHJpY2VzKGxpZ2h0KTtcblx0fVxuXG5cdHVwZGF0ZU1hdHJpY2VzKGxpZ2h0OiBTcG90TGlnaHQpIHtcblx0XHR0aGlzLmNhbWVyYS5wb3NpdGlvbi5jb3B5KGxpZ2h0LnBvc2l0aW9uKTtcblx0XHRjb25zdCB7IHgsIHksIHogfSA9IGxpZ2h0LnRhcmdldDtcblx0XHR0aGlzLmNhbWVyYS5sb29rQXQoeCwgeSwgeik7XG5cdFx0dGhpcy5jYW1lcmEudXBkYXRlTWF0cml4KCk7XG5cdFx0dGhpcy52cE1hdHJpeERpcnR5ID0gdHJ1ZTtcblx0fVxufVxuIiwiaW1wb3J0IHsgTGlnaHRUeXBlIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcclxuaW1wb3J0IFZlY3RvcjMgZnJvbSBcIi4uL21hdGgvVmVjdG9yM1wiO1xyXG5pbXBvcnQgeyBMaWdodCB9IGZyb20gXCIuL0xpZ2h0XCI7XHJcbmltcG9ydCB7IFNwb3RMaWdodFNoYWRvdyB9IGZyb20gXCIuL3NoYWRvd3MvU3BvdExpZ2h0U2hhZG93XCI7XHJcblxyXG5leHBvcnQgY2xhc3MgU3BvdExpZ2h0IGV4dGVuZHMgTGlnaHQge1xyXG5cdHByaXZhdGUgX2Rpc3RhbmNlOiBudW1iZXI7XHJcblx0cHJpdmF0ZSBfYW5nbGU6IG51bWJlcjtcclxuXHRwcml2YXRlIF9wZW51bWJyYTogbnVtYmVyO1xyXG5cdHByaXZhdGUgX2RlY2F5OiBudW1iZXI7XHJcblx0ZGVjYXlEaXJ0eTogYm9vbGVhbjtcclxuXHRkaXN0YW5jZURpcnR5OiBib29sZWFuO1xyXG5cdHByaXZhdGUgX2NvbmVDb3M6IG51bWJlcjtcclxuXHRwcml2YXRlIF9wZW51bWJyYUNvczogbnVtYmVyO1xyXG5cdGNvbmVDb3NEaXJ0eTogYm9vbGVhbjtcclxuXHRwZW51bWJyYURpcnR5OiBib29sZWFuO1xyXG5cdGFuZ2xlRGlydHk6IGJvb2xlYW47XHJcblx0cGVudW1icmFDb3NEaXJ0eTogYm9vbGVhbjtcclxuXHRjb25zdHJ1Y3Rvcihjb2xvciwgaW50ZW5zaXR5LCBkaXN0YW5jZSA9IDAsIGFuZ2xlID0gNjAsIHBlbnVtYnJhID0gNjAsIGRlY2F5ID0gNCwgb3BlblNoYWRvdyA9IHRydWUpIHtcclxuXHRcdHN1cGVyKGNvbG9yLCBpbnRlbnNpdHkpO1xyXG5cdFx0dGhpcy5fZGlzdGFuY2UgPSBkaXN0YW5jZTtcclxuXHRcdHRoaXMuX2FuZ2xlID0gKGFuZ2xlIC8gMTgwKSAqIE1hdGguUEk7XHJcblx0XHR0aGlzLl9wZW51bWJyYSA9IChwZW51bWJyYSAvIDE4MCkgKiBNYXRoLlBJO1xyXG5cdFx0dGhpcy5fZGVjYXkgPSBkZWNheTtcclxuXHRcdHRoaXMubGlnaHRUeXBlID0gTGlnaHRUeXBlLlNwb3RMaWdodDtcclxuXHRcdHRoaXMuYW5nbGVEaXJ0eSA9IHRydWU7XHJcblx0XHR0aGlzLnBlbnVtYnJhRGlydHkgPSB0cnVlO1xyXG5cdFx0dGhpcy5kaXN0YW5jZURpcnR5ID0gdHJ1ZTtcclxuXHRcdHRoaXMuZGVjYXlEaXJ0eSA9IHRydWU7XHJcblx0XHR0aGlzLmNvbmVDb3NEaXJ0eSA9IHRydWU7XHJcblx0XHR0aGlzLnBlbnVtYnJhQ29zRGlydHkgPSB0cnVlO1xyXG5cdFx0aWYgKG9wZW5TaGFkb3cpIHRoaXMuc2hhZG93ID0gbmV3IFNwb3RMaWdodFNoYWRvdygpO1xyXG5cdFx0dGhpcy51cGRhdGVDb25lQ29zT3JQZW51bWJyYUNvcygpO1xyXG5cdH1cclxuXHJcblx0Z2V0IGRpcnRlY3REaXJ0eSgpIHtcclxuXHRcdHJldHVybiB0aGlzLnBvc2l0aW9uRGlydHkgfHwgdGhpcy50YXJnZXREaXJ0eTtcclxuXHR9XHJcblxyXG5cdHNldCBkaXJ0ZWN0RGlydHkodmFsdWUpIHtcclxuXHRcdHRoaXMucG9zaXRpb25EaXJ0eSA9IHZhbHVlO1xyXG5cdFx0dGhpcy50YXJnZXREaXJ0eSA9IHZhbHVlO1xyXG5cdH1cclxuXHJcblx0Z2V0IGRpcmVjdGlvbmFsKCkge1xyXG5cdFx0Y29uc3QgcmVzdWx0ID0gbmV3IFZlY3RvcjMoKTtcclxuXHRcdFZlY3RvcjMuc3VidHJhY3QodGhpcy5wb3NpdGlvbiwgdGhpcy50YXJnZXQsIHJlc3VsdCk7XHJcblx0XHRyZXR1cm4gVmVjdG9yMy5ub3JtYWxpemUocmVzdWx0LCBuZXcgVmVjdG9yMygpKTtcclxuXHR9XHJcblx0Z2V0IGFuZ2xlKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuX2FuZ2xlO1xyXG5cdH1cclxuXHRzZXQgYW5nbGUodmFsdWUpIHtcclxuXHRcdHRoaXMuYW5nbGVEaXJ0eSA9IHRydWU7XHJcblx0XHR0aGlzLl9hbmdsZSA9ICh2YWx1ZSAvIDE4MCkgKiBNYXRoLlBJO1xyXG5cdFx0dGhpcy51cGRhdGVDb25lQ29zT3JQZW51bWJyYUNvcygpO1xyXG5cdH1cclxuXHRnZXQgcGVudW1icmEoKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5fcGVudW1icmE7XHJcblx0fVxyXG5cdHNldCBwZW51bWJyYSh2YWx1ZSkge1xyXG5cdFx0dGhpcy5wZW51bWJyYURpcnR5ID0gdHJ1ZTtcclxuXHRcdHRoaXMuX3BlbnVtYnJhID0gKHZhbHVlIC8gMTgwKSAqIE1hdGguUEk7XHJcblx0XHR0aGlzLnVwZGF0ZUNvbmVDb3NPclBlbnVtYnJhQ29zKCk7XHJcblx0fVxyXG5cdHNldCBkaXN0YW5jZSh2YWx1ZSkge1xyXG5cdFx0dGhpcy5kaXN0YW5jZURpcnR5ID0gdHJ1ZTtcclxuXHRcdHRoaXMuX2Rpc3RhbmNlID0gdmFsdWU7XHJcblx0fVxyXG5cdGdldCBkaXN0YW5jZSgpIHtcclxuXHRcdHJldHVybiB0aGlzLl9kaXN0YW5jZTtcclxuXHR9XHJcblx0c2V0IGRlY2F5KHZhbHVlKSB7XHJcblx0XHR0aGlzLmRlY2F5RGlydHkgPSB0cnVlO1xyXG5cdFx0dGhpcy5fZGVjYXkgPSB2YWx1ZTtcclxuXHR9XHJcblx0Z2V0IGRlY2F5KCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuX2RlY2F5O1xyXG5cdH1cclxuXHRzZXQgY29uZUNvcyh2YWx1ZSkge1xyXG5cdFx0dGhpcy5jb25lQ29zRGlydHkgPSB0cnVlO1xyXG5cdFx0dGhpcy5fY29uZUNvcyA9IHZhbHVlO1xyXG5cdH1cclxuXHRnZXQgY29uZUNvcygpIHtcclxuXHRcdHJldHVybiB0aGlzLl9jb25lQ29zO1xyXG5cdH1cclxuXHRzZXQgcGVudW1icmFDb3ModmFsdWUpIHtcclxuXHRcdHRoaXMucGVudW1icmFDb3NEaXJ0eSA9IHRydWU7XHJcblx0XHR0aGlzLl9wZW51bWJyYUNvcyA9IHZhbHVlO1xyXG5cdH1cclxuXHRnZXQgcGVudW1icmFDb3MoKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5fcGVudW1icmFDb3M7XHJcblx0fVxyXG5cdHByaXZhdGUgdXBkYXRlQ29uZUNvc09yUGVudW1icmFDb3MoKSB7XHJcblx0XHR0aGlzLl9jb25lQ29zID0gTWF0aC5jb3ModGhpcy5hbmdsZSk7XHJcblx0XHR0aGlzLl9wZW51bWJyYUNvcyA9IE1hdGguY29zKHRoaXMuYW5nbGUgKyB0aGlzLnBlbnVtYnJhKTtcclxuXHR9XHJcbn1cclxuLy8gdW5pZm9ybVxyXG4vLyBjb2xvcjoge30sXHJcbi8vIHBvc2l0aW9uOiB7fSxcclxuLy8gZGlyZWN0aW9uOiB7fSxcclxuLy8gZGlzdGFuY2U6IHt9LFxyXG4vLyBjb25lQ29zOiB7fSxcclxuLy8gcGVudW1icmFDb3M6IHt9LFxyXG4vLyBkZWNheToge31cclxuIiwiaW1wb3J0IE9ydGhvZ3JhcGhpY0NhbWVyYSBmcm9tIFwiLi4vLi4vY2FtZXJhL09ydGhvZ3JhcGhpY0NhbWVyYVwiO1xuaW1wb3J0IFZlY3RvcjIgZnJvbSBcIi4uLy4uL21hdGgvVmVjdG9yMlwiO1xuaW1wb3J0IHsgRGlyZWN0aW9uYWxMaWdodCB9IGZyb20gXCIuLi9EaXJlY3Rpb25hbExpZ2h0XCI7XG5pbXBvcnQgeyBCYXNlU2hhZG93IH0gZnJvbSBcIi4vQmFzZVNoYWRvd1wiO1xuXG5leHBvcnQgY2xhc3MgRGlyZWN0aW9uYWxMaWdodFNoYWRvdyBleHRlbmRzIEJhc2VTaGFkb3cge1xuXHRwdWJsaWMgdHlwZTogc3RyaW5nO1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRjb25zdCBjYW1lcmEgPSBuZXcgT3J0aG9ncmFwaGljQ2FtZXJhKC01MCwgNTAsIDUwLCAtNTAsIDAsIDEwMCk7XG5cdFx0c3VwZXIobmV3IFZlY3RvcjIoMTAyNCwgMTAyNCksIGNhbWVyYSk7XG5cdFx0dGhpcy50eXBlID0gXCJkaXJlY3Rpb25hbExpZ2h0U2hhZG93XCI7XG5cdH1cblxuXHRwdWJsaWMgdXBkYXRlKGxpZ2h0OiBEaXJlY3Rpb25hbExpZ2h0KSB7XG5cdFx0dGhpcy51cGRhdGVNYXRyaWNlcyhsaWdodCk7XG5cdH1cblxuXHR1cGRhdGVNYXRyaWNlcyhsaWdodDogRGlyZWN0aW9uYWxMaWdodCkge1xuXHRcdHRoaXMuY2FtZXJhLnBvc2l0aW9uLmNvcHkobGlnaHQucG9zaXRpb24pO1xuXHRcdGNvbnN0IHsgeCwgeSwgeiB9ID0gbGlnaHQudGFyZ2V0O1xuXHRcdHRoaXMuY2FtZXJhLmxvb2tBdCh4LCB5LCB6KTtcblx0XHR0aGlzLmNhbWVyYS51cGRhdGVNYXRyaXgoKTtcblx0XHR0aGlzLnZwTWF0cml4RGlydHkgPSB0cnVlO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBMaWdodFR5cGUgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVUeXBlc1wiO1xuaW1wb3J0IFZlY3RvcjMgZnJvbSBcIi4uL21hdGgvVmVjdG9yM1wiO1xuaW1wb3J0IHsgTGlnaHQgfSBmcm9tIFwiLi9MaWdodFwiO1xuaW1wb3J0IHsgRGlyZWN0aW9uYWxMaWdodFNoYWRvdyB9IGZyb20gXCIuL3NoYWRvd3MvRGlyZWN0aW9uYWxMaWdodFNoYWRvd1wiO1xuXG5leHBvcnQgY2xhc3MgRGlyZWN0aW9uYWxMaWdodCBleHRlbmRzIExpZ2h0IHtcblx0Y29uc3RydWN0b3IoY29sb3I6IFZlY3RvcjMsIGludGVuc2l0eTogbnVtYmVyLCBvcGVuU2hhZG93ID0gdHJ1ZSkge1xuXHRcdHN1cGVyKGNvbG9yLCBpbnRlbnNpdHkpO1xuXHRcdHRoaXMubGlnaHRUeXBlID0gTGlnaHRUeXBlLkRpcmVjdGlvbmFsTGlnaHQ7XG5cdFx0aWYgKG9wZW5TaGFkb3cpIHRoaXMuc2hhZG93ID0gbmV3IERpcmVjdGlvbmFsTGlnaHRTaGFkb3coKTtcblx0fVxuXG5cdGdldCBkaXJ0ZWN0RGlydHkoKSB7XG5cdFx0cmV0dXJuIHRoaXMucG9zaXRpb25EaXJ0eSB8fCB0aGlzLnRhcmdldERpcnR5O1xuXHR9XG5cblx0c2V0IGRpcnRlY3REaXJ0eSh2YWx1ZSkge1xuXHRcdHRoaXMucG9zaXRpb25EaXJ0eSA9IHZhbHVlO1xuXHRcdHRoaXMudGFyZ2V0RGlydHkgPSB2YWx1ZTtcblx0fVxuXG5cdGdldCBkaXJlY3Rpb25hbCgpIHtcblx0XHRjb25zdCByZXN1bHQgPSBuZXcgVmVjdG9yMygpO1xuXHRcdFZlY3RvcjMuc3VidHJhY3QodGhpcy50YXJnZXQsIHRoaXMucG9zaXRpb24sIHJlc3VsdCk7XG5cdFx0cmV0dXJuIHJlc3VsdC5ub3JtYWxpemUoKTtcblx0fVxufVxuLy8gdW5pZm9ybVxuLy8gZGlyZWN0aW9uOiB7fSxcbi8vIGNvbG9yOiB7fVxuIiwiaW1wb3J0IENhbWVyYSBmcm9tIFwiLi4vY2FtZXJhL0NhbWVyYVwiO1xyXG5pbXBvcnQgeyBGcmFtZVN0YXRlIH0gZnJvbSBcIi4uL2NvcmUvRnJhbWVTdGF0ZVwiO1xyXG5pbXBvcnQgUmVuZGVyT2JqZWN0IGZyb20gXCIuLi9jb3JlL1JlbmRlck9iamVjdFwiO1xyXG5pbXBvcnQgeyBSZW5kZXJPYmplY3RUeXBlIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcclxuaW1wb3J0IGNyZWF0ZUd1aWQgZnJvbSBcIi4uL3V0aWxzL2NyZWF0ZUd1aWRcIjtcclxuaW1wb3J0IHsgTWVzaCB9IGZyb20gXCIuL01lc2hcIjtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE5vZGUgZXh0ZW5kcyBSZW5kZXJPYmplY3Qge1xyXG5cdHVpZDogc3RyaW5nO1xyXG5cdGNoaWxkcmVuOiBNYXA8c3RyaW5nLCBOb2RlIHwgTWVzaD47XHJcblx0bmFtZTogc3RyaW5nO1xyXG5cdGNvbnN0cnVjdG9yKCkge1xyXG5cdFx0c3VwZXIoKTtcclxuXHRcdHRoaXMudHlwZSA9IFJlbmRlck9iamVjdFR5cGUuTm9kZTtcclxuXHRcdHRoaXMuY2hpbGRyZW4gPSBuZXcgTWFwKCk7XHJcblx0XHR0aGlzLnBhcmVudCA9IG51bGw7XHJcblx0XHR0aGlzLnVpZCA9IGNyZWF0ZUd1aWQoKTtcclxuXHR9XHJcblx0YWRkKG5vZGU6IE5vZGUgfCBNZXNoKSB7XHJcblx0XHRub2RlLnBhcmVudCA9IHRoaXM7XHJcblx0XHR0aGlzLmNoaWxkcmVuLnNldChub2RlLnVpZCwgbm9kZSk7XHJcblx0fVxyXG5cdHJlbW92ZShub2RlOiBOb2RlIHwgTWVzaCkge1xyXG5cdFx0dGhpcy5jaGlsZHJlbi5kZWxldGUobm9kZS51aWQpO1xyXG5cdH1cclxuXHR1cGRhdGUoZnJhbWVTdGF0ZTogRnJhbWVTdGF0ZSwgY2FtZXJhPzogQ2FtZXJhKSB7XHJcblx0XHR0aGlzLnVwZGF0ZU1hdHJpeCh0aGlzPy5wYXJlbnQ/Lm1vZGVsTWF0cml4Py5jbG9uZSgpKTtcclxuXHRcdHRoaXM/LmNoaWxkcmVuPy5mb3JFYWNoPy4oKG5vZGUpID0+IHtcclxuXHRcdFx0bm9kZS51cGRhdGUoZnJhbWVTdGF0ZSwgY2FtZXJhKTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHRkZXN0cm95KCkge1xyXG5cdFx0dGhpcy5jaGlsZHJlbi5mb3JFYWNoKChub2RlKSA9PiB7XHJcblx0XHRcdG5vZGUuZGVzdHJveSgpO1xyXG5cdFx0fSk7XHJcblx0XHR0aGlzPy5jaGlsZHJlbj8uY2xlYXIoKTtcclxuXHR9XHJcblx0dHJhdmVyc2UodHJhdmVyc2VGdW5jdGlvbjogRnVuY3Rpb24sIHBhcmFtOiB7IFtwcm9wOiBzdHJpbmddOiBhbnkgfSk6IHZvaWQge1xyXG5cdFx0Zm9yIChsZXQgaSA9IDAsIGxlbiA9IHRoaXMuY2hpbGRyZW4uc2l6ZTsgaSA8IGxlbjsgaSsrKSB7XHJcblx0XHRcdHRoaXMuY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQpID0+IHtcclxuXHRcdFx0XHRjaGlsZC50cmF2ZXJzZSh0cmF2ZXJzZUZ1bmN0aW9uLCBwYXJhbSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdH1cclxufVxyXG4iLCJpbXBvcnQgQ2FtZXJhIGZyb20gXCIuLi9jYW1lcmEvQ2FtZXJhXCI7XG5pbXBvcnQgeyBGcmFtZVN0YXRlIH0gZnJvbSBcIi4uL2NvcmUvRnJhbWVTdGF0ZVwiO1xuaW1wb3J0IHsgQnVmZmVyQmluZGluZ1R5cGUsIEJ1ZmZlclVzYWdlIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVQ29uc3RhbnRcIjtcbmltcG9ydCB7IFJlbmRlck9iamVjdFR5cGUsIFVuaWZvcm1FbnVtIH0gZnJvbSBcIi4uL2NvcmUvV2ViR1BVVHlwZXNcIjtcbmltcG9ydCBHZW9tZXRyeSBmcm9tIFwiLi4vZ2VvbWV0cnkvR2VvbWV0cnlcIjtcbmltcG9ydCB7IE1hdGVyaWFsIH0gZnJvbSBcIi4uL21hdGVyaWFsL01hdGVyaWFsXCI7XG5pbXBvcnQgTWF0cml4NCBmcm9tIFwiLi4vbWF0aC9NYXRyaXg0XCI7XG5pbXBvcnQgVW5pZm9ybUJ1ZmZlciBmcm9tIFwiLi4vcmVuZGVyL1VuaWZvcm1CdWZmZXJcIjtcbmltcG9ydCB7IE1lc2ggfSBmcm9tIFwiLi9NZXNoXCI7XG5pbXBvcnQgTm9kZSBmcm9tIFwiLi9Ob2RlXCI7XG5cbmV4cG9ydCBjbGFzcyBTS2luTWVzaCBleHRlbmRzIE1lc2gge1xuXHRpbnZlcnNlQmluZE1hdHJpY2VzOiBBcnJheTxNYXRyaXg0Pjtcblx0dW5pZm9ybU1hdHJpeHM6IEFycmF5PE1hdHJpeDQ+O1xuXHRqb2ludHM6IEFycmF5PE5vZGU+O1xuXHRwcml2YXRlIGhhc0FkZEpvaW50czogYm9vbGVhbjtcblx0Y29uc3RydWN0b3IoZ2VvbWV0cnk/OiBHZW9tZXRyeSwgbWF0ZXJpYWw/OiBNYXRlcmlhbCkge1xuXHRcdHN1cGVyKGdlb21ldHJ5LCBtYXRlcmlhbCk7XG5cdFx0dGhpcy50eXBlID0gUmVuZGVyT2JqZWN0VHlwZS5Ta2luTWVzaDtcblx0XHR0aGlzLnVuaWZvcm1NYXRyaXhzID0gW107XG5cdFx0dGhpcy5oYXNBZGRKb2ludHMgPSBmYWxzZTtcblx0fVxuXHRzZXRTa2luRGF0YShkYXRhOiBTa2luRGF0YVR5cGUpIHtcblx0XHR0aGlzLmludmVyc2VCaW5kTWF0cmljZXMgPSBkYXRhLmludmVyc2VCaW5kTWF0cmljZXM7XG5cdFx0dGhpcy5qb2ludHMgPSBkYXRhLmpvaW50cztcblx0fVxuXHR1cGRhdGUoZnJhbWVTdGF0ZTogRnJhbWVTdGF0ZSwgY2FtZXJhPzogQ2FtZXJhKSB7XG5cdFx0dGhpcy51bmlmb3JtTWF0cml4cyA9IHRoaXMuam9pbnRzLm1hcCgoam9pbnQpID0+IChqb2ludCBhcyBOb2RlKS5tb2RlbE1hdHJpeCk7XG5cdFx0c3VwZXIudXBkYXRlKGZyYW1lU3RhdGUsIGNhbWVyYSk7XG5cdFx0aWYgKCF0aGlzLmhhc0FkZEpvaW50cykgdGhpcy5hZGRVbmlmb3Jtc1RvTWF0ZXJpYWwoKTtcblx0fVxuXHRwcml2YXRlIGFkZFVuaWZvcm1zVG9NYXRlcmlhbCgpIHtcblx0XHRpZiAoIXRoaXMubWF0ZXJpYWwuc2hhZGVyRGF0YSkgcmV0dXJuO1xuXHRcdHRoaXMuaGFzQWRkSm9pbnRzID0gdHJ1ZTtcblx0XHRpZiAodGhpcy5qb2ludHMpIHtcblx0XHRcdGNvbnN0IHNraW5Kb2ludHNCdWZmZXIgPSBuZXcgVW5pZm9ybUJ1ZmZlcih7XG5cdFx0XHRcdGxhYmVsOiBcInNraW5Kb2ludHNCdWZmZXJcIixcblx0XHRcdFx0dHlwZTogQnVmZmVyQmluZGluZ1R5cGUuUmVhZE9ubHlTdG9yYWdlLFxuXHRcdFx0XHR1c2FnZTogQnVmZmVyVXNhZ2UuU3RvcmFnZSB8IEJ1ZmZlclVzYWdlLkNvcHlEc3QsXG5cdFx0XHRcdHNpemU6IDMwMDBcblx0XHRcdH0pO1xuXHRcdFx0Y29uc3QgaW52c0J1ZmZlciA9IG5ldyBVbmlmb3JtQnVmZmVyKHtcblx0XHRcdFx0bGFiZWw6IFwiaW52c0J1ZmZlclwiLFxuXHRcdFx0XHR0eXBlOiBCdWZmZXJCaW5kaW5nVHlwZS5SZWFkT25seVN0b3JhZ2UsXG5cdFx0XHRcdHVzYWdlOiBCdWZmZXJVc2FnZS5TdG9yYWdlIHwgQnVmZmVyVXNhZ2UuQ29weURzdCxcblx0XHRcdFx0c2l6ZTogMzAwMFxuXHRcdFx0fSk7XG5cdFx0XHRza2luSm9pbnRzQnVmZmVyLnNldFVuaWZvcm0oXG5cdFx0XHRcdFwiam9pbnRzXCIsXG5cdFx0XHRcdCgpID0+IHtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy51bmlmb3JtTWF0cml4cztcblx0XHRcdFx0fSxcblx0XHRcdFx0VW5pZm9ybUVudW0uTWF0NEFycmF5LFxuXHRcdFx0XHR0aGlzLnVuaWZvcm1NYXRyaXhzLmxlbmd0aFxuXHRcdFx0KTtcblx0XHRcdGludnNCdWZmZXIuc2V0VW5pZm9ybShcblx0XHRcdFx0XCJqb2ludHNJbnZcIixcblx0XHRcdFx0KCkgPT4ge1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLmludmVyc2VCaW5kTWF0cmljZXM7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdFVuaWZvcm1FbnVtLk1hdDRBcnJheSxcblx0XHRcdFx0dGhpcy5pbnZlcnNlQmluZE1hdHJpY2VzLmxlbmd0aFxuXHRcdFx0KTtcblx0XHRcdHRoaXMubWF0ZXJpYWwuc2hhZGVyRGF0YS5zZXRVbmlmb3JtQnVmZmVyKFwic2tpbkpvaW50c0J1ZmZlclwiLCBza2luSm9pbnRzQnVmZmVyKTtcblx0XHRcdHRoaXMubWF0ZXJpYWwuc2hhZGVyRGF0YS5zZXRVbmlmb3JtQnVmZmVyKFwiaW52c0J1ZmZlclwiLCBpbnZzQnVmZmVyKTtcblx0XHR9XG5cdH1cbn1cbmV4cG9ydCB0eXBlIFNraW5EYXRhVHlwZSA9IHtcblx0aW52ZXJzZUJpbmRNYXRyaWNlcz86IEFycmF5PE1hdHJpeDQ+O1xuXHRqb2ludHM/OiBBcnJheTxOb2RlPjtcbn07XG4iLCJpbXBvcnQgeyBRdWF0ZXJuaW9uIH0gZnJvbSBcIi4uL21hdGgvUXVhdGVybmlvblwiO1xyXG5pbXBvcnQgVmVjdG9yMiBmcm9tIFwiLi4vbWF0aC9WZWN0b3IyXCI7XHJcbmltcG9ydCBWZWN0b3IzIGZyb20gXCIuLi9tYXRoL1ZlY3RvcjNcIjtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjbGFtcChudW06IG51bWJlciwgbWluOiBudW1iZXIsIG1heDogbnVtYmVyKSB7XHJcblx0cmV0dXJuIE1hdGgubWluKE1hdGgubWF4KG51bSwgbWluKSwgbWF4KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHRvRmxvYXQobnVtOiBudW1iZXIgfCB1bmRlZmluZWQsIGRlZmF1bHRWYWx1ZSA9IDEpIHtcclxuXHRjb25zdCBuID0gbnVtICE9PSB1bmRlZmluZWQgPyBudW0gOiBkZWZhdWx0VmFsdWU7XHJcblx0aWYgKE51bWJlci5pc0ludGVnZXIobikpIHtcclxuXHRcdHJldHVybiBgJHtufS4wYDtcclxuXHR9XHJcblx0cmV0dXJuIG47XHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIFR5cGVkQXJyYXkgPSBJbnQ4QXJyYXkgfCBVaW50OEFycmF5IHwgSW50MTZBcnJheSB8IFVpbnQxNkFycmF5IHwgVWludDMyQXJyYXkgfCBGbG9hdDMyQXJyYXk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbmV3VHlwZWRBcnJheSh0eXBlOiBudW1iZXIsIGJ1ZmZlcjogQXJyYXlCdWZmZXIsIGJ5dGVPZmZzZXQ6IG51bWJlciwgbGVuZ3RoOiBudW1iZXIpIHtcclxuXHRzd2l0Y2ggKHR5cGUpIHtcclxuXHRcdGNhc2UgNTEyMDpcclxuXHRcdFx0cmV0dXJuIG5ldyBJbnQ4QXJyYXkoYnVmZmVyLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xyXG5cdFx0Y2FzZSA1MTIxOlxyXG5cdFx0XHRyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xyXG5cdFx0Y2FzZSA1MTIyOlxyXG5cdFx0XHRyZXR1cm4gbmV3IEludDE2QXJyYXkoYnVmZmVyLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xyXG5cdFx0Y2FzZSA1MTIzOlxyXG5cdFx0XHRyZXR1cm4gbmV3IFVpbnQxNkFycmF5KGJ1ZmZlciwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcclxuXHRcdGNhc2UgNTEyNDpcclxuXHRcdFx0cmV0dXJuIG5ldyBJbnQzMkFycmF5KGJ1ZmZlciwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcclxuXHRcdGNhc2UgNTEyNTpcclxuXHRcdFx0cmV0dXJuIG5ldyBVaW50MzJBcnJheShidWZmZXIsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XHJcblx0XHRjYXNlIDUxMjY6XHJcblx0XHRcdHJldHVybiBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlciwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcclxuXHRcdGRlZmF1bHQ6XHJcblx0XHRcdHRocm93IG5ldyBFcnJvcihcImludmFsaWQgY29tcG9uZW50IHR5cGVcIik7XHJcblx0fVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdG9JbmRpY2VzKGFycmF5OiBUeXBlZEFycmF5KTogVWludDE2QXJyYXkgfCBVaW50MzJBcnJheSB7XHJcblx0aWYgKGFycmF5IGluc3RhbmNlb2YgVWludDE2QXJyYXkgfHwgYXJyYXkgaW5zdGFuY2VvZiBVaW50MzJBcnJheSkge1xyXG5cdFx0cmV0dXJuIGFycmF5O1xyXG5cdH1cclxuXHRsZXQgdG9BcnJheTtcclxuXHRpZiAoYXJyYXkgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkpIHtcclxuXHRcdHRvQXJyYXkgPSBuZXcgVWludDMyQXJyYXkoYXJyYXkubGVuZ3RoKTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0dG9BcnJheSA9IG5ldyBVaW50MTZBcnJheShhcnJheS5sZW5ndGgpO1xyXG5cdH1cclxuXHRhcnJheS5mb3JFYWNoKChlbGVtZW50LCBpbmRleCkgPT4ge1xyXG5cdFx0dG9BcnJheVtpbmRleF0gPSBlbGVtZW50O1xyXG5cdH0pO1xyXG5cdHJldHVybiB0b0FycmF5O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gam9pbkFycmF5KGFycmF5czogQXJyYXk8RmxvYXQzMkFycmF5Pikge1xyXG5cdGxldCBsZW5ndGggPSAwO1xyXG5cdGFycmF5cy5mb3JFYWNoKChhcnJheSkgPT4ge1xyXG5cdFx0bGVuZ3RoICs9IGFycmF5Lmxlbmd0aDtcclxuXHR9KTtcclxuXHRjb25zdCBqb2luZWQgPSBuZXcgRmxvYXQzMkFycmF5KGxlbmd0aCk7XHJcblx0bGVuZ3RoID0gMDtcclxuXHRhcnJheXMuZm9yRWFjaCgoYXJyYXkpID0+IHtcclxuXHRcdGpvaW5lZC5zZXQoYXJyYXksIGxlbmd0aCk7XHJcblx0XHRsZW5ndGggKz0gYXJyYXkubGVuZ3RoO1xyXG5cdH0pO1xyXG5cdHJldHVybiBqb2luZWQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVHUFVCdWZmZXIoYXJyYXk6IFR5cGVkQXJyYXksIHVzYWdlOiBudW1iZXIsIGRldmljZTogR1BVRGV2aWNlKSB7XHJcblx0Y29uc3QgYnVmZmVyID0gZGV2aWNlLmNyZWF0ZUJ1ZmZlcih7XHJcblx0XHRzaXplOiAoYXJyYXkuYnl0ZUxlbmd0aCArIDMpICYgfjMsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tYml0d2lzZVxyXG5cdFx0dXNhZ2UsXHJcblx0XHRtYXBwZWRBdENyZWF0aW9uOiB0cnVlXHJcblx0fSk7XHJcblx0bGV0IHdyaXRlQXJhcnk7XHJcblx0aWYgKGFycmF5IGluc3RhbmNlb2YgSW50OEFycmF5KSB7XHJcblx0XHR3cml0ZUFyYXJ5ID0gbmV3IEludDhBcnJheShidWZmZXIuZ2V0TWFwcGVkUmFuZ2UoKSk7XHJcblx0fSBlbHNlIGlmIChhcnJheSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcclxuXHRcdHdyaXRlQXJhcnkgPSBuZXcgVWludDhBcnJheShidWZmZXIuZ2V0TWFwcGVkUmFuZ2UoKSk7XHJcblx0fSBlbHNlIGlmIChhcnJheSBpbnN0YW5jZW9mIEludDE2QXJyYXkpIHtcclxuXHRcdHdyaXRlQXJhcnkgPSBuZXcgSW50MTZBcnJheShidWZmZXIuZ2V0TWFwcGVkUmFuZ2UoKSk7XHJcblx0fSBlbHNlIGlmIChhcnJheSBpbnN0YW5jZW9mIFVpbnQxNkFycmF5KSB7XHJcblx0XHR3cml0ZUFyYXJ5ID0gbmV3IFVpbnQxNkFycmF5KGJ1ZmZlci5nZXRNYXBwZWRSYW5nZSgpKTtcclxuXHR9IGVsc2UgaWYgKGFycmF5IGluc3RhbmNlb2YgVWludDMyQXJyYXkpIHtcclxuXHRcdHdyaXRlQXJhcnkgPSBuZXcgVWludDMyQXJyYXkoYnVmZmVyLmdldE1hcHBlZFJhbmdlKCkpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHR3cml0ZUFyYXJ5ID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXIuZ2V0TWFwcGVkUmFuZ2UoKSk7XHJcblx0fVxyXG5cdHdyaXRlQXJhcnkuc2V0KGFycmF5KTtcclxuXHRidWZmZXIudW5tYXAoKTtcclxuXHRyZXR1cm4gYnVmZmVyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVOb3JtYWxzKGluZGljZXM6IFR5cGVkQXJyYXkgfCBudWxsLCBwb3NpdGlvbnM6IFR5cGVkQXJyYXkpIHtcclxuXHRjb25zdCBub3JtYWxzID0gbmV3IEZsb2F0MzJBcnJheShwb3NpdGlvbnMubGVuZ3RoKTtcclxuXHRjb25zdCB2ZXJ0ZXhDb3VudCA9IGluZGljZXMgPyBpbmRpY2VzLmxlbmd0aCA6IHBvc2l0aW9ucy5sZW5ndGg7XHJcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCB2ZXJ0ZXhDb3VudDsgaSArPSAzKSB7XHJcblx0XHRjb25zdCB0cmlJbmRpY2VzID0gW107XHJcblx0XHRmb3IgKGxldCBuID0gMDsgbiA8IDM7IG4gKz0gMSkge1xyXG5cdFx0XHRpZiAoaW5kaWNlcykge1xyXG5cdFx0XHRcdHRyaUluZGljZXMucHVzaChpbmRpY2VzW2kgKyBuXSk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0dHJpSW5kaWNlcy5wdXNoKGkgKyBuKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0Y29uc3QgdHJpYW5nbGUgPSB0cmlJbmRpY2VzLm1hcCgodmVydGV4SW5kZXgpID0+IHtcclxuXHRcdFx0Y29uc3QgaW5kZXggPSB2ZXJ0ZXhJbmRleCAqIDM7XHJcblx0XHRcdHJldHVybiBuZXcgVmVjdG9yMyhwb3NpdGlvbnNbaW5kZXhdLCBwb3NpdGlvbnNbaW5kZXggKyAxXSwgcG9zaXRpb25zW2luZGV4ICsgMl0pO1xyXG5cdFx0fSk7XHJcblx0XHRjb25zdCBkdjEgPSBuZXcgVmVjdG9yMygpO1xyXG5cdFx0VmVjdG9yMy5zdWJ0cmFjdCh0cmlhbmdsZVsxXSwgdHJpYW5nbGVbMF0sIGR2MSk7XHJcblx0XHRjb25zdCBkdjIgPSBuZXcgVmVjdG9yMygpO1xyXG5cdFx0VmVjdG9yMy5zdWJ0cmFjdCh0cmlhbmdsZVsyXSwgdHJpYW5nbGVbMF0sIGR2Mik7XHJcblx0XHRjb25zdCBub3JtYWwgPSBuZXcgVmVjdG9yMygpO1xyXG5cdFx0VmVjdG9yMy5jcm9zcyhkdjEubm9ybWFsaXplKCksIGR2Mi5ub3JtYWxpemUoKSwgbm9ybWFsKTtcclxuXHRcdGZvciAobGV0IG4gPSAwOyBuIDwgMzsgbiArPSAxKSB7XHJcblx0XHRcdGNvbnN0IGluZGV4ID0gKGkgKyBuKSAqIDM7XHJcblx0XHRcdG5vcm1hbHNbaW5kZXggKyAwXSArPSBub3JtYWwueDtcclxuXHRcdFx0bm9ybWFsc1tpbmRleCArIDFdICs9IG5vcm1hbC55O1xyXG5cdFx0XHRub3JtYWxzW2luZGV4ICsgMl0gKz0gbm9ybWFsLno7XHJcblx0XHR9XHJcblx0fVxyXG5cdHJldHVybiBub3JtYWxzO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVUYW5nZW50cyhcclxuXHRpbmRpY2VzOiBUeXBlZEFycmF5IHwgbnVsbCxcclxuXHRwb3NpdGlvbnM6IFR5cGVkQXJyYXksXHJcblx0bm9ybWFsczogVHlwZWRBcnJheSxcclxuXHR1dnM6IFR5cGVkQXJyYXlcclxuKSB7XHJcblx0Y29uc3QgdGFuZ2VudHMgPSBuZXcgRmxvYXQzMkFycmF5KChub3JtYWxzLmxlbmd0aCAvIDMpICogNCk7XHJcblx0Y29uc3QgdmVydGV4Q291bnQgPSBpbmRpY2VzID8gaW5kaWNlcy5sZW5ndGggOiBwb3NpdGlvbnMubGVuZ3RoO1xyXG5cdGZvciAobGV0IGkgPSAwOyBpIDwgdmVydGV4Q291bnQ7IGkgKz0gMykge1xyXG5cdFx0Y29uc3QgdHJpSW5kaWNlcyA9IFtdO1xyXG5cdFx0Zm9yIChsZXQgbiA9IDA7IG4gPCAzOyBuICs9IDEpIHtcclxuXHRcdFx0aWYgKGluZGljZXMpIHtcclxuXHRcdFx0XHR0cmlJbmRpY2VzLnB1c2goaW5kaWNlc1tpICsgbl0pO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHRyaUluZGljZXMucHVzaChpICsgbik7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdGNvbnN0IHBvcyA9IHRyaUluZGljZXMubWFwKCh2ZXJ0ZXhJbmRleCkgPT4ge1xyXG5cdFx0XHRjb25zdCBpbmRleCA9IHZlcnRleEluZGV4ICogMztcclxuXHRcdFx0cmV0dXJuIG5ldyBWZWN0b3IzKHBvc2l0aW9uc1tpbmRleF0sIHBvc2l0aW9uc1tpbmRleCArIDFdLCBwb3NpdGlvbnNbaW5kZXggKyAyXSk7XHJcblx0XHR9KTtcclxuXHRcdGNvbnN0IHV2ID0gdHJpSW5kaWNlcy5tYXAoKHZlcnRleEluZGV4KSA9PiB7XHJcblx0XHRcdGNvbnN0IGluZGV4ID0gdmVydGV4SW5kZXggKiAyO1xyXG5cdFx0XHRyZXR1cm4gbmV3IFZlY3RvcjIodXZzPy5baW5kZXhdLCB1dnM/LltpbmRleCArIDFdKTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdGNvbnN0IGR2MSA9IG5ldyBWZWN0b3IzKCk7XHJcblx0XHRWZWN0b3IzLnN1YnRyYWN0KHBvc1sxXSwgcG9zWzBdLCBkdjEpO1xyXG5cdFx0Y29uc3QgZHYyID0gbmV3IFZlY3RvcjMoKTtcclxuXHRcdFZlY3RvcjMuc3VidHJhY3QocG9zWzJdLCBwb3NbMF0sIGR2Mik7XHJcblx0XHRjb25zdCBkdXYxID0gbmV3IFZlY3RvcjIoKTtcclxuXHRcdFZlY3RvcjIuc3VidHJhY3QodXZbMV0sIHV2WzBdLCBkdXYxKTtcclxuXHRcdGNvbnN0IGR1djIgPSBuZXcgVmVjdG9yMigpO1xyXG5cdFx0VmVjdG9yMi5zdWJ0cmFjdCh1dlsyXSwgdXZbMF0sIGR1djIpO1xyXG5cclxuXHRcdGNvbnN0IHRhbmdlbnQgPSBuZXcgVmVjdG9yMygpO1xyXG5cdFx0VmVjdG9yMy5tdWx0aXBseUJ5U2NhbGFyKGR2MSwgZHV2MS55LCBkdjEpO1xyXG5cdFx0VmVjdG9yMy5tdWx0aXBseUJ5U2NhbGFyKGR2MiwgZHV2Mi55LCBkdjIpO1xyXG5cdFx0VmVjdG9yMy5zdWJ0cmFjdChkdjEsIGR2MiwgdGFuZ2VudCk7XHJcblxyXG5cdFx0VmVjdG9yMy5tdWx0aXBseUJ5U2NhbGFyKHRhbmdlbnQsIGR1djIueSAqIGR1djEueCAtIGR1djEueSAqIGR1djIueCwgdGFuZ2VudCk7XHJcblxyXG5cdFx0dGFuZ2VudC5ub3JtYWxpemUoKTtcclxuXHRcdGZvciAobGV0IG4gPSAwOyBuIDwgMzsgbiArPSAxKSB7XHJcblx0XHRcdGNvbnN0IGluZGV4ID0gKGkgKyBuKSAqIDQ7XHJcblxyXG5cdFx0XHR0YW5nZW50c1tpbmRleCArIDBdICs9IHRhbmdlbnQueDtcclxuXHRcdFx0dGFuZ2VudHNbaW5kZXggKyAxXSArPSB0YW5nZW50Lnk7XHJcblx0XHRcdHRhbmdlbnRzW2luZGV4ICsgMl0gKz0gdGFuZ2VudC56O1xyXG5cdFx0XHR0YW5nZW50c1tpbmRleCArIDNdID0gMTtcclxuXHRcdH1cclxuXHR9XHJcblx0cmV0dXJuIHRhbmdlbnRzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBsZXJwKGE6IG51bWJlciwgYjogbnVtYmVyLCB4OiBudW1iZXIpIHtcclxuXHRpZiAoeCA8IGEpIHtcclxuXHRcdHJldHVybiAwO1xyXG5cdH1cclxuXHRpZiAoeCA+IGIpIHtcclxuXHRcdHJldHVybiAxO1xyXG5cdH1cclxuXHRyZXR1cm4gKHggLSBhKSAvIChiIC0gYSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBpbnRlcnBRdWF0KGlucHV0OiBUeXBlZEFycmF5LCBvOiBUeXBlZEFycmF5LCB0aW1lOiBudW1iZXIsIG1ldGhvZDogc3RyaW5nKSB7XHJcblx0bGV0IGluZGV4ID0gMTtcclxuXHR3aGlsZSAoaW5kZXggPCBpbnB1dC5sZW5ndGggLSAxICYmIHRpbWUgPj0gaW5wdXRbaW5kZXhdKSB7XHJcblx0XHRpbmRleCArPSAxO1xyXG5cdH1cclxuXHRjb25zdCB0ID0gbGVycChpbnB1dFtpbmRleCAtIDFdLCBpbnB1dFtpbmRleF0sIHRpbWUpO1xyXG5cclxuXHRpZiAobWV0aG9kID09PSBcIkNVQklDU1BMSU5FXCIpIHtcclxuXHRcdGNvbnN0IHRkID0gaW5wdXRbaW5kZXhdIC0gaW5wdXRbaW5kZXggLSAxXTtcclxuXHRcdGNvbnN0IHQyID0gdCAqIHQ7XHJcblx0XHRjb25zdCB0MyA9IHQyICogdDtcclxuXHRcdGNvbnN0IGkgPSAxMiAqIGluZGV4O1xyXG5cclxuXHRcdGNvbnN0IHYwID0gbmV3IFF1YXRlcm5pb24ob1tpIC0gOF0sIG9baSAtIDddLCBvW2kgLSA2XSwgb1tpIC0gNV0pO1xyXG5cdFx0Y29uc3QgYjAgPSBuZXcgUXVhdGVybmlvbihvW2kgLSA0XSwgb1tpIC0gM10sIG9baSAtIDJdLCBvW2kgLSAxXSk7XHJcblx0XHRjb25zdCB2MSA9IG5ldyBRdWF0ZXJuaW9uKG9baSArIDRdLCBvW2kgKyA1XSwgb1tpICsgNl0sIG9baSArIDddKTtcclxuXHRcdGNvbnN0IGExID0gbmV3IFF1YXRlcm5pb24ob1tpXSwgb1tpICsgMV0sIG9baSArIDJdLCBvW2kgKyAzXSk7XHJcblx0XHRRdWF0ZXJuaW9uLm11bHRpcGx5QnlTY2FsYXIodjAsIDIgKiB0MyAtIDMgKiB0MiArIDEsIHYwKTtcclxuXHRcdFF1YXRlcm5pb24ubXVsdGlwbHlCeVNjYWxhcihiMCwgdGQgKiAodDMgLSAyICogdDIgKyB0KSwgYjApO1xyXG5cdFx0UXVhdGVybmlvbi5tdWx0aXBseUJ5U2NhbGFyKHYxLCAtMiAqIHQzICsgMyAqIHQyLCB2MSk7XHJcblx0XHRRdWF0ZXJuaW9uLm11bHRpcGx5QnlTY2FsYXIoYTEsIHRkICogKHQzIC0gdDIpLCBhMSk7XHJcblxyXG5cdFx0Y29uc3QgcmVzdWx0ID0gbmV3IFF1YXRlcm5pb24oKTtcclxuXHRcdFF1YXRlcm5pb24uYWRkKHJlc3VsdCwgdjAsIHJlc3VsdCk7XHJcblx0XHRRdWF0ZXJuaW9uLmFkZChyZXN1bHQsIGIwLCByZXN1bHQpO1xyXG5cdFx0UXVhdGVybmlvbi5hZGQocmVzdWx0LCB2MSwgcmVzdWx0KTtcclxuXHRcdFF1YXRlcm5pb24uYWRkKHJlc3VsdCwgYTEsIHJlc3VsdCk7XHJcblx0XHRRdWF0ZXJuaW9uLm5vcm1hbGl6ZShyZXN1bHQsIHJlc3VsdCk7XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxuXHJcblx0Y29uc3QgcSA9IFtdO1xyXG5cdGZvciAobGV0IG4gPSAtMTsgbiA8IDE7IG4gKz0gMSkge1xyXG5cdFx0Y29uc3QgaSA9IDQgKiAoaW5kZXggKyBuKTtcclxuXHRcdHEucHVzaChuZXcgUXVhdGVybmlvbihvW2ldLCBvW2kgKyAxXSwgb1tpICsgMl0sIG9baSArIDNdKSk7XHJcblx0fVxyXG5cclxuXHRpZiAobWV0aG9kID09PSBcIlNURVBcIikge1xyXG5cdFx0cmV0dXJuIHQgPCAxID8gcVswXSA6IHFbMV07XHJcblx0fVxyXG5cdGNvbnN0IHJlc3VsdCA9IG5ldyBRdWF0ZXJuaW9uKCk7XHJcblx0UXVhdGVybmlvbi5zbGVycChxWzBdLCBxWzFdLCB0LCByZXN1bHQpO1xyXG5cdHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBpbnRlcnBWZWMzKGlucHV0OiBUeXBlZEFycmF5LCBvdXRwdXQ6IFR5cGVkQXJyYXksIHRpbWU6IG51bWJlciwgbWV0aG9kOiBzdHJpbmcpIHtcclxuXHRsZXQgaW5kZXggPSAxO1xyXG5cdHdoaWxlIChpbmRleCA8IGlucHV0Lmxlbmd0aCAtIDEgJiYgdGltZSA+PSBpbnB1dFtpbmRleF0pIHtcclxuXHRcdGluZGV4ICs9IDE7XHJcblx0fVxyXG5cdGNvbnN0IHQgPSBsZXJwKGlucHV0W2luZGV4IC0gMV0sIGlucHV0W2luZGV4XSwgdGltZSk7XHJcblxyXG5cdGlmIChtZXRob2QgPT09IFwiQ1VCSUNTUExJTkVcIikge1xyXG5cdFx0Y29uc3QgdGQgPSBpbnB1dFtpbmRleF0gLSBpbnB1dFtpbmRleCAtIDFdO1xyXG5cdFx0Y29uc3QgdDIgPSB0ICogdDtcclxuXHRcdGNvbnN0IHQzID0gdDIgKiB0O1xyXG5cdFx0Y29uc3QgaSA9IDkgKiBpbmRleDtcclxuXHRcdGNvbnN0IHYwID0gbmV3IFZlY3RvcjMob3V0cHV0W2kgLSA2XSwgb3V0cHV0W2kgLSA1XSwgb3V0cHV0W2kgLSA0XSk7XHJcblx0XHRjb25zdCBiMCA9IG5ldyBWZWN0b3IzKG91dHB1dFtpIC0gM10sIG91dHB1dFtpIC0gMl0sIG91dHB1dFtpIC0gMV0pO1xyXG5cdFx0Y29uc3QgdjEgPSBuZXcgVmVjdG9yMyhvdXRwdXRbaSArIDNdLCBvdXRwdXRbaSArIDRdLCBvdXRwdXRbaSArIDVdKTtcclxuXHRcdGNvbnN0IGExID0gbmV3IFZlY3RvcjMob3V0cHV0W2ldLCBvdXRwdXRbaSArIDFdLCBvdXRwdXRbaSArIDJdKTtcclxuXHRcdFZlY3RvcjMubXVsdGlwbHlCeVNjYWxhcih2MCwgMiAqIHQzIC0gMyAqIHQyICsgMSwgdjApO1xyXG5cdFx0VmVjdG9yMy5tdWx0aXBseUJ5U2NhbGFyKGIwLCB0ZCAqICh0MyAtIDIgKiB0MiArIHQpLCBiMCk7XHJcblx0XHRWZWN0b3IzLm11bHRpcGx5QnlTY2FsYXIodjEsIC0yICogdDMgKyAzICogdDIsIHYxKTtcclxuXHRcdFZlY3RvcjMubXVsdGlwbHlCeVNjYWxhcihhMSwgdGQgKiAodDMgLSB0MiksIGExKTtcclxuXHRcdGNvbnN0IHJlc3VsdCA9IG5ldyBWZWN0b3IzKCk7XHJcblx0XHRWZWN0b3IzLmFkZChyZXN1bHQsIHYwLCByZXN1bHQpO1xyXG5cdFx0VmVjdG9yMy5hZGQocmVzdWx0LCBiMCwgcmVzdWx0KTtcclxuXHRcdFZlY3RvcjMuYWRkKHJlc3VsdCwgdjEsIHJlc3VsdCk7XHJcblx0XHRWZWN0b3IzLmFkZChyZXN1bHQsIGExLCByZXN1bHQpO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9XHJcblxyXG5cdGNvbnN0IHYgPSBbXTtcclxuXHRmb3IgKGxldCBuID0gLTE7IG4gPCAxOyBuICs9IDEpIHtcclxuXHRcdGNvbnN0IGkgPSAzICogKGluZGV4ICsgbik7XHJcblx0XHR2LnB1c2gobmV3IFZlY3RvcjMob3V0cHV0W2ldLCBvdXRwdXRbaSArIDFdLCBvdXRwdXRbaSArIDJdKSk7XHJcblx0fVxyXG5cclxuXHRpZiAobWV0aG9kID09PSBcIlNURVBcIikge1xyXG5cdFx0cmV0dXJuIHQgPCAxID8gdlswXSA6IHZbMV07XHJcblx0fVxyXG5cdGNvbnN0IHJlc3VsdCA9IG5ldyBWZWN0b3IzKCk7XHJcblx0cmV0dXJuIFZlY3RvcjMubGVycCh2WzBdLCB2WzFdLCB0LCByZXN1bHQpO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgZ2x0ZkVudW06IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIHwgbnVtYmVyIH0gPSB7XHJcblx0U0NBTEFSOiAxLFxyXG5cdFZFQzI6IDIsXHJcblx0VkVDMzogMyxcclxuXHRWRUM0OiA0LFxyXG5cdE1BVDI6IDQsXHJcblx0TUFUMzogOSxcclxuXHRNQVQ0OiAxNixcclxuXHQ1MTIwOiAxLFxyXG5cdDUxMjE6IDEsXHJcblx0NTEyMjogMixcclxuXHQ1MTIzOiAyLFxyXG5cdDUxMjU6IDQsXHJcblx0NTEyNjogNCxcclxuXHQ5NzI4OiBcIm5lYXJlc3RcIixcclxuXHQ5NzI5OiBcImxpbmVhclwiLFxyXG5cdDk5ODQ6IFwibGluZWFyXCIsXHJcblx0OTk4NTogXCJsaW5lYXJcIixcclxuXHQ5OTg2OiBcImxpbmVhclwiLFxyXG5cdDk5ODc6IFwibGluZWFyXCIsXHJcblx0MzMwNzE6IFwiY2xhbXAtdG8tZWRnZVwiLFxyXG5cdDMzNjQ4OiBcIm1pcnJvci1yZXBlYXRcIixcclxuXHQxMDQ5NzogXCJyZXBlYXRcIlxyXG59O1xyXG4iLCJpbXBvcnQgTWF0cml4NCBmcm9tIFwiLi4vLi4vLi4vbWF0aC9NYXRyaXg0XCI7XHJcbmltcG9ydCBWZWN0b3I0IGZyb20gXCIuLi8uLi8uLi9tYXRoL1ZlY3RvcjRcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBBY2Nlc3NvciB7XHJcblx0dmFsdWVzOiBhbnk7XHJcblx0aWQ6IG51bWJlcjtcclxuXHRjb3VudDogbnVtYmVyO1xyXG5cdGNvbXBvbmVudFR5cGU6IG51bWJlcjtcclxuXHR0eXBlOiBudW1iZXI7XHJcblx0bWluOiBudW1iZXJbXTtcclxuXHRtYXg6IG51bWJlcltdO1xyXG5cdGNvbnN0cnVjdG9yKG9wdGlvbnM6IEFjY2Vzc29yUGFybXMpIHtcclxuXHRcdHRoaXMudmFsdWVzID0gb3B0aW9ucy52YWx1ZXMgPz8gW107XHJcblx0XHR0aGlzLmlkID0gb3B0aW9ucy5pZDtcclxuXHRcdHRoaXMuY291bnQgPSBvcHRpb25zLmNvdW50O1xyXG5cdFx0dGhpcy5jb21wb25lbnRUeXBlID0gb3B0aW9ucy5jb21wb25lbnRUeXBlO1xyXG5cdFx0dGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xyXG5cdFx0dGhpcy5taW4gPSBvcHRpb25zLm1pbjtcclxuXHRcdHRoaXMubWF4ID0gb3B0aW9ucy5tYXg7XHJcblx0fVxyXG5cdGdldEFycmF5KCk6IG51bWJlcltdIHtcclxuXHRcdHJldHVybiBBcnJheS5mcm9tKHRoaXMudmFsdWVzKTtcclxuXHR9XHJcblx0Z2V0VmVjNEFycmF5KCk6IFZlY3RvcjRbXSB7XHJcblx0XHRjb25zdCByZXN1bHQgPSBbXTtcclxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52YWx1ZXMubGVuZ3RoOyBpICs9IDQpIHtcclxuXHRcdFx0cmVzdWx0LnB1c2gobmV3IFZlY3RvcjQodGhpcy52YWx1ZXNbaV0sIHRoaXMudmFsdWVzW2kgKyAxXSwgdGhpcy52YWx1ZXNbaSArIDJdLCB0aGlzLnZhbHVlc1tpICsgM10pKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fVxyXG5cdGdldE1hdDRBcnJheSgpOiBNYXRyaXg0W10ge1xyXG5cdFx0Y29uc3QgcmVzdWx0ID0gW107XHJcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMudmFsdWVzLmxlbmd0aDsgaSArPSAxNikge1xyXG5cdFx0XHRjb25zdCBtYXQ0ID0gbmV3IE1hdHJpeDQoKTtcclxuXHRcdFx0TWF0cml4NC5mcm9tQ29sdW1uTWFqb3JBcnJheSh0aGlzLnZhbHVlcy5zbGljZShpLCBpICsgMTYpLCBtYXQ0KTtcclxuXHRcdFx0cmVzdWx0LnB1c2gobWF0NCk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gcmVzdWx0O1xyXG5cdH1cclxufVxyXG5leHBvcnQgdHlwZSBBY2Nlc3NvclBhcm1zID0gUGFydGlhbDxBY2Nlc3Nvcj47XHJcbiIsImltcG9ydCB7IFF1YXRlcm5pb24gfSBmcm9tIFwiLi4vLi4vLi4vbWF0aC9RdWF0ZXJuaW9uXCI7XG5pbXBvcnQgVmVjdG9yNCBmcm9tIFwiLi4vLi4vLi4vbWF0aC9WZWN0b3I0XCI7XG5pbXBvcnQgeyBBbmltYXRpb25DaGFubmVsIH0gZnJvbSBcIi4vQW5pbWF0aW9uQ2hhbm5lbFwiO1xuaW1wb3J0IHsgQW5pbWF0aW9uU2FtcGxlciB9IGZyb20gXCIuL0FuaW1hdGlvblNhbXBsZXJcIjtcblxuZXhwb3J0IGNsYXNzIEFuaW1hdGlvbiB7XG5cdGNvbnN0cnVjdG9yKHB1YmxpYyBuYW1lOiBzdHJpbmcsIHB1YmxpYyBzYW1wbGVyczogQW5pbWF0aW9uU2FtcGxlcltdLCBwdWJsaWMgY2hhbm5lbHM6IEFuaW1hdGlvbkNoYW5uZWxbXSkge31cblx0cGxheSh0aW1lOiBudW1iZXIpIHtcblx0XHRsZXQgbm9kZSwgYW5pbWF0aW9uU2FtcGxlciwgdGFyZ2V0O1xuXHRcdHRoaXM/LmNoYW5uZWxzPy5tYXAoKGNoYW5uZWwpID0+IHtcblx0XHRcdGFuaW1hdGlvblNhbXBsZXIgPSBjaGFubmVsLnNhbXBsZXI7XG5cdFx0XHRhbmltYXRpb25TYW1wbGVyLmdldFZhbHVlKHRpbWUpO1xuXHRcdFx0dGFyZ2V0ID0gY2hhbm5lbC50YXJnZXQ7XG5cdFx0XHRub2RlID0gdGFyZ2V0Lm5vZGU7XG5cdFx0XHRzd2l0Y2ggKHRhcmdldC5wYXRoKSB7XG5cdFx0XHRcdGNhc2UgXCJyb3RhdGlvblwiOlxuXHRcdFx0XHRcdFF1YXRlcm5pb24uY2xvbmUoYW5pbWF0aW9uU2FtcGxlci5jdXJyZW50VmFsdWUsIG5vZGUucXVhdGVybmlvbik7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgXCJ0cmFuc2xhdGlvblwiOlxuXHRcdFx0XHRcdFZlY3RvcjQuY2xvbmUoYW5pbWF0aW9uU2FtcGxlci5jdXJyZW50VmFsdWUsIG5vZGUucG9zaXRpb24pO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIFwic2NhbGVcIjpcblx0XHRcdFx0XHRWZWN0b3I0LmNsb25lKGFuaW1hdGlvblNhbXBsZXIuY3VycmVudFZhbHVlLCBub2RlLnNjYWxlKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9KTtcblx0fVxufVxuIiwiaW1wb3J0IHsgQW5pbWF0aW9uQ2hhbm5lbFRhcmdldCB9IGZyb20gXCIuL0FuaW1hdGlvbkNoYW5uZWxUYXJnZXRcIjtcbmltcG9ydCB7IEFuaW1hdGlvblNhbXBsZXIgfSBmcm9tIFwiLi9BbmltYXRpb25TYW1wbGVyXCI7XG5cbmV4cG9ydCBjbGFzcyBBbmltYXRpb25DaGFubmVsIHtcblx0c2FtcGxlcjogQW5pbWF0aW9uU2FtcGxlcjtcblx0dGFyZ2V0OiBBbmltYXRpb25DaGFubmVsVGFyZ2V0O1xuXHRjb25zdHJ1Y3RvcigpIHt9XG59XG4iLCJpbXBvcnQgTm9kZSBmcm9tIFwiLi4vLi4vLi4vbWVzaC9Ob2RlXCI7XG5cbmV4cG9ydCBjbGFzcyBBbmltYXRpb25DaGFubmVsVGFyZ2V0IHtcblx0bm9kZTogTm9kZTtcblx0cGF0aDogXCJ0cmFuc2xhdGlvblwiIHwgXCJyb3RhdGlvblwiIHwgXCJzY2FsZVwiIHwgXCJ3ZWlnaHRzXCI7XG5cdGNvbnN0cnVjdG9yKG5vZGUsIHBhdGgpIHtcblx0XHR0aGlzLm5vZGUgPSBub2RlO1xuXHRcdHRoaXMucGF0aCA9IHBhdGg7XG5cdH1cbn1cbiIsImV4cG9ydCBlbnVtIFR5cGUyTnVtT2ZDb21wb25lbnQge1xyXG5cdFwiU0NBTEFSXCIgPSAxLFxyXG5cdFwiVkVDMlwiID0gMixcclxuXHRcIlZFQzNcIiA9IDMsXHJcblx0XCJWRUM0XCIgPSA0LFxyXG5cdFwiTUFUMlwiID0gNCxcclxuXHRcIk1BVDNcIiA9IDksXHJcblx0XCJNQVQ0XCIgPSAxNlxyXG59XHJcbiIsImltcG9ydCB7IFF1YXRlcm5pb24gfSBmcm9tIFwiLi4vLi4vLi4vbWF0aC9RdWF0ZXJuaW9uXCI7XHJcbmltcG9ydCBWZWN0b3I0IGZyb20gXCIuLi8uLi8uLi9tYXRoL1ZlY3RvcjRcIjtcclxuaW1wb3J0IHsgVHlwZTJOdW1PZkNvbXBvbmVudCB9IGZyb20gXCIuLi90eXBlcy9nbHRmVHlwZVwiO1xyXG5leHBvcnQgY2xhc3MgQW5pbWF0aW9uU2FtcGxlciB7XHJcblx0aW5wdXQ6IGFueTtcclxuXHRpbnRlcnBvbGF0aW9uOiBcIkxJTkVBUlwiIHwgXCJTVEVQXCIgfCBcIkNVQklDU1BMSU5FXCI7XHJcblx0b3V0cHV0OiBhbnk7XHJcblx0Y3VycmVudEluZGV4OiBudW1iZXI7XHJcblx0c3RhcnRUaW1lOiBudW1iZXI7XHJcblx0ZW5kVGltZTogbnVtYmVyO1xyXG5cdGN1cnJlbnRWYWx1ZTogVmVjdG9yNCB8IFF1YXRlcm5pb247XHJcblx0ZHVyYXRpb246IG51bWJlcjtcclxuXHRpbnB1dE1heDogbnVtYmVyO1xyXG5cdHByaXZhdGUgaW5wdXRUeXBlOiBzdHJpbmc7XHJcblx0cHJpdmF0ZSBvdXRwdXRUeXBlOiBzdHJpbmc7XHJcblx0Y29uc3RydWN0b3IoKSB7fVxyXG5cdGZvcm1HbHRmKGdsdGYsIHNhbXBsZXIpIHtcclxuXHRcdHRoaXMuaW5wdXQgPSBnbHRmLmFjY2Vzc29yc1tzYW1wbGVyLmlucHV0XS52YWx1ZXM7IC8vcmVxdWlyZWQsIGFjY2Vzc29yIG9iamVjdFxyXG5cdFx0dGhpcy5vdXRwdXQgPSBnbHRmLmFjY2Vzc29yc1tzYW1wbGVyLm91dHB1dF0udmFsdWVzOyAvL3JlcXVpcmVkLCBhY2Nlc3NvciBvYmplY3RcclxuXHRcdHRoaXMuaW50ZXJwb2xhdGlvbiA9IHNhbXBsZXIuaW50ZXJwb2xhdGlvbiAhPT0gdW5kZWZpbmVkID8gc2FtcGxlci5pbnRlcnBvbGF0aW9uIDogXCJMSU5FQVJcIjtcclxuXHRcdHRoaXMuY3VycmVudEluZGV4ID0gMDtcclxuXHRcdC8vIHRoaXMuY3VycmVudFZhbHVlPW5ldyBWZWN0b3I0KCk7XHJcblx0XHR0aGlzLmVuZFRpbWUgPSB0aGlzLmlucHV0W3RoaXMuaW5wdXQubGVuZ3RoIC0gMV07XHJcblx0XHR0aGlzLmlucHV0TWF4ID0gdGhpcy5lbmRUaW1lIC0gdGhpcy5pbnB1dFswXTtcclxuXHRcdHRoaXMuaW5wdXRUeXBlID0gZ2x0Zj8uanNvbj8uYWNjZXNzb3JzW3NhbXBsZXIuaW5wdXRdPy50eXBlO1xyXG5cdFx0dGhpcy5vdXRwdXRUeXBlID0gZ2x0Zj8uanNvbj8uYWNjZXNzb3JzW3NhbXBsZXIub3V0cHV0XT8udHlwZTtcclxuXHR9XHJcblx0Z2V0VmFsdWUodGltZTogbnVtYmVyKTogdm9pZCB7XHJcblx0XHRpZiAodGltZSA+IHRoaXMuZW5kVGltZSkge1xyXG5cdFx0XHR0aW1lIC09IHRoaXMuaW5wdXRNYXggKiBNYXRoLmNlaWwoKHRpbWUgLSB0aGlzLmVuZFRpbWUpIC8gdGhpcy5pbnB1dE1heCk7XHJcblx0XHRcdHRoaXMuY3VycmVudEluZGV4ID0gMDtcclxuXHRcdH1cclxuXHJcblx0XHRjb25zdCBsZW4gPSB0aGlzLmlucHV0Lmxlbmd0aDtcclxuXHRcdHdoaWxlICh0aGlzLmN1cnJlbnRJbmRleCA8PSBsZW4gLSAyICYmIHRpbWUgPj0gdGhpcy5pbnB1dFt0aGlzLmN1cnJlbnRJbmRleCArIDFdKSB7XHJcblx0XHRcdHRoaXMuY3VycmVudEluZGV4Kys7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKHRoaXMuY3VycmVudEluZGV4ID49IGxlbiAtIDEpIHtcclxuXHRcdFx0Ly8gbG9vcFxyXG5cdFx0XHR0aW1lIC09IHRoaXMuaW5wdXRNYXg7XHJcblx0XHRcdHRoaXMuY3VycmVudEluZGV4ID0gMDtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBAdG1wOiBhc3N1bWUgbm8gc3RyaWRlXHJcblx0XHRjb25zdCBjb3VudCA9IFR5cGUyTnVtT2ZDb21wb25lbnRbdGhpcy5vdXRwdXRUeXBlXTtcclxuXHJcblx0XHRjb25zdCBhbmltYXRpb25PdXRwdXRWYWx1ZVZlYzRhID0gY291bnQgPT09IDQgPyBuZXcgUXVhdGVybmlvbigpIDogbmV3IFZlY3RvcjQoKTtcclxuXHRcdGNvbnN0IGFuaW1hdGlvbk91dHB1dFZhbHVlVmVjNGIgPSBjb3VudCA9PT0gNCA/IG5ldyBRdWF0ZXJuaW9uKCkgOiBuZXcgVmVjdG9yNCgpO1xyXG5cdFx0aWYgKCF0aGlzLmN1cnJlbnRWYWx1ZSkgdGhpcy5jdXJyZW50VmFsdWUgPSBjb3VudCA9PT0gNCA/IG5ldyBRdWF0ZXJuaW9uKCkgOiBuZXcgVmVjdG9yNCgpO1xyXG5cdFx0Y29uc3QgaSA9IHRoaXMuY3VycmVudEluZGV4O1xyXG5cdFx0Y29uc3QgbyA9IGkgKiBjb3VudDtcclxuXHRcdGNvbnN0IG9uID0gbyArIGNvdW50O1xyXG5cclxuXHRcdGNvbnN0IHUgPSBNYXRoLm1heCgwLCB0aW1lIC0gdGhpcy5pbnB1dFtpXSkgLyAodGhpcy5pbnB1dFtpICsgMV0gLSB0aGlzLmlucHV0W2ldKTtcclxuXHRcdGFuaW1hdGlvbk91dHB1dFZhbHVlVmVjNGEuc2V0KHRoaXMub3V0cHV0W28gKyAwXSwgdGhpcy5vdXRwdXRbbyArIDFdLCB0aGlzLm91dHB1dFtvICsgMl0sIHRoaXMub3V0cHV0W28gKyAzXSk7XHJcblx0XHRhbmltYXRpb25PdXRwdXRWYWx1ZVZlYzRiLnNldChcclxuXHRcdFx0dGhpcy5vdXRwdXRbb24gKyAwXSxcclxuXHRcdFx0dGhpcy5vdXRwdXRbb24gKyAxXSxcclxuXHRcdFx0dGhpcy5vdXRwdXRbb24gKyAyXSxcclxuXHRcdFx0dGhpcy5vdXRwdXRbb24gKyAzXVxyXG5cdFx0KTtcclxuXHRcdHN3aXRjaCAodGhpcy5pbnRlcnBvbGF0aW9uKSB7XHJcblx0XHRcdGNhc2UgXCJMSU5FQVJcIjpcclxuXHRcdFx0XHRjb3VudCA9PT0gNFxyXG5cdFx0XHRcdFx0PyBRdWF0ZXJuaW9uLnNsZXJwKFxyXG5cdFx0XHRcdFx0XHRcdDxRdWF0ZXJuaW9uPmFuaW1hdGlvbk91dHB1dFZhbHVlVmVjNGEsXHJcblx0XHRcdFx0XHRcdFx0PFF1YXRlcm5pb24+YW5pbWF0aW9uT3V0cHV0VmFsdWVWZWM0YixcclxuXHRcdFx0XHRcdFx0XHR1LFxyXG5cdFx0XHRcdFx0XHRcdDxRdWF0ZXJuaW9uPnRoaXMuY3VycmVudFZhbHVlXHJcblx0XHRcdFx0XHQgIClcclxuXHRcdFx0XHRcdDogVmVjdG9yNC5sZXJwKFxyXG5cdFx0XHRcdFx0XHRcdDxWZWN0b3I0PmFuaW1hdGlvbk91dHB1dFZhbHVlVmVjNGEsXHJcblx0XHRcdFx0XHRcdFx0PFZlY3RvcjQ+YW5pbWF0aW9uT3V0cHV0VmFsdWVWZWM0YixcclxuXHRcdFx0XHRcdFx0XHR1LFxyXG5cdFx0XHRcdFx0XHRcdDxWZWN0b3I0PnRoaXMuY3VycmVudFZhbHVlXHJcblx0XHRcdFx0XHQgICk7XHJcblx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdGRlZmF1bHQ6XHJcblx0XHRcdFx0YnJlYWs7XHJcblx0XHR9XHJcblx0fVxyXG59XHJcbiIsImltcG9ydCB7IFJlbmRlck9iamVjdFR5cGUgfSBmcm9tIFwiLi4vY29yZS9XZWJHUFVUeXBlc1wiO1xyXG5pbXBvcnQgR2VvbWV0cnkgZnJvbSBcIi4uL2dlb21ldHJ5L0dlb21ldHJ5XCI7XHJcbmltcG9ydCBQYnJNYXRlcmlhbCBmcm9tIFwiLi4vbWF0ZXJpYWwvUGJyTWF0ZXJpYWxcIjtcclxuaW1wb3J0IENvbG9yIGZyb20gXCIuLi9tYXRoL0NvbG9yXCI7XHJcbmltcG9ydCBNYXRyaXg0IGZyb20gXCIuLi9tYXRoL01hdHJpeDRcIjtcclxuaW1wb3J0IHsgUXVhdGVybmlvbiB9IGZyb20gXCIuLi9tYXRoL1F1YXRlcm5pb25cIjtcclxuaW1wb3J0IFZlY3RvcjMgZnJvbSBcIi4uL21hdGgvVmVjdG9yM1wiO1xyXG5pbXBvcnQgeyBNZXNoIH0gZnJvbSBcIi4uL21lc2gvTWVzaFwiO1xyXG5pbXBvcnQgTm9kZSBmcm9tIFwiLi4vbWVzaC9Ob2RlXCI7XHJcbmltcG9ydCB7IFNLaW5NZXNoIH0gZnJvbSBcIi4uL21lc2gvU0tpbk1lc2hcIjtcclxuaW1wb3J0IHsgRmxvYXQzMkF0dHJpYnV0ZSB9IGZyb20gXCIuLi9yZW5kZXIvQXR0cmlidXRlXCI7XHJcbmltcG9ydCBTYW1wbGVyIGZyb20gXCIuLi9yZW5kZXIvU2FtcGxlclwiO1xyXG5pbXBvcnQgVGV4dHVyZSBmcm9tIFwiLi4vcmVuZGVyL1RleHR1cmVcIjtcclxuaW1wb3J0IHsgZ2VuZXJhdGVOb3JtYWxzLCBnbHRmRW51bSwgbmV3VHlwZWRBcnJheSwgdG9JbmRpY2VzLCBUeXBlZEFycmF5IH0gZnJvbSBcIi4uL3V0aWxzL2dsdGZVdGlsc1wiO1xyXG5pbXBvcnQgeyBBY2Nlc3NvciB9IGZyb20gXCIuL2dsdGYvbGlicy9BY2Nlc3NvclwiO1xyXG5pbXBvcnQgeyBBbmltYXRpb24gfSBmcm9tIFwiLi9nbHRmL2xpYnMvQW5pbWF0aW9uXCI7XHJcbmltcG9ydCB7IEFuaW1hdGlvbkNoYW5uZWwgfSBmcm9tIFwiLi9nbHRmL2xpYnMvQW5pbWF0aW9uQ2hhbm5lbFwiO1xyXG5pbXBvcnQgeyBBbmltYXRpb25DaGFubmVsVGFyZ2V0IH0gZnJvbSBcIi4vZ2x0Zi9saWJzL0FuaW1hdGlvbkNoYW5uZWxUYXJnZXRcIjtcclxuaW1wb3J0IHsgQW5pbWF0aW9uU2FtcGxlciB9IGZyb20gXCIuL2dsdGYvbGlicy9BbmltYXRpb25TYW1wbGVyXCI7XHJcblxyXG5leHBvcnQgdHlwZSBHTFRGUHJpbWl0aXZlID0ge1xyXG5cdHZlcnRleENvdW50OiBudW1iZXI7XHJcblx0aW5kaWNlczogVWludDE2QXJyYXkgfCBVaW50MzJBcnJheSB8IG51bGw7XHJcblx0cG9zaXRpb25zOiBUeXBlZEFycmF5O1xyXG5cdG5vcm1hbHM6IFR5cGVkQXJyYXk7XHJcblx0dXZzOiBUeXBlZEFycmF5IHwgbnVsbDtcclxuXHR1djFzOiBUeXBlZEFycmF5IHwgbnVsbDtcclxuXHR0YW5nZW50czogVHlwZWRBcnJheSB8IG51bGw7XHJcblx0Y29sb3JzOiBUeXBlZEFycmF5IHwgbnVsbDtcclxuXHRtYXRlcmlhbDogYW55O1xyXG5cdGJvdW5kaW5nQm94OiB7XHJcblx0XHRtYXg6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcclxuXHRcdG1pbjogW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xyXG5cdH07XHJcbn07XHJcblxyXG5leHBvcnQgdHlwZSBHTFRGTWVzaCA9IEFycmF5PEdMVEZQcmltaXRpdmU+O1xyXG5cclxuZXhwb3J0IHR5cGUgR0xURkFuaW1hdGlvbiA9IHtcclxuXHRjaGFubmVsczogQXJyYXk8e1xyXG5cdFx0aW5wdXQ6IFR5cGVkQXJyYXk7XHJcblx0XHRvdXRwdXQ6IFR5cGVkQXJyYXk7XHJcblx0XHRpbnRlcnBvbGF0aW9uOiBzdHJpbmc7XHJcblx0XHRub2RlOiBudW1iZXI7XHJcblx0XHRwYXRoOiBzdHJpbmc7XHJcblx0fT47XHJcblx0bGVuZ3RoOiBudW1iZXI7XHJcbn07XHJcblxyXG5leHBvcnQgY2xhc3MgR0xURiB7XHJcblx0c2NlbmVzOiBBcnJheTxOb2RlPjtcclxuXHJcblx0bm9kZXM6IEFycmF5PGFueT47XHJcblxyXG5cdGNhbWVyYXM6IEFycmF5PGFueT47XHJcblxyXG5cdG1lc2hlczogQXJyYXk8YW55PjtcclxuXHJcblx0aW1hZ2VzOiBBcnJheTxJbWFnZUJpdG1hcD47XHJcblxyXG5cdGFuaW1hdGlvbnM6IEFycmF5PEdMVEZBbmltYXRpb24+O1xyXG5cclxuXHRwcml2YXRlIGdsYk9mZnNldDogbnVtYmVyO1xyXG5cclxuXHRwcml2YXRlIGJ1ZmZlcnM6IEFycmF5QnVmZmVyW107XHJcblxyXG5cdHByaXZhdGUgYnVmZmVyVmlld3M6IGFueTtcclxuXHJcblx0YWNjZXNzb3JzOiBhbnk7XHJcblxyXG5cdGpzb246IGFueTtcclxuXHJcblx0cHJpdmF0ZSBtYXRlcmlhbHM6IGFueTtcclxuXHJcblx0cHJpdmF0ZSBnbGJCaW4/OiBBcnJheUJ1ZmZlcjtcclxuXHJcblx0cHJpdmF0ZSByb290VXJsOiBzdHJpbmc7XHJcblxyXG5cdHRleHR1cmVzOiBhbnlbXTtcclxuXHJcblx0c2FtcGxlcnM6IFNhbXBsZXJbXTtcclxuXHJcblx0Y29uc3RydWN0b3IoanNvbjogYW55LCByb290VXJsOiBzdHJpbmcsIGdsYk9mZnNldCA9IDAsIGdsYkJpbj86IEFycmF5QnVmZmVyKSB7XHJcblx0XHR0aGlzLmpzb24gPSBqc29uO1xyXG5cdFx0dGhpcy5idWZmZXJWaWV3cyA9IGpzb24uYnVmZmVyVmlld3M7XHJcblx0XHR0aGlzLmdsYk9mZnNldCA9IGdsYk9mZnNldDtcclxuXHRcdHRoaXMucm9vdFVybCA9IHJvb3RVcmw7XHJcblx0XHR0aGlzLnNjZW5lcyA9IGpzb24uc2NlbmVzO1xyXG5cdFx0dGhpcy5jYW1lcmFzID0ganNvbi5jYW1lcmFzIHx8IFtdO1xyXG5cdFx0dGhpcy5nbGJCaW4gPSBnbGJCaW47XHJcblx0XHR0aGlzLm1lc2hlcyA9IFtdO1xyXG5cdH1cclxuXHRhc3luYyBwYXJzZURhdGEoKSB7XHJcblx0XHR0aGlzLmJ1ZmZlcnMgPSBhd2FpdCB0aGlzLmxvYWRCdWZmZXMoKTtcclxuXHRcdHRoaXMuaW1hZ2VzID0gYXdhaXQgdGhpcy5sb2FkSW1hZ2VzKCk7XHJcblx0XHR0aGlzLnBhcnNlU2FtcGxlcnMoKTtcclxuXHRcdHRoaXMucGFyc2VUZXh0dXJlcygpO1xyXG5cdFx0dGhpcy5wYXJzZU1hdGVyaWFscygpO1xyXG5cdFx0dGhpcy5wYXJzZUFjY2Vzc29ycygpO1xyXG5cdFx0dGhpcy5wYXJzZU1lc2hzKCk7XHJcblx0XHR0aGlzLnBhcnNlTm9kZXMoKTtcclxuXHRcdHRoaXMubm9ybWFsaXplRGF0YSgpO1xyXG5cdFx0dGhpcy5wYXJzZVNjZW5lcygpO1xyXG5cdFx0dGhpcy5wYXJzZUFuaW1hdGlvbnMoKTtcclxuXHR9XHJcblx0cHJpdmF0ZSBnZXRBY2Nlc3NvcihpbmRleDogbnVtYmVyKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5hY2Nlc3NvcnNbaW5kZXhdO1xyXG5cdH1cclxuXHRwcml2YXRlIHBhcnNlU2FtcGxlcnMoKSB7XHJcblx0XHR0aGlzLnNhbXBsZXJzID0gdGhpcy5qc29uLnNhbXBsZXJzXHJcblx0XHRcdD8gKHRoaXMuanNvbi5zYW1wbGVycyBhcyBBcnJheTxhbnk+KS5tYXAoKHNhbXBsZXIpID0+IHRoaXMuZ2V0U2FtcGxlcihzYW1wbGVyKSlcclxuXHRcdFx0OiBbXTtcclxuXHR9XHJcblx0cHJpdmF0ZSBwYXJzZVNjZW5lcygpIHtcclxuXHRcdHRoaXMuc2NlbmVzID0gdGhpcy5qc29uLnNjZW5lcy5tYXAoKHNjZW5lKSA9PiB7XHJcblx0XHRcdGNvbnN0IG5vZGVzID0gc2NlbmU/Lm5vZGVzPy5tYXAoKG5vZGVJZCkgPT4ge1xyXG5cdFx0XHRcdHJldHVybiB0aGlzLm5vZGVzW25vZGVJZF07XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRyZXR1cm4gbm9kZXM7XHJcblx0XHR9KTtcclxuXHR9XHJcblx0cHJpdmF0ZSBwYXJzZVRleHR1cmVzKCkge1xyXG5cdFx0dGhpcy50ZXh0dXJlcyA9IHRoaXMuanNvbi50ZXh0dXJlc1xyXG5cdFx0XHQ/ICh0aGlzLmpzb24udGV4dHVyZXMgYXMgQXJyYXk8YW55PikubWFwKCh0ZXh0dXJlKSA9PiB7XHJcblx0XHRcdFx0XHRyZXR1cm4ge1xyXG5cdFx0XHRcdFx0XHRzYW1wbGVyOiB0ZXh0dXJlLnNhbXBsZXIgIT09IHVuZGVmaW5lZCA/IHRoaXMuc2FtcGxlcnNbdGV4dHVyZS5zYW1wbGVyXSA6IHRoaXMuZ2V0U2FtcGxlcih7fSksXHJcblx0XHRcdFx0XHRcdHRleHR1cmU6IHRoaXMuY3JlYXRlVGV4dHVyZSh0ZXh0dXJlLnNvdXJjZSlcclxuXHRcdFx0XHRcdH07XHJcblx0XHRcdCAgfSlcclxuXHRcdFx0OiBbXTtcclxuXHR9XHJcblx0cHJpdmF0ZSBwYXJzZU1hdGVyaWFscygpIHtcclxuXHRcdHRoaXMubWF0ZXJpYWxzID0gdGhpcy5qc29uLm1hdGVyaWFsc1xyXG5cdFx0XHQ/ICh0aGlzLmpzb24ubWF0ZXJpYWxzIGFzIEFycmF5PGFueT4pLm1hcCgobWF0ZXJpYWwpID0+IHtcclxuXHRcdFx0XHRcdGNvbnN0IG1hdCA9IG5ldyBQYnJNYXRlcmlhbCgpO1xyXG5cdFx0XHRcdFx0Y29uc3Qge1xyXG5cdFx0XHRcdFx0XHRiYXNlQ29sb3JGYWN0b3IsXHJcblx0XHRcdFx0XHRcdG1ldGFsbGljRmFjdG9yLFxyXG5cdFx0XHRcdFx0XHRtZXRhbGxpY1JvdWdobmVzc1RleHR1cmUsXHJcblx0XHRcdFx0XHRcdGJhc2VDb2xvclRleHR1cmUsXHJcblx0XHRcdFx0XHRcdHJvdWdobmVzc0ZhY3RvclxyXG5cdFx0XHRcdFx0fSA9IG1hdGVyaWFsLnBick1ldGFsbGljUm91Z2huZXNzO1xyXG5cdFx0XHRcdFx0aWYgKG1hdGVyaWFsLm5vcm1hbFRleHR1cmUpIG1hdC5ub3JtYWxUZXh0dXJlID0gdGhpcy50ZXh0dXJlc1ttYXRlcmlhbC5ub3JtYWxUZXh0dXJlLmluZGV4XS50ZXh0dXJlO1xyXG5cdFx0XHRcdFx0aWYgKG1hdGVyaWFsLm9jY2x1c2lvblRleHR1cmUpXHJcblx0XHRcdFx0XHRcdG1hdC5hb1RleHR1cmUgPSB0aGlzLnRleHR1cmVzW21hdGVyaWFsLm9jY2x1c2lvblRleHR1cmUuaW5kZXhdLnRleHR1cmU7XHJcblx0XHRcdFx0XHRpZiAobWF0ZXJpYWwuZW1pc3NpdmVUZXh0dXJlKVxyXG5cdFx0XHRcdFx0XHRtYXQuZW1pc3NpdmVUZXh0dXJlID0gdGhpcy50ZXh0dXJlc1ttYXRlcmlhbC5lbWlzc2l2ZVRleHR1cmUuaW5kZXhdLnRleHR1cmU7XHJcblx0XHRcdFx0XHRpZiAoYmFzZUNvbG9yVGV4dHVyZSkgbWF0LmJhc2VUZXh0dXJlID0gdGhpcy50ZXh0dXJlc1tiYXNlQ29sb3JUZXh0dXJlLmluZGV4XS50ZXh0dXJlO1xyXG5cdFx0XHRcdFx0aWYgKG1ldGFsbGljUm91Z2huZXNzVGV4dHVyZSlcclxuXHRcdFx0XHRcdFx0bWF0Lm1ldGFsbmVzc1JvdWdobmVzc1RleHR1cmUgPSB0aGlzLnRleHR1cmVzW21ldGFsbGljUm91Z2huZXNzVGV4dHVyZS5pbmRleF0udGV4dHVyZTtcclxuXHRcdFx0XHRcdGlmIChiYXNlQ29sb3JGYWN0b3IpXHJcblx0XHRcdFx0XHRcdG1hdC5jb2xvciA9IG5ldyBDb2xvcihiYXNlQ29sb3JGYWN0b3JbMF0sIGJhc2VDb2xvckZhY3RvclsxXSwgYmFzZUNvbG9yRmFjdG9yWzJdKTtcclxuXHRcdFx0XHRcdG1hdC5tZXRhbG5lc3MgPSBtZXRhbGxpY0ZhY3RvciA/PyAxLjA7XHJcblx0XHRcdFx0XHRtYXQucm91Z2huZXNzID0gcm91Z2huZXNzRmFjdG9yID8/IDAuMDtcclxuXHRcdFx0XHRcdG1hdC5iYXNlU2FtcGxlciA9IG5ldyBTYW1wbGVyKHtcclxuXHRcdFx0XHRcdFx0bWFnRmlsdGVyOiBcImxpbmVhclwiLFxyXG5cdFx0XHRcdFx0XHRtaW5GaWx0ZXI6IFwibGluZWFyXCIsXHJcblx0XHRcdFx0XHRcdGFkZHJlc3NNb2RlVTogXCJyZXBlYXRcIixcclxuXHRcdFx0XHRcdFx0YWRkcmVzc01vZGVWOiBcInJlcGVhdFwiXHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdHJldHVybiBtYXQ7XHJcblx0XHRcdCAgfSlcclxuXHRcdFx0OiBbXTtcclxuXHR9XHJcblx0cHJpdmF0ZSBwYXJzZUFjY2Vzc29ycygpIHtcclxuXHRcdHRoaXMuYWNjZXNzb3JzID0gKHRoaXMuanNvbi5hY2Nlc3NvcnMgYXMgQXJyYXk8YW55PikubWFwKChhY2Nlc3NvciwgaW5kZXgpID0+IHtcclxuXHRcdFx0Y29uc3QgbiA9IGdsdGZFbnVtW2FjY2Vzc29yLnR5cGVdIGFzIG51bWJlcjtcclxuXHRcdFx0bGV0IGFycmF5O1xyXG5cdFx0XHRpZiAoYWNjZXNzb3IuYnVmZmVyVmlldyA9PT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdFx0YXJyYXkgPSBuZXdUeXBlZEFycmF5KFxyXG5cdFx0XHRcdFx0YWNjZXNzb3IuY29tcG9uZW50VHlwZSxcclxuXHRcdFx0XHRcdG5ldyBBcnJheUJ1ZmZlcihuICogYWNjZXNzb3IuY291bnQgKiAoZ2x0ZkVudW1bYWNjZXNzb3IuY29tcG9uZW50VHlwZV0gYXMgbnVtYmVyKSksXHJcblx0XHRcdFx0XHQwLFxyXG5cdFx0XHRcdFx0YWNjZXNzb3IuY291bnQgKiBuXHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRhcnJheSA9IHRoaXMuZ2V0QnVmZmVyVmlldyhhY2Nlc3Nvciwgbik7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmIChhY2Nlc3Nvci5zcGFyc2UpIHtcclxuXHRcdFx0XHRhY2Nlc3Nvci5zcGFyc2UuaW5kaWNlcy5jb3VudCA9IGFjY2Vzc29yLnNwYXJzZS5jb3VudDtcclxuXHRcdFx0XHRhY2Nlc3Nvci5zcGFyc2UudmFsdWVzLmNvdW50ID0gYWNjZXNzb3Iuc3BhcnNlLmNvdW50O1xyXG5cdFx0XHRcdGFjY2Vzc29yLnNwYXJzZS52YWx1ZXMuY29tcG9uZW50VHlwZSA9IGFjY2Vzc29yLmNvbXBvbmVudFR5cGU7XHJcblx0XHRcdFx0Y29uc3QgaW5kaWNlcyA9IHRoaXMuZ2V0QnVmZmVyVmlldyhhY2Nlc3Nvci5zcGFyc2UuaW5kaWNlcywgMSk7XHJcblx0XHRcdFx0Y29uc3QgdmFsdWVzID0gdGhpcy5nZXRCdWZmZXJWaWV3KGFjY2Vzc29yLnNwYXJzZS52YWx1ZXMsIG4pO1xyXG5cdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYWNjZXNzb3Iuc3BhcnNlLmNvdW50OyBpICs9IDEpIHtcclxuXHRcdFx0XHRcdGZvciAobGV0IGogPSAwOyBqIDwgbjsgaiArPSAxKSB7XHJcblx0XHRcdFx0XHRcdGFycmF5W2luZGljZXNbaV0gKiBuICsgal0gPSB2YWx1ZXNbaSAqIG4gKyBqXTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIG5ldyBBY2Nlc3Nvcih7XHJcblx0XHRcdFx0Y29tcG9uZW50VHlwZTogPG51bWJlcj5nbHRmRW51bVthY2Nlc3Nvci5jb21wb25lbnRUeXBlXSxcclxuXHRcdFx0XHRjb3VudDogYWNjZXNzb3IuY291bnQsXHJcblx0XHRcdFx0dHlwZTogbixcclxuXHRcdFx0XHR2YWx1ZXM6IGFycmF5LFxyXG5cdFx0XHRcdGlkOiBpbmRleCxcclxuXHRcdFx0XHRtaW46IGFjY2Vzc29yPy5taW4sXHJcblx0XHRcdFx0bWF4OiBhY2Nlc3Nvcj8ubWF4XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cdHByaXZhdGUgcGFyc2VBbmltYXRpb25zKCkge1xyXG5cdFx0dGhpcy5hbmltYXRpb25zID0gdGhpcz8uanNvbj8uYW5pbWF0aW9ucz8ubWFwKChnbHRmQW5pbWF0aW9uLCBpbmRleCkgPT4ge1xyXG5cdFx0XHRjb25zdCBzYW1wbGVycyA9IGdsdGZBbmltYXRpb24/LnNhbXBsZXJzPy5tYXAoKGdsdGZTYW1wbGVyKSA9PiB7XHJcblx0XHRcdFx0Y29uc3Qgc2FtcGxlciA9IG5ldyBBbmltYXRpb25TYW1wbGVyKCk7XHJcblx0XHRcdFx0c2FtcGxlci5mb3JtR2x0Zih0aGlzLCBnbHRmU2FtcGxlcik7XHJcblx0XHRcdFx0cmV0dXJuIHNhbXBsZXI7XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRjb25zdCBjaGFubmVscyA9IGdsdGZBbmltYXRpb24/LmNoYW5uZWxzPy5tYXAoKGdsdGZDaGFubmVsKSA9PiB7XHJcblx0XHRcdFx0Y29uc3QgYW5pbWF0aW9uQ2hhbm5lbCA9IG5ldyBBbmltYXRpb25DaGFubmVsKCk7XHJcblx0XHRcdFx0YW5pbWF0aW9uQ2hhbm5lbC5zYW1wbGVyID0gc2FtcGxlcnNbZ2x0ZkNoYW5uZWwuc2FtcGxlcl07XHJcblx0XHRcdFx0YW5pbWF0aW9uQ2hhbm5lbC50YXJnZXQgPSBuZXcgQW5pbWF0aW9uQ2hhbm5lbFRhcmdldChcclxuXHRcdFx0XHRcdHRoaXMubm9kZXNbZ2x0ZkNoYW5uZWwudGFyZ2V0Lm5vZGVdLFxyXG5cdFx0XHRcdFx0Z2x0ZkNoYW5uZWwudGFyZ2V0LnBhdGhcclxuXHRcdFx0XHQpO1xyXG5cdFx0XHRcdHJldHVybiBhbmltYXRpb25DaGFubmVsO1xyXG5cdFx0XHR9KTtcclxuXHRcdFx0Y29uc3QgYW5pbWF0aW9uID0gbmV3IEFuaW1hdGlvbihpbmRleC50b1N0cmluZygpLCBzYW1wbGVycywgY2hhbm5lbHMpO1xyXG5cdFx0XHRyZXR1cm4gYW5pbWF0aW9uO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cdHByaXZhdGUgcGFyc2VNZXNocygpIHtcclxuXHRcdHRoaXMubWVzaGVzID0gdGhpcz8uanNvbj8ubWVzaGVzPy5tYXA/LigoZ2x0Zm1lc2gpID0+IHtcclxuXHRcdFx0cmV0dXJuIHtcclxuXHRcdFx0XHRuYW1lOiBnbHRmbWVzaC5uYW1lLFxyXG5cdFx0XHRcdHByaW1pdGl2ZXM6IGdsdGZtZXNoPy5wcmltaXRpdmVzPy5tYXA/LigocHJpbWl0aXZlKSA9PiB7XHJcblx0XHRcdFx0XHRjb25zdCBtYXRlcmlhbCA9XHJcblx0XHRcdFx0XHRcdHByaW1pdGl2ZS5tYXRlcmlhbCAhPT0gdW5kZWZpbmVkXHJcblx0XHRcdFx0XHRcdFx0PyB0aGlzLm1hdGVyaWFsc1twcmltaXRpdmUubWF0ZXJpYWxdXHJcblx0XHRcdFx0XHRcdFx0OiB7IHBick1ldGFsbGljUm91Z2huZXNzOiB7fSB9O1xyXG5cdFx0XHRcdFx0Y29uc3QgZ2VvID0gdGhpcy5jcmVhdGVHZW9tZXRyeShwcmltaXRpdmUsIG1hdGVyaWFsKTtcclxuXHRcdFx0XHRcdGNvbnN0IG1lc2ggPSBuZXcgTWVzaChnZW8sIG1hdGVyaWFsKTtcclxuXHRcdFx0XHRcdG1lc2gubmFtZSA9IGdsdGZtZXNoLm5hbWU7XHJcblx0XHRcdFx0XHRyZXR1cm4gbWVzaDtcclxuXHRcdFx0XHR9KVxyXG5cdFx0XHR9O1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cdHByaXZhdGUgZ2V0U2FtcGxlcihzYW1wbGVySnNvbjogYW55KSB7XHJcblx0XHRyZXR1cm4gbmV3IFNhbXBsZXIoe1xyXG5cdFx0XHRtYWdGaWx0ZXI6IGdsdGZFbnVtW3NhbXBsZXJKc29uLm1hZ0ZpbHRlciB8fCA5NzI5XSBhcyBHUFVGaWx0ZXJNb2RlLFxyXG5cdFx0XHRtaW5GaWx0ZXI6IGdsdGZFbnVtW3NhbXBsZXJKc29uLm1pbkZpbHRlciB8fCA5NzI5XSBhcyBHUFVGaWx0ZXJNb2RlLFxyXG5cdFx0XHRhZGRyZXNzTW9kZVU6IGdsdGZFbnVtW3NhbXBsZXJKc29uLndyYXBTIHx8IDEwNDk3XSBhcyBHUFVBZGRyZXNzTW9kZSxcclxuXHRcdFx0YWRkcmVzc01vZGVWOiBnbHRmRW51bVtzYW1wbGVySnNvbi53cmFwVCB8fCAxMDQ5N10gYXMgR1BVQWRkcmVzc01vZGVcclxuXHRcdH0pO1xyXG5cdH1cclxuXHRwcml2YXRlIGdldEJ1ZmZlclZpZXcoYWNjZXNzb3I6IGFueSwgbjogbnVtYmVyKSB7XHJcblx0XHRjb25zdCBidWZmZXJWaWV3ID0gdGhpcy5idWZmZXJWaWV3c1thY2Nlc3Nvci5idWZmZXJWaWV3XTtcclxuXHRcdGNvbnN0IG9mZnNldCA9IChidWZmZXJWaWV3LmJ5dGVPZmZzZXQgfHwgMCkgKyAoYWNjZXNzb3IuYnl0ZU9mZnNldCB8fCAwKTtcclxuXHRcdGNvbnN0IHN0cmlkZSA9IE1hdGgubWF4KGJ1ZmZlclZpZXcuYnl0ZVN0cmlkZSAvIDQgfHwgMCwgbik7XHJcblx0XHRsZXQgYXJyYXkgPSBuZXdUeXBlZEFycmF5KFxyXG5cdFx0XHRhY2Nlc3Nvci5jb21wb25lbnRUeXBlLFxyXG5cdFx0XHR0aGlzLmJ1ZmZlcnNbYnVmZmVyVmlldy5idWZmZXJdLFxyXG5cdFx0XHRidWZmZXJWaWV3LmJ1ZmZlciA9PT0gMCA/IG9mZnNldCArIHRoaXMuZ2xiT2Zmc2V0IDogb2Zmc2V0LFxyXG5cdFx0XHQoYWNjZXNzb3IuY291bnQgLSAxKSAqIHN0cmlkZSArIG5cclxuXHRcdCk7XHJcblx0XHRpZiAoc3RyaWRlID4gbikge1xyXG5cdFx0XHRjb25zdCBUeXBlZEFycmF5Q29uc3RydWN0b3IgPSBhcnJheS5jb25zdHJ1Y3RvciBhcyB7XHJcblx0XHRcdFx0bmV3ICguLi5hcmdzOiBhbnkpOiBUeXBlZEFycmF5O1xyXG5cdFx0XHR9O1xyXG5cdFx0XHRjb25zdCBzdHJpZGVkID0gbmV3IFR5cGVkQXJyYXlDb25zdHJ1Y3RvcihhY2Nlc3Nvci5jb3VudCAqIG4pO1xyXG5cdFx0XHRmb3IgKGxldCBpID0gMCwgaiA9IDA7IGkgPCBzdHJpZGVkLmxlbmd0aDsgaSArPSBuLCBqICs9IHN0cmlkZSkge1xyXG5cdFx0XHRcdGZvciAobGV0IGsgPSAwOyBrIDwgbjsgayArPSAxKSB7XHJcblx0XHRcdFx0XHRzdHJpZGVkW2kgKyBrXSA9IGFycmF5W2ogKyBrXTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0YXJyYXkgPSBzdHJpZGVkO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGFycmF5O1xyXG5cdH1cclxuXHRwcml2YXRlIGNyZWF0ZUdlb21ldHJ5KHByaW1pdGl2ZSwgbWF0ZXJpYWwpIHtcclxuXHRcdGxldCBpbmRpY2VzID0gbnVsbDtcclxuXHRcdGxldCBhY2Nlc3NvciA9IG51bGw7XHJcblx0XHRjb25zdCBkZWZpbmVzOiB7IFtwcm9wOiBzdHJpbmddOiBib29sZWFuIHwgbnVtYmVyIH0gPSB7IEhBU19OT1JNQUw6IHRydWUgfTtcclxuXHRcdGxldCB2ZXJ0ZXhDb3VudDtcclxuXHRcdGFjY2Vzc29yID0gdGhpcy5nZXRBY2Nlc3NvcihwcmltaXRpdmUuYXR0cmlidXRlcy5QT1NJVElPTik7XHJcblx0XHRjb25zdCBwb3NpdGlvbnMgPSBhY2Nlc3Nvci5nZXRBcnJheSgpO1xyXG5cdFx0dmVydGV4Q291bnQgPSBhY2Nlc3Nvci5jb3VudDtcclxuXHRcdC8vIGNvbnN0IHsgbWF4LCBtaW4gfSA9IGFjY2Vzc29yO1xyXG5cdFx0Ly8gY29uc3QgYm91bmRpbmdCb3ggPSB7IG1heCwgbWluIH07XHJcblx0XHRpZiAocHJpbWl0aXZlLmluZGljZXMgIT09IHVuZGVmaW5lZCkge1xyXG5cdFx0XHRhY2Nlc3NvciA9IHRoaXMuZ2V0QWNjZXNzb3IocHJpbWl0aXZlLmluZGljZXMpO1xyXG5cdFx0XHRpbmRpY2VzID0gdG9JbmRpY2VzKGFjY2Vzc29yLmdldEFycmF5KCkpO1xyXG5cdFx0XHR2ZXJ0ZXhDb3VudCA9IGFjY2Vzc29yLmNvdW50O1xyXG5cdFx0fVxyXG5cdFx0bGV0IG5vcm1hbHM7XHJcblxyXG5cdFx0aWYgKHByaW1pdGl2ZS5hdHRyaWJ1dGVzLk5PUk1BTCAhPT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdGFjY2Vzc29yID0gdGhpcy5nZXRBY2Nlc3NvcihwcmltaXRpdmUuYXR0cmlidXRlcy5OT1JNQUwpO1xyXG5cdFx0XHRub3JtYWxzID0gYWNjZXNzb3IuZ2V0QXJyYXkoKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdG5vcm1hbHMgPSBnZW5lcmF0ZU5vcm1hbHMoaW5kaWNlcywgcG9zaXRpb25zKTtcclxuXHRcdH1cclxuXHJcblx0XHRsZXQgdXZzID0gbnVsbDtcclxuXHRcdGlmIChwcmltaXRpdmUuYXR0cmlidXRlcy5URVhDT09SRF8wICE9PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0YWNjZXNzb3IgPSB0aGlzLmdldEFjY2Vzc29yKHByaW1pdGl2ZS5hdHRyaWJ1dGVzLlRFWENPT1JEXzApO1xyXG5cdFx0XHR1dnMgPSBhY2Nlc3Nvci5nZXRBcnJheSgpO1xyXG5cdFx0XHRkZWZpbmVzLkhBU19VViA9IHRydWU7XHJcblx0XHR9XHJcblx0XHRsZXQgdXYxcyA9IG51bGw7XHJcblx0XHRpZiAocHJpbWl0aXZlLmF0dHJpYnV0ZXMuVEVYQ09PUkRfMSAhPT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdGFjY2Vzc29yID0gdGhpcy5nZXRBY2Nlc3NvcihwcmltaXRpdmUuYXR0cmlidXRlcy5URVhDT09SRF8xKTtcclxuXHRcdFx0dXYxcyA9IGFjY2Vzc29yLmdldEFycmF5KCk7XHJcblx0XHRcdGRlZmluZXMuSEFTX1VWMSA9IHRydWU7XHJcblx0XHR9XHJcblxyXG5cdFx0bGV0IHRhbmdlbnRzID0gbnVsbDtcclxuXHRcdGlmIChwcmltaXRpdmUuYXR0cmlidXRlcy5UQU5HRU5UICE9PSB1bmRlZmluZWQgJiYgcHJpbWl0aXZlLmF0dHJpYnV0ZXMuTk9STUFMICE9PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0YWNjZXNzb3IgPSB0aGlzLmdldEFjY2Vzc29yKHByaW1pdGl2ZS5hdHRyaWJ1dGVzLlRBTkdFTlQpO1xyXG5cdFx0XHR0YW5nZW50cyA9IGFjY2Vzc29yLmdldEFycmF5KCk7XHJcblx0XHRcdC8vIGRlZmluZXMuSEFTX1RBTkdFTlQgPSB0cnVlO1xyXG5cdFx0fSBlbHNlIGlmIChtYXRlcmlhbC5ub3JtYWxUZXh0dXJlKSB7XHJcblx0XHRcdC8vIHRhbmdlbnRzID0gZ2VuZXJhdGVUYW5nZW50cyhpbmRpY2VzLCBwb3NpdGlvbnMsIG5vcm1hbHMsIHV2cyEpO1xyXG5cdFx0fVxyXG5cdFx0bGV0IGNvbG9ycyA9IG51bGwsXHJcblx0XHRcdGNvbG9yU2l6ZSA9IDM7XHJcblx0XHRpZiAocHJpbWl0aXZlLmF0dHJpYnV0ZXMuQ09MT1JfMCAhPT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdGFjY2Vzc29yID0gdGhpcy5hY2Nlc3NvcnNbcHJpbWl0aXZlLmF0dHJpYnV0ZXMuQ09MT1JfMF07XHJcblx0XHRcdGNvbG9ycyA9IGFjY2Vzc29yLmdldEFycmF5KCk7XHJcblx0XHRcdGNvbG9yU2l6ZSA9IGFjY2Vzc29yLnR5cGU7XHJcblx0XHRcdGRlZmluZXMuSEFTX0NPTE9SID0gdHJ1ZTtcclxuXHRcdH1cclxuXHRcdGxldCBqb2ludHMgPSBudWxsO1xyXG5cdFx0aWYgKHByaW1pdGl2ZS5hdHRyaWJ1dGVzLkpPSU5UU18wICE9PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0YWNjZXNzb3IgPSB0aGlzLmdldEFjY2Vzc29yKHByaW1pdGl2ZS5hdHRyaWJ1dGVzLkpPSU5UU18wKTtcclxuXHRcdFx0am9pbnRzID0gYWNjZXNzb3IuZ2V0QXJyYXkoKTtcclxuXHRcdFx0ZGVmaW5lcy5IQVNfU0tJTiA9IHRydWU7XHJcblx0XHR9XHJcblx0XHRsZXQgd2VpZ2h0cyA9IG51bGw7XHJcblx0XHRpZiAocHJpbWl0aXZlLmF0dHJpYnV0ZXMuV0VJR0hUU18wICE9PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0YWNjZXNzb3IgPSB0aGlzLmdldEFjY2Vzc29yKHByaW1pdGl2ZS5hdHRyaWJ1dGVzLldFSUdIVFNfMCk7XHJcblx0XHRcdHdlaWdodHMgPSBhY2Nlc3Nvci5nZXRBcnJheSgpO1xyXG5cdFx0fVxyXG5cdFx0Y29uc3QgZ2VvID0gbmV3IEdlb21ldHJ5KHsgdHlwZTogXCJwYnJHZW9tdHJ5XCIgfSk7XHJcblx0XHRpZiAoaW5kaWNlcykgZ2VvLnNldEluZGljZShBcnJheS5mcm9tKGluZGljZXMpKTtcclxuXHRcdGlmIChwb3NpdGlvbnMpIGdlby5zZXRBdHRyaWJ1dGUobmV3IEZsb2F0MzJBdHRyaWJ1dGUoXCJwb3NpdGlvblwiLCBBcnJheS5mcm9tKHBvc2l0aW9ucyksIDMpKTtcclxuXHRcdGlmIChub3JtYWxzKSBnZW8uc2V0QXR0cmlidXRlKG5ldyBGbG9hdDMyQXR0cmlidXRlKFwibm9ybWFsXCIsIEFycmF5LmZyb20obm9ybWFscyksIDMpKTtcclxuXHRcdGlmIChjb2xvcnMpIGdlby5zZXRBdHRyaWJ1dGUobmV3IEZsb2F0MzJBdHRyaWJ1dGUoXCJjb2xvclwiLCBBcnJheS5mcm9tKGNvbG9ycyksIGNvbG9yU2l6ZSkpO1xyXG5cdFx0aWYgKHV2cykgZ2VvLnNldEF0dHJpYnV0ZShuZXcgRmxvYXQzMkF0dHJpYnV0ZShcInV2XCIsIEFycmF5LmZyb20odXZzKSwgMikpO1xyXG5cdFx0aWYgKGpvaW50cykgZ2VvLnNldEF0dHJpYnV0ZShuZXcgRmxvYXQzMkF0dHJpYnV0ZShcImpvaW50MFwiLCBBcnJheS5mcm9tKGpvaW50cyksIDQpKTtcclxuXHRcdGlmICh3ZWlnaHRzKSBnZW8uc2V0QXR0cmlidXRlKG5ldyBGbG9hdDMyQXR0cmlidXRlKFwid2VpZ2h0MFwiLCBBcnJheS5mcm9tKHdlaWdodHMpLCA0KSk7XHJcblx0XHRnZW8uZGVmaW5lcyA9IGRlZmluZXM7XHJcblx0XHRnZW8uY29tcHV0ZUJvdW5kaW5nU3BoZXJlKEFycmF5LmZyb20ocG9zaXRpb25zKSk7XHJcblx0XHRnZW8uY291bnQgPSB2ZXJ0ZXhDb3VudDtcclxuXHRcdHJldHVybiBnZW87XHJcblx0fVxyXG5cdHByaXZhdGUgY3JlYXRlVGV4dHVyZShzb3VyY2U6IG51bWJlcikge1xyXG5cdFx0cmV0dXJuIG5ldyBUZXh0dXJlKHtcclxuXHRcdFx0c2l6ZToge1xyXG5cdFx0XHRcdHdpZHRoOiB0aGlzLmltYWdlc1tzb3VyY2VdLndpZHRoLFxyXG5cdFx0XHRcdGhlaWdodDogdGhpcy5pbWFnZXNbc291cmNlXS5oZWlnaHQsXHJcblx0XHRcdFx0ZGVwdGg6IDFcclxuXHRcdFx0fSxcclxuXHRcdFx0ZGF0YToge1xyXG5cdFx0XHRcdHNvdXJjZTogdGhpcy5pbWFnZXNbc291cmNlXVxyXG5cdFx0XHR9LFxyXG5cdFx0XHRmb3JtYXQ6IFwicmdiYTh1bm9ybVwiLFxyXG5cdFx0XHR1c2FnZTogR1BVVGV4dHVyZVVzYWdlLlRFWFRVUkVfQklORElORyB8IEdQVVRleHR1cmVVc2FnZS5DT1BZX0RTVCB8IEdQVVRleHR1cmVVc2FnZS5SRU5ERVJfQVRUQUNITUVOVFxyXG5cdFx0fSk7XHJcblx0fVxyXG5cdHByaXZhdGUgYXN5bmMgbG9hZEltYWdlcygpIHtcclxuXHRcdGNvbnN0IGltYWdlczogQXJyYXk8SW1hZ2VCaXRtYXA+ID0gW107XHJcblx0XHRsZXQgbG9hZEV4dGVybmFsSW1hZ2VzOiBQcm9taXNlPGFueT4gPSBQcm9taXNlLnJlc29sdmUoKTtcclxuXHRcdGlmICh0aGlzLmpzb24uaW1hZ2VzKSB7XHJcblx0XHRcdGxvYWRFeHRlcm5hbEltYWdlcyA9IFByb21pc2UuYWxsKFxyXG5cdFx0XHRcdHRoaXMuanNvbi5pbWFnZXMubWFwKGFzeW5jIChpbWFnZTogYW55LCBpbmRleDogbnVtYmVyKSA9PiB7XHJcblx0XHRcdFx0XHRpZiAoaW1hZ2UudXJpKSB7XHJcblx0XHRcdFx0XHRcdGNvbnN0IGltYWdlVXJsID0gaW1hZ2UudXJpLnNsaWNlKDAsIDUpID09PSBcImRhdGE6XCIgPyBpbWFnZS51cmkgOiBgJHt0aGlzLnJvb3RVcmx9LyR7aW1hZ2UudXJpfWA7XHJcblx0XHRcdFx0XHRcdGltYWdlc1tpbmRleF0gPSBhd2FpdCBmZXRjaChpbWFnZVVybClcclxuXHRcdFx0XHRcdFx0XHQudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJsb2IoKSlcclxuXHRcdFx0XHRcdFx0XHQudGhlbigoYmxvYikgPT5cclxuXHRcdFx0XHRcdFx0XHRcdGNyZWF0ZUltYWdlQml0bWFwKGJsb2IsIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0Y29sb3JTcGFjZUNvbnZlcnNpb246IFwibm9uZVwiXHJcblx0XHRcdFx0XHRcdFx0XHR9KVxyXG5cdFx0XHRcdFx0XHRcdCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHRcdH1cclxuXHRcdGxldCBsb2FkSW50ZXJuYWxJbWFnZXM6IFByb21pc2U8YW55PiA9IFByb21pc2UucmVzb2x2ZSgpO1xyXG5cdFx0aWYgKHRoaXMuanNvbi5pbWFnZXMpIHtcclxuXHRcdFx0bG9hZEludGVybmFsSW1hZ2VzID0gUHJvbWlzZS5hbGwoXHJcblx0XHRcdFx0dGhpcy5qc29uLmltYWdlcy5tYXAoYXN5bmMgKGltYWdlOiBhbnksIGluZGV4OiBudW1iZXIpID0+IHtcclxuXHRcdFx0XHRcdGlmIChpbWFnZS5idWZmZXJWaWV3ICE9PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0XHRcdFx0Y29uc3QgeyBidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGggfSA9IHRoaXMuanNvbi5idWZmZXJWaWV3c1tpbWFnZS5idWZmZXJWaWV3XTtcclxuXHRcdFx0XHRcdFx0Y29uc3QgYXJyYXkgPSBuZXcgVWludDhBcnJheShcclxuXHRcdFx0XHRcdFx0XHR0aGlzLmJ1ZmZlcnNbYnVmZmVyXSxcclxuXHRcdFx0XHRcdFx0XHRidWZmZXIgPT09IDAgPyBieXRlT2Zmc2V0ICsgdGhpcy5nbGJPZmZzZXQgOiBieXRlT2Zmc2V0LFxyXG5cdFx0XHRcdFx0XHRcdGJ5dGVMZW5ndGhcclxuXHRcdFx0XHRcdFx0KTtcclxuXHRcdFx0XHRcdFx0bGV0IHR5cGU7XHJcblx0XHRcdFx0XHRcdGlmIChpbWFnZS5taW1lVHlwZSkge1xyXG5cdFx0XHRcdFx0XHRcdHR5cGUgPSBpbWFnZS5taW1lVHlwZTtcclxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHR0eXBlID0gYXJyYXlbMF0gPT09IDB4ZmYgPyBcImltYWdlL2pwZWdcIiA6IFwiaW1hZ2UvcG5nXCI7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0Y29uc3QgYmxvYiA9IG5ldyBCbG9iKFthcnJheV0sIHsgdHlwZSB9KTtcclxuXHRcdFx0XHRcdFx0aW1hZ2VzW2luZGV4XSA9IGF3YWl0IGNyZWF0ZUltYWdlQml0bWFwKGJsb2IsIHtcclxuXHRcdFx0XHRcdFx0XHRjb2xvclNwYWNlQ29udmVyc2lvbjogXCJub25lXCJcclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0XHRhd2FpdCBQcm9taXNlLmFsbChbbG9hZEV4dGVybmFsSW1hZ2VzLCBsb2FkSW50ZXJuYWxJbWFnZXNdKTtcclxuXHRcdHJldHVybiBpbWFnZXM7XHJcblx0fVxyXG5cdHByaXZhdGUgYXN5bmMgbG9hZEJ1ZmZlcygpIHtcclxuXHRcdGNvbnN0IGJ1ZmZlcnM6IEFycmF5PEFycmF5QnVmZmVyPiA9IFtdO1xyXG5cdFx0YXdhaXQgUHJvbWlzZS5hbGwoXHJcblx0XHRcdHRoaXMuanNvbi5idWZmZXJzLm1hcCgoYnVmZmVyOiBhbnksIGluZGV4OiBudW1iZXIpID0+IHtcclxuXHRcdFx0XHRpZiAoIWJ1ZmZlci51cmkpIHtcclxuXHRcdFx0XHRcdGlmIChpbmRleCAhPT0gMCkge1xyXG5cdFx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJidWZmZXIgdXJpIHVuZGVmaW5lZFwiKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGJ1ZmZlcnNbaW5kZXhdID0gdGhpcy5nbGJCaW4hO1xyXG5cdFx0XHRcdFx0cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRjb25zdCBidWZmZXJVcmwgPSBidWZmZXIudXJpLnNsaWNlKDAsIDUpID09PSBcImRhdGE6XCIgPyBidWZmZXIudXJpIDogYCR7dGhpcy5yb290VXJsfS8ke2J1ZmZlci51cml9YDtcclxuXHRcdFx0XHRyZXR1cm4gZmV0Y2goYnVmZmVyVXJsKVxyXG5cdFx0XHRcdFx0LnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5hcnJheUJ1ZmZlcigpKVxyXG5cdFx0XHRcdFx0LnRoZW4oKGFycmF5QnVmZmVyOiBBcnJheUJ1ZmZlcikgPT4ge1xyXG5cdFx0XHRcdFx0XHRidWZmZXJzW2luZGV4XSA9IGFycmF5QnVmZmVyO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdH0pXHJcblx0XHQpO1xyXG5cdFx0cmV0dXJuIGJ1ZmZlcnM7XHJcblx0fVxyXG5cdHByaXZhdGUgcGFyc2VOb2RlcygpIHtcclxuXHRcdHRoaXMubm9kZXMgPSB0aGlzPy5qc29uPy5ub2Rlcz8ubWFwKChnbHRmTm9kZSkgPT4ge1xyXG5cdFx0XHRjb25zdCBub2RlID0gbmV3IE5vZGUoKTtcclxuXHRcdFx0dGhpcy5wYXJzZU5vZGVUUlMobm9kZSwgZ2x0Zk5vZGUpO1xyXG5cdFx0XHRpZiAoZ2x0Zk5vZGUubmFtZSkgbm9kZS5uYW1lID0gZ2x0Zk5vZGUubmFtZTtcclxuXHRcdFx0aWYgKGdsdGZOb2RlLm1lc2ggIT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdFx0bGV0IGdsdGZTa2luID0gdW5kZWZpbmVkLFxyXG5cdFx0XHRcdFx0aXNTa2luTWVzaCA9IGZhbHNlO1xyXG5cdFx0XHRcdGlmIChnbHRmTm9kZS5za2luICE9IHVuZGVmaW5lZCkge1xyXG5cdFx0XHRcdFx0Z2x0ZlNraW4gPSB0aGlzLmpzb24uc2tpbnNbZ2x0Zk5vZGUuc2tpbl07XHJcblx0XHRcdFx0XHRpc1NraW5NZXNoID0gdHJ1ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0dGhpcy5tZXNoZXNbZ2x0Zk5vZGUubWVzaF0ucHJpbWl0aXZlcy5mb3JFYWNoKChwcmltaXRpdmU6IE1lc2gsIGluZGV4OiBudW1iZXIsIHNvdXJjZTogQXJyYXk8TWVzaD4pID0+IHtcclxuXHRcdFx0XHRcdGNvbnN0IHRlbXBQcmltaXRpdmUgPVxyXG5cdFx0XHRcdFx0XHRpc1NraW5NZXNoICYmIHByaW1pdGl2ZS50eXBlID09IFJlbmRlck9iamVjdFR5cGUuTWVzaFxyXG5cdFx0XHRcdFx0XHRcdD8gbmV3IFNLaW5NZXNoKHByaW1pdGl2ZS5nZW9tZXRyeSwgcHJpbWl0aXZlLm1hdGVyaWFsKVxyXG5cdFx0XHRcdFx0XHRcdDogcHJpbWl0aXZlO1xyXG5cdFx0XHRcdFx0aWYgKGlzU2tpbk1lc2ggJiYgcHJpbWl0aXZlLnR5cGUgPT0gUmVuZGVyT2JqZWN0VHlwZS5NZXNoKSB7XHJcblx0XHRcdFx0XHRcdHNvdXJjZVtpbmRleF0gPSB0ZW1wUHJpbWl0aXZlO1xyXG5cdFx0XHRcdFx0XHR0ZW1wUHJpbWl0aXZlLnNldFNraW5EYXRhKHtcclxuXHRcdFx0XHRcdFx0XHRpbnZlcnNlQmluZE1hdHJpY2VzOiB0aGlzLmdldEFjY2Vzc29yKGdsdGZTa2luLmludmVyc2VCaW5kTWF0cmljZXMpLmdldE1hdDRBcnJheSgpLFxyXG5cdFx0XHRcdFx0XHRcdGpvaW50czogZ2x0ZlNraW4uam9pbnRzXHJcblx0XHRcdFx0XHRcdFx0Ly8gbmFtZTogZ2x0ZlNraW4ubmFtZSxcclxuXHRcdFx0XHRcdFx0XHQvLyBza2VsZXRvbjogZ2x0ZlNraW4uc2tlbGV0b25cclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRub2RlLmFkZCh0ZW1wUHJpbWl0aXZlKTtcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gbm9kZTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHRwcml2YXRlIHBhcnNlTm9kZVRSUyhub2RlOiBOb2RlLCBnbHRmTm9kZTogR0xURk5vZGVQYXJtcyk6IE5vZGUge1xyXG5cdFx0bGV0IHsgbWF0cml4LCByb3RhdGlvbiwgdHJhbnNsYXRpb24sIHNjYWxlIH0gPSBnbHRmTm9kZTtcclxuXHRcdGlmIChtYXRyaXgpIHtcclxuXHRcdFx0Y29uc3QgdGVtcE1hdHJpeDQgPSBuZXcgTWF0cml4NCgpLFxyXG5cdFx0XHRcdHRlbXBTY2FsZSA9IG5ldyBWZWN0b3IzKCksXHJcblx0XHRcdFx0dGVtcFRyYW5zbGF0aW9uID0gbmV3IFZlY3RvcjMoKSxcclxuXHRcdFx0XHR0ZW1wUm90YXRpb24gPSBuZXcgUXVhdGVybmlvbigpO1xyXG5cdFx0XHRNYXRyaXg0LmZyb21Db2x1bW5NYWpvckFycmF5KG1hdHJpeCwgdGVtcE1hdHJpeDQpO1xyXG5cdFx0XHRNYXRyaXg0LmdldFNjYWxlKHRlbXBNYXRyaXg0LCB0ZW1wU2NhbGUpO1xyXG5cdFx0XHRNYXRyaXg0LmdldFRyYW5zbGF0aW9uKHRlbXBNYXRyaXg0LCB0ZW1wVHJhbnNsYXRpb24pO1xyXG5cdFx0XHRNYXRyaXg0LmdldFJvdGF0aW9uKHRlbXBNYXRyaXg0LCB0ZW1wUm90YXRpb24pO1xyXG5cdFx0XHRyb3RhdGlvbiA9IHRlbXBSb3RhdGlvbi50b0FycmF5KCk7XHJcblx0XHRcdHRyYW5zbGF0aW9uID0gdGVtcFRyYW5zbGF0aW9uLnRvQXJyYXkoKTtcclxuXHRcdFx0c2NhbGUgPSB0ZW1wU2NhbGUudG9BcnJheSgpO1xyXG5cdFx0fVxyXG5cdFx0aWYgKHJvdGF0aW9uKSBub2RlLnF1YXRlcm5pb24uc2V0KHJvdGF0aW9uWzBdLCByb3RhdGlvblsxXSwgcm90YXRpb25bMl0sIHJvdGF0aW9uWzNdKTtcclxuXHRcdGlmICh0cmFuc2xhdGlvbikgbm9kZS5wb3NpdGlvbi5zZXQodHJhbnNsYXRpb25bMF0sIHRyYW5zbGF0aW9uWzFdLCB0cmFuc2xhdGlvblsyXSk7XHJcblx0XHRpZiAoc2NhbGUpIG5vZGUuc2NhbGUuc2V0KHNjYWxlWzBdLCBzY2FsZVsxXSwgc2NhbGVbMl0pO1xyXG5cdFx0cmV0dXJuIG5vZGU7XHJcblx0fVxyXG5cdHByaXZhdGUgbm9ybWFsaXplRGF0YSgpIHtcclxuXHRcdHRoaXM/Lm5vZGVzPy5tYXA/Ligobm9kZTogTm9kZSwgaW5kZXgpID0+IHtcclxuXHRcdFx0dGhpcy5qc29uPy5ub2Rlc1tpbmRleF0/LmNoaWxkcmVuPy5tYXAoKG5vZGVJZDogbnVtYmVyKSA9PiB7XHJcblx0XHRcdFx0Y29uc3QgY2hpbGROb2RlID0gdGhpcy5ub2Rlc1tub2RlSWRdO1xyXG5cdFx0XHRcdG5vZGUuYWRkKGNoaWxkTm9kZSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblx0XHR0aGlzLm1lc2hlcy5tYXAoKG1lc2gpID0+IHtcclxuXHRcdFx0bWVzaC5wcmltaXRpdmVzLm1hcCgocHJpbWl0aXZlKSA9PiB7XHJcblx0XHRcdFx0aWYgKHByaW1pdGl2ZS50eXBlID09IFJlbmRlck9iamVjdFR5cGUuU2tpbk1lc2gpXHJcblx0XHRcdFx0XHRwcmltaXRpdmUuam9pbnRzID0gcHJpbWl0aXZlLmpvaW50cy5tYXAoKGpvaW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdHJldHVybiB0aGlzLm5vZGVzWzxudW1iZXI+am9pbnRdO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblx0fVxyXG59XHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2FkR0xURih1cmw6IHN0cmluZykge1xyXG5cdGxldCBnbHRmO1xyXG5cdGNvbnN0IGV4dCA9IHVybC5zcGxpdChcIi5cIikucG9wKCk7XHJcblx0Y29uc3Qgcm9vdFVybCA9IHVybC5zdWJzdHJpbmcoMCwgdXJsLmxhc3RJbmRleE9mKFwiL1wiKSk7XHJcblx0aWYgKGV4dCA9PT0gXCJnbHRmXCIpIHtcclxuXHRcdGNvbnN0IGpzb24gPSBhd2FpdCBmZXRjaCh1cmwpLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5qc29uKCkpO1xyXG5cdFx0Z2x0ZiA9IG5ldyBHTFRGKGpzb24sIHJvb3RVcmwsIDApO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRjb25zdCBnbGIgPSBhd2FpdCBmZXRjaCh1cmwpLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5hcnJheUJ1ZmZlcigpKTtcclxuXHRcdGNvbnN0IGpzb25MZW5ndGggPSBuZXcgVWludDMyQXJyYXkoZ2xiLCAxMiwgMSlbMF07XHJcblx0XHRjb25zdCBqc29uQ2h1bmsgPSBuZXcgVWludDhBcnJheShnbGIsIDIwLCBqc29uTGVuZ3RoKTtcclxuXHRcdGNvbnN0IGpzb24gPSBKU09OLnBhcnNlKG5ldyBUZXh0RGVjb2RlcihcInV0Zi04XCIpLmRlY29kZShqc29uQ2h1bmspKTtcclxuXHRcdGdsdGYgPSBuZXcgR0xURihqc29uLCByb290VXJsLCAyOCArIGpzb25MZW5ndGgsIGdsYik7XHJcblx0fVxyXG5cdGF3YWl0IGdsdGYucGFyc2VEYXRhKCk7XHJcblx0cmV0dXJuIGdsdGY7XHJcbn1cclxudHlwZSBHTFRGTm9kZVBhcm1zID0ge1xyXG5cdGNoaWxkcmVuPzogbnVtYmVyW107XHJcblx0bWF0cml4PzogbnVtYmVyW107XHJcblx0c2NhbGU/OiBudW1iZXJbXTtcclxuXHRyb3RhdGlvbj86IG51bWJlcltdO1xyXG5cdHRyYW5zbGF0aW9uPzogbnVtYmVyW107XHJcbn07XHJcbiIsImltcG9ydCBUZXh0dXJlIGZyb20gXCIuLi9yZW5kZXIvVGV4dHVyZVwiO1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9hZFBiclRleHR1cmUoYnJkZiwgZGlmZnVzZSwgc3BlY3VsYXIpIHtcclxuXHRpZiAoIWJyZGYpIHJldHVybjtcclxuXHRjb25zdCBicmRmVGV4dHVyZSA9IGF3YWl0IGxvYWRUZXh0dXJlKGJyZGYpO1xyXG5cdGNvbnN0IGRpZmZ1c2VUZXh0dXJlID0gYXdhaXQgbG9hZEN1YmVUZXh0dXJlKGRpZmZ1c2UpO1xyXG5cdGNvbnN0IHNwZWN1bGFyVGV4dHVyZSA9IGF3YWl0IGxvYWRDdWJlVGV4dHVyZShzcGVjdWxhcik7XHJcblx0cmV0dXJuIHtcclxuXHRcdGJyZGZUZXh0dXJlLFxyXG5cdFx0ZGlmZnVzZVRleHR1cmUsXHJcblx0XHRzcGVjdWxhclRleHR1cmVcclxuXHR9O1xyXG59XHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2FkQ3ViZVRleHR1cmUodXJscykge1xyXG5cdGNvbnN0IHByb21pc2VzID0gdXJscy5tYXAoKHNyYykgPT4ge1xyXG5cdFx0Y29uc3QgaW1nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImltZ1wiKTtcclxuXHRcdGltZy5zcmMgPSBzcmM7XHJcblx0XHRyZXR1cm4gaW1nLmRlY29kZSgpLnRoZW4oKCkgPT4gY3JlYXRlSW1hZ2VCaXRtYXAoaW1nKSk7XHJcblx0fSk7XHJcblx0Y29uc3QgaW1hZ2VzID0gYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xyXG5cdGF3YWl0IFByb21pc2UuYWxsKGltYWdlcyk7XHJcblx0Y29uc3QgZGF0YSA9IGltYWdlcy5tYXAoKGltYWdlLCBpKSA9PiB7XHJcblx0XHRyZXR1cm4ge1xyXG5cdFx0XHRzb3VyY2U6IGltYWdlLFxyXG5cdFx0XHR3aWR0aDogaW1hZ2Uud2lkdGgsXHJcblx0XHRcdGhlaWdodDogaW1hZ2UuaGVpZ2h0LFxyXG5cdFx0XHRkZXB0aDogMSxcclxuXHRcdFx0eDogMCxcclxuXHRcdFx0eTogMCxcclxuXHRcdFx0ejogaVxyXG5cdFx0fTtcclxuXHR9KTtcclxuXHRyZXR1cm4gbmV3IFRleHR1cmUoe1xyXG5cdFx0c2l6ZToge1xyXG5cdFx0XHR3aWR0aDogaW1hZ2VzWzBdLndpZHRoLFxyXG5cdFx0XHRoZWlnaHQ6IGltYWdlc1swXS5oZWlnaHQsXHJcblx0XHRcdGRlcHRoOiA2XHJcblx0XHR9LFxyXG5cdFx0Zm9ybWF0OiBcInJnYmE4dW5vcm1cIixcclxuXHRcdHVzYWdlOiBHUFVUZXh0dXJlVXNhZ2UuVEVYVFVSRV9CSU5ESU5HIHwgR1BVVGV4dHVyZVVzYWdlLkNPUFlfRFNUIHwgR1BVVGV4dHVyZVVzYWdlLlJFTkRFUl9BVFRBQ0hNRU5ULFxyXG5cdFx0ZGF0YSxcclxuXHRcdHZpZXdGb3JtYXRzOiBcImN1YmVcIixcclxuXHRcdG1pcExldmVsQ291bnQ6IDYsXHJcblx0XHRuZWVkTWlwTWFwOiB0cnVlXHJcblx0fSk7XHJcbn1cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWRUZXh0dXJlKHVybCkge1xyXG5cdGNvbnN0IGltZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIik7XHJcblx0aW1nLnNyYyA9IHVybDtcclxuXHRhd2FpdCBpbWcuZGVjb2RlKCk7XHJcblx0Y29uc3QgaW1hZ2VCaXRtYXAgPSBhd2FpdCBjcmVhdGVJbWFnZUJpdG1hcChpbWcpO1xyXG5cdGNvbnN0IGJhc2VUZXh0dXJlID0gbmV3IFRleHR1cmUoe1xyXG5cdFx0c2l6ZTogeyB3aWR0aDogaW1hZ2VCaXRtYXAud2lkdGgsIGhlaWdodDogaW1hZ2VCaXRtYXAuaGVpZ2h0LCBkZXB0aDogMSB9LFxyXG5cdFx0ZGF0YToge1xyXG5cdFx0XHRzb3VyY2U6IGltYWdlQml0bWFwXHJcblx0XHR9LFxyXG5cdFx0Zm9ybWF0OiBcInJnYmE4dW5vcm1cIlxyXG5cdH0pO1xyXG5cdHJldHVybiBiYXNlVGV4dHVyZTtcclxufVxyXG4iLCJpbXBvcnQgR01hdGggZnJvbSBcIi4vTWF0aC5qc1wiO1xuaW1wb3J0IFZlY3RvcjMgZnJvbSBcIi4vVmVjdG9yMy5qc1wiO1xuLy8gZnJvbSB0aHJlZS5qc1xuY2xhc3MgU3BoZXJpY2FsIHtcblx0cmFkaXVzOiBudW1iZXI7XG5cdHBoaTogbnVtYmVyO1xuXHR0aGV0YTogbnVtYmVyO1xuXG5cdGNvbnN0cnVjdG9yKHJhZGl1cyA9IDEsIHBoaSA9IDAsIHRoZXRhID0gMCkge1xuXHRcdHRoaXMucmFkaXVzID0gcmFkaXVzO1xuXHRcdHRoaXMucGhpID0gcGhpOyAvLyBwb2xhciBhbmdsZVxuXHRcdHRoaXMudGhldGEgPSB0aGV0YTsgLy8gYXppbXV0aGFsIGFuZ2xlXG5cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXHRzZXQocmFkaXVzOiBudW1iZXIsIHBoaTogbnVtYmVyLCB0aGV0YTogbnVtYmVyKTogU3BoZXJpY2FsIHtcblx0XHR0aGlzLnJhZGl1cyA9IHJhZGl1cztcblx0XHR0aGlzLnBoaSA9IHBoaTtcblx0XHR0aGlzLnRoZXRhID0gdGhldGE7XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXHRjb3B5KG90aGVyOiBTcGhlcmljYWwpOiBTcGhlcmljYWwge1xuXHRcdHRoaXMucmFkaXVzID0gb3RoZXIucmFkaXVzO1xuXHRcdHRoaXMucGhpID0gb3RoZXIucGhpO1xuXHRcdHRoaXMudGhldGEgPSBvdGhlci50aGV0YTtcblxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cdC8vIHJlc3RyaWN0IHBoaSB0byBiZSBiZXR3ZWVuIEVQUyBhbmQgUEktRVBTXG5cdG1ha2VTYWZlKCk6IFNwaGVyaWNhbCB7XG5cdFx0Y29uc3QgRVBTID0gMC4wMDAwMDE7XG5cdFx0dGhpcy5waGkgPSBNYXRoLm1heChFUFMsIE1hdGgubWluKE1hdGguUEkgLSBFUFMsIHRoaXMucGhpKSk7XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdHNldEZyb21WZWN0b3IzKHY6IFZlY3RvcjMpOiBTcGhlcmljYWwge1xuXHRcdHJldHVybiB0aGlzLnNldEZyb21DYXJ0ZXNpYW5Db29yZHModi54LCB2LnksIHYueik7XG5cdH1cblx0c2V0RnJvbUNhcnRlc2lhbkNvb3Jkcyh4OiBudW1iZXIsIHk6IG51bWJlciwgejogbnVtYmVyKTogU3BoZXJpY2FsIHtcblx0XHR0aGlzLnJhZGl1cyA9IE1hdGguc3FydCh4ICogeCArIHkgKiB5ICsgeiAqIHopO1xuXG5cdFx0aWYgKHRoaXMucmFkaXVzID09PSAwKSB7XG5cdFx0XHR0aGlzLnRoZXRhID0gMDtcblx0XHRcdHRoaXMucGhpID0gMDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy50aGV0YSA9IE1hdGguYXRhbjIoeCwgeik7XG5cdFx0XHR0aGlzLnBoaSA9IE1hdGguYWNvcyhHTWF0aC5jbGFtcCh5IC8gdGhpcy5yYWRpdXMsIC0xLCAxKSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHRjbG9uZSgpOiBTcGhlcmljYWwge1xuXHRcdHJldHVybiBuZXcgU3BoZXJpY2FsKHRoaXMucmFkaXVzLCB0aGlzLnBoaSwgdGhpcy50aGV0YSk7XG5cdH1cbn1cblxuZXhwb3J0IHsgU3BoZXJpY2FsIH07XG4iLCJpbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tIFwiLi4vY29yZS9FdmVudERpc3BhdGNoZXJcIjtcclxuaW1wb3J0IHsgUXVhdGVybmlvbiB9IGZyb20gXCIuLi9tYXRoL1F1YXRlcm5pb25cIjtcclxuaW1wb3J0IHsgU3BoZXJpY2FsIH0gZnJvbSBcIi4uL21hdGgvU3BoZXJpY2FsXCI7XHJcbmltcG9ydCBWZWN0b3IyIGZyb20gXCIuLi9tYXRoL1ZlY3RvcjJcIjtcclxuaW1wb3J0IFZlY3RvcjMgZnJvbSBcIi4uL21hdGgvVmVjdG9yM1wiO1xyXG4vL2Zyb20gdGhyZWUuanNcclxuXHJcbmNvbnN0IF9jaGFuZ2VFdmVudCA9IHsgdHlwZTogXCJjaGFuZ2VcIiB9O1xyXG5jb25zdCBfc3RhcnRFdmVudCA9IHsgdHlwZTogXCJzdGFydFwiIH07XHJcbmNvbnN0IF9lbmRFdmVudCA9IHsgdHlwZTogXCJlbmRcIiB9O1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgT3JiaXRDb250cm9sIGV4dGVuZHMgRXZlbnREaXNwYXRjaGVyIHtcclxuICBkb21FbGVtZW50OiBhbnk7XHJcbiAgb2JqZWN0OiBhbnk7XHJcbiAgZW5hYmxlZDogYm9vbGVhbjtcclxuICB0YXJnZXQ6IGFueTtcclxuICBtaW5EaXN0YW5jZTogbnVtYmVyO1xyXG4gIG1heERpc3RhbmNlOiBudW1iZXI7XHJcbiAgbWluWm9vbTogbnVtYmVyO1xyXG4gIG1heFpvb206IG51bWJlcjtcclxuICBtaW5Qb2xhckFuZ2xlOiBudW1iZXI7XHJcbiAgbWF4UG9sYXJBbmdsZTogbnVtYmVyO1xyXG4gIG1pbkF6aW11dGhBbmdsZTogbnVtYmVyO1xyXG4gIG1heEF6aW11dGhBbmdsZTogbnVtYmVyO1xyXG4gIGVuYWJsZURhbXBpbmc6IGJvb2xlYW47XHJcbiAgZGFtcGluZ0ZhY3RvcjogbnVtYmVyO1xyXG4gIGVuYWJsZVpvb206IGJvb2xlYW47XHJcbiAgem9vbVNwZWVkOiBudW1iZXI7XHJcbiAgZW5hYmxlUm90YXRlOiBib29sZWFuO1xyXG4gIHJvdGF0ZVNwZWVkOiBudW1iZXI7XHJcbiAgZW5hYmxlUGFuOiBib29sZWFuO1xyXG4gIHBhblNwZWVkOiBudW1iZXI7XHJcbiAgc2NyZWVuU3BhY2VQYW5uaW5nOiBib29sZWFuO1xyXG4gIGtleVBhblNwZWVkOiBudW1iZXI7XHJcbiAgYXV0b1JvdGF0ZTogYm9vbGVhbjtcclxuICBhdXRvUm90YXRlU3BlZWQ6IG51bWJlcjtcclxuICBrZXlzOiB7IExFRlQ6IHN0cmluZzsgVVA6IHN0cmluZzsgUklHSFQ6IHN0cmluZzsgQk9UVE9NOiBzdHJpbmcgfTtcclxuICBtb3VzZUJ1dHRvbnM6IHsgTEVGVDogYW55OyBNSURETEU6IGFueTsgUklHSFQ6IGFueSB9O1xyXG4gIHRvdWNoZXM6IHsgT05FOiBhbnk7IFRXTzogYW55IH07XHJcbiAgdGFyZ2V0MDogYW55O1xyXG4gIHBvc2l0aW9uMDogYW55O1xyXG4gIHpvb20wOiBhbnk7XHJcbiAgcHJpdmF0ZSBfZG9tRWxlbWVudEtleUV2ZW50czogYW55O1xyXG4gIHNwaGVyaWNhbDogYW55O1xyXG4gIG9uUG9pbnRlck1vdmU6IChldmVudDogYW55KSA9PiB2b2lkO1xyXG4gIG9uUG9pbnRlclVwOiAoZXZlbnQ6IGFueSkgPT4gdm9pZDtcclxuICBvbkNvbnRleHRNZW51OiAoZXZlbnQ6IGFueSkgPT4gdm9pZDtcclxuICBvblBvaW50ZXJEb3duOiAoZXZlbnQ6IGFueSkgPT4gdm9pZDtcclxuICBvbk1vdXNlV2hlZWw6IChldmVudDogYW55KSA9PiB2b2lkO1xyXG4gIG9uS2V5RG93bjogKGV2ZW50OiBhbnkpID0+IHZvaWQ7XHJcbiAgZ2V0QXV0b1JvdGF0aW9uQW5nbGU6ICgpID0+IG51bWJlcjtcclxuICB1cGRhdGU6ICgpID0+IGJvb2xlYW47XHJcbiAgY29uc3RydWN0b3Iob2JqZWN0LCBkb21FbGVtZW50KSB7XHJcbiAgICBzdXBlcigpO1xyXG5cclxuICAgIGlmIChkb21FbGVtZW50ID09PSB1bmRlZmluZWQpXHJcbiAgICAgIGNvbnNvbGUud2FybihcclxuICAgICAgICAnT3JiaXRDb250cm9sczogVGhlIHNlY29uZCBwYXJhbWV0ZXIgXCJkb21FbGVtZW50XCIgaXMgbm93IG1hbmRhdG9yeS4nXHJcbiAgICAgICk7XHJcbiAgICBpZiAoZG9tRWxlbWVudCA9PT0gZG9jdW1lbnQpXHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoXHJcbiAgICAgICAgJ09yYml0Q29udHJvbHM6IFwiZG9jdW1lbnRcIiBzaG91bGQgbm90IGJlIHVzZWQgYXMgdGhlIHRhcmdldCBcImRvbUVsZW1lbnRcIi4gUGxlYXNlIHVzZSBcInJlbmRlcmVyLmRvbUVsZW1lbnRcIiBpbnN0ZWFkLidcclxuICAgICAgKTtcclxuXHJcbiAgICB0aGlzLm9iamVjdCA9IG9iamVjdDtcclxuICAgIHRoaXMuZG9tRWxlbWVudCA9IGRvbUVsZW1lbnQ7XHJcbiAgICB0aGlzLmRvbUVsZW1lbnQuc3R5bGUudG91Y2hBY3Rpb24gPSBcIm5vbmVcIjsgLy8gZGlzYWJsZSB0b3VjaCBzY3JvbGxcclxuXHJcbiAgICAvLyBTZXQgdG8gZmFsc2UgdG8gZGlzYWJsZSB0aGlzIGNvbnRyb2xcclxuICAgIHRoaXMuZW5hYmxlZCA9IHRydWU7XHJcblxyXG4gICAgLy8gXCJ0YXJnZXRcIiBzZXRzIHRoZSBsb2NhdGlvbiBvZiBmb2N1cywgd2hlcmUgdGhlIG9iamVjdCBvcmJpdHMgYXJvdW5kXHJcbiAgICB0aGlzLnRhcmdldCA9IG5ldyBWZWN0b3IzKCk7XHJcblxyXG4gICAgLy8gSG93IGZhciB5b3UgY2FuIGRvbGx5IGluIGFuZCBvdXQgKCBQZXJzcGVjdGl2ZUNhbWVyYSBvbmx5IClcclxuICAgIHRoaXMubWluRGlzdGFuY2UgPSAwO1xyXG4gICAgdGhpcy5tYXhEaXN0YW5jZSA9IEluZmluaXR5O1xyXG5cclxuICAgIC8vIEhvdyBmYXIgeW91IGNhbiB6b29tIGluIGFuZCBvdXQgKCBPcnRob2dyYXBoaWNDYW1lcmEgb25seSApXHJcbiAgICB0aGlzLm1pblpvb20gPSAwO1xyXG4gICAgdGhpcy5tYXhab29tID0gSW5maW5pdHk7XHJcblxyXG4gICAgLy8gSG93IGZhciB5b3UgY2FuIG9yYml0IHZlcnRpY2FsbHksIHVwcGVyIGFuZCBsb3dlciBsaW1pdHMuXHJcbiAgICAvLyBSYW5nZSBpcyAwIHRvIE1hdGguUEkgcmFkaWFucy5cclxuICAgIHRoaXMubWluUG9sYXJBbmdsZSA9IDA7IC8vIHJhZGlhbnNcclxuICAgIHRoaXMubWF4UG9sYXJBbmdsZSA9IE1hdGguUEk7IC8vIHJhZGlhbnNcclxuXHJcbiAgICAvLyBIb3cgZmFyIHlvdSBjYW4gb3JiaXQgaG9yaXpvbnRhbGx5LCB1cHBlciBhbmQgbG93ZXIgbGltaXRzLlxyXG4gICAgLy8gSWYgc2V0LCB0aGUgaW50ZXJ2YWwgWyBtaW4sIG1heCBdIG11c3QgYmUgYSBzdWItaW50ZXJ2YWwgb2YgWyAtIDIgUEksIDIgUEkgXSwgd2l0aCAoIG1heCAtIG1pbiA8IDIgUEkgKVxyXG4gICAgdGhpcy5taW5BemltdXRoQW5nbGUgPSAtSW5maW5pdHk7IC8vIHJhZGlhbnNcclxuICAgIHRoaXMubWF4QXppbXV0aEFuZ2xlID0gSW5maW5pdHk7IC8vIHJhZGlhbnNcclxuXHJcbiAgICAvLyBTZXQgdG8gdHJ1ZSB0byBlbmFibGUgZGFtcGluZyAoaW5lcnRpYSlcclxuICAgIC8vIElmIGRhbXBpbmcgaXMgZW5hYmxlZCwgeW91IG11c3QgY2FsbCBjb250cm9scy51cGRhdGUoKSBpbiB5b3VyIGFuaW1hdGlvbiBsb29wXHJcbiAgICB0aGlzLmVuYWJsZURhbXBpbmcgPSBmYWxzZTtcclxuICAgIHRoaXMuZGFtcGluZ0ZhY3RvciA9IDAuMDU7XHJcblxyXG4gICAgLy8gVGhpcyBvcHRpb24gYWN0dWFsbHkgZW5hYmxlcyBkb2xseWluZyBpbiBhbmQgb3V0OyBsZWZ0IGFzIFwiem9vbVwiIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cclxuICAgIC8vIFNldCB0byBmYWxzZSB0byBkaXNhYmxlIHpvb21pbmdcclxuICAgIHRoaXMuZW5hYmxlWm9vbSA9IHRydWU7XHJcbiAgICB0aGlzLnpvb21TcGVlZCA9IDEuMDtcclxuXHJcbiAgICAvLyBTZXQgdG8gZmFsc2UgdG8gZGlzYWJsZSByb3RhdGluZ1xyXG4gICAgdGhpcy5lbmFibGVSb3RhdGUgPSB0cnVlO1xyXG4gICAgdGhpcy5yb3RhdGVTcGVlZCA9IDEuMDtcclxuXHJcbiAgICAvLyBTZXQgdG8gZmFsc2UgdG8gZGlzYWJsZSBwYW5uaW5nXHJcbiAgICB0aGlzLmVuYWJsZVBhbiA9IHRydWU7XHJcbiAgICB0aGlzLnBhblNwZWVkID0gMS4wO1xyXG4gICAgdGhpcy5zY3JlZW5TcGFjZVBhbm5pbmcgPSBmYWxzZTsgLy8gaWYgZmFsc2UsIHBhbiBvcnRob2dvbmFsIHRvIHdvcmxkLXNwYWNlIGRpcmVjdGlvbiBjYW1lcmEudXBcclxuICAgIHRoaXMua2V5UGFuU3BlZWQgPSA3LjA7IC8vIHBpeGVscyBtb3ZlZCBwZXIgYXJyb3cga2V5IHB1c2hcclxuXHJcbiAgICAvLyBTZXQgdG8gdHJ1ZSB0byBhdXRvbWF0aWNhbGx5IHJvdGF0ZSBhcm91bmQgdGhlIHRhcmdldFxyXG4gICAgLy8gSWYgYXV0by1yb3RhdGUgaXMgZW5hYmxlZCwgeW91IG11c3QgY2FsbCBjb250cm9scy51cGRhdGUoKSBpbiB5b3VyIGFuaW1hdGlvbiBsb29wXHJcbiAgICB0aGlzLmF1dG9Sb3RhdGUgPSBmYWxzZTtcclxuICAgIHRoaXMuYXV0b1JvdGF0ZVNwZWVkID0gMi4wOyAvLyAzMCBzZWNvbmRzIHBlciBvcmJpdCB3aGVuIGZwcyBpcyA2MFxyXG5cclxuICAgIC8vIFRoZSBmb3VyIGFycm93IGtleXNcclxuICAgIHRoaXMua2V5cyA9IHtcclxuICAgICAgTEVGVDogXCJBcnJvd0xlZnRcIixcclxuICAgICAgVVA6IFwiQXJyb3dVcFwiLFxyXG4gICAgICBSSUdIVDogXCJBcnJvd1JpZ2h0XCIsXHJcbiAgICAgIEJPVFRPTTogXCJBcnJvd0Rvd25cIixcclxuICAgIH07XHJcblxyXG4gICAgLy8gTW91c2UgYnV0dG9uc1xyXG4gICAgdGhpcy5tb3VzZUJ1dHRvbnMgPSB7XHJcbiAgICAgIExFRlQ6IE1PVVNFLlJPVEFURSxcclxuICAgICAgTUlERExFOiBNT1VTRS5ET0xMWSxcclxuICAgICAgUklHSFQ6IE1PVVNFLlBBTixcclxuICAgIH07XHJcblxyXG4gICAgLy8gVG91Y2ggZmluZ2Vyc1xyXG4gICAgdGhpcy50b3VjaGVzID0geyBPTkU6IFRPVUNILlJPVEFURSwgVFdPOiBUT1VDSC5ET0xMWV9QQU4gfTtcclxuXHJcbiAgICAvLyBmb3IgcmVzZXRcclxuICAgIHRoaXMudGFyZ2V0MCA9IHRoaXMudGFyZ2V0LmNsb25lKCk7XHJcbiAgICB0aGlzLnBvc2l0aW9uMCA9IHRoaXMub2JqZWN0LnBvc2l0aW9uLmNsb25lKCk7XHJcbiAgICB0aGlzLnpvb20wID0gdGhpcy5vYmplY3Quem9vbTtcclxuXHJcbiAgICAvLyB0aGUgdGFyZ2V0IERPTSBlbGVtZW50IGZvciBrZXkgZXZlbnRzXHJcbiAgICB0aGlzLl9kb21FbGVtZW50S2V5RXZlbnRzID0gbnVsbDtcclxuXHJcbiAgICAvL1xyXG4gICAgLy8gcHVibGljIG1ldGhvZHNcclxuICAgIC8vXHJcbiAgICAvLyB0aGlzIG1ldGhvZCBpcyBleHBvc2VkLCBidXQgcGVyaGFwcyBpdCB3b3VsZCBiZSBiZXR0ZXIgaWYgd2UgY2FuIG1ha2UgaXQgcHJpdmF0ZS4uLlxyXG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XHJcbiAgICB0aGlzLnVwZGF0ZSA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgIGNvbnN0IG9mZnNldCA9IG5ldyBWZWN0b3IzKCk7XHJcbiAgICAgIC8vIHNvIGNhbWVyYS51cCBpcyB0aGUgb3JiaXQgYXhpc1xyXG4gICAgICBjb25zdCBxdWF0ID0gbmV3IFF1YXRlcm5pb24oKS5zZXRGcm9tVW5pdFZlY3RvcnMoXHJcbiAgICAgICAgdGhhdC5vYmplY3QudXAsXHJcbiAgICAgICAgbmV3IFZlY3RvcjMoMCwgMSwgMClcclxuICAgICAgKTtcclxuICAgICAgY29uc3QgcXVhdEludmVyc2UgPSBxdWF0LmNsb25lKCkuaW52ZXJ0KCk7XHJcblxyXG4gICAgICBjb25zdCBsYXN0UG9zaXRpb24gPSBuZXcgVmVjdG9yMygpO1xyXG4gICAgICBjb25zdCBsYXN0UXVhdGVybmlvbiA9IG5ldyBRdWF0ZXJuaW9uKCk7XHJcblxyXG4gICAgICBjb25zdCB0d29QSSA9IDIgKiBNYXRoLlBJO1xyXG4gICAgICByZXR1cm4gZnVuY3Rpb24gdXBkYXRlKCkge1xyXG4gICAgICAgIGNvbnN0IHBvc2l0aW9uID0gdGhhdC5vYmplY3QucG9zaXRpb247XHJcblxyXG4gICAgICAgIG9mZnNldC5jb3B5KHBvc2l0aW9uKS5zdWJ0cmFjdCh0aGF0LnRhcmdldCk7XHJcblxyXG4gICAgICAgIC8vIHJvdGF0ZSBvZmZzZXQgdG8gXCJ5LWF4aXMtaXMtdXBcIiBzcGFjZVxyXG4gICAgICAgIG9mZnNldC5hcHBseVF1YXRlcm5pb24ocXVhdCk7XHJcblxyXG4gICAgICAgIC8vIGFuZ2xlIGZyb20gei1heGlzIGFyb3VuZCB5LWF4aXNcclxuICAgICAgICBzcGhlcmljYWwuc2V0RnJvbVZlY3RvcjMob2Zmc2V0KTtcclxuXHJcbiAgICAgICAgaWYgKHRoYXQuYXV0b1JvdGF0ZSAmJiBzdGF0ZSA9PT0gU1RBVEUuTk9ORSkge1xyXG4gICAgICAgICAgcm90YXRlTGVmdCh0aGF0LmdldEF1dG9Sb3RhdGlvbkFuZ2xlKCkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoYXQuZW5hYmxlRGFtcGluZykge1xyXG4gICAgICAgICAgc3BoZXJpY2FsLnRoZXRhICs9IHNwaGVyaWNhbERlbHRhLnRoZXRhICogdGhhdC5kYW1waW5nRmFjdG9yO1xyXG4gICAgICAgICAgc3BoZXJpY2FsLnBoaSArPSBzcGhlcmljYWxEZWx0YS5waGkgKiB0aGF0LmRhbXBpbmdGYWN0b3I7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHNwaGVyaWNhbC50aGV0YSArPSBzcGhlcmljYWxEZWx0YS50aGV0YTtcclxuICAgICAgICAgIHNwaGVyaWNhbC5waGkgKz0gc3BoZXJpY2FsRGVsdGEucGhpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gcmVzdHJpY3QgdGhldGEgdG8gYmUgYmV0d2VlbiBkZXNpcmVkIGxpbWl0c1xyXG5cclxuICAgICAgICBsZXQgbWluID0gdGhhdC5taW5BemltdXRoQW5nbGU7XHJcbiAgICAgICAgbGV0IG1heCA9IHRoYXQubWF4QXppbXV0aEFuZ2xlO1xyXG5cclxuICAgICAgICBpZiAoaXNGaW5pdGUobWluKSAmJiBpc0Zpbml0ZShtYXgpKSB7XHJcbiAgICAgICAgICBpZiAobWluIDwgLU1hdGguUEkpIG1pbiArPSB0d29QSTtcclxuICAgICAgICAgIGVsc2UgaWYgKG1pbiA+IE1hdGguUEkpIG1pbiAtPSB0d29QSTtcclxuXHJcbiAgICAgICAgICBpZiAobWF4IDwgLU1hdGguUEkpIG1heCArPSB0d29QSTtcclxuICAgICAgICAgIGVsc2UgaWYgKG1heCA+IE1hdGguUEkpIG1heCAtPSB0d29QSTtcclxuXHJcbiAgICAgICAgICBpZiAobWluIDw9IG1heCkge1xyXG4gICAgICAgICAgICBzcGhlcmljYWwudGhldGEgPSBNYXRoLm1heChtaW4sIE1hdGgubWluKG1heCwgc3BoZXJpY2FsLnRoZXRhKSk7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBzcGhlcmljYWwudGhldGEgPVxyXG4gICAgICAgICAgICAgIHNwaGVyaWNhbC50aGV0YSA+IChtaW4gKyBtYXgpIC8gMlxyXG4gICAgICAgICAgICAgICAgPyBNYXRoLm1heChtaW4sIHNwaGVyaWNhbC50aGV0YSlcclxuICAgICAgICAgICAgICAgIDogTWF0aC5taW4obWF4LCBzcGhlcmljYWwudGhldGEpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gcmVzdHJpY3QgcGhpIHRvIGJlIGJldHdlZW4gZGVzaXJlZCBsaW1pdHNcclxuICAgICAgICBzcGhlcmljYWwucGhpID0gTWF0aC5tYXgoXHJcbiAgICAgICAgICB0aGF0Lm1pblBvbGFyQW5nbGUsXHJcbiAgICAgICAgICBNYXRoLm1pbih0aGF0Lm1heFBvbGFyQW5nbGUsIHNwaGVyaWNhbC5waGkpXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgc3BoZXJpY2FsLm1ha2VTYWZlKCk7XHJcblxyXG4gICAgICAgIHNwaGVyaWNhbC5yYWRpdXMgKj0gc2NhbGU7XHJcblxyXG4gICAgICAgIC8vIHJlc3RyaWN0IHJhZGl1cyB0byBiZSBiZXR3ZWVuIGRlc2lyZWQgbGltaXRzXHJcbiAgICAgICAgc3BoZXJpY2FsLnJhZGl1cyA9IE1hdGgubWF4KFxyXG4gICAgICAgICAgdGhhdC5taW5EaXN0YW5jZSxcclxuICAgICAgICAgIE1hdGgubWluKHRoYXQubWF4RGlzdGFuY2UsIHNwaGVyaWNhbC5yYWRpdXMpXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgLy8gbW92ZSB0YXJnZXQgdG8gcGFubmVkIGxvY2F0aW9uXHJcblxyXG4gICAgICAgIGlmICh0aGF0LmVuYWJsZURhbXBpbmcgPT09IHRydWUpIHtcclxuICAgICAgICAgIHRoYXQudGFyZ2V0LmFkZFNjYWxlZFZlY3RvcihwYW5PZmZzZXQsIHRoYXQuZGFtcGluZ0ZhY3Rvcik7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoYXQudGFyZ2V0LmFkZChwYW5PZmZzZXQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBWZWN0b3IzLmZyb21TcGhlcmljYWwoc3BoZXJpY2FsLCBvZmZzZXQpO1xyXG4gICAgICAgIC8vIHJvdGF0ZSBvZmZzZXQgYmFjayB0byBcImNhbWVyYS11cC12ZWN0b3ItaXMtdXBcIiBzcGFjZVxyXG4gICAgICAgIG9mZnNldC5hcHBseVF1YXRlcm5pb24ocXVhdEludmVyc2UpO1xyXG5cclxuICAgICAgICBwb3NpdGlvbi5jb3B5KHRoYXQudGFyZ2V0KS5hZGQob2Zmc2V0KTtcclxuXHJcbiAgICAgICAgdGhhdC5vYmplY3QubG9va0F0KHRoYXQudGFyZ2V0LngsIHRoYXQudGFyZ2V0LnksIHRoYXQudGFyZ2V0LnopO1xyXG5cclxuICAgICAgICBpZiAodGhhdC5lbmFibGVEYW1waW5nID09PSB0cnVlKSB7XHJcbiAgICAgICAgICBzcGhlcmljYWxEZWx0YS50aGV0YSAqPSAxIC0gdGhhdC5kYW1waW5nRmFjdG9yO1xyXG4gICAgICAgICAgc3BoZXJpY2FsRGVsdGEucGhpICo9IDEgLSB0aGF0LmRhbXBpbmdGYWN0b3I7XHJcblxyXG4gICAgICAgICAgVmVjdG9yMy5tdWx0aXBseUJ5U2NhbGFyKFxyXG4gICAgICAgICAgICBwYW5PZmZzZXQsXHJcbiAgICAgICAgICAgIDEgLSB0aGF0LmRhbXBpbmdGYWN0b3IsXHJcbiAgICAgICAgICAgIHBhbk9mZnNldFxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIC8vIHBhbk9mZnNldC5tdWx0aXBseVNjYWxhciggMSAtIHRoaXMuZGFtcGluZ0ZhY3RvciApO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBzcGhlcmljYWxEZWx0YS5zZXQoMCwgMCwgMCk7XHJcblxyXG4gICAgICAgICAgcGFuT2Zmc2V0LnNldCgwLCAwLCAwKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHNjYWxlID0gMTtcclxuXHJcbiAgICAgICAgLy8gdXBkYXRlIGNvbmRpdGlvbiBpczpcclxuICAgICAgICAvLyBtaW4oY2FtZXJhIGRpc3BsYWNlbWVudCwgY2FtZXJhIHJvdGF0aW9uIGluIHJhZGlhbnMpXjIgPiBFUFNcclxuICAgICAgICAvLyB1c2luZyBzbWFsbC1hbmdsZSBhcHByb3hpbWF0aW9uIGNvcyh4LzIpID0gMSAtIHheMiAvIDhcclxuXHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgem9vbUNoYW5nZWQgfHxcclxuICAgICAgICAgIFZlY3RvcjMuZGlzdGFuY2VTcXVhcmVkKGxhc3RQb3NpdGlvbiwgdGhhdC5vYmplY3QucG9zaXRpb24pID4gRVBTIHx8XHJcbiAgICAgICAgICA4ICogKDEgLSBsYXN0UXVhdGVybmlvbi5kb3QodGhhdC5vYmplY3QucXVhdGVybmlvbikpID4gRVBTXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICB0aGF0LmRpc3BhdGNoRXZlbnQoX2NoYW5nZUV2ZW50KTtcclxuXHJcbiAgICAgICAgICAvL2xhc3RQb3NpdGlvbi5jb3B5KCB0aGlzLm9iamVjdC5wb3NpdGlvbiApO1xyXG4gICAgICAgICAgVmVjdG9yMy5jbG9uZSh0aGF0Lm9iamVjdC5wb3NpdGlvbiwgbGFzdFBvc2l0aW9uKTtcclxuICAgICAgICAgIFF1YXRlcm5pb24uY2xvbmUodGhhdC5vYmplY3QucXVhdGVybmlvbiwgbGFzdFF1YXRlcm5pb24pO1xyXG4gICAgICAgICAgLy9sYXN0UXVhdGVybmlvbi5jb3B5KCB0aGlzLm9iamVjdC5xdWF0ZXJuaW9uICk7XHJcbiAgICAgICAgICB6b29tQ2hhbmdlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICB9O1xyXG4gICAgfSkoKTtcclxuICAgIHRoaXMuaW5pdCgpO1xyXG4gIH1cclxuICBnZXRQb2xhckFuZ2xlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc3BoZXJpY2FsLnBoaTtcclxuICB9XHJcbiAgZ2V0QXppbXV0aGFsQW5nbGUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zcGhlcmljYWwudGhldGE7XHJcbiAgfVxyXG5cclxuICBnZXREaXN0YW5jZSgpIHtcclxuICAgIHJldHVybiBWZWN0b3IzLmRpc3RhbmNlKHRoaXMub2JqZWN0LnBvc2l0aW9uLCB0aGlzLnRhcmdldCk7XHJcbiAgfVxyXG5cclxuICBsaXN0ZW5Ub0tleUV2ZW50cyhkb21FbGVtZW50KSB7XHJcbiAgICBkb21FbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsIHRoaXMub25LZXlEb3duKTtcclxuICAgIHRoaXMuX2RvbUVsZW1lbnRLZXlFdmVudHMgPSBkb21FbGVtZW50O1xyXG4gIH1cclxuXHJcbiAgc2F2ZVN0YXRlKCkge1xyXG4gICAgVmVjdG9yMy5jbG9uZSh0aGlzLnRhcmdldCwgdGhpcy50YXJnZXQwKTtcclxuICAgIC8vdGhpcy50YXJnZXQwLmNvcHkoIHRoaXMudGFyZ2V0ICk7XHJcbiAgICBWZWN0b3IzLmNsb25lKHRoaXMub2JqZWN0LnBvc2l0aW9uLCB0aGlzLnBvc2l0aW9uMCk7XHJcbiAgICAvL3RoaXMucG9zaXRpb24wLmNvcHkoIHRoaXMub2JqZWN0LnBvc2l0aW9uICk7XHJcbiAgICB0aGlzLnpvb20wID0gdGhpcy5vYmplY3Quem9vbTtcclxuICB9XHJcblxyXG4gIHJlc2V0KCkge1xyXG4gICAgVmVjdG9yMy5jbG9uZSh0aGlzLnRhcmdldDAsIHRoaXMudGFyZ2V0KTtcclxuICAgIC8vdGhpcy50YXJnZXQuY29weSggdGhpcy50YXJnZXQwICk7XHJcbiAgICBWZWN0b3IzLmNsb25lKHRoaXMucG9zaXRpb24wLCB0aGlzLm9iamVjdC5wb3NpdGlvbik7XHJcbiAgICAvL3RoaXMub2JqZWN0LnBvc2l0aW9uLmNvcHkoIHRoaXMucG9zaXRpb24wICk7XHJcbiAgICB0aGlzLm9iamVjdC56b29tID0gdGhpcy56b29tMDtcclxuXHJcbiAgICB0aGlzLm9iamVjdC51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XHJcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoX2NoYW5nZUV2ZW50KTtcclxuXHJcbiAgICB0aGlzLnVwZGF0ZSgpO1xyXG5cclxuICAgIHN0YXRlID0gU1RBVEUuTk9ORTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgaW5pdCgpIHtcclxuICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xyXG4gICAgY29uc3QgcGFuTGVmdCA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgIGNvbnN0IHYgPSBuZXcgVmVjdG9yMygpO1xyXG4gICAgICByZXR1cm4gZnVuY3Rpb24gcGFuTGVmdChkaXN0YW5jZSwgb2JqZWN0TWF0cml4KSB7XHJcbiAgICAgICAgdi5zZXRGcm9tTWF0cml4Q29sdW1uKG9iamVjdE1hdHJpeCwgMCk7IC8vIGdldCBYIGNvbHVtbiBvZiBvYmplY3RNYXRyaXhcclxuICAgICAgICB2Lm11bHRpcGx5QnlTY2FsYXIoLWRpc3RhbmNlKTtcclxuICAgICAgICBwYW5PZmZzZXQuYWRkKHYpO1xyXG4gICAgICB9O1xyXG4gICAgfSkoKTtcclxuICAgIGNvbnN0IHBhblVwID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgY29uc3QgcGFuVXBWID0gbmV3IFZlY3RvcjMoKTtcclxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHBhblVwKGRpc3RhbmNlLCBvYmplY3RNYXRyaXgpIHtcclxuICAgICAgICBpZiAodGhhdC5zY3JlZW5TcGFjZVBhbm5pbmcgPT09IHRydWUpIHtcclxuICAgICAgICAgIHBhblVwVi5zZXRGcm9tTWF0cml4Q29sdW1uKG9iamVjdE1hdHJpeCwgMSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHBhblVwVi5zZXRGcm9tTWF0cml4Q29sdW1uKG9iamVjdE1hdHJpeCwgMCk7XHJcbiAgICAgICAgICAvL3BhblVwVi5jcm9zc1ZlY3RvcnMoIHRoaXMub2JqZWN0LnVwLCBwYW5VcFYgKTtcclxuICAgICAgICAgIFZlY3RvcjMuY3Jvc3ModGhhdC5vYmplY3QudXAsIHBhblVwViwgcGFuVXBWKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHBhblVwVi5tdWx0aXBseUJ5U2NhbGFyKGRpc3RhbmNlKTtcclxuXHJcbiAgICAgICAgcGFuT2Zmc2V0LmFkZChwYW5VcFYpO1xyXG4gICAgICB9O1xyXG4gICAgfSkoKTtcclxuICAgIC8vIGRlbHRhWCBhbmQgZGVsdGFZIGFyZSBpbiBwaXhlbHM7IHJpZ2h0IGFuZCBkb3duIGFyZSBwb3NpdGl2ZVxyXG4gICAgY29uc3QgcGFuID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgY29uc3Qgb2Zmc2V0ID0gbmV3IFZlY3RvcjMoKTtcclxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHBhbihkZWx0YVgsIGRlbHRhWSkge1xyXG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGF0LmRvbUVsZW1lbnQ7XHJcbiAgICAgICAgaWYgKHRoYXQub2JqZWN0LmlzUGVyc3BlY3RpdmVDYW1lcmEpIHtcclxuICAgICAgICAgIC8vIHBlcnNwZWN0aXZlXHJcbiAgICAgICAgICBjb25zdCBwb3NpdGlvbiA9IHRoYXQub2JqZWN0LnBvc2l0aW9uO1xyXG4gICAgICAgICAgb2Zmc2V0LmNvcHkocG9zaXRpb24pLnN1YnRyYWN0KHRoYXQudGFyZ2V0KTtcclxuICAgICAgICAgIGxldCB0YXJnZXREaXN0YW5jZSA9IG9mZnNldC5sZW5ndGgoKTtcclxuXHJcbiAgICAgICAgICAvLyBoYWxmIG9mIHRoZSBmb3YgaXMgY2VudGVyIHRvIHRvcCBvZiBzY3JlZW5cclxuICAgICAgICAgIHRhcmdldERpc3RhbmNlICo9IE1hdGgudGFuKCgodGhhdC5vYmplY3QuZm92IC8gMikgKiBNYXRoLlBJKSAvIDE4MC4wKTtcclxuXHJcbiAgICAgICAgICAvLyB3ZSB1c2Ugb25seSBjbGllbnRIZWlnaHQgaGVyZSBzbyBhc3BlY3QgcmF0aW8gZG9lcyBub3QgZGlzdG9ydCBzcGVlZFxyXG4gICAgICAgICAgcGFuTGVmdChcclxuICAgICAgICAgICAgKDIgKiBkZWx0YVggKiB0YXJnZXREaXN0YW5jZSkgLyBlbGVtZW50LmNsaWVudEhlaWdodCxcclxuICAgICAgICAgICAgdGhhdC5vYmplY3QubW9kZWxNYXRyaXhcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICBwYW5VcChcclxuICAgICAgICAgICAgKDIgKiBkZWx0YVkgKiB0YXJnZXREaXN0YW5jZSkgLyBlbGVtZW50LmNsaWVudEhlaWdodCxcclxuICAgICAgICAgICAgdGhhdC5vYmplY3QubW9kZWxNYXRyaXhcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGF0Lm9iamVjdC5pc09ydGhvZ3JhcGhpY0NhbWVyYSkge1xyXG4gICAgICAgICAgLy8gb3J0aG9ncmFwaGljXHJcbiAgICAgICAgICBwYW5MZWZ0KFxyXG4gICAgICAgICAgICAoZGVsdGFYICogKHRoYXQub2JqZWN0LnJpZ2h0IC0gdGhhdC5vYmplY3QubGVmdCkpIC9cclxuICAgICAgICAgICAgICB0aGF0Lm9iamVjdC56b29tIC9cclxuICAgICAgICAgICAgICBlbGVtZW50LmNsaWVudFdpZHRoLFxyXG4gICAgICAgICAgICB0aGF0Lm9iamVjdC5tb2RlbE1hdHJpeFxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHBhblVwKFxyXG4gICAgICAgICAgICAoZGVsdGFZICogKHRoYXQub2JqZWN0LnRvcCAtIHRoYXQub2JqZWN0LmJvdHRvbSkpIC9cclxuICAgICAgICAgICAgICB0aGF0Lm9iamVjdC56b29tIC9cclxuICAgICAgICAgICAgICBlbGVtZW50LmNsaWVudEhlaWdodCxcclxuICAgICAgICAgICAgdGhhdC5vYmplY3QubW9kZWxNYXRyaXhcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIGNhbWVyYSBuZWl0aGVyIG9ydGhvZ3JhcGhpYyBub3IgcGVyc3BlY3RpdmVcclxuICAgICAgICAgIGNvbnNvbGUud2FybihcclxuICAgICAgICAgICAgXCJXQVJOSU5HOiBPcmJpdENvbnRyb2xzLmpzIGVuY291bnRlcmVkIGFuIHVua25vd24gY2FtZXJhIHR5cGUgLSBwYW4gZGlzYWJsZWQuXCJcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICB0aGF0LmVuYWJsZVBhbiA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgfTtcclxuICAgIH0pKCk7XHJcbiAgICBjb25zdCBkb2xseU91dCA9IChkb2xseVNjYWxlKSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLm9iamVjdC5pc1BlcnNwZWN0aXZlQ2FtZXJhKSB7XHJcbiAgICAgICAgc2NhbGUgLz0gZG9sbHlTY2FsZTtcclxuICAgICAgfSBlbHNlIGlmICh0aGlzLm9iamVjdC5pc09ydGhvZ3JhcGhpY0NhbWVyYSkge1xyXG4gICAgICAgIHRoaXMub2JqZWN0Lnpvb20gPSBNYXRoLm1heChcclxuICAgICAgICAgIHRoaXMubWluWm9vbSxcclxuICAgICAgICAgIE1hdGgubWluKHRoaXMubWF4Wm9vbSwgdGhpcy5vYmplY3Quem9vbSAqIGRvbGx5U2NhbGUpXHJcbiAgICAgICAgKTtcclxuICAgICAgICB0aGlzLm9iamVjdC51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XHJcbiAgICAgICAgem9vbUNoYW5nZWQgPSB0cnVlO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNvbnNvbGUud2FybihcclxuICAgICAgICAgIFwiV0FSTklORzogT3JiaXRDb250cm9scy5qcyBlbmNvdW50ZXJlZCBhbiB1bmtub3duIGNhbWVyYSB0eXBlIC0gZG9sbHkvem9vbSBkaXNhYmxlZC5cIlxyXG4gICAgICAgICk7XHJcbiAgICAgICAgdGhpcy5lbmFibGVab29tID0gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgY29uc3QgZG9sbHlJbiA9IChkb2xseVNjYWxlKSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLm9iamVjdC5pc1BlcnNwZWN0aXZlQ2FtZXJhKSB7XHJcbiAgICAgICAgc2NhbGUgKj0gZG9sbHlTY2FsZTtcclxuICAgICAgfSBlbHNlIGlmICh0aGlzLm9iamVjdC5pc09ydGhvZ3JhcGhpY0NhbWVyYSkge1xyXG4gICAgICAgIHRoaXMub2JqZWN0Lnpvb20gPSBNYXRoLm1heChcclxuICAgICAgICAgIHRoaXMubWluWm9vbSxcclxuICAgICAgICAgIE1hdGgubWluKHRoaXMubWF4Wm9vbSwgdGhpcy5vYmplY3Quem9vbSAvIGRvbGx5U2NhbGUpXHJcbiAgICAgICAgKTtcclxuICAgICAgICB0aGlzLm9iamVjdC51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XHJcbiAgICAgICAgem9vbUNoYW5nZWQgPSB0cnVlO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNvbnNvbGUud2FybihcclxuICAgICAgICAgIFwiV0FSTklORzogT3JiaXRDb250cm9scy5qcyBlbmNvdW50ZXJlZCBhbiB1bmtub3duIGNhbWVyYSB0eXBlIC0gZG9sbHkvem9vbSBkaXNhYmxlZC5cIlxyXG4gICAgICAgICk7XHJcbiAgICAgICAgdGhpcy5lbmFibGVab29tID0gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgIH07XHJcbiAgICBjb25zdCBoYW5kbGVNb3VzZU1vdmVSb3RhdGUgPSAoZXZlbnQpID0+IHtcclxuICAgICAgcm90YXRlRW5kLnNldChldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZKTtcclxuXHJcbiAgICAgIFZlY3RvcjIuc3VidHJhY3Qocm90YXRlRW5kLCByb3RhdGVTdGFydCwgcm90YXRlRGVsdGEpO1xyXG4gICAgICBWZWN0b3IyLm11bHRpcGx5QnlTY2FsYXIocm90YXRlRGVsdGEsIHRoaXMucm90YXRlU3BlZWQsIHJvdGF0ZURlbHRhKTtcclxuICAgICAgLy9yb3RhdGVEZWx0YS5zdWJWZWN0b3JzKCByb3RhdGVFbmQsIHJvdGF0ZVN0YXJ0ICkubXVsdGlwbHlTY2FsYXIoIHRoaXMucm90YXRlU3BlZWQgKTtcclxuXHJcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmRvbUVsZW1lbnQ7XHJcblxyXG4gICAgICByb3RhdGVMZWZ0KCgyICogTWF0aC5QSSAqIHJvdGF0ZURlbHRhLngpIC8gZWxlbWVudC5jbGllbnRIZWlnaHQpOyAvLyB5ZXMsIGhlaWdodFxyXG5cclxuICAgICAgcm90YXRlVXAoKDIgKiBNYXRoLlBJICogcm90YXRlRGVsdGEueSkgLyBlbGVtZW50LmNsaWVudEhlaWdodCk7XHJcblxyXG4gICAgICBWZWN0b3IyLmNsb25lKHJvdGF0ZUVuZCwgcm90YXRlU3RhcnQpO1xyXG4gICAgICAvL3JvdGF0ZVN0YXJ0LmNvcHkoIHJvdGF0ZUVuZCApO1xyXG5cclxuICAgICAgdGhpcy51cGRhdGUoKTtcclxuICAgIH07XHJcblxyXG4gICAgY29uc3QgaGFuZGxlTW91c2VNb3ZlRG9sbHkgPSAoZXZlbnQpID0+IHtcclxuICAgICAgZG9sbHlFbmQuc2V0KGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFkpO1xyXG5cclxuICAgICAgVmVjdG9yMi5zdWJ0cmFjdChkb2xseUVuZCwgZG9sbHlTdGFydCwgZG9sbHlEZWx0YSk7XHJcbiAgICAgIC8vIGRvbGx5RGVsdGEuc3ViVmVjdG9ycyggZG9sbHlFbmQsIGRvbGx5U3RhcnQgKTtcclxuXHJcbiAgICAgIGlmIChkb2xseURlbHRhLnkgPiAwKSB7XHJcbiAgICAgICAgZG9sbHlPdXQoZ2V0Wm9vbVNjYWxlKCkpO1xyXG4gICAgICB9IGVsc2UgaWYgKGRvbGx5RGVsdGEueSA8IDApIHtcclxuICAgICAgICBkb2xseUluKGdldFpvb21TY2FsZSgpKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgVmVjdG9yMi5jbG9uZShkb2xseUVuZCwgZG9sbHlTdGFydCk7XHJcbiAgICAgIC8vIGRvbGx5U3RhcnQuY29weSggZG9sbHlFbmQgKTtcclxuXHJcbiAgICAgIHRoaXMudXBkYXRlKCk7XHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0IGhhbmRsZU1vdXNlTW92ZVBhbiA9IChldmVudCkgPT4ge1xyXG4gICAgICBwYW5FbmQuc2V0KGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFkpO1xyXG5cclxuICAgICAgVmVjdG9yMi5zdWJ0cmFjdChwYW5FbmQsIHBhblN0YXJ0LCBwYW5EZWx0YSk7XHJcbiAgICAgIFZlY3RvcjIubXVsdGlwbHlCeVNjYWxhcihwYW5EZWx0YSwgdGhpcy5wYW5TcGVlZCwgcGFuRGVsdGEpO1xyXG4gICAgICAvL3BhbkRlbHRhLnN1YlZlY3RvcnMoIHBhbkVuZCwgcGFuU3RhcnQgKS5tdWx0aXBseVNjYWxhciggdGhpcy5wYW5TcGVlZCApO1xyXG5cclxuICAgICAgcGFuKHBhbkRlbHRhLngsIHBhbkRlbHRhLnkpO1xyXG5cclxuICAgICAgVmVjdG9yMi5jbG9uZShwYW5FbmQsIHBhblN0YXJ0KTtcclxuICAgICAgLy9wYW5TdGFydC5jb3B5KCBwYW5FbmQgKTtcclxuXHJcbiAgICAgIHRoaXMudXBkYXRlKCk7XHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0IGhhbmRsZU1vdXNlV2hlZWwgPSAoZXZlbnQpID0+IHtcclxuICAgICAgaWYgKGV2ZW50LmRlbHRhWSA8IDApIHtcclxuICAgICAgICBkb2xseUluKGdldFpvb21TY2FsZSgpKTtcclxuICAgICAgfSBlbHNlIGlmIChldmVudC5kZWx0YVkgPiAwKSB7XHJcbiAgICAgICAgZG9sbHlPdXQoZ2V0Wm9vbVNjYWxlKCkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLnVwZGF0ZSgpO1xyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBoYW5kbGVLZXlEb3duID0gKGV2ZW50KSA9PiB7XHJcbiAgICAgIGxldCBuZWVkc1VwZGF0ZSA9IGZhbHNlO1xyXG5cclxuICAgICAgc3dpdGNoIChldmVudC5jb2RlKSB7XHJcbiAgICAgICAgY2FzZSB0aGlzLmtleXMuVVA6XHJcbiAgICAgICAgICBwYW4oMCwgdGhpcy5rZXlQYW5TcGVlZCk7XHJcbiAgICAgICAgICBuZWVkc1VwZGF0ZSA9IHRydWU7XHJcbiAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgY2FzZSB0aGlzLmtleXMuQk9UVE9NOlxyXG4gICAgICAgICAgcGFuKDAsIC10aGlzLmtleVBhblNwZWVkKTtcclxuICAgICAgICAgIG5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBjYXNlIHRoaXMua2V5cy5MRUZUOlxyXG4gICAgICAgICAgcGFuKHRoaXMua2V5UGFuU3BlZWQsIDApO1xyXG4gICAgICAgICAgbmVlZHNVcGRhdGUgPSB0cnVlO1xyXG4gICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgIGNhc2UgdGhpcy5rZXlzLlJJR0hUOlxyXG4gICAgICAgICAgcGFuKC10aGlzLmtleVBhblNwZWVkLCAwKTtcclxuICAgICAgICAgIG5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAobmVlZHNVcGRhdGUpIHtcclxuICAgICAgICAvLyBwcmV2ZW50IHRoZSBicm93c2VyIGZyb20gc2Nyb2xsaW5nIG9uIGN1cnNvciBrZXlzXHJcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgICAgdGhpcy51cGRhdGUoKTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBoYW5kbGVUb3VjaFN0YXJ0RG9sbHlQYW4gPSAoKSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLmVuYWJsZVpvb20pIGhhbmRsZVRvdWNoU3RhcnREb2xseSgpO1xyXG5cclxuICAgICAgaWYgKHRoaXMuZW5hYmxlUGFuKSBoYW5kbGVUb3VjaFN0YXJ0UGFuKCk7XHJcbiAgICB9O1xyXG4gICAgY29uc3QgaGFuZGxlVG91Y2hTdGFydERvbGx5Um90YXRlID0gKCkgPT4ge1xyXG4gICAgICBpZiAodGhpcy5lbmFibGVab29tKSBoYW5kbGVUb3VjaFN0YXJ0RG9sbHkoKTtcclxuXHJcbiAgICAgIGlmICh0aGlzLmVuYWJsZVJvdGF0ZSkgaGFuZGxlVG91Y2hTdGFydFJvdGF0ZSgpO1xyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBoYW5kbGVUb3VjaE1vdmVSb3RhdGUgPSAoZXZlbnQpID0+IHtcclxuICAgICAgaWYgKHBvaW50ZXJzLmxlbmd0aCA9PSAxKSB7XHJcbiAgICAgICAgcm90YXRlRW5kLnNldChldmVudC5wYWdlWCwgZXZlbnQucGFnZVkpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNvbnN0IHBvc2l0aW9uID0gZ2V0U2Vjb25kUG9pbnRlclBvc2l0aW9uKGV2ZW50KTtcclxuXHJcbiAgICAgICAgY29uc3QgeCA9IDAuNSAqIChldmVudC5wYWdlWCArIHBvc2l0aW9uLngpO1xyXG4gICAgICAgIGNvbnN0IHkgPSAwLjUgKiAoZXZlbnQucGFnZVkgKyBwb3NpdGlvbi55KTtcclxuXHJcbiAgICAgICAgcm90YXRlRW5kLnNldCh4LCB5KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgVmVjdG9yMi5zdWJ0cmFjdChyb3RhdGVFbmQsIHJvdGF0ZVN0YXJ0LCByb3RhdGVEZWx0YSk7XHJcbiAgICAgIFZlY3RvcjIubXVsdGlwbHlCeVNjYWxhcihyb3RhdGVEZWx0YSwgdGhpcy5yb3RhdGVTcGVlZCwgcm90YXRlRGVsdGEpO1xyXG4gICAgICAvL3JvdGF0ZURlbHRhLnN1YlZlY3RvcnMoIHJvdGF0ZUVuZCwgcm90YXRlU3RhcnQgKS5tdWx0aXBseVNjYWxhciggdGhpcy5yb3RhdGVTcGVlZCApO1xyXG5cclxuICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZG9tRWxlbWVudDtcclxuXHJcbiAgICAgIHJvdGF0ZUxlZnQoKDIgKiBNYXRoLlBJICogcm90YXRlRGVsdGEueCkgLyBlbGVtZW50LmNsaWVudEhlaWdodCk7IC8vIHllcywgaGVpZ2h0XHJcblxyXG4gICAgICByb3RhdGVVcCgoMiAqIE1hdGguUEkgKiByb3RhdGVEZWx0YS55KSAvIGVsZW1lbnQuY2xpZW50SGVpZ2h0KTtcclxuICAgICAgVmVjdG9yMi5jbG9uZShyb3RhdGVFbmQsIHJvdGF0ZVN0YXJ0KTtcclxuICAgICAgLy9yb3RhdGVTdGFydC5jb3B5KCByb3RhdGVFbmQgKTtcclxuICAgIH07XHJcblxyXG4gICAgY29uc3QgaGFuZGxlVG91Y2hNb3ZlUGFuID0gKGV2ZW50KSA9PiB7XHJcbiAgICAgIGlmIChwb2ludGVycy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICBwYW5FbmQuc2V0KGV2ZW50LnBhZ2VYLCBldmVudC5wYWdlWSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgcG9zaXRpb24gPSBnZXRTZWNvbmRQb2ludGVyUG9zaXRpb24oZXZlbnQpO1xyXG5cclxuICAgICAgICBjb25zdCB4ID0gMC41ICogKGV2ZW50LnBhZ2VYICsgcG9zaXRpb24ueCk7XHJcbiAgICAgICAgY29uc3QgeSA9IDAuNSAqIChldmVudC5wYWdlWSArIHBvc2l0aW9uLnkpO1xyXG5cclxuICAgICAgICBwYW5FbmQuc2V0KHgsIHkpO1xyXG4gICAgICB9XHJcbiAgICAgIFZlY3RvcjIuc3VidHJhY3QocGFuRW5kLCBwYW5TdGFydCwgcGFuRGVsdGEpO1xyXG4gICAgICBWZWN0b3IyLm11bHRpcGx5QnlTY2FsYXIocGFuRGVsdGEsIHRoaXMucGFuU3BlZWQsIHBhbkRlbHRhKTtcclxuXHJcbiAgICAgIC8vcGFuRGVsdGEuc3ViVmVjdG9ycyggcGFuRW5kLCBwYW5TdGFydCApLm11bHRpcGx5U2NhbGFyKCB0aGlzLnBhblNwZWVkICk7XHJcblxyXG4gICAgICBwYW4ocGFuRGVsdGEueCwgcGFuRGVsdGEueSk7XHJcblxyXG4gICAgICBWZWN0b3IyLmNsb25lKHBhbkVuZCwgcGFuU3RhcnQpO1xyXG4gICAgICAvLyBwYW5TdGFydC5jb3B5KCBwYW5FbmQgKTtcclxuICAgIH07XHJcblxyXG4gICAgY29uc3QgaGFuZGxlVG91Y2hNb3ZlRG9sbHkgPSAoZXZlbnQpID0+IHtcclxuICAgICAgY29uc3QgcG9zaXRpb24gPSBnZXRTZWNvbmRQb2ludGVyUG9zaXRpb24oZXZlbnQpO1xyXG5cclxuICAgICAgY29uc3QgZHggPSBldmVudC5wYWdlWCAtIHBvc2l0aW9uLng7XHJcbiAgICAgIGNvbnN0IGR5ID0gZXZlbnQucGFnZVkgLSBwb3NpdGlvbi55O1xyXG5cclxuICAgICAgY29uc3QgZGlzdGFuY2UgPSBNYXRoLnNxcnQoZHggKiBkeCArIGR5ICogZHkpO1xyXG5cclxuICAgICAgZG9sbHlFbmQuc2V0KDAsIGRpc3RhbmNlKTtcclxuXHJcbiAgICAgIGRvbGx5RGVsdGEuc2V0KDAsIE1hdGgucG93KGRvbGx5RW5kLnkgLyBkb2xseVN0YXJ0LnksIHRoaXMuem9vbVNwZWVkKSk7XHJcblxyXG4gICAgICBkb2xseU91dChkb2xseURlbHRhLnkpO1xyXG5cclxuICAgICAgVmVjdG9yMi5jbG9uZShkb2xseUVuZCwgZG9sbHlTdGFydCk7XHJcbiAgICAgIC8vZG9sbHlTdGFydC5jb3B5KCBkb2xseUVuZCApO1xyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBoYW5kbGVUb3VjaE1vdmVEb2xseVBhbiA9IChldmVudCkgPT4ge1xyXG4gICAgICBpZiAodGhpcy5lbmFibGVab29tKSBoYW5kbGVUb3VjaE1vdmVEb2xseShldmVudCk7XHJcblxyXG4gICAgICBpZiAodGhpcy5lbmFibGVQYW4pIGhhbmRsZVRvdWNoTW92ZVBhbihldmVudCk7XHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0IGhhbmRsZVRvdWNoTW92ZURvbGx5Um90YXRlID0gKGV2ZW50KSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLmVuYWJsZVpvb20pIGhhbmRsZVRvdWNoTW92ZURvbGx5KGV2ZW50KTtcclxuXHJcbiAgICAgIGlmICh0aGlzLmVuYWJsZVJvdGF0ZSkgaGFuZGxlVG91Y2hNb3ZlUm90YXRlKGV2ZW50KTtcclxuICAgIH07XHJcblxyXG4gICAgLy9cclxuICAgIC8vIGV2ZW50IGhhbmRsZXJzIC0gRlNNOiBsaXN0ZW4gZm9yIGV2ZW50cyBhbmQgcmVzZXQgc3RhdGVcclxuICAgIC8vXHJcblxyXG4gICAgdGhpcy5vblBvaW50ZXJEb3duID0gKGV2ZW50KSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLmVuYWJsZWQgPT09IGZhbHNlKSByZXR1cm47XHJcblxyXG4gICAgICBpZiAocG9pbnRlcnMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgdGhpcy5kb21FbGVtZW50LnNldFBvaW50ZXJDYXB0dXJlKGV2ZW50LnBvaW50ZXJJZCk7XHJcblxyXG4gICAgICAgIHRoaXMuZG9tRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwicG9pbnRlcm1vdmVcIiwgdGhpcy5vblBvaW50ZXJNb3ZlKTtcclxuICAgICAgICB0aGlzLmRvbUVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInBvaW50ZXJ1cFwiLCB0aGlzLm9uUG9pbnRlclVwKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy9cclxuXHJcbiAgICAgIGFkZFBvaW50ZXIoZXZlbnQpO1xyXG5cclxuICAgICAgaWYgKGV2ZW50LnBvaW50ZXJUeXBlID09PSBcInRvdWNoXCIpIHtcclxuICAgICAgICBvblRvdWNoU3RhcnQoZXZlbnQpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIG9uTW91c2VEb3duKGV2ZW50KTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLm9uUG9pbnRlck1vdmUgPSAoZXZlbnQpID0+IHtcclxuICAgICAgaWYgKHRoaXMuZW5hYmxlZCA9PT0gZmFsc2UpIHJldHVybjtcclxuXHJcbiAgICAgIGlmIChldmVudC5wb2ludGVyVHlwZSA9PT0gXCJ0b3VjaFwiKSB7XHJcbiAgICAgICAgb25Ub3VjaE1vdmUoZXZlbnQpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIG9uTW91c2VNb3ZlKGV2ZW50KTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLm9uUG9pbnRlclVwID0gKGV2ZW50KSA9PiB7XHJcbiAgICAgIHJlbW92ZVBvaW50ZXIoZXZlbnQpO1xyXG5cclxuICAgICAgaWYgKHBvaW50ZXJzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgIHRoaXMuZG9tRWxlbWVudC5yZWxlYXNlUG9pbnRlckNhcHR1cmUoZXZlbnQucG9pbnRlcklkKTtcclxuXHJcbiAgICAgICAgdGhpcy5kb21FbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJwb2ludGVybW92ZVwiLCB0aGlzLm9uUG9pbnRlck1vdmUpO1xyXG4gICAgICAgIHRoaXMuZG9tRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwicG9pbnRlcnVwXCIsIHRoaXMub25Qb2ludGVyVXApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoX2VuZEV2ZW50KTtcclxuXHJcbiAgICAgIHN0YXRlID0gU1RBVEUuTk9ORTtcclxuICAgIH07XHJcblxyXG4gICAgY29uc3Qgb25Nb3VzZURvd24gPSAoZXZlbnQpID0+IHtcclxuICAgICAgbGV0IG1vdXNlQWN0aW9uO1xyXG5cclxuICAgICAgc3dpdGNoIChldmVudC5idXR0b24pIHtcclxuICAgICAgICBjYXNlIDA6XHJcbiAgICAgICAgICBtb3VzZUFjdGlvbiA9IHRoaXMubW91c2VCdXR0b25zLkxFRlQ7XHJcbiAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgY2FzZSAxOlxyXG4gICAgICAgICAgbW91c2VBY3Rpb24gPSB0aGlzLm1vdXNlQnV0dG9ucy5NSURETEU7XHJcbiAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgY2FzZSAyOlxyXG4gICAgICAgICAgbW91c2VBY3Rpb24gPSB0aGlzLm1vdXNlQnV0dG9ucy5SSUdIVDtcclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgbW91c2VBY3Rpb24gPSAtMTtcclxuICAgICAgfVxyXG5cclxuICAgICAgc3dpdGNoIChtb3VzZUFjdGlvbikge1xyXG4gICAgICAgIGNhc2UgTU9VU0UuRE9MTFk6XHJcbiAgICAgICAgICBpZiAodGhpcy5lbmFibGVab29tID09PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgIGhhbmRsZU1vdXNlRG93bkRvbGx5KGV2ZW50KTtcclxuXHJcbiAgICAgICAgICBzdGF0ZSA9IFNUQVRFLkRPTExZO1xyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBjYXNlIE1PVVNFLlJPVEFURTpcclxuICAgICAgICAgIGlmIChldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkgfHwgZXZlbnQuc2hpZnRLZXkpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuZW5hYmxlUGFuID09PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgaGFuZGxlTW91c2VEb3duUGFuKGV2ZW50KTtcclxuXHJcbiAgICAgICAgICAgIHN0YXRlID0gU1RBVEUuUEFOO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuZW5hYmxlUm90YXRlID09PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgaGFuZGxlTW91c2VEb3duUm90YXRlKGV2ZW50KTtcclxuXHJcbiAgICAgICAgICAgIHN0YXRlID0gU1RBVEUuUk9UQVRFO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBjYXNlIE1PVVNFLlBBTjpcclxuICAgICAgICAgIGlmIChldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkgfHwgZXZlbnQuc2hpZnRLZXkpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuZW5hYmxlUm90YXRlID09PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgaGFuZGxlTW91c2VEb3duUm90YXRlKGV2ZW50KTtcclxuXHJcbiAgICAgICAgICAgIHN0YXRlID0gU1RBVEUuUk9UQVRFO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuZW5hYmxlUGFuID09PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgaGFuZGxlTW91c2VEb3duUGFuKGV2ZW50KTtcclxuXHJcbiAgICAgICAgICAgIHN0YXRlID0gU1RBVEUuUEFOO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgc3RhdGUgPSBTVEFURS5OT05FO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoc3RhdGUgIT09IFNUQVRFLk5PTkUpIHtcclxuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoX3N0YXJ0RXZlbnQpO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0IG9uTW91c2VNb3ZlID0gKGV2ZW50KSA9PiB7XHJcbiAgICAgIHN3aXRjaCAoc3RhdGUpIHtcclxuICAgICAgICBjYXNlIFNUQVRFLlJPVEFURTpcclxuICAgICAgICAgIGlmICh0aGlzLmVuYWJsZVJvdGF0ZSA9PT0gZmFsc2UpIHJldHVybjtcclxuXHJcbiAgICAgICAgICBoYW5kbGVNb3VzZU1vdmVSb3RhdGUoZXZlbnQpO1xyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBjYXNlIFNUQVRFLkRPTExZOlxyXG4gICAgICAgICAgaWYgKHRoaXMuZW5hYmxlWm9vbSA9PT0gZmFsc2UpIHJldHVybjtcclxuXHJcbiAgICAgICAgICBoYW5kbGVNb3VzZU1vdmVEb2xseShldmVudCk7XHJcblxyXG4gICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgIGNhc2UgU1RBVEUuUEFOOlxyXG4gICAgICAgICAgaWYgKHRoaXMuZW5hYmxlUGFuID09PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgIGhhbmRsZU1vdXNlTW92ZVBhbihldmVudCk7XHJcblxyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5vbk1vdXNlV2hlZWwgPSAoZXZlbnQpID0+IHtcclxuICAgICAgaWYgKFxyXG4gICAgICAgIHRoaXMuZW5hYmxlZCA9PT0gZmFsc2UgfHxcclxuICAgICAgICB0aGlzLmVuYWJsZVpvb20gPT09IGZhbHNlIHx8XHJcbiAgICAgICAgc3RhdGUgIT09IFNUQVRFLk5PTkVcclxuICAgICAgKVxyXG4gICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoX3N0YXJ0RXZlbnQpO1xyXG5cclxuICAgICAgaGFuZGxlTW91c2VXaGVlbChldmVudCk7XHJcblxyXG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoX2VuZEV2ZW50KTtcclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5vbktleURvd24gPSAoZXZlbnQpID0+IHtcclxuICAgICAgaWYgKHRoaXMuZW5hYmxlZCA9PT0gZmFsc2UgfHwgdGhpcy5lbmFibGVQYW4gPT09IGZhbHNlKSByZXR1cm47XHJcblxyXG4gICAgICBoYW5kbGVLZXlEb3duKGV2ZW50KTtcclxuICAgIH07XHJcblxyXG4gICAgY29uc3Qgb25Ub3VjaFN0YXJ0ID0gKGV2ZW50KSA9PiB7XHJcbiAgICAgIHRyYWNrUG9pbnRlcihldmVudCk7XHJcblxyXG4gICAgICBzd2l0Y2ggKHBvaW50ZXJzLmxlbmd0aCkge1xyXG4gICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgIHN3aXRjaCAodGhpcy50b3VjaGVzLk9ORSkge1xyXG4gICAgICAgICAgICBjYXNlIFRPVUNILlJPVEFURTpcclxuICAgICAgICAgICAgICBpZiAodGhpcy5lbmFibGVSb3RhdGUgPT09IGZhbHNlKSByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgIGhhbmRsZVRvdWNoU3RhcnRSb3RhdGUoKTtcclxuXHJcbiAgICAgICAgICAgICAgc3RhdGUgPSBTVEFURS5UT1VDSF9ST1RBVEU7XHJcblxyXG4gICAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICAgICAgY2FzZSBUT1VDSC5QQU46XHJcbiAgICAgICAgICAgICAgaWYgKHRoaXMuZW5hYmxlUGFuID09PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICBoYW5kbGVUb3VjaFN0YXJ0UGFuKCk7XHJcblxyXG4gICAgICAgICAgICAgIHN0YXRlID0gU1RBVEUuVE9VQ0hfUEFOO1xyXG5cclxuICAgICAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgc3RhdGUgPSBTVEFURS5OT05FO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICBzd2l0Y2ggKHRoaXMudG91Y2hlcy5UV08pIHtcclxuICAgICAgICAgICAgY2FzZSBUT1VDSC5ET0xMWV9QQU46XHJcbiAgICAgICAgICAgICAgaWYgKHRoaXMuZW5hYmxlWm9vbSA9PT0gZmFsc2UgJiYgdGhpcy5lbmFibGVQYW4gPT09IGZhbHNlKSByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgIGhhbmRsZVRvdWNoU3RhcnREb2xseVBhbigpO1xyXG5cclxuICAgICAgICAgICAgICBzdGF0ZSA9IFNUQVRFLlRPVUNIX0RPTExZX1BBTjtcclxuXHJcbiAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICBjYXNlIFRPVUNILkRPTExZX1JPVEFURTpcclxuICAgICAgICAgICAgICBpZiAodGhpcy5lbmFibGVab29tID09PSBmYWxzZSAmJiB0aGlzLmVuYWJsZVJvdGF0ZSA9PT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgIGhhbmRsZVRvdWNoU3RhcnREb2xseVJvdGF0ZSgpO1xyXG5cclxuICAgICAgICAgICAgICBzdGF0ZSA9IFNUQVRFLlRPVUNIX0RPTExZX1JPVEFURTtcclxuXHJcbiAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgIHN0YXRlID0gU1RBVEUuTk9ORTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgIHN0YXRlID0gU1RBVEUuTk9ORTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHN0YXRlICE9PSBTVEFURS5OT05FKSB7XHJcbiAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KF9zdGFydEV2ZW50KTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBvblRvdWNoTW92ZSA9IChldmVudCkgPT4ge1xyXG4gICAgICB0cmFja1BvaW50ZXIoZXZlbnQpO1xyXG5cclxuICAgICAgc3dpdGNoIChzdGF0ZSkge1xyXG4gICAgICAgIGNhc2UgU1RBVEUuVE9VQ0hfUk9UQVRFOlxyXG4gICAgICAgICAgaWYgKHRoaXMuZW5hYmxlUm90YXRlID09PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgIGhhbmRsZVRvdWNoTW92ZVJvdGF0ZShldmVudCk7XHJcblxyXG4gICAgICAgICAgdGhpcy51cGRhdGUoKTtcclxuXHJcbiAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgY2FzZSBTVEFURS5UT1VDSF9QQU46XHJcbiAgICAgICAgICBpZiAodGhpcy5lbmFibGVQYW4gPT09IGZhbHNlKSByZXR1cm47XHJcblxyXG4gICAgICAgICAgaGFuZGxlVG91Y2hNb3ZlUGFuKGV2ZW50KTtcclxuXHJcbiAgICAgICAgICB0aGlzLnVwZGF0ZSgpO1xyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBjYXNlIFNUQVRFLlRPVUNIX0RPTExZX1BBTjpcclxuICAgICAgICAgIGlmICh0aGlzLmVuYWJsZVpvb20gPT09IGZhbHNlICYmIHRoaXMuZW5hYmxlUGFuID09PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgIGhhbmRsZVRvdWNoTW92ZURvbGx5UGFuKGV2ZW50KTtcclxuXHJcbiAgICAgICAgICB0aGlzLnVwZGF0ZSgpO1xyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBjYXNlIFNUQVRFLlRPVUNIX0RPTExZX1JPVEFURTpcclxuICAgICAgICAgIGlmICh0aGlzLmVuYWJsZVpvb20gPT09IGZhbHNlICYmIHRoaXMuZW5hYmxlUm90YXRlID09PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgIGhhbmRsZVRvdWNoTW92ZURvbGx5Um90YXRlKGV2ZW50KTtcclxuXHJcbiAgICAgICAgICB0aGlzLnVwZGF0ZSgpO1xyXG5cclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgc3RhdGUgPSBTVEFURS5OT05FO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMub25Db250ZXh0TWVudSA9IChldmVudCkgPT4ge1xyXG4gICAgICBpZiAodGhpcy5lbmFibGVkID09PSBmYWxzZSkgcmV0dXJuO1xyXG5cclxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIH07XHJcbiAgICB0aGlzLmdldEF1dG9Sb3RhdGlvbkFuZ2xlID0gKCkgPT4ge1xyXG4gICAgICByZXR1cm4gKCgyICogTWF0aC5QSSkgLyA2MCAvIDYwKSAqIHRoaXMuYXV0b1JvdGF0ZVNwZWVkO1xyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBnZXRab29tU2NhbGUgPSAoKSA9PiB7XHJcbiAgICAgIHJldHVybiBNYXRoLnBvdygwLjk1LCB0aGlzLnpvb21TcGVlZCk7XHJcbiAgICB9O1xyXG4gICAgdGhpcy5kb21FbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJjb250ZXh0bWVudVwiLCB0aGlzLm9uQ29udGV4dE1lbnUpO1xyXG5cclxuICAgIHRoaXMuZG9tRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwicG9pbnRlcmRvd25cIiwgdGhpcy5vblBvaW50ZXJEb3duKTtcclxuICAgIHRoaXMuZG9tRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwicG9pbnRlcmNhbmNlbFwiLCBvblBvaW50ZXJDYW5jZWwpO1xyXG4gICAgdGhpcy5kb21FbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ3aGVlbFwiLCB0aGlzLm9uTW91c2VXaGVlbCwge1xyXG4gICAgICBwYXNzaXZlOiBmYWxzZSxcclxuICAgIH0pO1xyXG4gIH1cclxuICBkaXNwb3NlKCkge1xyXG4gICAgdGhpcy5kb21FbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjb250ZXh0bWVudVwiLCB0aGlzLm9uQ29udGV4dE1lbnUpO1xyXG5cclxuICAgIHRoaXMuZG9tRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwicG9pbnRlcmRvd25cIiwgdGhpcy5vblBvaW50ZXJEb3duKTtcclxuICAgIHRoaXMuZG9tRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwicG9pbnRlcmNhbmNlbFwiLCBvblBvaW50ZXJDYW5jZWwpO1xyXG4gICAgdGhpcy5kb21FbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ3aGVlbFwiLCB0aGlzLm9uTW91c2VXaGVlbCk7XHJcblxyXG4gICAgdGhpcy5kb21FbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJwb2ludGVybW92ZVwiLCB0aGlzLm9uUG9pbnRlck1vdmUpO1xyXG4gICAgdGhpcy5kb21FbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJwb2ludGVydXBcIiwgdGhpcy5vblBvaW50ZXJVcCk7XHJcblxyXG4gICAgaWYgKHRoaXMuX2RvbUVsZW1lbnRLZXlFdmVudHMgIT09IG51bGwpIHtcclxuICAgICAgdGhpcy5fZG9tRWxlbWVudEtleUV2ZW50cy5yZW1vdmVFdmVudExpc3RlbmVyKFwia2V5ZG93blwiLCB0aGlzLm9uS2V5RG93bik7XHJcbiAgICB9XHJcblxyXG4gICAgLy90aGlzLmRpc3BhdGNoRXZlbnQoIHsgdHlwZTogJ2Rpc3Bvc2UnIH0gKTsgLy8gc2hvdWxkIHRoaXMgYmUgYWRkZWQgaGVyZT9cclxuICB9XHJcbn1cclxuY29uc3QgU1RBVEUgPSB7XHJcbiAgTk9ORTogLTEsXHJcbiAgUk9UQVRFOiAwLFxyXG4gIERPTExZOiAxLFxyXG4gIFBBTjogMixcclxuICBUT1VDSF9ST1RBVEU6IDMsXHJcbiAgVE9VQ0hfUEFOOiA0LFxyXG4gIFRPVUNIX0RPTExZX1BBTjogNSxcclxuICBUT1VDSF9ET0xMWV9ST1RBVEU6IDYsXHJcbn07XHJcblxyXG5sZXQgc3RhdGUgPSBTVEFURS5OT05FO1xyXG5cclxuY29uc3QgRVBTID0gMC4wMDAwMDE7XHJcblxyXG4vLyBjdXJyZW50IHBvc2l0aW9uIGluIHNwaGVyaWNhbCBjb29yZGluYXRlc1xyXG5jb25zdCBzcGhlcmljYWwgPSBuZXcgU3BoZXJpY2FsKCk7XHJcbmNvbnN0IHNwaGVyaWNhbERlbHRhID0gbmV3IFNwaGVyaWNhbCgpO1xyXG5cclxubGV0IHNjYWxlID0gMTtcclxuY29uc3QgcGFuT2Zmc2V0ID0gbmV3IFZlY3RvcjMoKTtcclxubGV0IHpvb21DaGFuZ2VkID0gZmFsc2U7XHJcblxyXG5jb25zdCByb3RhdGVTdGFydCA9IG5ldyBWZWN0b3IyKCk7XHJcbmNvbnN0IHJvdGF0ZUVuZCA9IG5ldyBWZWN0b3IyKCk7XHJcbmNvbnN0IHJvdGF0ZURlbHRhID0gbmV3IFZlY3RvcjIoKTtcclxuXHJcbmNvbnN0IHBhblN0YXJ0ID0gbmV3IFZlY3RvcjIoKTtcclxuY29uc3QgcGFuRW5kID0gbmV3IFZlY3RvcjIoKTtcclxuY29uc3QgcGFuRGVsdGEgPSBuZXcgVmVjdG9yMigpO1xyXG5cclxuY29uc3QgZG9sbHlTdGFydCA9IG5ldyBWZWN0b3IyKCk7XHJcbmNvbnN0IGRvbGx5RW5kID0gbmV3IFZlY3RvcjIoKTtcclxuY29uc3QgZG9sbHlEZWx0YSA9IG5ldyBWZWN0b3IyKCk7XHJcblxyXG5jb25zdCBwb2ludGVycyA9IFtdO1xyXG5jb25zdCBwb2ludGVyUG9zaXRpb25zID0ge307XHJcbmV4cG9ydCBlbnVtIE1PVVNFIHtcclxuICBMRUZUID0gMCxcclxuICBNSURETEUgPSAxLFxyXG4gIFJJR0hUID0gMixcclxuICBST1RBVEUgPSAwLFxyXG4gIERPTExZID0gMSxcclxuICBQQU4gPSAyLFxyXG59XHJcblxyXG5leHBvcnQgZW51bSBUT1VDSCB7XHJcbiAgUk9UQVRFLFxyXG4gIFBBTixcclxuICBET0xMWV9QQU4sXHJcbiAgRE9MTFlfUk9UQVRFLFxyXG59XHJcbmZ1bmN0aW9uIHJvdGF0ZUxlZnQoYW5nbGUpIHtcclxuICBzcGhlcmljYWxEZWx0YS50aGV0YSAtPSBhbmdsZTtcclxufVxyXG5cclxuZnVuY3Rpb24gcm90YXRlVXAoYW5nbGUpIHtcclxuICBzcGhlcmljYWxEZWx0YS5waGkgLT0gYW5nbGU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFkZFBvaW50ZXIoZXZlbnQpIHtcclxuICBwb2ludGVycy5wdXNoKGV2ZW50KTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVtb3ZlUG9pbnRlcihldmVudCkge1xyXG4gIGRlbGV0ZSBwb2ludGVyUG9zaXRpb25zW2V2ZW50LnBvaW50ZXJJZF07XHJcblxyXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcG9pbnRlcnMubGVuZ3RoOyBpKyspIHtcclxuICAgIGlmIChwb2ludGVyc1tpXS5wb2ludGVySWQgPT0gZXZlbnQucG9pbnRlcklkKSB7XHJcbiAgICAgIHBvaW50ZXJzLnNwbGljZShpLCAxKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gdHJhY2tQb2ludGVyKGV2ZW50KSB7XHJcbiAgbGV0IHBvc2l0aW9uID0gcG9pbnRlclBvc2l0aW9uc1tldmVudC5wb2ludGVySWRdO1xyXG5cclxuICBpZiAocG9zaXRpb24gPT09IHVuZGVmaW5lZCkge1xyXG4gICAgcG9zaXRpb24gPSBuZXcgVmVjdG9yMigpO1xyXG4gICAgcG9pbnRlclBvc2l0aW9uc1tldmVudC5wb2ludGVySWRdID0gcG9zaXRpb247XHJcbiAgfVxyXG5cclxuICBwb3NpdGlvbi5zZXQoZXZlbnQucGFnZVgsIGV2ZW50LnBhZ2VZKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0U2Vjb25kUG9pbnRlclBvc2l0aW9uKGV2ZW50KSB7XHJcbiAgY29uc3QgcG9pbnRlciA9XHJcbiAgICBldmVudC5wb2ludGVySWQgPT09IHBvaW50ZXJzWzBdLnBvaW50ZXJJZCA/IHBvaW50ZXJzWzFdIDogcG9pbnRlcnNbMF07XHJcblxyXG4gIHJldHVybiBwb2ludGVyUG9zaXRpb25zW3BvaW50ZXIucG9pbnRlcklkXTtcclxufVxyXG5cclxuZnVuY3Rpb24gaGFuZGxlTW91c2VEb3duUm90YXRlKGV2ZW50KSB7XHJcbiAgcm90YXRlU3RhcnQuc2V0KGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFkpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBoYW5kbGVNb3VzZURvd25Eb2xseShldmVudCkge1xyXG4gIGRvbGx5U3RhcnQuc2V0KGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFkpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBoYW5kbGVNb3VzZURvd25QYW4oZXZlbnQpIHtcclxuICBwYW5TdGFydC5zZXQoZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSk7XHJcbn1cclxuZnVuY3Rpb24gb25Qb2ludGVyQ2FuY2VsKGV2ZW50KSB7XHJcbiAgcmVtb3ZlUG9pbnRlcihldmVudCk7XHJcbn1cclxuZnVuY3Rpb24gaGFuZGxlVG91Y2hTdGFydFJvdGF0ZSgpIHtcclxuICBpZiAocG9pbnRlcnMubGVuZ3RoID09PSAxKSB7XHJcbiAgICByb3RhdGVTdGFydC5zZXQocG9pbnRlcnNbMF0ucGFnZVgsIHBvaW50ZXJzWzBdLnBhZ2VZKTtcclxuICB9IGVsc2Uge1xyXG4gICAgY29uc3QgeCA9IDAuNSAqIChwb2ludGVyc1swXS5wYWdlWCArIHBvaW50ZXJzWzFdLnBhZ2VYKTtcclxuICAgIGNvbnN0IHkgPSAwLjUgKiAocG9pbnRlcnNbMF0ucGFnZVkgKyBwb2ludGVyc1sxXS5wYWdlWSk7XHJcblxyXG4gICAgcm90YXRlU3RhcnQuc2V0KHgsIHkpO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gaGFuZGxlVG91Y2hTdGFydFBhbigpIHtcclxuICBpZiAocG9pbnRlcnMubGVuZ3RoID09PSAxKSB7XHJcbiAgICBwYW5TdGFydC5zZXQocG9pbnRlcnNbMF0ucGFnZVgsIHBvaW50ZXJzWzBdLnBhZ2VZKTtcclxuICB9IGVsc2Uge1xyXG4gICAgY29uc3QgeCA9IDAuNSAqIChwb2ludGVyc1swXS5wYWdlWCArIHBvaW50ZXJzWzFdLnBhZ2VYKTtcclxuICAgIGNvbnN0IHkgPSAwLjUgKiAocG9pbnRlcnNbMF0ucGFnZVkgKyBwb2ludGVyc1sxXS5wYWdlWSk7XHJcblxyXG4gICAgcGFuU3RhcnQuc2V0KHgsIHkpO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gaGFuZGxlVG91Y2hTdGFydERvbGx5KCkge1xyXG4gIGNvbnN0IGR4ID0gcG9pbnRlcnNbMF0ucGFnZVggLSBwb2ludGVyc1sxXS5wYWdlWDtcclxuICBjb25zdCBkeSA9IHBvaW50ZXJzWzBdLnBhZ2VZIC0gcG9pbnRlcnNbMV0ucGFnZVk7XHJcblxyXG4gIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTtcclxuXHJcbiAgZG9sbHlTdGFydC5zZXQoMCwgZGlzdGFuY2UpO1xyXG59XHJcbiJdLCJuYW1lcyI6WyJNZXJzZW5uZVR3aXN0ZXIiLCJkaXN0YW5jZVNjcmF0Y2giLCJsZXJwU2NyYXRjaCIsImFuZ2xlQmV0d2VlblNjcmF0Y2giLCJhbmdsZUJldHdlZW5TY3JhdGNoMiIsIm1vc3RPcnRob2dvbmFsQXhpc1NjcmF0Y2giLCJzY2FsZVNjcmF0Y2gxIiwic2NyYXRjaENvbHVtbiIsInNjYWxlU2NyYXRjaDMiLCJzY2FsZVNjcmF0Y2g0Iiwic2NhbGVTY3JhdGNoNSIsInNjcmF0Y2hUcmFuc3Bvc2VNYXRyaXgiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0EsSUFBWSxvQkFFWCxDQUFBO0FBRkQsQ0FBQSxVQUFZLG9CQUFvQixFQUFBO0FBQy9CLElBQUEsb0JBQUEsQ0FBQSxNQUFBLENBQUEsR0FBQSxNQUFhLENBQUE7QUFDZCxDQUFDLEVBRlcsb0JBQW9CLEtBQXBCLG9CQUFvQixHQUUvQixFQUFBLENBQUEsQ0FBQSxDQUFBO0FBRUQ7QUFDQSxJQUFZLGVBR1gsQ0FBQTtBQUhELENBQUEsVUFBWSxlQUFlLEVBQUE7QUFDMUIsSUFBQSxlQUFBLENBQUEsVUFBQSxDQUFBLEdBQUEsV0FBc0IsQ0FBQTtBQUN0QixJQUFBLGVBQUEsQ0FBQSxpQkFBQSxDQUFBLEdBQUEsa0JBQW9DLENBQUE7QUFDckMsQ0FBQyxFQUhXLGVBQWUsS0FBZixlQUFlLEdBRzFCLEVBQUEsQ0FBQSxDQUFBLENBQUE7QUFFRDtBQUNBLElBQVksV0FXWCxDQUFBO0FBWEQsQ0FBQSxVQUFZLFdBQVcsRUFBQTtBQUN0QixJQUFBLFdBQUEsQ0FBQSxrQkFBQSxDQUFBLEdBQUEsb0JBQXVDLENBQUE7QUFDdkMsSUFBQSxXQUFBLENBQUEsc0JBQUEsQ0FBQSxHQUFBLHVCQUE4QyxDQUFBO0FBQzlDLElBQUEsV0FBQSxDQUFBLHNCQUFBLENBQUEsR0FBQSx1QkFBOEMsQ0FBQTtBQUM5QyxJQUFBLFdBQUEsQ0FBQSxzQkFBQSxDQUFBLEdBQUEsd0JBQStDLENBQUE7QUFDL0MsSUFBQSxXQUFBLENBQUEsd0JBQUEsQ0FBQSxHQUFBLDBCQUFtRCxDQUFBO0FBQ25ELElBQUEsV0FBQSxDQUFBLHdCQUFBLENBQUEsR0FBQSwwQkFBbUQsQ0FBQTtBQUNuRCxJQUFBLFdBQUEsQ0FBQSxnQkFBQSxDQUFBLEdBQUEsaUJBQWtDLENBQUE7QUFDbEMsSUFBQSxXQUFBLENBQUEsdUJBQUEsQ0FBQSxHQUFBLHlCQUFpRCxDQUFBO0FBQ2pELElBQUEsV0FBQSxD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YSxHQUFHLFNBQVMsUUFBUSxFQUFFLFVBQVUsRUFBRTtBQUN6RSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDYixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDMUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNWLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUM7QUFDL0MsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtBQUNoQixFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBQztBQUM5QyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLFVBQVUsTUFBTSxFQUFFLElBQUksT0FBTyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUMsR0FBRyxVQUFVLElBQUksT0FBTyxDQUFDLENBQUM7QUFDM0csSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDcEIsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ1gsRUFBRSxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDekQsRUFBRSxJQUFJLENBQUMsRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN6QixFQUFFO0FBQ0YsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7QUFDMUIsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztBQUMvQyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLFVBQVUsTUFBTSxFQUFFLElBQUksVUFBVSxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxVQUFVLElBQUksVUFBVSxDQUFDO0FBQy9HLElBQUksQ0FBQyxDQUFDO0FBQ04sRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNwQixFQUFFLENBQUMsRUFBRSxDQUFDO0FBQ04sRUFBRSxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDekQsRUFBRTtBQUNGO0FBQ0EsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQztBQUN6QixFQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsZUFBZSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEdBQUcsV0FBVztBQUNsRCxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ1AsQ0FBQyxJQUFJLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzNDO0FBQ0E7QUFDQSxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQyxFQUFFO0FBQ3pCLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDVDtBQUNBLEVBQUUsSUFBSSxJQUFJLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxQixHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDeEI7QUFDQSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFO0FBQ25DLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUNyRSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQ2pFLEdBQUc7QUFDSCxFQUFFLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFO0FBQzFCLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUNyRSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUMxRSxHQUFHO0FBQ0gsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUN2RSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFDckU7QUFDQSxFQUFFLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQ2YsRUFBRTtBQUNGO0FBQ0EsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztBQUN6QjtBQUNBO0FBQ0EsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO0FBQ2pCLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxVQUFVLENBQUM7QUFDNUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxJ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Q0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksT0FBTyxFQUFFLENBQUMsQ0FBQztLQUMxQztJQUNELE1BQU0sR0FBQTtBQUNMLFFBQUEsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7S0FDdEU7QUFDRCxJQUFBLFlBQVksQ0FBQyxNQUFlLEVBQUE7QUFDM0IsUUFBQSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxFQUNmLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxFQUNWLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ1osTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDO0FBQ2pCLFFBQUEsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3hELFFBQUEsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDdEQsUUFBQSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN0RCxRQUFBLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3ZELFFBQUEsT0FBTyxJQUFJLENBQUM7S0FDWjtBQUNELElBQUEsWUFBWSxDQUFDLE1BQWUsRUFBQTtBQUMzQixRQUFBLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEVBQ2YsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEVBQ1YsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDWixJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2RCxRQUFBLE9BQU8sSUFBSSxDQUFDO0tBQ1o7QUFDRCxJQUFBLGtCQUFrQixDQUFDLE1BQXlCLEVBQUE7QUFDM0MsUUFBQSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxFQUNmLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxFQUNWLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ1osTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN4QyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pDLFFBQUEsT0FBTyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7S0FDeEI7QUFFRCxJQUFBLHFCQUFxQixDQUFDLE1BQWUsRUFBQTtRQUNwQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUM7QUFFakIsUUFBQSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNmLFFBQUEsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDZixRQUFBLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBRWYsUUFBQSxPQUFPLElBQUksQ0FBQztLQUNaO0lBRUQsU0FBUyxHQUFBO0FBQ1IsUUFBQSxPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztBQUM5QixRQUFBLE9BQU8sSUFBSSxDQUFDO0tBQ1o7QUFFRCxJQUFBLE1BQU0sQ0FBQyxLQUFjLEVBQUE7UUFDcEIsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztLQUNuQztJQUVELGFBQWEsQ0FBQyxLQUFjLEVBQUUsZUFBZSxHQUFHLENBQUMsRUFBRSxlQUFlLEdBQUcsQ0FBQyxFQUFBO0FBQ3JFLFFBQUEsT0FBTyxPQUFPLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLGVBQWUsQ0FBQyxDQUFDO0tBQzVFO0lBRUQsUUFBUSxHQUFBO0FBQ1AsUUFBQSxPQUFPLENBQUksQ0FBQSxFQUFBLElBQUksQ0FBQyxDQUFDLENBQUssRUFBQSxFQUFBLElBQUksQ0FBQyxDQUFDLENBQUssRUFBQSxFQUFBLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQztLQUMzQztJQUNELG1CQUFtQixDQUFDLFNBQW9CLEVBQUUsS0FBYSxFQUFBO1FBQ3RELElBQUksQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0IsSUFBSSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQy9CLFFBQUEsT0FBTyxJQUFJLENBQUM7S0FDWjtBQUNELElBQUEsT0FBTyxXQUFXLENBQUMsSUFBYSxFQUFFLE1BQWUsRUFBQTtBQUNoRCxRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUNsQixRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUNsQixRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUNsQixRQUFBLE9BQU8sTUFBTSxDQUFDO0tBQ2Q7QUFFRCxJQUFBLE9BQU8sYUFBYSxDQUFDLFNBQW9CLEVBQUUsTUFBZSxFQUFBO0FBQ3pELFFBQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtBQUNyQixZQUFBLE1BQU0sR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0FBQ3ZCLFNBQUE7UUFDRCxNQUFNLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxTQUFTLENBQUM7UUFDekMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUM7UUFDNUMsTUFBTSxDQUFDLENBQUMsR0FBRyxZQUFZLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ2xDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsWUFBWSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDMUMsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0lBRUQsT0FBTyxZQUFZLENBQUMsQ0FBUyxFQUFFLENBQVMsRUFBRSxDQUFTLEVBQUUsTUFBZSxFQUFBO0FBQ25FLFFBQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNyQixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDNUIsU0FBQTtBQUVELFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtJQUVELE9BQU8sS0FBSyxDQUFDLFNBQWtCLEVBQUUsTUFBa0IsR0FBQSxJQUFJLE9BQU8sRUFBRSxFQUFBO0FBQy9ELFFBQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRTtBQUN4QixZQUFBLE9BQU8sU0FBUyxDQUFDO0FBQ2pCLFNBQUE7QUFDRCxRQUFBLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7QUFDckIsWUFBQSxPQUFPLElBQUksT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUQsU0FBQTtBQUVELFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtJQUVELE9BQU8sZ0JBQWdCLENBQUMsU0FBa0IsRUFBQTtBQUN6QyxRQUFBLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQ3ZEO0lBRUQsT0FBTyxnQkFBZ0IsQ0FBQyxTQUFrQixFQUFBO0FBQ3pDLFFBQUEsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7S0FDdkQ7QUFFRCxJQUFBLE9BQU8sa0JBQWtCLENBQUMsS0FBYyxFQUFFLE1BQWUsRUFBRSxNQUFlLEVBQUE7QUFDekUsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkMsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkMsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFdkMsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLGtCQUFrQixDQUFDLEtBQWMsRUFBRSxNQUFlLEVBQUUsTUFBZSxFQUFBO0FBQ3pFLFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZDLFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZDLFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZDLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtJQUVELE9BQU8sS0FBSyxDQUFDLEtBQWMsRUFBRSxHQUFZLEVBQUUsR0FBWSxFQUFFLE1BQWUsRUFBQTtBQUN2RSxRQUFBLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3QyxRQUFBLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3QyxRQUFBLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUU3QyxRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFFYixRQUFBLE9BQU8sTUFBTSxDQUFDO0tBQ2Q7SUFFRCxPQUFPLGdCQUFnQixDQUFDLFNBQWtCLEVBQUE7UUFDekMsT0FBTyxTQUFTLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztLQUN6RjtJQUVELE9BQU8sU0FBUyxDQUFDLFNBQWtCLEVBQUE7UUFDbEMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO0tBQ3REO0FBRUQsSUFBQSxPQUFPLFFBQVEsQ0FBQyxJQUFhLEVBQUUsS0FBYyxFQUFBO1FBQzVDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRUosaUJBQWUsQ0FBQyxDQUFDO0FBQy9DLFFBQUEsT0FBTyxPQUFPLENBQUMsU0FBUyxDQUFDQSxpQkFBZSxDQUFDLENBQUM7S0FDMUM7QUFFRCxJQUFBLE9BQU8sZUFBZSxDQUFDLElBQWEsRUFBRSxLQUFjLEVBQUE7UUFDbkQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFQSxpQkFBZSxDQUFDLENBQUM7QUFDL0MsUUFBQSxPQUFPLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQ0EsaUJBQWUsQ0FBQyxDQUFDO0tBQ2pEO0FBRUQsSUFBQSxPQUFPLFNBQVMsQ0FBQyxTQUFrQixFQUFFLE1BQWUsRUFBQTtRQUNuRCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRS9DLE1BQU0sQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUM7UUFDbkMsTUFBTSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQztRQUNuQyxNQUFNLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDO1FBRW5DLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDMUQsWUFBQSxNQUFNLElBQUksS0FBSyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7QUFDckQsU0FBQTtBQUVELFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxHQUFHLENBQUMsSUFBYSxFQUFFLEtBQWMsRUFBQTtRQUN2QyxPQUFPLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0tBQzlEO0FBRUQsSUFBQSxPQUFPLGtCQUFrQixDQUFDLElBQWEsRUFBRSxLQUFjLEVBQUUsTUFBZSxFQUFBO1FBQ3ZFLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzVCLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxnQkFBZ0IsQ0FBQyxJQUFhLEVBQUUsS0FBYyxFQUFFLE1BQWUsRUFBQTtRQUNyRSxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUM1QixNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUM1QixNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUM1QixRQUFBLE9BQU8sTUFBTSxDQUFDO0tBQ2Q7QUFFRCxJQUFBLE9BQU8sR0FBRyxDQUFDLElBQWEsRUFBRSxLQUFjLEVBQUUsTUFBZSxFQUFBO1FBQ3hELE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzVCLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxRQUFRLENBQUMsSUFBYSxFQUFFLEtBQWMsRUFBRSxNQUFlLEVBQUE7UUFDN0QsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDNUIsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDNUIsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDNUIsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLGdCQUFnQixDQUFDLFNBQWtCLEVBQUUsTUFBYyxFQUFFLE1BQWUsRUFBQTtRQUMxRSxNQUFNLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ2hDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUM7UUFDaEMsTUFBTSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQztBQUNoQyxRQUFBLE9BQU8sTUFBTSxDQUFDO0tBQ2Q7QUFFRCxJQUFBLE9BQU8sY0FBYyxDQUFDLFNBQWtCLEVBQUUsTUFBYyxFQUFFLE1BQWUsRUFBQTtRQUN4RSxNQUFNLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ2hDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUM7UUFDaEMsTUFBTSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQztBQUNoQyxRQUFBLE9BQU8sTUFBTSxDQUFDO0tBQ2Q7QUFFRCxJQUFBLE9BQU8sTUFBTSxDQUFDLFNBQWtCLEVBQUUsTUFBZSxFQUFBO0FBQ2hELFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxHQUFHLENBQUMsU0FBa0IsRUFBRSxNQUFlLEVBQUE7UUFDN0MsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqQyxNQUFNLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDakMsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0lBRUQsT0FBTyxJQUFJLENBQUMsS0FBYyxFQUFFLEdBQVksRUFBRSxDQUFTLEVBQUUsTUFBZSxFQUFBO1FBQ25FLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFQyxhQUFXLENBQUMsQ0FBQztBQUM5QyxRQUFBLE1BQU0sR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLEdBQUcsR0FBRyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDMUQsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDQSxhQUFXLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0tBQ2hEO0FBRUQsSUFBQSxPQUFPLFlBQVksQ0FBQyxJQUFhLEVBQUUsS0FBYyxFQUFBO0FBQ2hELFFBQUEsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztBQUM3QyxRQUFBLE9BQU8sQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLG9CQUFvQixDQUFDLENBQUM7UUFDL0MsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO0FBQ3RFLFFBQUEsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLG1CQUFtQixFQUFFLG9CQUFvQixFQUFFLG1CQUFtQixDQUFDLENBQUMsQ0FBQztRQUM5RyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0tBQ2hDO0FBRUQsSUFBQSxPQUFPLGtCQUFrQixDQUFDLFNBQWtCLEVBQUUsTUFBZSxFQUFBO1FBQzVELE1BQU0sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLHlCQUF5QixDQUFDLENBQUM7QUFDbEUsUUFBQSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUVsQixRQUFBLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFO0FBQ2YsWUFBQSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDZixNQUFNLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQy9DLGFBQUE7QUFBTSxpQkFBQTtnQkFDTixNQUFNLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQy9DLGFBQUE7QUFDRCxTQUFBO0FBQU0sYUFBQSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUN0QixNQUFNLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQy9DLFNBQUE7QUFBTSxhQUFBO1lBQ04sTUFBTSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUMvQyxTQUFBO0FBRUQsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLGFBQWEsQ0FBQyxDQUFVLEVBQUUsQ0FBVSxFQUFFLE1BQWUsRUFBQTtBQUMzRCxRQUFBLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3JELE9BQU8sT0FBTyxDQUFDLGdCQUFnQixDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7S0FDbkQ7QUFFRCxJQUFBLE9BQU8sTUFBTSxDQUFDLElBQWEsRUFBRSxLQUFjLEVBQUE7UUFDMUMsUUFDQyxJQUFJLEtBQUssS0FBSztBQUNkLGFBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxLQUFLLEtBQUssQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUNsRztLQUNGO0FBRUQ7O0FBRUc7QUFDSCxJQUFBLE9BQU8sV0FBVyxDQUFDLFNBQWtCLEVBQUUsS0FBZSxFQUFFLE1BQWMsRUFBQTtBQUNyRSxRQUFBLE9BQU8sU0FBUyxDQUFDLENBQUMsS0FBSyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksU0FBUyxDQUFDLENBQUMsS0FBSyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztLQUMvRztBQUVELElBQUEsT0FBTyxhQUFhLENBQUMsSUFBYSxFQUFFLEtBQWMsRUFBRSxlQUFlLEdBQUcsQ0FBQyxFQUFFLGVBQWUsR0FBRyxDQUFDLEVBQUE7UUFDM0YsUUFDQyxJQUFJLEtBQUssS0FBSzthQUNiLE9BQU8sQ0FBQyxJQUFJLENBQUM7Z0JBQ2IsT0FBTyxDQUFDLEtBQUssQ0FBQztBQUNkLGdCQUFBLEtBQUssQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLGVBQWUsRUFBRSxlQUFlLENBQUM7QUFDdEUsZ0JBQUEsS0FBSyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUUsZUFBZSxFQUFFLGVBQWUsQ0FBQztBQUN0RSxnQkFBQSxLQUFLLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxlQUFlLEVBQUUsZUFBZSxDQUFDLENBQUMsRUFDdkU7S0FDRjtBQUVELElBQUEsT0FBTyxLQUFLLENBQUMsSUFBYSxFQUFFLEtBQWMsRUFBRSxNQUFlLEVBQUE7QUFDMUQsUUFBQSxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3JCLFFBQUEsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUNyQixRQUFBLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDckIsUUFBQSxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLFFBQUEsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUN2QixRQUFBLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFdkIsTUFBTSxDQUFDLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEdBQUcsTUFBTSxDQUFDO1FBQzFDLE1BQU0sQ0FBQyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sQ0FBQztRQUMxQyxNQUFNLENBQUMsR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLENBQUM7QUFFMUMsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkOztBQTNaYSxPQUFBLENBQUEsSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBRWpELE9BQUEsQ0FBQSxHQUFHLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFFaEQsT0FBQSxDQUFBLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUVuRCxPQUFBLENBQUEsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBRW5ELE9BQUEsQ0FBQSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFxWjFELE9BQUEsQ0FBQSxRQUFRLEdBQUcsVUFBVSxJQUFhLEVBQUUsS0FBYyxFQUFFLE1BQWUsRUFBQTtBQUN6RSxJQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDO0FBQ3BDLElBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUM7QUFDcEMsSUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQztBQUVwQyxJQUFBLE9BQU8sTUFBTSxDQUFDO0FBQ2YsQ0FBQyxDQUFDO0FBRUgsTUFBTUQsaUJBQWUsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0FBQ3RDLE1BQU1DLGFBQVcsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0FBQ2xDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztBQUMxQyxNQUFNLG9CQUFvQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7QUFDM0MsTUFBTSx5QkFBeUIsR0FBRyxJQUFJLE9BQU8sRUFBRTs7TUM3YWxDLFNBQVMsQ0FBQTtBQVVyQixJQUFBLFdBQUEsQ0FBbUIsSUFBWSxFQUFTLEtBQW9CLEVBQVMsUUFBZ0IsRUFBQTtRQUFsRSxJQUFJLENBQUEsSUFBQSxHQUFKLElBQUksQ0FBUTtRQUFTLElBQUssQ0FBQSxLQUFBLEdBQUwsS0FBSyxDQUFlO1FBQVMsSUFBUSxDQUFBLFFBQUEsR0FBUixRQUFRLENBQVE7QUFDcEYsUUFBQSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztBQUNqQixRQUFBLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBQ2hCLFFBQUEsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUM7QUFDeEIsUUFBQSxJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQyxTQUFTLENBQUM7QUFDN0MsUUFBQSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztLQUNsQjtJQUNELGVBQWUsR0FBQTtRQUNkLE9BQU87QUFDTixZQUFBO2dCQUNDLGNBQWMsRUFBRSxJQUFJLENBQUMsY0FBYztnQkFDbkMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO2dCQUNuQixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07QUFDbkIsYUFBQTtTQUNELENBQUM7S0FDRjtJQUNELE9BQU8sR0FBQTtBQUNOLFFBQUEsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7S0FDaEI7QUFDRCxJQUFBLFlBQVksQ0FBQyxPQUFPLEVBQUE7QUFDbkIsUUFBQSxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssQ0FBQyxFQUFFO1lBQ3hCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQ2xFLFNBQVMsQ0FBQyxFQUFFLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzFDLGdCQUFBLFNBQVMsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ25DLGdCQUFBLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDOUMsYUFBQTtBQUNELFNBQUE7QUFBTSxhQUFBLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxDQUFDLEVBQUU7WUFDL0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDbEUsU0FBUyxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDMUMsZ0JBQUEsU0FBUyxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0QsYUFBQTtBQUNELFNBQUE7QUFDRCxRQUFBLE9BQU8sSUFBSSxDQUFDO0tBQ1o7QUFDRCxJQUFBLFlBQVksQ0FBQyxPQUFPLEVBQUE7UUFDbkIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNsRSxTQUFTLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMxQyxZQUFBLFNBQVMsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ25DLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0QsU0FBQTtBQUNELFFBQUEsT0FBTyxJQUFJLENBQUM7S0FDWjtJQUNELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFBO1FBQ1osSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN0QyxRQUFBLE9BQU8sSUFBSSxDQUFDO0tBQ1o7QUFDRCxJQUFBLElBQUksQ0FBQyxLQUFLLEVBQUE7QUFDVCxRQUFBLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUM1QyxRQUFBLE9BQU8sQ0FBQyxDQUFDO0tBQ1Q7SUFDRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBQTtBQUNaLFFBQUEsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDMUMsUUFBQSxPQUFPLElBQUksQ0FBQztLQUNaO0FBQ0QsSUFBQSxJQUFJLENBQUMsS0FBSyxFQUFBO0FBQ1QsUUFBQSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2hELFFBQUEsT0FBTyxDQUFDLENBQUM7S0FDVDtJQUNELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFBO0FBQ1osUUFBQSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMxQyxRQUFBLE9BQU8sSUFBSSxDQUFDO0tBQ1o7QUFDRCxJQUFBLElBQUksQ0FBQyxLQUFLLEVBQUE7QUFDVCxRQUFBLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDaEQs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VCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQ1QsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUNULE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFDVCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQ1QsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUNULE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FDVCxDQUFDO0FBQ0YsU0FBQTtRQUNELE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxjQUFjLENBQUMsVUFBc0IsRUFBRSxNQUFnQixFQUFBO1FBQzdELE1BQU0sRUFBRSxHQUFHLFVBQVUsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUN2QyxNQUFNLEVBQUUsR0FBRyxVQUFVLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDdkMsTUFBTSxFQUFFLEdBQUcsVUFBVSxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sRUFBRSxHQUFHLFVBQVUsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUN2QyxNQUFNLEVBQUUsR0FBRyxVQUFVLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDdkMsTUFBTSxFQUFFLEdBQUcsVUFBVSxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sRUFBRSxHQUFHLFVBQVUsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUN2QyxNQUFNLEVBQUUsR0FBRyxVQUFVLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDdkMsTUFBTSxFQUFFLEdBQUcsVUFBVSxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sRUFBRSxHQUFHLFVBQVUsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUV2QyxNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7UUFDOUIsTUFBTSxHQUFHLEdBQUcsR0FBRyxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUM1QixNQUFNLEdBQUcsR0FBRyxHQUFHLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBRTVCLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDNUIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7UUFDL0IsTUFBTSxHQUFHLEdBQUcsR0FBRyxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUU1QixNQUFNLEdBQUcsR0FBRyxHQUFHLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQzVCLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxFQUFF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UyxDQUFDLENBQUMsQ0FBQztRQUNoQyxNQUFNLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLFFBQVEsQ0FBQyxNQUFlLEVBQUUsS0FBYyxFQUFFLE1BQWUsRUFBQTtRQUMvRCxNQUFNLGFBQWEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRUksZUFBYSxDQUFDLENBQUM7UUFDOUQsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLENBQUMsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQztRQUM5QyxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUM7UUFFOUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7UUFDcEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7UUFDcEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7UUFDcEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7UUFDcEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7UUFDcEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7UUFDcEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7UUFDcEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7UUFDcEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFFcEMsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLFFBQVEsQ0FBQyxNQUFlLEVBQUUsTUFBZSxFQUFBO0FBQy9DLFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUVDLGVBQWEsQ0FBQyxDQUFDLENBQUM7QUFDbkcsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRUEsZUFBYSxDQUFDLENBQUMsQ0FBQztBQUNuRyxRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFQSxlQUFhLENBQUMsQ0FBQyxDQUFDO0FBQ25HLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtJQUVELE9BQU8sZUFBZSxDQUFDLE1BQWUsRUFBQTtBQUNyQyxRQUFBLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFQyxlQUFhLENBQUMsQ0FBQztBQUN4QyxRQUFBLE9BQU8sT0FBTyxDQUFDLGdCQUFnQixDQUFDQSxlQUFhLENBQUMsQ0FBQztLQUMvQztBQUVELElBQUEsT0FBTyxXQUFXLENBQUMsTUFBZSxFQUFFLFFBQWlCLEVBQUUsTUFBZSxFQUFBO1FBQ3JFLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFQyxlQUFhLENBQUMsQ0FBQztBQUV0RCxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNsQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNsQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNsQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNsQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNsQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNsQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNsQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNsQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUVsQyxRQUFBLE9BQU8sTUFBTSxDQUFDO0tBQ2Q7QUFFRCxJQUFBLE9BQU8sV0FBVyxDQUFDLE1BQWUsRUFBRSxNQUFlLEVBQUE7UUFDbEQsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUVDLGVBQWEsQ0FBQyxDQUFDO0FBRXRELFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBRWhDLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxRQUFRLENBQUMsSUFBYSxFQUFFLEtBQWMsRUFBRSxNQUFlLEVBQUE7QUFDN0QsUUFBQSxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqRixRQUFBLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pGLFFBQUEsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFakYsUUFBQSxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqRixRQUFBLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pGLFFBQUEsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFakYsUUFBQSxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqRixRQUFBLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pGLFFBQUEsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFakYsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLEdBQUcsQ0FBQyxJQUFhLEVBQUUsS0FBYyxFQUFFLE1BQWUsRUFBQTtBQUN4RCxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE9BQU8sTUFBTSxDQUFDO0tBQ2Q7QUFFRCxJQUFBLE9BQU8sUUFBUSxDQUFDLElBQWEsRUFBRSxLQUFjLEVBQUUsTUFBZSxFQUFBO0FBQzdELFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxnQkFBZ0IsQ0FBQyxNQUFlLEVBQUUsU0FBa0IsRUFBRSxNQUFlLEVBQUE7QUFDM0UsUUFBQSxNQUFNLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLFFBQUEsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUN2QixRQUFBLE1BQU0sRUFBRSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFFdkIsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDM0QsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDM0QsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFFM0QsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLGdCQUFnQixDQUFDLE1BQWUsRUFBRSxNQUFjLEVBQUUsTUFBZSxFQUFBO1FBQ3ZFLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO0FBQy9CLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxlQUFlLENBQUMsTUFBZSxFQUFFLEtBQWMsRUFBRSxNQUFlLEVBQUE7QUFDdEUsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFFaEMsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLE1BQU0sQ0FBQyxNQUFlLEVBQUUsTUFBZSxFQUFBO1FBQzdDLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxTQUFTLENBQUMsTUFBZSxFQUFFLE1BQWUsRUFBQTtBQUNoRCxRQUFBLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QixRQUFBLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QixRQUFBLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QixRQUFBLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QixRQUFBLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QixRQUFBLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QixRQUFBLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QixRQUFBLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QixRQUFBLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUU5QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE9BQU8sTUFBTSxDQUFDO0tBQ2Q7QUFFRCxJQUFBLE9BQU8sR0FBRyxDQUFDLE1BQWUsRUFBRSxNQUFlLEVBQUE7QUFDMUMsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFaEMsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0lBRUQsT0FBTyxXQUFXLENBQUMsTUFBZSxFQUFBO0FBQ2pDLFFBQUEsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRXRCLFFBQUEsT0FBTyxHQUFHLElBQUksR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztLQUNyRztBQUVELElBQUEsT0FBTyxPQUFPLENBQUMsTUFBZSxFQUFFLE1BQWUsRUFBQTtBQUM5QyxRQUFBLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV0QixNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDOztRQUdoRCxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRTtBQUM3QyxZQUFBLE1BQU0sSUFBSSxLQUFLLENBQUMsMEJBQTBCLENBQUMsQ0FBQztBQUM1QyxTQUFBOztRQUdELE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDbEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUNsQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdB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T0FBTyxDQUFBO0FBT1o7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWtCRztBQUNILElBQUEsV0FBQSxDQUNDLFdBQVcsR0FBRyxDQUFDLEVBQ2YsV0FBVyxHQUFHLENBQUMsRUFDZixXQUFXLEdBQUcsQ0FBQyxFQUNmLFdBQVcsR0FBRyxDQUFDLEVBQ2YsV0FBVyxHQUFHLENBQUMsRUFDZixXQUFXLEdBQUcsQ0FBQyxFQUNmLFdBQVcsR0FBRyxDQUFDLEVBQ2YsV0FBVyxHQUFHLENBQUMsRUFDZixXQUFXLEdBQUcsQ0FBQyxFQUNmLFdBQVcsR0FBRyxDQUFDLEVBQ2YsV0FBVyxHQUFHLENBQUMsRUFDZixXQUFXLEdBQUcsQ0FBQyxFQUNmLFdBQVcsR0FBRyxDQUFDLEVBQ2YsV0FBVyxHQUFHLENBQUMsRUFDZixXQUFXLEdBQUcsQ0FBQyxFQUNmLFdBQVcsR0FBRyxDQUFDLEVBQUE7QUFFZixRQUFBLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDdEIsUUFBQSxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3RCLFFBQUEsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN0QixRQUFBLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDdEIsUUFBQSxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3RCLFFBQUEsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN0QixRQUFBLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDdEIsUUFBQSxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3RCLFFBQUEsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN0QixRQUFBLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDdEIsUUFBQSxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3ZCLFFBQUEsSUFBSSxD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QUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFakIsUUFBQSxPQUFPLElBQUksQ0FBQztLQUNaO0lBQ0QsUUFBUSxHQUFBO1FBQ1AsUUFDQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQSxFQUFBLEVBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFLLEVBQUEsRUFBQSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFLLEdBQUEsQ0FBQTtBQUNyRCxZQUFBLENBQUEsQ0FBQSxFQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBSyxFQUFBLEVBQUEsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQSxFQUFBLEVBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFLLEdBQUEsQ0FBQTtBQUNyRCxZQUFBLENBQUEsQ0FBQSxFQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBSyxFQUFBLEVBQUEsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQSxFQUFBLEVBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFLLEdBQUEsQ0FBQTtZQUN0RCxDQUFJLENBQUEsRUFBQSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFBLEVBQUEsRUFBSyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUssRUFBQSxFQUFBLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBRyxDQUFBLENBQUEsRUFDbkQ7S0FDRjtBQUNELElBQUEsT0FBTyxLQUFLLENBQUMsTUFBMEIsRUFBRSxNQUFlLEVBQUE7QUFDdkQsUUFBQSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFO0FBQ3JCLFlBQUEsT0FBTyxTQUFTLENBQUM7QUFDakIsU0FBQTtBQUNELFFBQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtBQUNyQixZQUFBLE9BQU8sSUFBSSxPQUFPLENBQ2pCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFDVCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQ1QsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUNULE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFDVixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQ1QsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUNULE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFDVCxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQ1YsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUNULE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFDVCxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQ1YsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUNWLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFDVCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQ1QsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUNWLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FDVixDQUFDO0FBQ0YsU0FBQTtRQUNELE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4QixNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3hCLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDeEIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4QixNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3hCLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDeEIsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLG9CQUFvQixDQUFDLE1BQWdCLEVBQUUsTUFBZSxFQUFBO1FBQzVELE9BQU8sT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7S0FDckM7QUFFRCxJQUFBLE9BQU8saUJBQWlCLENBQUMsTUFBZ0IsRUFBRSxNQUFlLEVBQUE7QUFDekQsUUFBQSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFO0FBQ3JCLFlBQUEsT0FBTyxJQUFJLE9BQU8sQ0FDakIsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUNULE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFDVCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQ1QsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUNULE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFDVCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQ1QsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUNULE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFDVCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQ1QsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUNULE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFDVixNQUFNLENBQUMsRUFBRSxDQUFDLEVBQ1YsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUNWLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFDVixNQUFNLENBQUMsRUFBRSxDQUFDLEVBQ1YsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUNWLENBQUM7QUFDRixTQUFBO1FBQ0QsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN2QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3hCLE1BQU0sQ0FBQyxF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Q0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7QUFDckIsWUFBQSxNQUFNLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztBQUN2QixTQUFBO0FBRUQsUUFBQSxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLFFBQUEsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUN2QixRQUFBLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFdkIsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ25DLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNuQyxNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDbkMsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ25DLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNuQyxNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDbkMsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ25DLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNuQyxNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDbkMsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBRW5DLE1BQU0sR0FBRyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUM5QixNQUFNLEdBQUcsR0FBRyxHQUFHLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQzVCLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFFNUIsTUFBTSxHQUFHLEdBQUcsR0FBRyxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUM1QixNQUFNLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUMvQixNQUFNLEdBQUcsR0FBRyxHQUFHLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBRTVCLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDNUIsTUFBTSxHQUFHLEdBQUcsR0FBRyxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUM1QixNQUFNLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUUvQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsTUFBTSxDQUFDO0FBQ3pCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUM7QUFDekIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLE1BQU0sQ0FBQztBQUN6QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDaEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLE1BQU0sQ0FBQztBQUN6QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsTUFBTSxDQUFDO0FBQ3pCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUM7QUFDekIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxNQUFNLENBQUM7QUFDekIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLE1BQU0sQ0FBQztBQUN6QixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsTUFBTSxDQUFDO0FBQzFCLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNqQixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDO0FBQzNCLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUM7QUFDM0IsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQztBQUMzQixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFFakIsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLDRCQUE0QixDQUNsQyx3QkFJQyxFQUNELE1BQWUsRUFBQTtBQUVmLFFBQUEsT0FBTyxPQUFPLENBQUMsc0NBQXNDLENBQ3BELHdCQUF3QixDQUFDLFdBQVcsRUFDcEMsd0JBQXdCLENBQUMsUUFBUSxFQUNqQyx3QkFBd0IsQ0FBQyxLQUFLLEVBQzlCLE1BQU0sQ0FDTixDQUFDO0tBQ0Y7QUFFRCxJQUFBLE9BQU8sZUFBZSxDQUFDLFdBQW9CLEVBQUUsTUFBZSxFQUFBO0FBQzNELFFBQUEsT0FBTyxPQUFPLENBQUMsdUJBQXVCLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUM7S0FDOUU7QUFFRCxJQUFBLE9BQU8sU0FBUyxDQUFDLEtBQWMsRUFBRSxNQUFlLEVBQUE7QUFDL0MsUUFBQSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFO0FBQ3JCLFlBQUEsT0FBTyxJQUFJLE9BQU8sQ0FDakIsS0FBSyxDQUFDLENBQUMsRUFDUCxHQUFHLEVBQ0gsR0FBRyxFQUNILEdBQUcsRUFDSCxHQUFHLEVBQ0gsS0FBSyxDQUFDLENBQUMsRUFDUCxHQUFHLEVBQ0gsR0FBRyxFQUNILEdBQUcsRUFDSCxHQUFHLEVBQ0gsS0FBSyxDQUFDLENBQUMsRUFDUCxHQUFHLEVBQ0gsR0FBRyxFQUNILEdBQUcsRUFDSCxHQUFHLEVBQ0gsR0FBRyxDQUNILENBQUM7QUFDRixTQUFBO0FBRUQsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNwQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDaEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNoQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDaEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNwQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDaEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNoQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDaEIsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNyQixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDakIsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2pCLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNqQixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENB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LElBQUksQ0FBQyxDQUFDO1FBRTdCLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxHQUFHLElBQUksSUFBSSxDQUFDLENBQUM7UUFDN0IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQztBQUM3QixRQUFBLE1BQU0sQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUM7QUFFbkIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNsQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNoQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZCxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2xCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNkLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNkLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDcEIsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDaEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2QsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFD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QUVELElBQUEsT0FBTyxjQUFjLENBQUMsTUFBZSxFQUFFLFdBQW9CLEVBQUUsTUFBZSxFQUFBO1FBQzNFLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4QixNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBRXhCLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUM7QUFDM0IsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQztBQUMzQixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBQzNC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QUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxHQUFHLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFeEIsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztRQUM3QixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO1FBQzdCLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7UUFDN0IsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztRQUM3QixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO1FBQzdCLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7UUFDN0IsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztRQUM3QixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO1FBQzdCLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7QUFFOUIsUUFBQSxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFVixJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUU7WUFDZCxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQy9CLFlBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDO1lBQ3BCLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQztZQUM3QixNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUM7WUFDN0IsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDO0FBQzdCLFNBQUE7QUFBTSxhQUFBLElBQUksSUFBSSxHQUFHLElBQUksSUFBSSxJQUFJLEdBQUcsSUFBSSxFQUFFO0FBQ3RDLFlBQUEsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzVDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQztBQUM3QixZQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQztZQUNwQixNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUM7WUFDN0IsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDO0FBQzdCLFNBQUE7YUFBTSxJQUFJLElBQUksR0FBRyxJQUFJLEVBQUU7QUFDdkIsWUFBQSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDNUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDO1lBQzdCLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQztBQUM3QixZQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQztZQUNwQixNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUM7QUFDN0IsU0FBQTtBQUFNLGFBQUE7QUFDTixZQUFBLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM1QyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUM7WUFDN0IsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDO1lBQzdCLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQztBQUM3QixZQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQztBQUNwQixTQUFBO0FBQ0QsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLFFBQVEsQ0FBQyxJQUFhLEVBQUUsS0FBYyxFQUFFLE1BQWUsRUFBQTtBQUM3RCxRQUFBLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUV4QixRQUFBLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4QixRQUFBLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMxQixRQUFBLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMxQixRQUFBLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMxQixRQUFBLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMxQixRQUFBLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMxQixRQUFBLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUUxQixRQUFBLE1BQU0sV0FBVyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLE1BQU0sR0FBRyxNQUFNLENBQUM7QUFDdkYsUUFBQSxNQUFNLFdBQVcsR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxNQUFNLEdBQUcsTUFBTSxDQUFDO0FBQ3ZGLFFBQUEsTUFBTSxXQUFXLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLE1BQU0sR0FBRyxNQUFNLEdBQUcsTUFBTSxHQUFHLE1BQU0sQ0FBQztBQUN4RixRQUFBLE1BQU0sV0FBVyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxNQUFNLEdBQUcsTUFBTSxHQUFHLE1BQU0sR0FBRyxNQUFNLENBQUM7QUFFeEYsUUFBQSxNQUFNLFdBQVcsR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxNQUFNLEdBQUcsTUFBTSxDQUFDO0FBQ3ZGLFFBQUEsTUFBTSxXQUFXLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsTUFBTSxHQUFHLE1BQU0sQ0FBQztBQUN2RixRQUFBLE1BQU0sV0FBVyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxNQUFNLEdBQUcsTUFBTSxHQUFHLE1BQU0sR0FBRyxNQUFNLENBQUM7QUFDeEYsUUFBQSxNQUFNLFdBQVcsR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsTUFBTSxHQUFHLE1BQU0sR0FBRyxNQUFNLEdBQUcsTUFBTSxDQUFDO0FBRXhGLFFBQUEsTUFBTSxXQUFXLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxPQUFPLEdBQUcsTUFBTSxHQUFHLE9BQU8sQ0FBQztBQUN6RixRQUFBLE1BQU0sV0FBVyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEdBQUcsT0FBTyxHQUFHLE1BQU0sR0FBRyxPQUFPLENBQUM7QUFDekYsUUFBQSxNQUFNLFdBQVcsR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsTUFBTSxHQUFHLE9BQU8sR0FBRyxNQUFNLEdBQUcsT0FBTyxDQUFDO0FBQzFGLFFBQUEsTUFBTSxXQUFXLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLE1BQU0sR0FBRyxPQUFPLEdBQUcsTUFBTSxHQUFHLE9BQU8sQ0FBQztBQUUxRixRQUFBLE1BQU0sV0FBVyxHQUFHLEtBQUssR0FBRyxPQUFPLEdBQUcsS0FBSyxHQUFHLE9BQU8sR0FBRyxLQUFLLEdBQUcsT0FBTyxHQUFHLE1BQU0sR0FBRyxPQUFPLENBQUM7QUFDM0YsUUFBQSxNQUFNLFdBQVcsR0FBRyxLQUFLLEdBQUcsT0FBTyxHQUFHLEtBQUssR0FBRyxPQUFPLEdBQUcsS0FBSyxHQUFHLE9BQU8sR0FBRyxNQUFNLEdBQUcsT0FBTyxDQUFDO0FBQzNGLFFBQUEsTUFBTSxXQUFXLEdBQUcsS0FBSyxHQUFHLE9BQU8sR0FBRyxLQUFLLEdBQUcsT0FBTyxHQUFHLE1BQU0sR0FBRyxPQUFPLEdBQUcsTUFBTSxHQUFHLE9BQU8sQ0FBQztBQUM1RixRQUFBLE1BQU0sV0FBVyxHQUFHLEtBQUssR0FBRyxPQUFPLEdBQUcsS0FBSyxHQUFHLE9BQU8sR0FBRyxNQUFNLEdBQUcsT0FBTyxHQUFHLE1BQU0sR0FBRyxPQUFPLENBQUM7QUFFNUYsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN6QixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDekIsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3pCLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN6QixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDekIsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3pCLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxHQUFHLENBQUMsSUFBYSxFQUFFLEtBQWMsRUFBRSxNQUFlLEVBQUE7QUFDeEQsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xDLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEMsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsQyxRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xDLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEMsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsQyxRQUFBLE9BQU8sTUFBTSxDQUFDO0tBQ2Q7QUFFRCxJQUFBLE9BQU8sUUFBUSxDQUFDLElBQWEsRUFBRSxLQUFjLEVBQUUsTUFBZSxFQUFBO0FBQzdELFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsQyxRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xDLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEMsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNsQyxRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2xDLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDbEMsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLHNCQUFzQixDQUFDLElBQWEsRUFBRSxLQUFjLEVBQUUsTUFBZSxFQUFBO0FBQzNFLFFBQUEsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBRXhCLFFBQUEsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzFCLFFBQUEsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzFCLFFBQUEsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzFCLFFBQUEsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBRTFCLFFBQUEsTUFBTSxXQUFXLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLENBQUM7QUFDckUsUUFBQSxNQUFNLFdBQVcsR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sQ0FBQztBQUNyRSxRQUFBLE1BQU0sV0FBVyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxNQUFNLEdBQUcsTUFBTSxDQUFDO0FBRXRFLFFBQUEsTUFBTSxXQUFXLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLENBQUM7QUFDckUsUUFBQSxNQUFNLFdBQVcsR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sQ0FBQztBQUNyRSxRQUFBLE1BQU0sV0FBVyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxNQUFNLEdBQUcsTUFBTSxDQUFDO0FBRXRFLFFBQUEsTUFBTSxXQUFXLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxPQUFPLENBQUM7QUFDdEUsUUFBQSxNQUFNLFdBQVcsR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE9BQU8sQ0FBQztBQUN0RSxRQUFBLE1BQU0sV0FBVyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxNQUFNLEdBQUcsT0FBTyxDQUFDO0FBRXZFLFFBQUEsTUFBTSxXQUFXLEdBQUcsS0FBSyxHQUFHLE9BQU8sR0FBRyxLQUFLLEdBQUcsT0FBTyxHQUFHLEtBQUssR0FBRyxPQUFPLEdBQUcsTUFBTSxDQUFDO0FBQ2pGLFFBQUEsTUFBTSxXQUFXLEdBQUcsS0FBSyxHQUFHLE9BQU8sR0FBRyxLQUFLLEdBQUcsT0FBTyxHQUFHLEtBQUssR0FBRyxPQUFPLEdBQUcsTUFBTSxDQUFDO0FBQ2pGLFFBQUEsTUFBTSxXQUFXLEdBQUcsS0FBSyxHQUFHLE9BQU8sR0FBRyxLQUFLLEdBQUcsT0FBTyxHQUFHLE1BQU0sR0FBRyxPQUFPLEdBQUcsTUFBTSxDQUFDO0FBRWxGLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNoQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDaEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDekIsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2pCLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN6QixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDekIsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3pCLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNqQixRQUFBLE9BQU8sTUFBTSxDQUFDO0tBQ2Q7QUFFRCxJQUFBLE9BQU8saUJBQWlCLENBQUMsTUFBZSxFQUFFLFFBQWlCLEVBQUUsTUFBZSxFQUFBO0FBQzNFLFFBQUEsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBRTFCLFFBQUEsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLFFBQUEsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLFFBQUEsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLFFBQUEsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLFFBQUEsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLFFBQUEsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLFFBQUEsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLFFBQUEsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNCLFFBQUEsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRTVCLFFBQUEsTUFBTSxXQUFXLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLENBQUM7QUFDckUsUUFBQSxNQUFNLFdBQVcsR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sQ0FBQztBQUNyRSxRQUFBLE1BQU0sV0FBVyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxNQUFNLEdBQUcsTUFBTSxDQUFDO0FBRXRFLFFBQUEsTUFBTSxXQUFXLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLENBQUM7QUFDckUsUUFBQSxNQUFNLFdBQVcsR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sQ0FBQztBQUNyRSxRQUFBLE1BQU0sV0FBVyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxNQUFNLEdBQUcsTUFBTSxDQUFDO0FBRXRFLFFBQUEsTUFBTSxXQUFXLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxPQUFPLENBQUM7QUFDdEUsUUFBQSxNQUFNLFdBQVcsR0FBRyxLQUFLLEdBQUcsTUFBTSxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE9BQU8sQ0FBQztBQUN0RSxRQUFBLE1BQU0sV0FBVyxHQUFHLEtBQUssR0FBRyxNQUFNLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxNQUFNLEdBQUcsT0FBTyxDQUFDO0FBRXZFLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNoQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDaEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDekIsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO1FBQ2pCLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDeEIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4QixNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3hCLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDeEIsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLHFCQUFxQixDQUFDLE1BQWUsRUFBRSxXQUFvQixFQUFFLE1BQWUsRUFBQTtBQUNsRixRQUFBLE1BQU0sQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUV4QixNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDdEUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3RFLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUV2RSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDeEIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxH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QUMsTUFBZSxFQUFFLFNBQWtCLEVBQUUsTUFBZSxFQUFBO0FBQzNFLFFBQUEsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUN2QixRQUFBLE1BQU0sRUFBRSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsUUFBQSxNQUFNLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLFFBQUEsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUV2QixRQUFBLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDN0UsUUFBQSxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQzdFLFFBQUEsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUM5RSxRQUFBLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7QUFFOUUsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyx1QkFBdUIsQ0FBQyxNQUFlLEVBQUUsU0FBa0IsRUFBRSxNQUFlLEVBQUE7QUFDbEYsUUFBQSxNQUFNLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLFFBQUEsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUN2QixRQUFBLE1BQU0sRUFBRSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFFdkIsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDM0QsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDM0QsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7QUFFNUQsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLGVBQWUsQ0FBQyxNQUFlLEVBQUUsU0FBa0IsRUFBRSxNQUFlLEVBQUE7QUFDMUUsUUFBQSxNQUFNLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDO0FBQ3ZCLFFBQUEsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUN2QixRQUFBLE1BQU0sRUFBRSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFFdkIsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3hFLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4RSxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFFekUsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDYixRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLGdCQUFnQixDQUFDLE1BQWUsRUFBRSxNQUFjLEVBQUUsTUFBZSxFQUFBO1FBQ3ZFLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ2pDLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ2pDLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ2pDLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ2pDLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ2pDLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO0FBQ2pDLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxNQUFNLENBQUMsTUFBZSxFQUFFLE1BQWUsRUFBQTtRQUM3QyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3pCLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN6QixNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDekIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3pCLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN6QixNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDekIsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLFNBQVMsQ0FBQyxNQUFlLEVBQUUsTUFBZSxFQUFBO0FBQ2hELFFBQUEsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFCLFFBQUEsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFCLFFBQUEsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFCLFFBQUEsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFCLFFBQUEsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFCLFFBQUEsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRTVCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDdkIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDO1FBQ3BCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQztBQUNwQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUM7UUFDcEIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4QixNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQztBQUNyQixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUM7QUFDckIsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsUUFBUSxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDeEIsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLEdBQUcsQ0FBQyxNQUFlLEVBQUUsTUFBZSxFQUFBO0FBQzFDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEMsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNsQyxRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2xDLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDbEMsUUFBQSxNQUFNLENBQUMsRUFBRSxD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QUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTztBQUN2QyxnQkFBQSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxPQUFPO0FBQ3ZDLGdCQUFBLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU87QUFDdkMsZ0JBQUEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTztBQUN2QyxnQkFBQSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxPQUFPO0FBQ3ZDLGdCQUFBLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU87QUFDdkMsZ0JBQUEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTztBQUN2QyxnQkFBQSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxPQUFPO0FBQ3pDLGdCQUFBLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLE9BQU87QUFDekMsZ0JBQUEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksT0FBTztBQUN6QyxnQkFBQSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxPQUFPO0FBQ3pDLGdCQUFBLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLE9BQU87QUFDekMsZ0JBQUEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksT0FBTyxDQUFDLEVBQzFDO0tBQ0Y7QUFFRCxJQUFBLE9BQU8sY0FBYyxDQUFDLE1BQWUsRUFBRSxNQUFlLEVBQUE7QUFDckQsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUN0QixRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3RCLFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDdEIsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLFVBQVUsQ0FBQyxNQUFlLEVBQUUsTUFBZSxFQUFBO1FBQ2pELE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZCLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxPQUFPLENBQUMsTUFBZSxFQUFFLE1BQWUsRUFBQTs7Ozs7QUFLOUMsUUFBQSxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsUUFBQSxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsUUFBQSxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsUUFBQSxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDeEIsUUFBQSxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsUUFBQSxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsUUFBQSxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsUUFBQSxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDeEIsUUFBQSxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsUUFBQSxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdkIsUUFBQSxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDekIsUUFBQSxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDekIsUUFBQSxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDeEIsUUFBQSxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDeEIsUUFBQSxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDekIsUUFBQSxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7O0FBR3pCLFFBQUEsSUFBSSxJQUFJLEdBQUcsS0FBSyxHQUFHLEtBQUssQ0FBQztBQUN6QixRQUFBLElBQUksSUFBSSxHQUFHLEtBQUssR0FBRyxLQUFLLENBQUM7QUFDekIsUUFBQSxJQUFJLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUFDO0FBQ3hCLFFBQUEsSUFBSSxJQUFJLEdBQUcsS0FBSyxHQUFHLEtBQUssQ0FBQztBQUN6QixRQUFBLElBQUksSUFBSSxHQUFHLElBQUksR0FBRyxLQUFLLENBQUM7QUFDeEIsUUFBQSxJQUFJLElBQUksR0FBRyxLQUFLLEdBQUcsS0FBSyxDQUFDO0FBQ3pCLFFBQUEsSUFBSSxJQUFJLEdBQUcsSUFBSSxHQUFHLEtBQUssQ0FBQztBQUN4QixRQUFBLElBQUksSUFBSSxHQUFHLEtBQUssR0FBRyxLQUFLLENBQUM7QUFDekIsUUFBQSxJQUFJLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUFDO0FBQ3hCLFFBQUEsSUFBSSxJQUFJLEdBQUcsS0FBSyxHQUFHLEtBQUssQ0FBQztBQUN6QixRQUFBLElBQUksS0FBSyxHQUFHLElBQUksR0FBRyxLQUFLLENBQUM7QUFDekIsUUFBQSxJQUFJLEtBQUssR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUFDOztRQUd6QixNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksSUFBSSxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQ2pHLE1BQU0sSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFDakcsTUFBTSxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLElBQUksSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQztRQUNuRyxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUksSUFBSSxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQ25HLE1BQU0sSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFDakcsTUFBTSxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLElBQUksSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQztRQUNqRyxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUksSUFBSSxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQ25HLE1BQU0sSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxLQUFLLEdBQUcsSUFBSSxJQUFJLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUM7O0FBR25HLFFBQUEsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFDbkIsUUFBQSxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUNuQixRQUFBLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ25CLFFBQUEsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFDbkIsUUFBQSxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUNuQixRQUFBLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ25CLFFBQUEsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFDbkIsUUFBQSxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUNuQixRQUFBLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ25CLFFBQUEsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFDbkIsUUFBQSxLQUFLLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUNwQixRQUFBLEtBQUssR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDOztRQUdwQixNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUksR0FBRyxLQUFLLEdBQUcsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUksR0FBRyxLQUFLLEdBQUcsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDO1FBQ3ZHLE1BQU0sSUFBSSxHQUFHLElBQUksR0FBRyxLQUFLLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsS0FBSyxJQUFJLElBQUksR0FBRyxLQUFLLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUM7UUFDdkcsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLEtBQUssR0FBRyxLQUFLLElBQUksSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLEtBQUssR0FBRyxLQUFLLENBQUMsQ0FBQztRQUMxRyxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUksR0FBRyxLQUFLLEdBQUcsS0FBSyxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUksR0FBRyxLQUFLLEdBQUcsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDO1FBQzFHLE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxLQUFLLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksR0FBRyxLQUFLLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUM7UUFDdEcsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxLQUFLLElBQUksSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQztRQUN0RyxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FBRyxLQUFLLEdBQUcsSUFBSSxHQUFHLElBQUksSUFBSSxLQUFLLEdBQUcsS0FBSyxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQ3RHLE1BQU0sS0FBSyxHQUFHLEtBQUssR0FBRyxLQUFLLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksR0FBRyxJQUFJLEdBQUcsS0FBSyxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUM7O0FBR3RHLFFBQUEsSUFBSSxHQUFHLEdBQUcsSUFBSSxHQUFHLElB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QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsR0FBRyxDQUFDO0FBQ3ZCLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssR0FBRyxHQUFHLENBQUM7QUFDekIsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxHQUFHLEdBQUcsQ0FBQztBQUN6QixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDO0FBQ3pCLFFBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssR0FBRyxHQUFHLENBQUM7QUFDekIsUUFBQSxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxHQUFHLEdBQUcsQ0FBQztBQUN6QixRQUFBLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDO0FBQ3pCLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxxQkFBcUIsQ0FBQyxNQUFlLEVBQUUsTUFBZSxFQUFBOzs7Ozs7QUFPNUQsUUFBQSxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUIsUUFBQSxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUIsUUFBQSxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUIsUUFBQSxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUIsUUFBQSxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUIsUUFBQSxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUIsUUFBQSxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUIsUUFBQSxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDMUIsUUFBQSxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFFNUIsUUFBQSxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDdEIsUUFBQSxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDdEIsUUFBQSxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7QUFFdEIsUUFBQSxNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sR0FBRyxFQUFFLEdBQUcsT0FBTyxHQUFHLEVBQUUsR0FBRyxPQUFPLEdBQUcsRUFBRSxDQUFDO0FBQ3RELFFBQUEsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEdBQUcsRUFBRSxHQUFHLE9BQU8sR0FBRyxFQUFFLEdBQUcsT0FBTyxHQUFHLEVBQUUsQ0FBQztBQUN0RCxRQUFBLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxHQUFHLEVBQUUsR0FBRyxPQUFPLEdBQUcsRUFBRSxHQUFHLFFBQVEsR0FBRyxFQUFFLENBQUM7QUFFdkQsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDO0FBQ3BCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQztBQUNwQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUM7QUFDcEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ2hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQztBQUNwQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUM7QUFDcEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDO0FBQ3BCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUNoQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUM7QUFDcEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFD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QyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzVCLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxRQUFRLENBQUMsSUFBZ0IsRUFBRSxLQUFpQixFQUFFLE1BQWtCLEVBQUE7UUFDdEUsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDNUIsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDNUIsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDNUIsTUFBTSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDNUIsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLE1BQU0sQ0FBQyxVQUFzQixFQUFFLE1BQWtCLEVBQUE7QUFDdkQsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztBQUN6QixRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO0FBQ3pCLFFBQUEsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7QUFDekIsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMs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QUFDLEVBQUU7QUFDckIsWUFBQSxPQUFPLElBQUksT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDNUQsU0FBQTtBQUNELFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQztBQUNyQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUM7QUFDckIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUM7QUFDdEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDO0FBQ3JCLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtJQUNELE9BQU8sR0FBQTtRQUNOLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQztBQUNsQixRQUFBLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQzlCLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxPQUFPLENBQUMsTUFBZSxFQUFFLE1BQWdCLEVBQUE7QUFDL0MsUUFBQSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ3JCLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwRCxTQUFBO1FBQ0QsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztB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O0FBQ2xDLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBRWxDLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxXQUFXLENBQUMsTUFBZSxFQUFFLE1BQWUsRUFBQTtRQUNsRCxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxhQUFhLENBQUMsQ0FBQztBQUV0RCxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNoQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNoQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNoQyxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUVoQyxRQUFBLE9BQU8sTUFBTSxDQUFDO0tBQ2Q7QUFFRCxJQUFBLE9BQU8sUUFBUSxDQUFDLElBQWEsRUFBRSxLQUFjLEVBQUUsTUFBZSxFQUFBO1FBQzdELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUU1RCxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDO0FBQ3hCLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUN4QixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUM7QUFDeEIsUUFBQSxPQUFPLE1BQU0sQ0FBQztLQUNkO0FBRUQsSUFBQSxPQUFPLEdBQUcsQ0FBQyxJQUFhLEVBQUUsS0FBYyxFQUFFLE1BQWUsRUFBQTtBQUN4RCxRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxRQUFRLENBQUMsSUFBYSxFQUFFLEtBQWMsRUFBRSxNQUFlLEVBQUE7QUFDN0QsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9CLFFBQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDL0IsUUFBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvQixRQUFBLE9BQU8sTUFBTSxDQUFDO0tBQ2Q7QUFFRCxJQUFBLE9BQU8sZ0JBQWdCLENBQUMsTUFBZSxFQUFFLFNBQWtCLEVBQUUsTUFBZSxFQUFBO0FBQzNFLFFBQUEsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUFDNUQsUUFBQSxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUU1RCxRQUFBLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsUUFBQSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNiLFFBQUEsT0FBTyxNQUFNLENBQUM7S0FDZDtBQUVELElBQUEsT0FBTyxnQkFBZ0IsQ0FBQyxNQUFlLEVBQUUsTUFBYyxFQUFFLE1BQWUsRUFBQTtRQUN2RSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FB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QUcsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQztBQUNqRCxJQUFBLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDO0lBQ2xELE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQztBQUMxRCxJQUFBLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztBQUNqQyxJQUFBLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7QUFDekMsSUFBQSxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0FBQzFDLElBQUEsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7QUFFbEQsSUFBQSxNQUFNLFNBQVMsR0FBRzs7QUFFakIsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDOztBQUdMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQzs7QUFHTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7O0FBR0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDOztBQUdMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQzs7QUFHTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7QUFDTCxRQUFBLEdBQUcsQ0FBQyxDQUFDO0FBQ0wsUUFBQSxHQUFHLENBQUMsQ0FBQztBQUNMLFFBQUEsR0FBRyxDQUFDLENBQUM7S0FDTCxDQUFDO0FBRUYsSUFBQSxNQUFNLEdBQUcsR0FBRzs7UUFFWCxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7O1FBR2xDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7UUFHbEMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDOztRQUdsQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7O1FBR2xDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7UUFHbEMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO0tBQ2xDLENBQUM7QUFFRixJQUFBLE1BQU0sT0FBTyxHQUFHOztBQUVmLFFBQUEsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDOztBQUdwRCxRQUFBLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7QUFHcEQsUUFBQSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7O0FBRzFELFFBQUEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDOztBQUcxRCxRQUFBLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQzs7QUFHcEQsUUFBQSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMs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LEdBQUcsUUFBUSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUMzRCxZQUFBLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsQ0FBQztBQUN2RSxZQUFBLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDaEQsWUFBQSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsQ0FBQztBQUM1RCxZQUFBLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQzNELFlBQUEsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0FBQ3ZFLFlBQUEsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsU0FBUyxDQUFDO1lBQ3ZCLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLFNBQVMsQ0FBQztBQUM3QixZQUFBLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFFBQVEsQ0FBQztZQUN0QixFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxRQUFRLENBQUM7QUFDNUIsWUFBQSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNYLFlBQUEsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFFWCxZQUFBLFNBQVMsQ0FBQyxFQUFF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SUFBSSxDQUFDO0lBQ1QsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNqQyxJQUFBLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN2RCxJQUFJLEdBQUcsS0FBSyxNQUFNLEVBQUU7UUFDbkIsTUFBTSxJQUFJLEdBQUcsTUFBTSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxLQUFLLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ2xFLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2xDLEtBQUE7QUFBTSxTQUFBO1FBQ04sTUFBTSxHQUFHLEdBQUcsTUFBTSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxLQUFLLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0FBQ3hFLFFBQUEsTUFBTSxVQUFVLEdBQUcsSUFBSSxXQUFXLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsRCxNQUFNLFNBQVMsR0FBRyxJQUFJLFVBQVUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ3RELFFBQUEsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUNwRSxRQUFBLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLEVBQUUsR0FBRyxVQUFVLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDckQsS0FBQTtBQUNELElBQUEsTUFBTSxJQUFJLENBQUMs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 diff --git a/example/mesh/instance.html b/example/mesh/instance.html index 4f05a1d..58a6beb 100644 --- a/example/mesh/instance.html +++ b/example/mesh/instance.html @@ -3,12 +3,7 @@ - - webworkerTask - + instance -
-
-
+