ngx-spine
Version:
[](https://travis-ci.org/PoiScript/ngx-spine)
478 lines • 37.1 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated May 1, 2019. Replaces all prior versions.
*
* Copyright (c) 2013-2019, Esoteric Software LLC
*
* Integration of the Spine Runtimes into software or otherwise creating
* derivative works of the Spine Runtimes is permitted under the terms and
* conditions of Section 2 of the Spine Editor License Agreement:
* http://esotericsoftware.com/spine-editor-license
*
* Otherwise, it is permitted to integrate the Spine Runtimes into software
* or otherwise create derivative works of the Spine Runtimes (collectively,
* "Products"), provided that each user of the Products must obtain their own
* Spine Editor license and redistribution of the Products in any form must
* include this license and copyright notice.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE LLC "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 ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS
* INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) 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.
*****************************************************************************/
import { ManagedWebGLRenderingContext } from "./WebGL";
export class Shader {
/**
* @param {?} context
* @param {?} vertexShader
* @param {?} fragmentShader
*/
constructor(context, vertexShader, fragmentShader) {
this.vertexShader = vertexShader;
this.fragmentShader = fragmentShader;
this.vs = null;
this.fs = null;
this.program = null;
this.tmp2x2 = new Float32Array(2 * 2);
this.tmp3x3 = new Float32Array(3 * 3);
this.tmp4x4 = new Float32Array(4 * 4);
this.vsSource = vertexShader;
this.fsSource = fragmentShader;
this.context =
context instanceof ManagedWebGLRenderingContext
? context
: new ManagedWebGLRenderingContext(context);
this.context.addRestorable(this);
this.compile();
}
/**
* @return {?}
*/
getProgram() {
return this.program;
}
/**
* @return {?}
*/
getVertexShader() {
return this.vertexShader;
}
/**
* @return {?}
*/
getFragmentShader() {
return this.fragmentShader;
}
/**
* @return {?}
*/
getVertexShaderSource() {
return this.vsSource;
}
/**
* @return {?}
*/
getFragmentSource() {
return this.fsSource;
}
/**
* @private
* @return {?}
*/
compile() {
/** @type {?} */
let gl = this.context.gl;
try {
this.vs = this.compileShader(gl.VERTEX_SHADER, this.vertexShader);
this.fs = this.compileShader(gl.FRAGMENT_SHADER, this.fragmentShader);
this.program = this.compileProgram(this.vs, this.fs);
}
catch (e) {
this.dispose();
throw e;
}
}
/**
* @private
* @param {?} type
* @param {?} source
* @return {?}
*/
compileShader(type, source) {
/** @type {?} */
let gl = this.context.gl;
/** @type {?} */
let shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
/** @type {?} */
let error = "Couldn't compile shader: " + gl.getShaderInfoLog(shader);
gl.deleteShader(shader);
if (!gl.isContextLost())
throw new Error(error);
}
return shader;
}
/**
* @private
* @param {?} vs
* @param {?} fs
* @return {?}
*/
compileProgram(vs, fs) {
/** @type {?} */
let gl = this.context.gl;
/** @type {?} */
let program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
/** @type {?} */
let error = "Couldn't compile shader program: " + gl.getProgramInfoLog(program);
gl.deleteProgram(program);
if (!gl.isContextLost())
throw new Error(error);
}
return program;
}
/**
* @return {?}
*/
restore() {
this.compile();
}
/**
* @return {?}
*/
bind() {
this.context.gl.useProgram(this.program);
}
/**
* @return {?}
*/
unbind() {
this.context.gl.useProgram(null);
}
/**
* @param {?} uniform
* @param {?} value
* @return {?}
*/
setUniformi(uniform, value) {
this.context.gl.uniform1i(this.getUniformLocation(uniform), value);
}
/**
* @param {?} uniform
* @param {?} value
* @return {?}
*/
setUniformf(uniform, value) {
this.context.gl.uniform1f(this.getUniformLocation(uniform), value);
}
/**
* @param {?} uniform
* @param {?} value
* @param {?} value2
* @return {?}
*/
setUniform2f(uniform, value, value2) {
this.context.gl.uniform2f(this.getUniformLocation(uniform), value, value2);
}
/**
* @param {?} uniform
* @param {?} value
* @param {?} value2
* @param {?} value3
* @return {?}
*/
setUniform3f(uniform, value, value2, value3) {
this.context.gl.uniform3f(this.getUniformLocation(uniform), value, value2, value3);
}
/**
* @param {?} uniform
* @param {?} value
* @param {?} value2
* @param {?} value3
* @param {?} value4
* @return {?}
*/
setUniform4f(uniform, value, value2, value3, value4) {
this.context.gl.uniform4f(this.getUniformLocation(uniform), value, value2, value3, value4);
}
/**
* @param {?} uniform
* @param {?} value
* @return {?}
*/
setUniform2x2f(uniform, value) {
/** @type {?} */
let gl = this.context.gl;
this.tmp2x2.set(value);
gl.uniformMatrix2fv(this.getUniformLocation(uniform), false, this.tmp2x2);
}
/**
* @param {?} uniform
* @param {?} value
* @return {?}
*/
setUniform3x3f(uniform, value) {
/** @type {?} */
let gl = this.context.gl;
this.tmp3x3.set(value);
gl.uniformMatrix3fv(this.getUniformLocation(uniform), false, this.tmp3x3);
}
/**
* @param {?} uniform
* @param {?} value
* @return {?}
*/
setUniform4x4f(uniform, value) {
/** @type {?} */
let gl = this.context.gl;
this.tmp4x4.set(value);
gl.uniformMatrix4fv(this.getUniformLocation(uniform), false, this.tmp4x4);
}
/**
* @param {?} uniform
* @return {?}
*/
getUniformLocation(uniform) {
/** @type {?} */
let gl = this.context.gl;
/** @type {?} */
let location = gl.getUniformLocation(this.program, uniform);
if (!location && !gl.isContextLost())
throw new Error(`Couldn't find location for uniform ${uniform}`);
return location;
}
/**
* @param {?} attribute
* @return {?}
*/
getAttributeLocation(attribute) {
/** @type {?} */
let gl = this.context.gl;
/** @type {?} */
let location = gl.getAttribLocation(this.program, attribute);
if (location == -1 && !gl.isContextLost())
throw new Error(`Couldn't find location for attribute ${attribute}`);
return location;
}
/**
* @return {?}
*/
dispose() {
this.context.removeRestorable(this);
/** @type {?} */
let gl = this.context.gl;
if (this.vs) {
gl.deleteShader(this.vs);
this.vs = null;
}
if (this.fs) {
gl.deleteShader(this.fs);
this.fs = null;
}
if (this.program) {
gl.deleteProgram(this.program);
this.program = null;
}
}
/**
* @param {?} context
* @return {?}
*/
static newColoredTextured(context) {
/** @type {?} */
let vs = `
attribute vec4 ${Shader.POSITION};
attribute vec4 ${Shader.COLOR};
attribute vec2 ${Shader.TEXCOORDS};
uniform mat4 ${Shader.MVP_MATRIX};
varying vec4 v_color;
varying vec2 v_texCoords;
void main () {
v_color = ${Shader.COLOR};
v_texCoords = ${Shader.TEXCOORDS};
gl_Position = ${Shader.MVP_MATRIX} * ${Shader.POSITION};
}
`;
/** @type {?} */
let fs = `
#ifdef GL_ES
#define LOWP lowp
precision mediump float;
#else
#define LOWP
#endif
varying LOWP vec4 v_color;
varying vec2 v_texCoords;
uniform sampler2D u_texture;
void main () {
gl_FragColor = v_color * texture2D(u_texture, v_texCoords);
}
`;
return new Shader(context, vs, fs);
}
/**
* @param {?} context
* @return {?}
*/
static newTwoColoredTextured(context) {
/** @type {?} */
let vs = `
attribute vec4 ${Shader.POSITION};
attribute vec4 ${Shader.COLOR};
attribute vec4 ${Shader.COLOR2};
attribute vec2 ${Shader.TEXCOORDS};
uniform mat4 ${Shader.MVP_MATRIX};
varying vec4 v_light;
varying vec4 v_dark;
varying vec2 v_texCoords;
void main () {
v_light = ${Shader.COLOR};
v_dark = ${Shader.COLOR2};
v_texCoords = ${Shader.TEXCOORDS};
gl_Position = ${Shader.MVP_MATRIX} * ${Shader.POSITION};
}
`;
/** @type {?} */
let fs = `
#ifdef GL_ES
#define LOWP lowp
precision mediump float;
#else
#define LOWP
#endif
varying LOWP vec4 v_light;
varying LOWP vec4 v_dark;
varying vec2 v_texCoords;
uniform sampler2D u_texture;
void main () {
vec4 texColor = texture2D(u_texture, v_texCoords);
gl_FragColor.a = texColor.a * v_light.a;
gl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;
}
`;
return new Shader(context, vs, fs);
}
/**
* @param {?} context
* @return {?}
*/
static newColored(context) {
/** @type {?} */
let vs = `
attribute vec4 ${Shader.POSITION};
attribute vec4 ${Shader.COLOR};
uniform mat4 ${Shader.MVP_MATRIX};
varying vec4 v_color;
void main () {
v_color = ${Shader.COLOR};
gl_Position = ${Shader.MVP_MATRIX} * ${Shader.POSITION};
}
`;
/** @type {?} */
let fs = `
#ifdef GL_ES
#define LOWP lowp
precision mediump float;
#else
#define LOWP
#endif
varying LOWP vec4 v_color;
void main () {
gl_FragColor = v_color;
}
`;
return new Shader(context, vs, fs);
}
}
Shader.MVP_MATRIX = "u_projTrans";
Shader.POSITION = "a_position";
Shader.COLOR = "a_color";
Shader.COLOR2 = "a_color2";
Shader.TEXCOORDS = "a_texCoords";
Shader.SAMPLER = "u_texture";
if (false) {
/** @type {?} */
Shader.MVP_MATRIX;
/** @type {?} */
Shader.POSITION;
/** @type {?} */
Shader.COLOR;
/** @type {?} */
Shader.COLOR2;
/** @type {?} */
Shader.TEXCOORDS;
/** @type {?} */
Shader.SAMPLER;
/**
* @type {?}
* @private
*/
Shader.prototype.context;
/**
* @type {?}
* @private
*/
Shader.prototype.vs;
/**
* @type {?}
* @private
*/
Shader.prototype.vsSource;
/**
* @type {?}
* @private
*/
Shader.prototype.fs;
/**
* @type {?}
* @private
*/
Shader.prototype.fsSource;
/**
* @type {?}
* @private
*/
Shader.prototype.program;
/**
* @type {?}
* @private
*/
Shader.prototype.tmp2x2;
/**
* @type {?}
* @private
*/
Shader.prototype.tmp3x3;
/**
* @type {?}
* @private
*/
Shader.prototype.tmp4x4;
/**
* @type {?}
* @private
*/
Shader.prototype.vertexShader;
/**
* @type {?}
* @private
*/
Shader.prototype.fragmentShader;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2hhZGVyLmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LXNwaW5lLyIsInNvdXJjZXMiOlsibGliL3NwaW5lLXRzL3dlYmdsL1NoYWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQThCQSxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFdkQsTUFBTSxPQUFPLE1BQU07Ozs7OztJQStCakIsWUFDRSxPQUE2RCxFQUNyRCxZQUFvQixFQUNwQixjQUFzQjtRQUR0QixpQkFBWSxHQUFaLFlBQVksQ0FBUTtRQUNwQixtQkFBYyxHQUFkLGNBQWMsQ0FBUTtRQTFCeEIsT0FBRSxHQUFnQixJQUFJLENBQUM7UUFFdkIsT0FBRSxHQUFnQixJQUFJLENBQUM7UUFFdkIsWUFBTyxHQUFpQixJQUFJLENBQUM7UUFDN0IsV0FBTSxHQUFpQixJQUFJLFlBQVksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDL0MsV0FBTSxHQUFpQixJQUFJLFlBQVksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDL0MsV0FBTSxHQUFpQixJQUFJLFlBQVksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFxQnJELElBQUksQ0FBQyxRQUFRLEdBQUcsWUFBWSxDQUFDO1FBQzdCLElBQUksQ0FBQyxRQUFRLEdBQUcsY0FBYyxDQUFDO1FBQy9CLElBQUksQ0FBQyxPQUFPO1lBQ1YsT0FBTyxZQUFZLDRCQUE0QjtnQkFDN0MsQ0FBQyxDQUFDLE9BQU87Z0JBQ1QsQ0FBQyxDQUFDLElBQUksNEJBQTRCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDaEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2pCLENBQUM7Ozs7SUE1Qk0sVUFBVTtRQUNmLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FB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LFVBQVU7OztpQkFHbkIsTUFBTSxDQUFDLEtBQUs7cUJBQ1IsTUFBTSxDQUFDLFVBQVUsTUFBTSxNQUFNLENBQUMsUUFBUTs7SUFFdkQ7O1lBQ0ksRUFBRSxHQUFHOzs7Ozs7Ozs7OztJQVdUO1FBQ0EsT0FBTyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7O0FBNVFhLGlCQUFVLEdBQUcsYUFBYSxDQUFDO0FBQzNCLGVBQVEsR0FBRyxZQUFZLENBQUM7QUFDeEIsWUFBSyxHQUFHLFNBQVMsQ0FBQztBQUNsQixhQUFNLEdBQUcsVUFBVSxDQUFDO0FBQ3BCLGdCQUFTLEdBQUcsYUFBYSxDQUFDO0FBQzFCLGNBQU8sR0FBRyxXQUFXLENBQUM7OztJQUxwQyxrQkFBeUM7O0lBQ3pDLGdCQUFzQzs7SUFDdEMsYUFBZ0M7O0lBQ2hDLGNBQWtDOztJQUNsQyxpQkFBd0M7O0lBQ3hDLGVBQW9DOzs7OztJQUNwQyx5QkFBOEM7Ozs7O0lBQzlDLG9CQUErQjs7Ozs7SUFDL0IsMEJBQXlCOzs7OztJQUN6QixvQkFBK0I7Ozs7O0lBQy9CLDBCQUF5Qjs7Ozs7SUFDekIseUJBQXFDOzs7OztJQUNyQyx3QkFBdUQ7Ozs7O0lBQ3ZELHdCQUF1RDs7Ozs7SUFDdkQsd0JBQXVEOzs7OztJQWtCckQsOEJBQTRCOzs7OztJQUM1QixnQ0FBOEIiLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbiAqIFNwaW5lIFJ1bnRpbWVzIExpY2Vuc2UgQWdyZWVtZW50XHJcbiAqIExhc3QgdXBkYXRlZCBNYXkgMSwgMjAxOS4gUmVwbGFjZXMgYWxsIHByaW9yIHZlcnNpb25zLlxyXG4gKlxyXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtMjAxOSwgRXNvdGVyaWMgU29mdHdhcmUgTExDXHJcbiAqXHJcbiAqIEludGVncmF0aW9uIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlIG9yIG90aGVyd2lzZSBjcmVhdGluZ1xyXG4gKiBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpcyBwZXJtaXR0ZWQgdW5kZXIgdGhlIHRlcm1zIGFuZFxyXG4gKiBjb25kaXRpb25zIG9mIFNlY3Rpb24gMiBvZiB0aGUgU3BpbmUgRWRpdG9yIExpY2Vuc2UgQWdyZWVtZW50OlxyXG4gKiBodHRwOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vc3BpbmUtZWRpdG9yLWxpY2Vuc2VcclxuICpcclxuICogT3RoZXJ3aXNlLCBpdCBpcyBwZXJtaXR0ZWQgdG8gaW50ZWdyYXRlIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlXHJcbiAqIG9yIG90aGVyd2lzZSBjcmVhdGUgZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgKGNvbGxlY3RpdmVseSxcclxuICogXCJQcm9kdWN0c1wiKSwgcHJvdmlkZWQgdGhhdCBlYWNoIHVzZXIgb2YgdGhlIFByb2R1Y3RzIG11c3Qgb2J0YWluIHRoZWlyIG93blxyXG4gKiBTcGluZSBFZGl0b3IgbGljZW5zZSBhbmQgcmVkaXN0cmlidXRpb24gb2YgdGhlIFByb2R1Y3RzIGluIGFueSBmb3JtIG11c3RcclxuICogaW5jbHVkZSB0aGlzIGxpY2Vuc2UgYW5kIGNvcHlyaWdodCBub3RpY2UuXHJcbiAqXHJcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgRVNPVEVSSUMgU09GVFdBUkUgTExDIFwiQVMgSVNcIiBBTkQgQU5ZIEVYUFJFU1NcclxuICogT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFU1xyXG4gKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTlxyXG4gKiBOTyBFVkVOVCBTSEFMTCBFU09URVJJQyBTT0ZUV0FSRSBMTEMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCxcclxuICogSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORyxcclxuICogQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTLCBCVVNJTkVTU1xyXG4gKiBJTlRFUlJVUFRJT04sIE9SIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZXHJcbiAqIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElOR1xyXG4gKiBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsXHJcbiAqIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXHJcbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cclxuXHJcbmltcG9ydCB7IERpc3Bvc2FibGUsIFJlc3RvcmFibGUgfSBmcm9tIFwiLi4vY29yZS9VdGlsc1wiO1xyXG5pbXBvcnQgeyBNYW5hZ2VkV2ViR0xSZW5kZXJpbmdDb250ZXh0IH0gZnJvbSBcIi4vV2ViR0xcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBTaGFkZXIgaW1wbGVtZW50cyBEaXNwb3NhYmxlLCBSZXN0b3JhYmxlIHtcclxuICBwdWJsaWMgc3RhdGljIE1WUF9NQVRSSVggPSBcInVfcHJvalRyYW5zXCI7XHJcbiAgcHVibGljIHN0YXRpYyBQT1NJVElPTiA9IFwiYV9wb3NpdGlvblwiO1xyXG4gIHB1YmxpYyBzdGF0aWMgQ09MT1IgPSBcImFfY29sb3JcIjtcclxuICBwdWJsaWMgc3RhdGljIENPTE9SMiA9IFwiYV9jb2xvcjJcIjtcclxuICBwdWJsaWMgc3RhdGljIFRFWENPT1JEUyA9IFwiYV90ZXhDb29yZHNcIjtcclxuICBwdWJsaWMgc3RhdGljIFNBTVBMRVIgPSBcInVfdGV4dHVyZVwiO1xyXG4gIHByaXZhdGUgY29udGV4dDogTWFuYWdlZFdlYkdMUmVuZGVyaW5nQ29udGV4dDtcclxuICBwcml2YXRlIHZzOiBXZWJHTFNoYWRlciA9IG51bGw7XHJcbiAgcHJpdmF0ZSB2c1NvdXJjZTogc3RyaW5nO1xyXG4gIHByaXZhdGUgZnM6IFdlYkdMU2hhZGVyID0gbnVsbDtcclxuICBwcml2YXRlIGZzU291cmNlOiBzdHJpbmc7XHJcbiAgcHJpdmF0ZSBwcm9ncmFtOiBXZWJHTFByb2dyYW0gPSBudWxsO1xyXG4gIHByaXZhdGUgdG1wMngyOiBGbG9hdDMyQXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KDIgKiAyKTtcclxuICBwcml2YXRlIHRtcDN4MzogRmxvYXQzMkFycmF5ID0gbmV3IEZsb2F0MzJBcnJheSgzICogMyk7XHJcbiAgcHJpdmF0ZSB0bXA0eDQ6IEZsb2F0MzJBcnJheSA9IG5ldyBGbG9hdDMyQXJyYXkoNCAqIDQpO1xyXG4gIHB1YmxpYyBnZXRQcm9ncmFtKCkge1xyXG4gICAgcmV0dXJuIHRoaXMucHJvZ3JhbTtcclxuICB9XHJcbiAgcHVibGljIGdldFZlcnRleFNoYWRlcigpIHtcclxuICAgIHJldHVybiB0aGlzLnZlcnRleFNoYWRlcjtcclxuICB9XHJcbiAgcHVibGljIGdldEZyYWdtZW50U2hhZGVyKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuZnJhZ21lbnRTaGFkZXI7XHJcbiAgfVxyXG4gIHB1YmxpYyBnZXRWZXJ0ZXhTaGFkZXJTb3VyY2UoKSB7XHJcbiAgICByZXR1cm4gdGhpcy52c1NvdXJjZTtcclxuICB9XHJcbiAgcHVibGljIGdldEZyYWdtZW50U291cmNlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuZnNTb3VyY2U7XHJcbiAgfVxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgY29udGV4dDogTWFuYWdlZFdlYkdMUmVuZGVyaW5nQ29udGV4dCB8IFdlYkdMUmVuZGVyaW5nQ29udGV4dCxcclxuICAgIHByaXZhdGUgdmVydGV4U2hhZGVyOiBzdHJpbmcsXHJcbiAgICBwcml2YXRlIGZyYWdtZW50U2hhZGVyOiBzdHJpbmdcclxuICApIHtcclxuICAgIHRoaXMudnNTb3VyY2UgPSB2ZXJ0ZXhTaGFkZXI7XHJcbiAgICB0aGlzLmZzU291cmNlID0gZnJhZ21lbnRTaGFkZXI7XHJcbiAgICB0aGlzLmNvbnRleHQgPVxyXG4gICAgICBjb250ZXh0IGluc3RhbmNlb2YgTWFuYWdlZFdlYkdMUmVuZGVyaW5nQ29udGV4dFxyXG4gICAgICAgID8gY29udGV4dFxyXG4gICAgICAgIDogbmV3IE1hbmFnZWRXZWJHTFJlbmRlcmluZ0NvbnRleHQoY29udGV4dCk7XHJcbiAgICB0aGlzLmNvbnRleHQuYWRkUmVzdG9yYWJsZSh0aGlzKTtcclxuICAgIHRoaXMuY29tcGlsZSgpO1xyXG4gIH1cclxuICBwcml2YXRlIGNvbXBpbGUoKSB7XHJcbiAgICBsZXQgZ2wgPSB0aGlzLmNvbnRleHQuZ2w7XHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLnZzID0gdGhpcy5jb21waWxlU2hhZGVyKGdsLlZFUlRFWF9TSEFERVIsIHRoaXMudmVydGV4U2hhZGVyKTtcclxuICAgICAgdGhpcy5mcyA9IHRoaXMuY29tcGlsZVNoYWRlcihnbC5GUkFHTUVOVF9TSEFERVIsIHRoaXMuZnJhZ21lbnRTaGFkZXIpO1xyXG4gICAgICB0aGlzLnByb2dyYW0gPSB0aGlzLmNvbXBpbGVQcm9ncmFtKHRoaXMudnMsIHRoaXMuZnMpO1xyXG4gICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICB0aGlzLmRpc3Bvc2UoKTtcclxuICAgICAgdGhyb3cgZTtcclxuICAgIH1cclxuICB9XHJcbiAgcHJpdmF0ZSBjb21waWxlU2hhZGVyKHR5cGU6IG51bWJlciwgc291cmNlOiBzdHJpbmcpIHtcclxuICAgIGxldCBnbCA9IHRoaXMuY29udGV4dC5nbDtcclxuICAgIGxldCBzaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIodHlwZSk7XHJcbiAgICBnbC5zaGFkZXJTb3VyY2Uoc2hhZGVyLCBzb3VyY2UpO1xyXG4gICAgZ2wuY29tcGlsZVNoYWRlcihzaGFkZXIpO1xyXG4gICAgaWYgKCFnbC5nZXRTaGFkZXJQYXJhbWV0ZXIoc2hhZGVyLCBnbC5DT01QSUxFX1NUQVRVUykpIHtcclxuICAgICAgbGV0IGVycm9yID0gXCJDb3VsZG4ndCBjb21waWxlIHNoYWRlcjogXCIgKyBnbC5nZXRTaGFkZXJJbmZvTG9nKHNoYWRlcik7XHJcbiAgICAgIGdsLmRlbGV0ZVNoYWRlcihzaGFkZXIpO1xyXG4gICAgICBpZiAoIWdsLmlzQ29udGV4dExvc3QoKSkgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcclxuICAgIH1cclxuICAgIHJldHVybiBzaGFkZXI7XHJcbiAgfVxyXG4gIHByaXZhdGUgY29tcGlsZVByb2dyYW0odnM6IFdlYkdMU2hhZGVyLCBmczogV2ViR0xTaGFkZXIpIHtcclxuICAgIGxldCBnbCA9IHRoaXMuY29udGV4dC5nbDtcclxuICAgIGxldCBwcm9ncmFtID0gZ2wuY3JlYXRlUHJvZ3JhbSgpO1xyXG4gICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIHZzKTtcclxuICAgIGdsLmF0dGFjaFNoYWRlcihwcm9ncmFtLCBmcyk7XHJcbiAgICBnbC5saW5rUHJvZ3JhbShwcm9ncmFtKTtcclxuICAgIGlmICghZ2wuZ2V0UHJvZ3JhbVBhcmFtZXRlcihwcm9ncmFtLCBnbC5MSU5LX1NUQVRVUykpIHtcclxuICAgICAgbGV0IGVycm9yID1cclxuICAgICAgICBcIkNvdWxkbid0IGNvbXBpbGUgc2hhZGVyIHByb2dyYW06IFwiICsgZ2wuZ2V0UHJvZ3JhbUluZm9Mb2cocHJvZ3JhbSk7XHJcbiAgICAgIGdsLmRlbGV0ZVByb2dyYW0ocHJvZ3JhbSk7XHJcbiAgICAgIGlmICghZ2wuaXNDb250ZXh0TG9zdCgpKSB0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHByb2dyYW07XHJcbiAgfVxyXG4gIHJlc3RvcmUoKSB7XHJcbiAgICB0aGlzLmNvbXBpbGUoKTtcclxuICB9XHJcbiAgcHVibGljIGJpbmQoKSB7XHJcbiAgICB0aGlzLmNvbnRleHQuZ2wudXNlUHJvZ3JhbSh0aGlzLnByb2dyYW0pO1xyXG4gIH1cclxuICBwdWJsaWMgdW5iaW5kKCkge1xyXG4gICAgdGhpcy5jb250ZXh0LmdsLnVzZVByb2dyYW0obnVsbCk7XHJcbiAgfVxyXG4gIHB1YmxpYyBzZXRVbmlmb3JtaSh1bmlmb3JtOiBzdHJpbmcsIHZhbHVlOiBudW1iZXIpIHtcclxuICAgIHRoaXMuY29udGV4dC5nbC51bmlmb3JtMWkodGhpcy5nZXRVbmlmb3JtTG9jYXRpb24odW5pZm9ybSksIHZhbHVlKTtcclxuICB9XHJcbiAgcHVibGljIHNldFVuaWZvcm1mKHVuaWZvcm06IHN0cmluZywgdmFsdWU6IG51bWJlcikge1xyXG4gICAgdGhpcy5jb250ZXh0LmdsLnVuaWZvcm0xZih0aGlzLmdldFVuaWZvcm1Mb2NhdGlvbih1bmlmb3JtKSwgdmFsdWUpO1xyXG4gIH1cclxuICBwdWJsaWMgc2V0VW5pZm9ybTJmKHVuaWZvcm06IHN0cmluZywgdmFsdWU6IG51bWJlciwgdmFsdWUyOiBudW1iZXIpIHtcclxuICAgIHRoaXMuY29udGV4dC5nbC51bmlmb3JtMmYodGhpcy5nZXRVbmlmb3JtTG9jYXRpb24odW5pZm9ybSksIHZhbHVlLCB2YWx1ZTIpO1xyXG4gIH1cclxuICBwdWJsaWMgc2V0VW5pZm9ybTNmKFxyXG4gICAgdW5pZm9ybTogc3RyaW5nLFxyXG4gICAgdmFsdWU6IG51bWJlcixcclxuICAgIHZhbHVlMjogbnVtYmVyLFxyXG4gICAgdmFsdWUzOiBudW1iZXJcclxuICApIHtcclxuICAgIHRoaXMuY29udGV4dC5nbC51bmlmb3JtM2YoXHJcbiAgICAgIHRoaXMuZ2V0VW5pZm9ybUxvY2F0aW9uKHVuaWZvcm0pLFxyXG4gICAgICB2YWx1ZSxcclxuICAgICAgdmFsdWUyLFxyXG4gICAgICB2YWx1ZTNcclxuICAgICk7XHJcbiAgfVxyXG4gIHB1YmxpYyBzZXRVbmlmb3JtNGYoXHJcbiAgICB1bmlmb3JtOiBzdHJpbmcsXHJcbiAgICB2YWx1ZTogbnVtYmVyLFxyXG4gICAgdmFsdWUyOiBudW1iZXIsXHJcbiAgICB2YWx1ZTM6IG51bWJlcixcclxuICAgIHZhbHVlNDogbnVtYmVyXHJcbiAgKSB7XHJcbiAgICB0aGlzLmNvbnRleHQuZ2wudW5pZm9ybTRmKFxyXG4gICAgICB0aGlzLmdldFVuaWZvcm1Mb2NhdGlvbih1bmlmb3JtKSxcclxuICAgICAgdmFsdWUsXHJcbiAgICAgIHZhbHVlMixcclxuICAgICAgdmFsdWUzLFxyXG4gICAgICB2YWx1ZTRcclxuICAgICk7XHJcbiAgfVxyXG4gIHB1YmxpYyBzZXRVbmlmb3JtMngyZih1bmlmb3JtOiBzdHJpbmcsIHZhbHVlOiBBcnJheUxpa2U8bnVtYmVyPikge1xyXG4gICAgbGV0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xyXG4gICAgdGhpcy50bXAyeDIuc2V0KHZhbHVlKTtcclxuICAgIGdsLnVuaWZvcm1NYXRyaXgyZnYodGhpcy5nZXRVbmlmb3JtTG9jYXRpb24odW5pZm9ybSksIGZhbHNlLCB0aGlzLnRtcDJ4Mik7XHJcbiAgfVxyXG4gIHB1YmxpYyBzZXRVbmlmb3JtM3gzZih1bmlmb3JtOiBzdHJpbmcsIHZhbHVlOiBBcnJheUxpa2U8bnVtYmVyPikge1xyXG4gICAgbGV0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xyXG4gICAgdGhpcy50bXAzeDMuc2V0KHZhbHVlKTtcclxuICAgIGdsLnVuaWZvcm1NYXRyaXgzZnYodGhpcy5nZXRVbmlmb3JtTG9jYXRpb24odW5pZm9ybSksIGZhbHNlLCB0aGlzLnRtcDN4Myk7XHJcbiAgfVxyXG4gIHB1YmxpYyBzZXRVbmlmb3JtNHg0Zih1bmlmb3JtOiBzdHJpbmcsIHZhbHVlOiBBcnJheUxpa2U8bnVtYmVyPikge1xyXG4gICAgbGV0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xyXG4gICAgdGhpcy50bXA0eDQuc2V0KHZhbHVlKTtcclxuICAgIGdsLnVuaWZvcm1NYXRyaXg0ZnYodGhpcy5nZXRVbmlmb3JtTG9jYXRpb24odW5pZm9ybSksIGZhbHNlLCB0aGlzLnRtcDR4NCk7XHJcbiAgfVxyXG4gIHB1YmxpYyBnZXRVbmlmb3JtTG9jYXRpb24odW5pZm9ybTogc3RyaW5nKTogV2ViR0xVbmlmb3JtTG9jYXRpb24ge1xyXG4gICAgbGV0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xyXG4gICAgbGV0IGxvY2F0aW9uID0gZ2wuZ2V0VW5pZm9ybUxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgdW5pZm9ybSk7XHJcbiAgICBpZiAoIWxvY2F0aW9uICYmICFnbC5pc0NvbnRleHRMb3N0KCkpXHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ291bGRuJ3QgZmluZCBsb2NhdGlvbiBmb3IgdW5pZm9ybSAke3VuaWZvcm19YCk7XHJcbiAgICByZXR1cm4gbG9jYXRpb247XHJcbiAgfVxyXG4gIHB1YmxpYyBnZXRBdHRyaWJ1dGVMb2NhdGlvbihhdHRyaWJ1dGU6IHN0cmluZyk6IG51bWJlciB7XHJcbiAgICBsZXQgZ2wgPSB0aGlzLmNvbnRleHQuZ2w7XHJcbiAgICBsZXQgbG9jYXRpb24gPSBnbC5nZXRBdHRyaWJMb2NhdGlvbih0aGlzLnByb2dyYW0sIGF0dHJpYnV0ZSk7XHJcbiAgICBpZiAobG9jYXRpb24gPT0gLTEgJiYgIWdsLmlzQ29udGV4dExvc3QoKSlcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZG4ndCBmaW5kIGxvY2F0aW9uIGZvciBhdHRyaWJ1dGUgJHthdHRyaWJ1dGV9YCk7XHJcbiAgICByZXR1cm4gbG9jYXRpb247XHJcbiAgfVxyXG4gIHB1YmxpYyBkaXNwb3NlKCkge1xyXG4gICAgdGhpcy5jb250ZXh0LnJlbW92ZVJlc3RvcmFibGUodGhpcyk7XHJcbiAgICBsZXQgZ2wgPSB0aGlzLmNvbnRleHQuZ2w7XHJcbiAgICBpZiAodGhpcy52cykge1xyXG4gICAgICBnbC5kZWxldGVTaGFkZXIodGhpcy52cyk7XHJcbiAgICAgIHRoaXMudnMgPSBudWxsO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuZnMpIHtcclxuICAgICAgZ2wuZGVsZXRlU2hhZGVyKHRoaXMuZnMpO1xyXG4gICAgICB0aGlzLmZzID0gbnVsbDtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLnByb2dyYW0pIHtcclxuICAgICAgZ2wuZGVsZXRlUHJvZ3JhbSh0aGlzLnByb2dyYW0pO1xyXG4gICAgICB0aGlzLnByb2dyYW0gPSBudWxsO1xyXG4gICAgfVxyXG4gIH1cclxuICBwdWJsaWMgc3RhdGljIG5ld0NvbG9yZWRUZXh0dXJlZChcclxuICAgIGNvbnRleHQ6IE1hbmFnZWRXZWJHTFJlbmRlcmluZ0NvbnRleHQgfCBXZWJHTFJlbmRlcmluZ0NvbnRleHRcclxuICApOiBTaGFkZXIge1xyXG4gICAgbGV0IHZzID0gYFxyXG5cdFx0XHRcdGF0dHJpYnV0ZSB2ZWM0ICR7U2hhZGVyLlBPU0lUSU9OfTtcclxuXHRcdFx0XHRhdHRyaWJ1dGUgdmVjNCAke1NoYWRlci5DT0xPUn07XHJcblx0XHRcdFx0YXR0cmlidXRlIHZlYzIgJHtTaGFkZXIuVEVYQ09PUkRTfTtcclxuXHRcdFx0XHR1bmlmb3JtIG1hdDQgJHtTaGFkZXIuTVZQX01BVFJJWH07XHJcblx0XHRcdFx0dmFyeWluZyB2ZWM0IHZfY29sb3I7XHJcblx0XHRcdFx0dmFyeWluZyB2ZWMyIHZfdGV4Q29vcmRzO1xyXG5cdFx0XHRcdHZvaWQgbWFpbiAoKSB7XHJcblx0XHRcdFx0XHR2X2NvbG9yID0gJHtTaGFkZXIuQ09MT1J9O1xyXG5cdFx0XHRcdFx0dl90ZXhDb29yZHMgPSAke1NoYWRlci5URVhDT09SRFN9O1xyXG5cdFx0XHRcdFx0Z2xfUG9zaXRpb24gPSAke1NoYWRlci5NVlBfTUFUUklYfSAqICR7U2hhZGVyLlBPU0lUSU9OfTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdGA7XHJcbiAgICBsZXQgZnMgPSBgXHJcblx0XHRcdFx0I2lmZGVmIEdMX0VTXHJcblx0XHRcdFx0XHQjZGVmaW5lIExPV1AgbG93cFxyXG5cdFx0XHRcdFx0cHJlY2lzaW9uIG1lZGl1bXAgZmxvYXQ7XHJcblx0XHRcdFx0I2Vsc2VcclxuXHRcdFx0XHRcdCNkZWZpbmUgTE9XUFxyXG5cdFx0XHRcdCNlbmRpZlxyXG5cdFx0XHRcdHZhcnlpbmcgTE9XUCB2ZWM0IHZfY29sb3I7XHJcblx0XHRcdFx0dmFyeWluZyB2ZWMyIHZfdGV4Q29vcmRzO1xyXG5cdFx0XHRcdHVuaWZvcm0gc2FtcGxlcjJEIHVfdGV4dHVyZTtcclxuXHRcdFx0XHR2b2lkIG1haW4gKCkge1xyXG5cdFx0XHRcdFx0Z2xfRnJhZ0NvbG9yID0gdl9jb2xvciAqIHRleHR1cmUyRCh1X3RleHR1cmUsIHZfdGV4Q29vcmRzKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdGA7XHJcbiAgICByZXR1cm4gbmV3IFNoYWRlcihjb250ZXh0LCB2cywgZnMpO1xyXG4gIH1cclxuICBwdWJsaWMgc3RhdGljIG5ld1R3b0NvbG9yZWRUZXh0dXJlZChcclxuICAgIGNvbnRleHQ6IE1hbmFnZWRXZWJHTFJlbmRlcmluZ0NvbnRleHQgfCBXZWJHTFJlbmRlcmluZ0NvbnRleHRcclxuICApOiBTaGFkZXIge1xyXG4gICAgbGV0IHZzID0gYFxyXG5cdFx0XHRcdGF0dHJpYnV0ZSB2ZWM0ICR7U2hhZGVyLlBPU0lUSU9OfTtcclxuXHRcdFx0XHRhdHRyaWJ1dGUgdmVjNCAke1NoYWRlci5DT0xPUn07XHJcblx0XHRcdFx0YXR0cmlidXRlIHZlYzQgJHtTaGFkZXIuQ09MT1IyfTtcclxuXHRcdFx0XHRhdHRyaWJ1dGUgdmVjMiAke1NoYWRlci5URVhDT09SRFN9O1xyXG5cdFx0XHRcdHVuaWZvcm0gbWF0NCAke1NoYWRlci5NVlBfTUFUUklYfTtcclxuXHRcdFx0XHR2YXJ5aW5nIHZlYzQgdl9saWdodDtcclxuXHRcdFx0XHR2YXJ5aW5nIHZlYzQgdl9kYXJrO1xyXG5cdFx0XHRcdHZhcnlpbmcgdmVjMiB2X3RleENvb3JkcztcclxuXHRcdFx0XHR2b2lkIG1haW4gKCkge1xyXG5cdFx0XHRcdFx0dl9saWdodCA9ICR7U2hhZGVyLkNPTE9SfTtcclxuXHRcdFx0XHRcdHZfZGFyayA9ICR7U2hhZGVyLkNPTE9SMn07XHJcblx0XHRcdFx0XHR2X3RleENvb3JkcyA9ICR7U2hhZGVyLlRFWENPT1JEU307XHJcblx0XHRcdFx0XHRnbF9Qb3NpdGlvbiA9ICR7U2hhZGVyLk1WUF9NQVRSSVh9ICogJHtTaGFkZXIuUE9TSVRJT059O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0YDtcclxuICAgIGxldCBmcyA9IGBcclxuXHRcdFx0XHQjaWZkZWYgR0xfRVNcclxuXHRcdFx0XHRcdCNkZWZpbmUgTE9XUCBsb3dwXHJcblx0XHRcdFx0XHRwcmVjaXNpb24gbWVkaXVtcCBmbG9hdDtcclxuXHRcdFx0XHQjZWxzZVxyXG5cdFx0XHRcdFx0I2RlZmluZSBMT1dQXHJcblx0XHRcdFx0I2VuZGlmXHJcblx0XHRcdFx0dmFyeWluZyBMT1dQIHZlYzQgdl9saWdodDtcclxuXHRcdFx0XHR2YXJ5aW5nIExPV1AgdmVjNCB2X2Rhcms7XHJcblx0XHRcdFx0dmFyeWluZyB2ZWMyIHZfdGV4Q29vcmRzO1xyXG5cdFx0XHRcdHVuaWZvcm0gc2FtcGxlcjJEIHVfdGV4dHVyZTtcclxuXHRcdFx0XHR2b2lkIG1haW4gKCkge1xyXG5cdFx0XHRcdFx0dmVjNCB0ZXhDb2xvciA9IHRleHR1cmUyRCh1X3RleHR1cmUsIHZfdGV4Q29vcmRzKTtcclxuXHRcdFx0XHRcdGdsX0ZyYWdDb2xvci5hID0gdGV4Q29sb3IuYSAqIHZfbGlnaHQuYTtcclxuXHRcdFx0XHRcdGdsX0ZyYWdDb2xvci5yZ2IgPSAoKHRleENvbG9yLmEgLSAxLjApICogdl9kYXJrLmEgKyAxLjAgLSB0ZXhDb2xvci5yZ2IpICogdl9kYXJrLnJnYiArIHRleENvbG9yLnJnYiAqIHZfbGlnaHQucmdiO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0YDtcclxuICAgIHJldHVybiBuZXcgU2hhZGVyKGNvbnRleHQsIHZzLCBmcyk7XHJcbiAgfVxyXG4gIHB1YmxpYyBzdGF0aWMgbmV3Q29sb3JlZChcclxuICAgIGNvbnRleHQ6IE1hbmFnZWRXZWJHTFJlbmRlcmluZ0NvbnRleHQgfCBXZWJHTFJlbmRlcmluZ0NvbnRleHRcclxuICApOiBTaGFkZXIge1xyXG4gICAgbGV0IHZzID0gYFxyXG5cdFx0XHRcdGF0dHJpYnV0ZSB2ZWM0ICR7U2hhZGVyLlBPU0lUSU9OfTtcclxuXHRcdFx0XHRhdHRyaWJ1dGUgdmVjNCAke1NoYWRlci5DT0xPUn07XHJcblx0XHRcdFx0dW5pZm9ybSBtYXQ0ICR7U2hhZGVyLk1WUF9NQVRSSVh9O1xyXG5cdFx0XHRcdHZhcnlpbmcgdmVjNCB2X2NvbG9yO1xyXG5cdFx0XHRcdHZvaWQgbWFpbiAoKSB7XHJcblx0XHRcdFx0XHR2X2NvbG9yID0gJHtTaGFkZXIuQ09MT1J9O1xyXG5cdFx0XHRcdFx0Z2xfUG9zaXRpb24gPSAke1NoYWRlci5NVlBfTUFUUklYfSAqICR7U2hhZGVyLlBPU0lUSU9OfTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdGA7XHJcbiAgICBsZXQgZnMgPSBgXHJcblx0XHRcdFx0I2lmZGVmIEdMX0VTXHJcblx0XHRcdFx0XHQjZGVmaW5lIExPV1AgbG93cFxyXG5cdFx0XHRcdFx0cHJlY2lzaW9uIG1lZGl1bXAgZmxvYXQ7XHJcblx0XHRcdFx0I2Vsc2VcclxuXHRcdFx0XHRcdCNkZWZpbmUgTE9XUFxyXG5cdFx0XHRcdCNlbmRpZlxyXG5cdFx0XHRcdHZhcnlpbmcgTE9XUCB2ZWM0IHZfY29sb3I7XHJcblx0XHRcdFx0dm9pZCBtYWluICgpIHtcclxuXHRcdFx0XHRcdGdsX0ZyYWdDb2xvciA9IHZfY29sb3I7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRgO1xyXG4gICAgcmV0dXJuIG5ldyBTaGFkZXIoY29udGV4dCwgdnMsIGZzKTtcclxuICB9XHJcbn1cclxuIl19