ngx-spine
Version:
[](https://travis-ci.org/PoiScript/ngx-spine)
746 lines • 59.7 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";
import { Mesh, ColorAttribute, Position2Attribute } from "./Mesh";
import { Color, Vector2, MathUtils } from "../core/Utils";
var ShapeRenderer = /** @class */ (function () {
function ShapeRenderer(context, maxVertices) {
if (maxVertices === void 0) { maxVertices = 10920; }
this.isDrawing = false;
this.shapeType = ShapeType.Filled;
this.color = new Color(1, 1, 1, 1);
this.vertexIndex = 0;
this.tmp = new Vector2();
if (maxVertices > 10920)
throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
this.context =
context instanceof ManagedWebGLRenderingContext
? context
: new ManagedWebGLRenderingContext(context);
this.mesh = new Mesh(context, [new Position2Attribute(), new ColorAttribute()], maxVertices, 0);
this.srcBlend = this.context.gl.SRC_ALPHA;
this.dstBlend = this.context.gl.ONE_MINUS_SRC_ALPHA;
}
/**
* @param {?} shader
* @return {?}
*/
ShapeRenderer.prototype.begin = /**
* @param {?} shader
* @return {?}
*/
function (shader) {
if (this.isDrawing)
throw new Error("ShapeRenderer.begin() has already been called");
this.shader = shader;
this.vertexIndex = 0;
this.isDrawing = true;
/** @type {?} */
var gl = this.context.gl;
gl.enable(gl.BLEND);
gl.blendFunc(this.srcBlend, this.dstBlend);
};
/**
* @param {?} srcBlend
* @param {?} dstBlend
* @return {?}
*/
ShapeRenderer.prototype.setBlendMode = /**
* @param {?} srcBlend
* @param {?} dstBlend
* @return {?}
*/
function (srcBlend, dstBlend) {
/** @type {?} */
var gl = this.context.gl;
this.srcBlend = srcBlend;
this.dstBlend = dstBlend;
if (this.isDrawing) {
this.flush();
gl.blendFunc(this.srcBlend, this.dstBlend);
}
};
/**
* @param {?} color
* @return {?}
*/
ShapeRenderer.prototype.setColor = /**
* @param {?} color
* @return {?}
*/
function (color) {
this.color.setFromColor(color);
};
/**
* @param {?} r
* @param {?} g
* @param {?} b
* @param {?} a
* @return {?}
*/
ShapeRenderer.prototype.setColorWith = /**
* @param {?} r
* @param {?} g
* @param {?} b
* @param {?} a
* @return {?}
*/
function (r, g, b, a) {
this.color.set(r, g, b, a);
};
/**
* @param {?} x
* @param {?} y
* @param {?=} color
* @return {?}
*/
ShapeRenderer.prototype.point = /**
* @param {?} x
* @param {?} y
* @param {?=} color
* @return {?}
*/
function (x, y, color) {
if (color === void 0) { color = null; }
this.check(ShapeType.Point, 1);
if (color === null)
color = this.color;
this.vertex(x, y, color);
};
/**
* @param {?} x
* @param {?} y
* @param {?} x2
* @param {?} y2
* @param {?=} color
* @return {?}
*/
ShapeRenderer.prototype.line = /**
* @param {?} x
* @param {?} y
* @param {?} x2
* @param {?} y2
* @param {?=} color
* @return {?}
*/
function (x, y, x2, y2, color) {
if (color === void 0) { color = null; }
this.check(ShapeType.Line, 2);
/** @type {?} */
var vertices = this.mesh.getVertices();
/** @type {?} */
var idx = this.vertexIndex;
if (color === null)
color = this.color;
this.vertex(x, y, color);
this.vertex(x2, y2, color);
};
/**
* @param {?} filled
* @param {?} x
* @param {?} y
* @param {?} x2
* @param {?} y2
* @param {?} x3
* @param {?} y3
* @param {?=} color
* @param {?=} color2
* @param {?=} color3
* @return {?}
*/
ShapeRenderer.prototype.triangle = /**
* @param {?} filled
* @param {?} x
* @param {?} y
* @param {?} x2
* @param {?} y2
* @param {?} x3
* @param {?} y3
* @param {?=} color
* @param {?=} color2
* @param {?=} color3
* @return {?}
*/
function (filled, x, y, x2, y2, x3, y3, color, color2, color3) {
if (color === void 0) { color = null; }
if (color2 === void 0) { color2 = null; }
if (color3 === void 0) { color3 = null; }
this.check(filled ? ShapeType.Filled : ShapeType.Line, 3);
/** @type {?} */
var vertices = this.mesh.getVertices();
/** @type {?} */
var idx = this.vertexIndex;
if (color === null)
color = this.color;
if (color2 === null)
color2 = this.color;
if (color3 === null)
color3 = this.color;
if (filled) {
this.vertex(x, y, color);
this.vertex(x2, y2, color2);
this.vertex(x3, y3, color3);
}
else {
this.vertex(x, y, color);
this.vertex(x2, y2, color2);
this.vertex(x2, y2, color);
this.vertex(x3, y3, color2);
this.vertex(x3, y3, color);
this.vertex(x, y, color2);
}
};
/**
* @param {?} filled
* @param {?} x
* @param {?} y
* @param {?} x2
* @param {?} y2
* @param {?} x3
* @param {?} y3
* @param {?} x4
* @param {?} y4
* @param {?=} color
* @param {?=} color2
* @param {?=} color3
* @param {?=} color4
* @return {?}
*/
ShapeRenderer.prototype.quad = /**
* @param {?} filled
* @param {?} x
* @param {?} y
* @param {?} x2
* @param {?} y2
* @param {?} x3
* @param {?} y3
* @param {?} x4
* @param {?} y4
* @param {?=} color
* @param {?=} color2
* @param {?=} color3
* @param {?=} color4
* @return {?}
*/
function (filled, x, y, x2, y2, x3, y3, x4, y4, color, color2, color3, color4) {
if (color === void 0) { color = null; }
if (color2 === void 0) { color2 = null; }
if (color3 === void 0) { color3 = null; }
if (color4 === void 0) { color4 = null; }
this.check(filled ? ShapeType.Filled : ShapeType.Line, 3);
/** @type {?} */
var vertices = this.mesh.getVertices();
/** @type {?} */
var idx = this.vertexIndex;
if (color === null)
color = this.color;
if (color2 === null)
color2 = this.color;
if (color3 === null)
color3 = this.color;
if (color4 === null)
color4 = this.color;
if (filled) {
this.vertex(x, y, color);
this.vertex(x2, y2, color2);
this.vertex(x3, y3, color3);
this.vertex(x3, y3, color3);
this.vertex(x4, y4, color4);
this.vertex(x, y, color);
}
else {
this.vertex(x, y, color);
this.vertex(x2, y2, color2);
this.vertex(x2, y2, color2);
this.vertex(x3, y3, color3);
this.vertex(x3, y3, color3);
this.vertex(x4, y4, color4);
this.vertex(x4, y4, color4);
this.vertex(x, y, color);
}
};
/**
* @param {?} filled
* @param {?} x
* @param {?} y
* @param {?} width
* @param {?} height
* @param {?=} color
* @return {?}
*/
ShapeRenderer.prototype.rect = /**
* @param {?} filled
* @param {?} x
* @param {?} y
* @param {?} width
* @param {?} height
* @param {?=} color
* @return {?}
*/
function (filled, x, y, width, height, color) {
if (color === void 0) { color = null; }
this.quad(filled, x, y, x + width, y, x + width, y + height, x, y + height, color, color, color, color);
};
/**
* @param {?} filled
* @param {?} x1
* @param {?} y1
* @param {?} x2
* @param {?} y2
* @param {?} width
* @param {?=} color
* @return {?}
*/
ShapeRenderer.prototype.rectLine = /**
* @param {?} filled
* @param {?} x1
* @param {?} y1
* @param {?} x2
* @param {?} y2
* @param {?} width
* @param {?=} color
* @return {?}
*/
function (filled, x1, y1, x2, y2, width, color) {
if (color === void 0) { color = null; }
this.check(filled ? ShapeType.Filled : ShapeType.Line, 8);
if (color === null)
color = this.color;
/** @type {?} */
var t = this.tmp.set(y2 - y1, x1 - x2);
t.normalize();
width *= 0.5;
/** @type {?} */
var tx = t.x * width;
/** @type {?} */
var ty = t.y * width;
if (!filled) {
this.vertex(x1 + tx, y1 + ty, color);
this.vertex(x1 - tx, y1 - ty, color);
this.vertex(x2 + tx, y2 + ty, color);
this.vertex(x2 - tx, y2 - ty, color);
this.vertex(x2 + tx, y2 + ty, color);
this.vertex(x1 + tx, y1 + ty, color);
this.vertex(x2 - tx, y2 - ty, color);
this.vertex(x1 - tx, y1 - ty, color);
}
else {
this.vertex(x1 + tx, y1 + ty, color);
this.vertex(x1 - tx, y1 - ty, color);
this.vertex(x2 + tx, y2 + ty, color);
this.vertex(x2 - tx, y2 - ty, color);
this.vertex(x2 + tx, y2 + ty, color);
this.vertex(x1 - tx, y1 - ty, color);
}
};
/**
* @param {?} x
* @param {?} y
* @param {?} size
* @return {?}
*/
ShapeRenderer.prototype.x = /**
* @param {?} x
* @param {?} y
* @param {?} size
* @return {?}
*/
function (x, y, size) {
this.line(x - size, y - size, x + size, y + size);
this.line(x - size, y + size, x + size, y - size);
};
/**
* @param {?} polygonVertices
* @param {?} offset
* @param {?} count
* @param {?=} color
* @return {?}
*/
ShapeRenderer.prototype.polygon = /**
* @param {?} polygonVertices
* @param {?} offset
* @param {?} count
* @param {?=} color
* @return {?}
*/
function (polygonVertices, offset, count, color) {
if (color === void 0) { color = null; }
if (count < 3)
throw new Error("Polygon must contain at least 3 vertices");
this.check(ShapeType.Line, count * 2);
if (color === null)
color = this.color;
/** @type {?} */
var vertices = this.mesh.getVertices();
/** @type {?} */
var idx = this.vertexIndex;
offset <<= 1;
count <<= 1;
/** @type {?} */
var firstX = polygonVertices[offset];
/** @type {?} */
var firstY = polygonVertices[offset + 1];
/** @type {?} */
var last = offset + count;
for (var i = offset, n = offset + count - 2; i < n; i += 2) {
/** @type {?} */
var x1 = polygonVertices[i];
/** @type {?} */
var y1 = polygonVertices[i + 1];
/** @type {?} */
var x2 = 0;
/** @type {?} */
var y2 = 0;
if (i + 2 >= last) {
x2 = firstX;
y2 = firstY;
}
else {
x2 = polygonVertices[i + 2];
y2 = polygonVertices[i + 3];
}
this.vertex(x1, y1, color);
this.vertex(x2, y2, color);
}
};
/**
* @param {?} filled
* @param {?} x
* @param {?} y
* @param {?} radius
* @param {?=} color
* @param {?=} segments
* @return {?}
*/
ShapeRenderer.prototype.circle = /**
* @param {?} filled
* @param {?} x
* @param {?} y
* @param {?} radius
* @param {?=} color
* @param {?=} segments
* @return {?}
*/
function (filled, x, y, radius, color, segments) {
if (color === void 0) { color = null; }
if (segments === void 0) { segments = 0; }
if (segments === 0)
segments = Math.max(1, (6 * MathUtils.cbrt(radius)) | 0);
if (segments <= 0)
throw new Error("segments must be > 0.");
if (color === null)
color = this.color;
/** @type {?} */
var angle = (2 * MathUtils.PI) / segments;
/** @type {?} */
var cos = Math.cos(angle);
/** @type {?} */
var sin = Math.sin(angle);
/** @type {?} */
var cx = radius;
/** @type {?} */
var cy = 0;
if (!filled) {
this.check(ShapeType.Line, segments * 2 + 2);
for (var i = 0; i < segments; i++) {
this.vertex(x + cx, y + cy, color);
/** @type {?} */
var temp_1 = cx;
cx = cos * cx - sin * cy;
cy = sin * temp_1 + cos * cy;
this.vertex(x + cx, y + cy, color);
}
// Ensure the last segment is identical to the first.
this.vertex(x + cx, y + cy, color);
}
else {
this.check(ShapeType.Filled, segments * 3 + 3);
segments--;
for (var i = 0; i < segments; i++) {
this.vertex(x, y, color);
this.vertex(x + cx, y + cy, color);
/** @type {?} */
var temp_2 = cx;
cx = cos * cx - sin * cy;
cy = sin * temp_2 + cos * cy;
this.vertex(x + cx, y + cy, color);
}
// Ensure the last segment is identical to the first.
this.vertex(x, y, color);
this.vertex(x + cx, y + cy, color);
}
/** @type {?} */
var temp = cx;
cx = radius;
cy = 0;
this.vertex(x + cx, y + cy, color);
};
/**
* @param {?} x1
* @param {?} y1
* @param {?} cx1
* @param {?} cy1
* @param {?} cx2
* @param {?} cy2
* @param {?} x2
* @param {?} y2
* @param {?} segments
* @param {?=} color
* @return {?}
*/
ShapeRenderer.prototype.curve = /**
* @param {?} x1
* @param {?} y1
* @param {?} cx1
* @param {?} cy1
* @param {?} cx2
* @param {?} cy2
* @param {?} x2
* @param {?} y2
* @param {?} segments
* @param {?=} color
* @return {?}
*/
function (x1, y1, cx1, cy1, cx2, cy2, x2, y2, segments, color) {
if (color === void 0) { color = null; }
this.check(ShapeType.Line, segments * 2 + 2);
if (color === null)
color = this.color;
// Algorithm from: http://www.antigrain.com/research/bezier_interpolation/index.html#PAGE_BEZIER_INTERPOLATION
/** @type {?} */
var subdiv_step = 1 / segments;
/** @type {?} */
var subdiv_step2 = subdiv_step * subdiv_step;
/** @type {?} */
var subdiv_step3 = subdiv_step * subdiv_step * subdiv_step;
/** @type {?} */
var pre1 = 3 * subdiv_step;
/** @type {?} */
var pre2 = 3 * subdiv_step2;
/** @type {?} */
var pre4 = 6 * subdiv_step2;
/** @type {?} */
var pre5 = 6 * subdiv_step3;
/** @type {?} */
var tmp1x = x1 - cx1 * 2 + cx2;
/** @type {?} */
var tmp1y = y1 - cy1 * 2 + cy2;
/** @type {?} */
var tmp2x = (cx1 - cx2) * 3 - x1 + x2;
/** @type {?} */
var tmp2y = (cy1 - cy2) * 3 - y1 + y2;
/** @type {?} */
var fx = x1;
/** @type {?} */
var fy = y1;
/** @type {?} */
var dfx = (cx1 - x1) * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3;
/** @type {?} */
var dfy = (cy1 - y1) * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3;
/** @type {?} */
var ddfx = tmp1x * pre4 + tmp2x * pre5;
/** @type {?} */
var ddfy = tmp1y * pre4 + tmp2y * pre5;
/** @type {?} */
var dddfx = tmp2x * pre5;
/** @type {?} */
var dddfy = tmp2y * pre5;
while (segments-- > 0) {
this.vertex(fx, fy, color);
fx += dfx;
fy += dfy;
dfx += ddfx;
dfy += ddfy;
ddfx += dddfx;
ddfy += dddfy;
this.vertex(fx, fy, color);
}
this.vertex(fx, fy, color);
this.vertex(x2, y2, color);
};
/**
* @private
* @param {?} x
* @param {?} y
* @param {?} color
* @return {?}
*/
ShapeRenderer.prototype.vertex = /**
* @private
* @param {?} x
* @param {?} y
* @param {?} color
* @return {?}
*/
function (x, y, color) {
/** @type {?} */
var idx = this.vertexIndex;
/** @type {?} */
var vertices = this.mesh.getVertices();
vertices[idx++] = x;
vertices[idx++] = y;
vertices[idx++] = color.r;
vertices[idx++] = color.g;
vertices[idx++] = color.b;
vertices[idx++] = color.a;
this.vertexIndex = idx;
};
/**
* @return {?}
*/
ShapeRenderer.prototype.end = /**
* @return {?}
*/
function () {
if (!this.isDrawing)
throw new Error("ShapeRenderer.begin() has not been called");
this.flush();
this.context.gl.disable(this.context.gl.BLEND);
this.isDrawing = false;
};
/**
* @private
* @return {?}
*/
ShapeRenderer.prototype.flush = /**
* @private
* @return {?}
*/
function () {
if (this.vertexIndex == 0)
return;
this.mesh.setVerticesLength(this.vertexIndex);
this.mesh.draw(this.shader, this.shapeType);
this.vertexIndex = 0;
};
/**
* @private
* @param {?} shapeType
* @param {?} numVertices
* @return {?}
*/
ShapeRenderer.prototype.check = /**
* @private
* @param {?} shapeType
* @param {?} numVertices
* @return {?}
*/
function (shapeType, numVertices) {
if (!this.isDrawing)
throw new Error("ShapeRenderer.begin() has not been called");
if (this.shapeType == shapeType) {
if (this.mesh.maxVertices() - this.mesh.numVertices() < numVertices)
this.flush();
else
return;
}
else {
this.flush();
this.shapeType = shapeType;
}
};
/**
* @return {?}
*/
ShapeRenderer.prototype.dispose = /**
* @return {?}
*/
function () {
this.mesh.dispose();
};
return ShapeRenderer;
}());
export { ShapeRenderer };
if (false) {
/**
* @type {?}
* @private
*/
ShapeRenderer.prototype.context;
/**
* @type {?}
* @private
*/
ShapeRenderer.prototype.isDrawing;
/**
* @type {?}
* @private
*/
ShapeRenderer.prototype.mesh;
/**
* @type {?}
* @private
*/
ShapeRenderer.prototype.shapeType;
/**
* @type {?}
* @private
*/
ShapeRenderer.prototype.color;
/**
* @type {?}
* @private
*/
ShapeRenderer.prototype.shader;
/**
* @type {?}
* @private
*/
ShapeRenderer.prototype.vertexIndex;
/**
* @type {?}
* @private
*/
ShapeRenderer.prototype.tmp;
/**
* @type {?}
* @private
*/
ShapeRenderer.prototype.srcBlend;
/**
* @type {?}
* @private
*/
ShapeRenderer.prototype.dstBlend;
}
/** @enum {number} */
var ShapeType = {
Point: 0,
Line: 1,
Filled: 4,
};
export { ShapeType };
ShapeType[ShapeType.Point] = 'Point';
ShapeType[ShapeType.Line] = 'Line';
ShapeType[ShapeType.Filled] = 'Filled';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2hhcGVSZW5kZXJlci5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1zcGluZS8iLCJzb3VyY2VzIjpbImxpYi9zcGluZS10cy93ZWJnbC9TaGFwZVJlbmRlcmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBNEJBLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN2RCxPQUFPLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUNsRSxPQUFPLEVBQWMsS0FBSyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHdEU7SUFXRSx1QkFDRSxPQUE2RCxFQUM3RCxXQUEyQjtRQUEzQiw0QkFBQSxFQUFBLG1CQUEyQjtRQVhyQixjQUFTLEdBQUcsS0FBSyxDQUFDO1FBRWxCLGNBQVMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO1FBQzdCLFVBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUU5QixnQkFBVyxHQUFHLENBQUMsQ0FBQztRQUNoQixRQUFHLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQU8xQixJQUFJLFdBQVcsR0FBRyxLQUFLO1lBQ3JCLE1BQU0sSUFBSSxLQUFLLENBQ2Isa0RBQWtELEdBQUcsV0FBVyxDQUNqRSxDQUFDO1FBQ0osSUFBSSxDQUFDLE9BQU87WUFDVixPQUFPLFlBQVksNEJBQTRCO2dCQUM3QyxDQUFDLENBQUMsT0FBTztnQkFDVCxDQUFDLENBQUMsSUFBSSw0QkFBNEIsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNoRCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUNsQixPQUFPLEVBQ1AsQ0FBQyxJQUFJLGtCQUFrQixFQUFFLEVBQUUsSUFBSSxjQUFjLEVBQUUsQ0FBQyxFQUNoRCxX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QUM7UUFDekMsSUFBSSxNQUFNLEtBQUssSUFBSTtZQUFFLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ3pDLElBQUksTUFBTSxLQUFLLElBQUk7WUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUN6QyxJQUFJLE1BQU0sRUFBRTtZQUNWLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN6QixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDNUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzVCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDNUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQzFCO2FBQU07WUFDTCxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDekIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzVCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDNUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzVCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDNUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQzFCO0lBQ0gsQ0FBQzs7Ozs7Ozs7OztJQUNELDRCQUFJOzs7Ozs7Ozs7SUFBSixVQUNFLE1BQWUsRUFDZixDQUFTLEVBQ1QsQ0FBUyxFQUNULEtBQWEsRUFDYixNQUFjLEVBQ2QsS0FBbUI7UUFBbkIsc0JBQUEsRUFBQSxZQUFtQjtRQUVuQixJQUFJLENBQUMsSUFBSSxDQUNQLE1BQU0sRUFDTixDQUFDLEVBQ0QsQ0FBQyxFQUNELENBQUMsR0FBRyxLQUFLLEVBQ1QsQ0FBQyxFQUNELENBQUMsR0FBRyxLQUFLLEVBQ1QsQ0FBQyxHQUFHLE1BQU0sRUFDVixDQUFDLEVBQ0QsQ0FBQyxHQUFHLE1BQU0sRUFDVixLQUFLLEVBQ0wsS0FBSyxFQUNMLEtBQUssRUFDTCxLQUFLLENBQ04sQ0FBQztJQUNKLENBQUM7Ozs7Ozs7Ozs7O0lBQ0QsZ0NBQVE7Ozs7Ozs7Ozs7SUFBUixVQUNFLE1BQWUsRUFDZixFQUFVLEVBQ1YsRUFBVSxFQUNWLEVBQVUsRUFDVixFQUFVLEVBQ1YsS0FBYSxFQUNiLEtBQW1CO1FBQW5CLHNCQUFBLEVBQUEsWUFBbUI7UUFFbkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUQsSUFBSSxLQUFLLEtBQUssSUFBSTtZQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDOztZQUNuQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNkLEtBQUssSUFBSSxHQUFHLENBQUM7O1lBQ1QsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSzs7WUFDaEIsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSztRQUNwQixJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ1gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7U0FDdEM7YUFBTTtZQUNMLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcs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ZSIsInNvdXJjZXNDb250ZW50IjpbIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuICogU3BpbmUgUnVudGltZXMgTGljZW5zZSBBZ3JlZW1lbnRcclxuICogTGFzdCB1cGRhdGVkIE1heSAxLCAyMDE5LiBSZXBsYWNlcyBhbGwgcHJpb3IgdmVyc2lvbnMuXHJcbiAqXHJcbiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDE5LCBFc290ZXJpYyBTb2Z0d2FyZSBMTENcclxuICpcclxuICogSW50ZWdyYXRpb24gb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3Igb3RoZXJ3aXNlIGNyZWF0aW5nXHJcbiAqIGRlcml2YXRpdmUgd29ya3Mgb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGlzIHBlcm1pdHRlZCB1bmRlciB0aGUgdGVybXMgYW5kXHJcbiAqIGNvbmRpdGlvbnMgb2YgU2VjdGlvbiAyIG9mIHRoZSBTcGluZSBFZGl0b3IgTGljZW5zZSBBZ3JlZW1lbnQ6XHJcbiAqIGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1lZGl0b3ItbGljZW5zZVxyXG4gKlxyXG4gKiBPdGhlcndpc2UsIGl0IGlzIHBlcm1pdHRlZCB0byBpbnRlZ3JhdGUgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmVcclxuICogb3Igb3RoZXJ3aXNlIGNyZWF0ZSBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyAoY29sbGVjdGl2ZWx5LFxyXG4gKiBcIlByb2R1Y3RzXCIpLCBwcm92aWRlZCB0aGF0IGVhY2ggdXNlciBvZiB0aGUgUHJvZHVjdHMgbXVzdCBvYnRhaW4gdGhlaXIgb3duXHJcbiAqIFNwaW5lIEVkaXRvciBsaWNlbnNlIGFuZCByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZHVjdHMgaW4gYW55IGZvcm0gbXVzdFxyXG4gKiBpbmNsdWRlIHRoaXMgbGljZW5zZSBhbmQgY29weXJpZ2h0IG5vdGljZS5cclxuICpcclxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBFU09URVJJQyBTT0ZUV0FSRSBMTEMgXCJBUyBJU1wiIEFORCBBTlkgRVhQUkVTU1xyXG4gKiBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTXHJcbiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOXHJcbiAqIE5PIEVWRU5UIFNIQUxMIEVTT1RFUklDIFNPRlRXQVJFIExMQyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULFxyXG4gKiBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLFxyXG4gKiBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVMsIEJVU0lORVNTXHJcbiAqIElOVEVSUlVQVElPTiwgT1IgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFMpIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTllcclxuICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HXHJcbiAqIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSxcclxuICogRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cclxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG5pbXBvcnQgeyBNYW5hZ2VkV2ViR0xSZW5kZXJpbmdDb250ZXh0IH0gZnJvbSBcIi4vV2ViR0xcIjtcclxuaW1wb3J0IHsgTWVzaCwgQ29sb3JBdHRyaWJ1dGUsIFBvc2l0aW9uMkF0dHJpYnV0ZSB9IGZyb20gXCIuL01lc2hcIjtcclxuaW1wb3J0IHsgRGlzcG9zYWJsZSwgQ29sb3IsIFZlY3RvcjIsIE1hdGhVdGlscyB9IGZyb20gXCIuLi9jb3JlL1V0aWxzXCI7XHJcbmltcG9ydCB7IFNoYWRlciB9IGZyb20gXCIuL1NoYWRlclwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFNoYXBlUmVuZGVyZXIgaW1wbGVtZW50cyBEaXNwb3NhYmxlIHtcclxuICBwcml2YXRlIGNvbnRleHQ6IE1hbmFnZWRXZWJHTFJlbmRlcmluZ0NvbnRleHQ7XHJcbiAgcHJpdmF0ZSBpc0RyYXdpbmcgPSBmYWxzZTtcclxuICBwcml2YXRlIG1lc2g6IE1lc2g7XHJcbiAgcHJpdmF0ZSBzaGFwZVR5cGUgPSBTaGFwZVR5cGUuRmlsbGVkO1xyXG4gIHByaXZhdGUgY29sb3IgPSBuZXcgQ29sb3IoMSwgMSwgMSwgMSk7XHJcbiAgcHJpdmF0ZSBzaGFkZXI6IFNoYWRlcjtcclxuICBwcml2YXRlIHZlcnRleEluZGV4ID0gMDtcclxuICBwcml2YXRlIHRtcCA9IG5ldyBWZWN0b3IyKCk7XHJcbiAgcHJpdmF0ZSBzcmNCbGVuZDogbnVtYmVyO1xyXG4gIHByaXZhdGUgZHN0QmxlbmQ6IG51bWJlcjtcclxuICBjb25zdHJ1Y3RvcihcclxuICAgIGNvbnRleHQ6IE1hbmFnZWRXZWJHTFJlbmRlcmluZ0NvbnRleHQgfCBXZWJHTFJlbmRlcmluZ0NvbnRleHQsXHJcbiAgICBtYXhWZXJ0aWNlczogbnVtYmVyID0gMTA5MjBcclxuICApIHtcclxuICAgIGlmIChtYXhWZXJ0aWNlcyA+IDEwOTIwKVxyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXHJcbiAgICAgICAgXCJDYW4ndCBoYXZlIG1vcmUgdGhhbiAxMDkyMCB0cmlhbmdsZXMgcGVyIGJhdGNoOiBcIiArIG1heFZlcnRpY2VzXHJcbiAgICAgICk7XHJcbiAgICB0aGlzLmNvbnRleHQgPVxyXG4gICAgICBjb250ZXh0IGluc3RhbmNlb2YgTWFuYWdlZFdlYkdMUmVuZGVyaW5nQ29udGV4dFxyXG4gICAgICAgID8gY29udGV4dFxyXG4gICAgICAgIDogbmV3IE1hbmFnZWRXZWJHTFJlbmRlcmluZ0NvbnRleHQoY29udGV4dCk7XHJcbiAgICB0aGlzLm1lc2ggPSBuZXcgTWVzaChcclxuICAgICAgY29udGV4dCxcclxuICAgICAgW25ldyBQb3NpdGlvbjJBdHRyaWJ1dGUoKSwgbmV3IENvbG9yQXR0cmlidXRlKCldLFxyXG4gICAgICBtYXhWZXJ0aWNlcyxcclxuICAgICAgMFxyXG4gICAgKTtcclxuICAgIHRoaXMuc3JjQmxlbmQgPSB0aGlzLmNvbnRleHQuZ2wuU1JDX0FMUEhBO1xyXG4gICAgdGhpcy5kc3RCbGVuZCA9IHRoaXMuY29udGV4dC5nbC5PTkVfTUlOVVNfU1JDX0FMUEhBO1xyXG4gIH1cclxuICBiZWdpbihzaGFkZXI6IFNoYWRlcikge1xyXG4gICAgaWYgKHRoaXMuaXNEcmF3aW5nKVxyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTaGFwZVJlbmRlcmVyLmJlZ2luKCkgaGFzIGFscmVhZHkgYmVlbiBjYWxsZWRcIik7XHJcbiAgICB0aGlzLnNoYWRlciA9IHNoYWRlcjtcclxuICAgIHRoaXMudmVydGV4SW5kZXggPSAwO1xyXG4gICAgdGhpcy5pc0RyYXdpbmcgPSB0cnVlO1xyXG4gICAgbGV0IGdsID0gdGhpcy5jb250ZXh0LmdsO1xyXG4gICAgZ2wuZW5hYmxlKGdsLkJMRU5EKTtcclxuICAgIGdsLmJsZW5kRnVuYyh0aGlzLnNyY0JsZW5kLCB0aGlzLmRzdEJsZW5kKTtcclxuICB9XHJcbiAgc2V0QmxlbmRNb2RlKHNyY0JsZW5kOiBudW1iZXIsIGRzdEJsZW5kOiBudW1iZXIpIHtcclxuICAgIGxldCBnbCA9IHRoaXMuY29udGV4dC5nbDtcclxuICAgIHRoaXMuc3JjQmxlbmQgPSBzcmNCbGVuZDtcclxuICAgIHRoaXMuZHN0QmxlbmQgPSBkc3RCbGVuZDtcclxuICAgIGlmICh0aGlzLmlzRHJhd2luZykge1xyXG4gICAgICB0aGlzLmZsdXNoKCk7XHJcbiAgICAgIGdsLmJsZW5kRnVuYyh0aGlzLnNyY0JsZW5kLCB0aGlzLmRzdEJsZW5kKTtcclxuICAgIH1cclxuICB9XHJcbiAgc2V0Q29sb3IoY29sb3I6IENvbG9yKSB7XHJcbiAgICB0aGlzLmNvbG9yLnNldEZyb21Db2xvcihjb2xvcik7XHJcbiAgfVxyXG4gIHNldENvbG9yV2l0aChyOiBudW1iZXIsIGc6IG51bWJlciwgYjogbnVtYmVyLCBhOiBudW1iZXIpIHtcclxuICAgIHRoaXMuY29sb3Iuc2V0KHIsIGcsIGIsIGEpO1xyXG4gIH1cclxuICBwb2ludCh4OiBudW1iZXIsIHk6IG51bWJlciwgY29sb3I6IENvbG9yID0gbnVsbCkge1xyXG4gICAgdGhpcy5jaGVjayhTaGFwZVR5cGUuUG9pbnQsIDEpO1xyXG4gICAgaWYgKGNvbG9yID09PSBudWxsKSBjb2xvciA9IHRoaXMuY29sb3I7XHJcbiAgICB0aGlzLnZlcnRleCh4LCB5LCBjb2xvcik7XHJcbiAgfVxyXG4gIGxpbmUoeDogbnVtYmVyLCB5OiBudW1iZXIsIHgyOiBudW1iZXIsIHkyOiBudW1iZXIsIGNvbG9yOiBDb2xvciA9IG51bGwpIHtcclxuICAgIHRoaXMuY2hlY2soU2hhcGVUeXBlLkxpbmUsIDIpO1xyXG4gICAgbGV0IHZlcnRpY2VzID0gdGhpcy5tZXNoLmdldFZlcnRpY2VzKCk7XHJcbiAgICBsZXQgaWR4ID0gdGhpcy52ZXJ0ZXhJbmRleDtcclxuICAgIGlmIChjb2xvciA9PT0gbnVsbCkgY29sb3IgPSB0aGlzLmNvbG9yO1xyXG4gICAgdGhpcy52ZXJ0ZXgoeCwgeSwgY29sb3IpO1xyXG4gICAgdGhpcy52ZXJ0ZXgoeDIsIHkyLCBjb2xvcik7XHJcbiAgfVxyXG4gIHRyaWFuZ2xlKFxyXG4gICAgZmlsbGVkOiBib29sZWFuLFxyXG4gICAgeDogbnVtYmVyLFxyXG4gICAgeTogbnVtYmVyLFxyXG4gICAgeDI6IG51bWJlcixcclxuICAgIHkyOiBudW1iZXIsXHJcbiAgICB4MzogbnVtYmVyLFxyXG4gICAgeTM6IG51bWJlcixcclxuICAgIGNvbG9yOiBDb2xvciA9IG51bGwsXHJcbiAgICBjb2xvcjI6IENvbG9yID0gbnVsbCxcclxuICAgIGNvbG9yMzogQ29sb3IgPSBudWxsXHJcbiAgKSB7XHJcbiAgICB0aGlzLmNoZWNrKGZpbGxlZCA/IFNoYXBlVHlwZS5GaWxsZWQgOiBTaGFwZVR5cGUuTGluZSwgMyk7XHJcbiAgICBsZXQgdmVydGljZXMgPSB0aGlzLm1lc2guZ2V0VmVydGljZXMoKTtcclxuICAgIGxldCBpZHggPSB0aGlzLnZlcnRleEluZGV4O1xyXG4gICAgaWYgKGNvbG9yID09PSBudWxsKSBjb2xvciA9IHRoaXMuY29sb3I7XHJcbiAgICBpZiAoY29sb3IyID09PSBudWxsKSBjb2xvcjIgPSB0aGlzLmNvbG9yO1xyXG4gICAgaWYgKGNvbG9yMyA9PT0gbnVsbCkgY29sb3IzID0gdGhpcy5jb2xvcjtcclxuICAgIGlmIChmaWxsZWQpIHtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeCwgeSwgY29sb3IpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MiwgeTIsIGNvbG9yMik7XHJcbiAgICAgIHRoaXMudmVydGV4KHgzLCB5MywgY29sb3IzKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMudmVydGV4KHgsIHksIGNvbG9yKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDIsIHkyLCBjb2xvcjIpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MiwgeTIsIGNvbG9yKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDMsIHkzLCBjb2xvcjIpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MywgeTMsIGNvbG9yKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeCwgeSwgY29sb3IyKTtcclxuICAgIH1cclxuICB9XHJcbiAgcXVhZChcclxuICAgIGZpbGxlZDogYm9vbGVhbixcclxuICAgIHg6IG51bWJlcixcclxuICAgIHk6IG51bWJlcixcclxuICAgIHgyOiBudW1iZXIsXHJcbiAgICB5MjogbnVtYmVyLFxyXG4gICAgeDM6IG51bWJlcixcclxuICAgIHkzOiBudW1iZXIsXHJcbiAgICB4NDogbnVtYmVyLFxyXG4gICAgeTQ6IG51bWJlcixcclxuICAgIGNvbG9yOiBDb2xvciA9IG51bGwsXHJcbiAgICBjb2xvcjI6IENvbG9yID0gbnVsbCxcclxuICAgIGNvbG9yMzogQ29sb3IgPSBudWxsLFxyXG4gICAgY29sb3I0OiBDb2xvciA9IG51bGxcclxuICApIHtcclxuICAgIHRoaXMuY2hlY2soZmlsbGVkID8gU2hhcGVUeXBlLkZpbGxlZCA6IFNoYXBlVHlwZS5MaW5lLCAzKTtcclxuICAgIGxldCB2ZXJ0aWNlcyA9IHRoaXMubWVzaC5nZXRWZXJ0aWNlcygpO1xyXG4gICAgbGV0IGlkeCA9IHRoaXMudmVydGV4SW5kZXg7XHJcbiAgICBpZiAoY29sb3IgPT09IG51bGwpIGNvbG9yID0gdGhpcy5jb2xvcjtcclxuICAgIGlmIChjb2xvcjIgPT09IG51bGwpIGNvbG9yMiA9IHRoaXMuY29sb3I7XHJcbiAgICBpZiAoY29sb3IzID09PSBudWxsKSBjb2xvcjMgPSB0aGlzLmNvbG9yO1xyXG4gICAgaWYgKGNvbG9yNCA9PT0gbnVsbCkgY29sb3I0ID0gdGhpcy5jb2xvcjtcclxuICAgIGlmIChmaWxsZWQpIHtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeCwgeSwgY29sb3IpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MiwgeTIsIGNvbG9yMik7XHJcbiAgICAgIHRoaXMudmVydGV4KHgzLCB5MywgY29sb3IzKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDMsIHkzLCBjb2xvcjMpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4NCwgeTQsIGNvbG9yNCk7XHJcbiAgICAgIHRoaXMudmVydGV4KHgsIHksIGNvbG9yKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMudmVydGV4KHgsIHksIGNvbG9yKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDIsIHkyLCBjb2xvcjIpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4MiwgeTIsIGNvbG9yMik7XHJcbiAgICAgIHRoaXMudmVydGV4KHgzLCB5MywgY29sb3IzKTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeDMsIHkzLCBjb2xvcjMpO1xyXG4gICAgICB0aGlzLnZlcnRleCh4NCwgeTQsIGNvbG9yNCk7XHJcbiAgICAgIHRoaXMudmVydGV4KHg0LCB5NCwgY29sb3I0KTtcclxuICAgICAgdGhpcy52ZXJ0ZXgoeCwgeSwgY29sb3IpO1xyXG4gICAgfVxyXG4gIH1cclxuICByZWN0KFxyXG4gICAgZmlsbGVkOiBib29sZWFuLFxyXG4gICAgeDogbnVtYmVyLFxyXG4gICAgeTogbnVtYmVyLFxy