@esotericsoftware/spine-pixi-v8
Version:
The official Spine Runtimes for PixiJS v8.
473 lines • 76.3 kB
JavaScript
/** ****************************************************************************
* Spine Runtimes License Agreement
* Last updated July 28, 2023. Replaces all prior versions.
*
* Copyright (c) 2013-2023, 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.
*
* THE SPINE RUNTIMES ARE 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 THE
* SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
import { Container, Graphics, Text } from 'pixi.js';
import { ClippingAttachment, MeshAttachment, PathAttachment, RegionAttachment, SkeletonBounds } from '@esotericsoftware/spine-core';
/**
* This is a debug renderer that uses PixiJS Graphics under the hood.
* @public
*/
export class SpineDebugRenderer {
registeredSpines = new Map();
drawMeshHull = true;
drawMeshTriangles = true;
drawBones = true;
drawPaths = true;
drawBoundingBoxes = true;
drawClipping = true;
drawRegionAttachments = true;
drawEvents = true;
lineWidth = 1;
regionAttachmentsColor = 0x0078ff;
meshHullColor = 0x0078ff;
meshTrianglesColor = 0xffcc00;
clippingPolygonColor = 0xff00ff;
boundingBoxesRectColor = 0x00ff00;
boundingBoxesPolygonColor = 0x00ff00;
boundingBoxesCircleColor = 0x00ff00;
pathsCurveColor = 0xff0000;
pathsLineColor = 0xff00ff;
skeletonXYColor = 0xff0000;
bonesColor = 0x00eecc;
eventFontSize = 24;
eventFontColor = 0x0;
/**
* The debug is attached by force to each spine object.
* So we need to create it inside the spine when we get the first update
*/
registerSpine(spine) {
if (this.registeredSpines.has(spine)) {
console.warn('SpineDebugRenderer.registerSpine() - this spine is already registered!', spine);
return;
}
const debugDisplayObjects = {
parentDebugContainer: new Container(),
bones: new Container(),
skeletonXY: new Graphics(),
regionAttachmentsShape: new Graphics(),
meshTrianglesLine: new Graphics(),
meshHullLine: new Graphics(),
clippingPolygon: new Graphics(),
boundingBoxesRect: new Graphics(),
boundingBoxesCircle: new Graphics(),
boundingBoxesPolygon: new Graphics(),
pathsCurve: new Graphics(),
pathsLine: new Graphics(),
eventText: new Container(),
eventCallback: {
event: (_, event) => {
if (this.drawEvents) {
const scale = Math.abs(spine.scale.x || spine.scale.y || 1);
const text = new Text({
text: event.data.name,
style: {
fontSize: this.eventFontSize / scale,
fill: this.eventFontColor,
fontFamily: 'monospace'
}
});
text.scale.x = Math.sign(spine.scale.x);
text.anchor.set(0.5);
debugDisplayObjects.eventText.addChild(text);
setTimeout(() => {
if (!text.destroyed) {
text.destroy();
}
}, 250);
}
},
},
};
debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.bones);
debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.skeletonXY);
debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.regionAttachmentsShape);
debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.meshTrianglesLine);
debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.meshHullLine);
debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.clippingPolygon);
debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.boundingBoxesRect);
debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.boundingBoxesCircle);
debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.boundingBoxesPolygon);
debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.pathsCurve);
debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.pathsLine);
debugDisplayObjects.parentDebugContainer.addChild(debugDisplayObjects.eventText);
debugDisplayObjects.parentDebugContainer.zIndex = 9999999;
// Disable screen reader and mouse input on debug objects.
debugDisplayObjects.parentDebugContainer.accessibleChildren = false;
debugDisplayObjects.parentDebugContainer.eventMode = 'none';
debugDisplayObjects.parentDebugContainer.interactiveChildren = false;
spine.addChild(debugDisplayObjects.parentDebugContainer);
spine.state.addListener(debugDisplayObjects.eventCallback);
this.registeredSpines.set(spine, debugDisplayObjects);
}
renderDebug(spine) {
if (!this.registeredSpines.has(spine)) {
// This should never happen. Spines are registered when you assign spine.debug
this.registerSpine(spine);
}
const debugDisplayObjects = this.registeredSpines.get(spine);
if (!debugDisplayObjects) {
return;
}
spine.addChild(debugDisplayObjects.parentDebugContainer);
debugDisplayObjects.skeletonXY.clear();
debugDisplayObjects.regionAttachmentsShape.clear();
debugDisplayObjects.meshTrianglesLine.clear();
debugDisplayObjects.meshHullLine.clear();
debugDisplayObjects.clippingPolygon.clear();
debugDisplayObjects.boundingBoxesRect.clear();
debugDisplayObjects.boundingBoxesCircle.clear();
debugDisplayObjects.boundingBoxesPolygon.clear();
debugDisplayObjects.pathsCurve.clear();
debugDisplayObjects.pathsLine.clear();
for (let len = debugDisplayObjects.bones.children.length; len > 0; len--) {
debugDisplayObjects.bones.children[len - 1].destroy({ children: true, texture: true, textureSource: true });
}
const scale = Math.abs(spine.scale.x || spine.scale.y || 1);
const lineWidth = this.lineWidth / scale;
if (this.drawBones) {
this.drawBonesFunc(spine, debugDisplayObjects, lineWidth, scale);
}
if (this.drawPaths) {
this.drawPathsFunc(spine, debugDisplayObjects, lineWidth);
}
if (this.drawBoundingBoxes) {
this.drawBoundingBoxesFunc(spine, debugDisplayObjects, lineWidth);
}
if (this.drawClipping) {
this.drawClippingFunc(spine, debugDisplayObjects, lineWidth);
}
if (this.drawMeshHull || this.drawMeshTriangles) {
this.drawMeshHullAndMeshTriangles(spine, debugDisplayObjects, lineWidth);
}
if (this.drawRegionAttachments) {
this.drawRegionAttachmentsFunc(spine, debugDisplayObjects, lineWidth);
}
if (this.drawEvents) {
for (const child of debugDisplayObjects.eventText.children) {
child.alpha -= 0.05;
child.y -= 2;
}
}
}
drawBonesFunc(spine, debugDisplayObjects, lineWidth, scale) {
const skeleton = spine.skeleton;
const skeletonX = skeleton.x;
const skeletonY = skeleton.y;
const bones = skeleton.bones;
debugDisplayObjects.skeletonXY.strokeStyle = { width: lineWidth, color: this.skeletonXYColor };
for (let i = 0, len = bones.length; i < len; i++) {
const bone = bones[i];
const boneLen = bone.data.length;
const starX = skeletonX + bone.worldX;
const starY = skeletonY + bone.worldY;
const endX = skeletonX + (boneLen * bone.a) + bone.worldX;
const endY = skeletonY + (boneLen * bone.b) + bone.worldY;
if (bone.data.name === 'root' || bone.data.parent === null) {
continue;
}
const w = Math.abs(starX - endX);
const h = Math.abs(starY - endY);
// a = w, // side length a
const a2 = Math.pow(w, 2); // square root of side length a
const b = h; // side length b
const b2 = Math.pow(h, 2); // square root of side length b
const c = Math.sqrt(a2 + b2); // side length c
const c2 = Math.pow(c, 2); // square root of side length c
const rad = Math.PI / 180;
// A = Math.acos([a2 + c2 - b2] / [2 * a * c]) || 0, // Angle A
// C = Math.acos([a2 + b2 - c2] / [2 * a * b]) || 0, // C angle
const B = Math.acos((c2 + b2 - a2) / (2 * b * c)) || 0; // angle of corner B
if (c === 0) {
continue;
}
const gp = new Graphics();
debugDisplayObjects.bones.addChild(gp);
// draw bone
const refRation = c / 50 / scale;
gp.context
.poly([0, 0, 0 - refRation, c - (refRation * 3), 0, c - refRation, 0 + refRation, c - (refRation * 3)])
.fill(this.bonesColor);
gp.x = starX;
gp.y = starY;
gp.pivot.y = c;
// Calculate bone rotation angle
let rotation = 0;
if (starX < endX && starY < endY) {
// bottom right
rotation = -B + (180 * rad);
}
else if (starX > endX && starY < endY) {
// bottom left
rotation = (180 * rad) + B;
}
else if (starX > endX && starY > endY) {
// top left
rotation = -B;
}
else if (starX < endX && starY > endY) {
// bottom left
rotation = B;
}
else if (starY === endY && starX < endX) {
// To the right
rotation = 90 * rad;
}
else if (starY === endY && starX > endX) {
// go left
rotation = -90 * rad;
}
else if (starX === endX && starY < endY) {
// down
rotation = 180 * rad;
}
else if (starX === endX && starY > endY) {
// up
rotation = 0;
}
gp.rotation = rotation;
// Draw the starting rotation point of the bone
gp.circle(0, c, refRation * 1.2)
.fill({ color: 0x000000, alpha: 0.6 })
.stroke({ width: lineWidth + refRation / 2.4, color: this.bonesColor });
}
// Draw the skeleton starting point "X" form
const startDotSize = lineWidth * 3;
debugDisplayObjects.skeletonXY.context
.moveTo(skeletonX - startDotSize, skeletonY - startDotSize)
.lineTo(skeletonX + startDotSize, skeletonY + startDotSize)
.moveTo(skeletonX + startDotSize, skeletonY - startDotSize)
.lineTo(skeletonX - startDotSize, skeletonY + startDotSize)
.stroke();
}
drawRegionAttachmentsFunc(spine, debugDisplayObjects, lineWidth) {
const skeleton = spine.skeleton;
const slots = skeleton.slots;
for (let i = 0, len = slots.length; i < len; i++) {
const slot = slots[i];
const attachment = slot.getAttachment();
if (attachment === null || !(attachment instanceof RegionAttachment)) {
continue;
}
const regionAttachment = attachment;
const vertices = new Float32Array(8);
regionAttachment.computeWorldVertices(slot, vertices, 0, 2);
debugDisplayObjects.regionAttachmentsShape.poly(Array.from(vertices.slice(0, 8)));
}
debugDisplayObjects.regionAttachmentsShape.stroke({
color: this.regionAttachmentsColor,
width: lineWidth
});
}
drawMeshHullAndMeshTriangles(spine, debugDisplayObjects, lineWidth) {
const skeleton = spine.skeleton;
const slots = skeleton.slots;
for (let i = 0, len = slots.length; i < len; i++) {
const slot = slots[i];
if (!slot.bone.active) {
continue;
}
const attachment = slot.getAttachment();
if (attachment === null || !(attachment instanceof MeshAttachment)) {
continue;
}
const meshAttachment = attachment;
const vertices = new Float32Array(meshAttachment.worldVerticesLength);
const triangles = meshAttachment.triangles;
let hullLength = meshAttachment.hullLength;
meshAttachment.computeWorldVertices(slot, 0, meshAttachment.worldVerticesLength, vertices, 0, 2);
// draw the skinned mesh (triangle)
if (this.drawMeshTriangles) {
for (let i = 0, len = triangles.length; i < len; i += 3) {
const v1 = triangles[i] * 2;
const v2 = triangles[i + 1] * 2;
const v3 = triangles[i + 2] * 2;
debugDisplayObjects.meshTrianglesLine.context
.moveTo(vertices[v1], vertices[v1 + 1])
.lineTo(vertices[v2], vertices[v2 + 1])
.lineTo(vertices[v3], vertices[v3 + 1]);
}
}
// draw skin border
if (this.drawMeshHull && hullLength > 0) {
hullLength = (hullLength >> 1) * 2;
let lastX = vertices[hullLength - 2];
let lastY = vertices[hullLength - 1];
for (let i = 0, len = hullLength; i < len; i += 2) {
const x = vertices[i];
const y = vertices[i + 1];
debugDisplayObjects.meshHullLine.context
.moveTo(x, y)
.lineTo(lastX, lastY);
lastX = x;
lastY = y;
}
}
}
debugDisplayObjects.meshHullLine.stroke({ width: lineWidth, color: this.meshHullColor });
debugDisplayObjects.meshTrianglesLine.stroke({ width: lineWidth, color: this.meshTrianglesColor });
}
drawClippingFunc(spine, debugDisplayObjects, lineWidth) {
const skeleton = spine.skeleton;
const slots = skeleton.slots;
for (let i = 0, len = slots.length; i < len; i++) {
const slot = slots[i];
if (!slot.bone.active) {
continue;
}
const attachment = slot.getAttachment();
if (attachment === null || !(attachment instanceof ClippingAttachment)) {
continue;
}
const clippingAttachment = attachment;
const nn = clippingAttachment.worldVerticesLength;
const world = new Float32Array(nn);
clippingAttachment.computeWorldVertices(slot, 0, nn, world, 0, 2);
debugDisplayObjects.clippingPolygon.poly(Array.from(world));
}
debugDisplayObjects.clippingPolygon.stroke({
width: lineWidth, color: this.clippingPolygonColor, alpha: 1
});
}
drawBoundingBoxesFunc(spine, debugDisplayObjects, lineWidth) {
// draw the total outline of the bounding box
const bounds = new SkeletonBounds();
bounds.update(spine.skeleton, true);
if (bounds.minX !== Infinity) {
debugDisplayObjects.boundingBoxesRect
.rect(bounds.minX, bounds.minY, bounds.getWidth(), bounds.getHeight())
.stroke({ width: lineWidth, color: this.boundingBoxesRectColor });
}
const polygons = bounds.polygons;
const drawPolygon = (polygonVertices, _offset, count) => {
if (count < 3) {
throw new Error('Polygon must contain at least 3 vertices');
}
const paths = [];
const dotSize = lineWidth * 2;
for (let i = 0, len = polygonVertices.length; i < len; i += 2) {
const x1 = polygonVertices[i];
const y1 = polygonVertices[i + 1];
// draw the bounding box node
debugDisplayObjects.boundingBoxesCircle.beginFill(this.boundingBoxesCircleColor);
debugDisplayObjects.boundingBoxesCircle.drawCircle(x1, y1, dotSize);
debugDisplayObjects.boundingBoxesCircle.fill(0);
debugDisplayObjects.boundingBoxesCircle
.circle(x1, y1, dotSize)
.fill({ color: this.boundingBoxesCircleColor });
paths.push(x1, y1);
}
// draw the bounding box area
debugDisplayObjects.boundingBoxesPolygon
.poly(paths)
.fill({
color: this.boundingBoxesPolygonColor,
alpha: 0.1
})
.stroke({
width: lineWidth,
color: this.boundingBoxesPolygonColor
});
};
for (let i = 0, len = polygons.length; i < len; i++) {
const polygon = polygons[i];
drawPolygon(polygon, 0, polygon.length);
}
}
drawPathsFunc(spine, debugDisplayObjects, lineWidth) {
const skeleton = spine.skeleton;
const slots = skeleton.slots;
for (let i = 0, len = slots.length; i < len; i++) {
const slot = slots[i];
if (!slot.bone.active) {
continue;
}
const attachment = slot.getAttachment();
if (attachment === null || !(attachment instanceof PathAttachment)) {
continue;
}
const pathAttachment = attachment;
let nn = pathAttachment.worldVerticesLength;
const world = new Float32Array(nn);
pathAttachment.computeWorldVertices(slot, 0, nn, world, 0, 2);
let x1 = world[2];
let y1 = world[3];
let x2 = 0;
let y2 = 0;
if (pathAttachment.closed) {
const cx1 = world[0];
const cy1 = world[1];
const cx2 = world[nn - 2];
const cy2 = world[nn - 1];
x2 = world[nn - 4];
y2 = world[nn - 3];
// curve
debugDisplayObjects.pathsCurve.moveTo(x1, y1);
debugDisplayObjects.pathsCurve.bezierCurveTo(cx1, cy1, cx2, cy2, x2, y2);
// handle
debugDisplayObjects.pathsLine.moveTo(x1, y1);
debugDisplayObjects.pathsLine.lineTo(cx1, cy1);
debugDisplayObjects.pathsLine.moveTo(x2, y2);
debugDisplayObjects.pathsLine.lineTo(cx2, cy2);
}
nn -= 4;
for (let ii = 4; ii < nn; ii += 6) {
const cx1 = world[ii];
const cy1 = world[ii + 1];
const cx2 = world[ii + 2];
const cy2 = world[ii + 3];
x2 = world[ii + 4];
y2 = world[ii + 5];
// curve
debugDisplayObjects.pathsCurve.moveTo(x1, y1);
debugDisplayObjects.pathsCurve.bezierCurveTo(cx1, cy1, cx2, cy2, x2, y2);
// handle
debugDisplayObjects.pathsLine.moveTo(x1, y1);
debugDisplayObjects.pathsLine.lineTo(cx1, cy1);
debugDisplayObjects.pathsLine.moveTo(x2, y2);
debugDisplayObjects.pathsLine.lineTo(cx2, cy2);
x1 = x2;
y1 = y2;
}
}
debugDisplayObjects.pathsCurve.stroke({ width: lineWidth, color: this.pathsCurveColor });
debugDisplayObjects.pathsLine.stroke({ width: lineWidth, color: this.pathsLineColor });
}
unregisterSpine(spine) {
if (!this.registeredSpines.has(spine)) {
console.warn('SpineDebugRenderer.unregisterSpine() - spine is not registered, can\'t unregister!', spine);
}
const debugDisplayObjects = this.registeredSpines.get(spine);
if (!debugDisplayObjects) {
return;
}
spine.state.removeListener(debugDisplayObjects.eventCallback);
debugDisplayObjects.parentDebugContainer.destroy({ textureSource: true, children: true, texture: true });
this.registeredSpines.delete(spine);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3BpbmVEZWJ1Z1JlbmRlcmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1NwaW5lRGVidWdSZW5kZXJlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFFL0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBRXBELE9BQU8sRUFDTixrQkFBa0IsRUFDbEIsY0FBYyxFQUNkLGNBQWMsRUFDZCxnQkFBZ0IsRUFDaEIsY0FBYyxFQUNkLE1BQU0sOEJBQThCLENBQUM7QUEwQ3RDOzs7R0FHRztBQUNILE1BQU0sT0FBTyxrQkFBa0I7SUFDYixnQkFBZ0IsR0FBb0MsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUV4RSxZQUFZLEdBQUcsSUFBSSxDQUFDO0lBQ3BCLGlCQUFpQixHQUFHLElBQUksQ0FBQztJQUN6QixTQUFTLEdBQUcsSUFBSSxDQUFDO0lBQ2pCLFNBQVMsR0FBRyxJQUFJLENBQUM7SUFDakIsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO0lBQ3pCLFlBQVksR0FBRyxJQUFJLENBQUM7SUFDcEIscUJBQXFCLEdBQUcsSUFBSSxDQUFDO0lBQzdCLFVBQVUsR0FBRyxJQUFJLENBQUM7SUFFbEIsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUNkLHNCQUFzQixHQUFHLFFBQVEsQ0FBQztJQUNsQyxhQUFhLEdBQUcsUUFBUSxDQUFDO0lBQ3pCLGtCQUFrQixHQUFHLFFBQVEsQ0FBQztJQUM5QixvQkFBb0IsR0FBRyxRQUFRLENBQUM7SUFDaEMsc0JBQXNCLEdBQUcsUUFBUSxDQUFDO0lBQ2xDLHlCQUF5QixHQUFHLFFBQVEsQ0FBQztJQUNyQyx3QkFBd0IsR0FBRyxRQUFRLENBQUM7SUFDcEMsZUFBZSxHQUFHLFFBQVEsQ0FBQztJQUMzQixjQUFjLEdBQUcsUUFBUSxDQUFDO0lBQzFCLGVBQWUsR0FBRyxRQUFRLENBQUM7SUFDM0IsVUFBVSxHQUFHLFFBQVEsQ0FBQztJQUN0QixhQUFhLEdBQUcsRUFBRSxDQUFDO0lBQ25CLGNBQWMsR0FBRyxHQUFHLENBQUM7SUFFNUI7OztPQUdHO0lBQ0ksYUFBYSxDQUFFLEtBQVk7UUFDakMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdEMsT0FBTyxDQUFDLElBQUksQ0FBQyx3RUFBd0UsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUU5RixPQUFPO1FBQ1IsQ0FBQztRQUNELE1BQU0sbUJBQW1CLEdBQXdCO1lBQ2hELG9CQUFvQixFQUFFLElBQUksU0FBUyxFQUFFO1lBQ3JDLEtBQUssRUFBRSxJQUFJLFNBQVMsRUFBRTtZQUN0QixVQUFVLEVBQUUsSUFBSSxRQUFRLEVBQUU7WUFDMUIsc0JBQXNCLEVBQUUsSUFBSSxRQUFRLEVBQUU7WUFDdEMsaUJBQWlCLEVBQUUsSUFBSSxRQUFRLEVBQUU7WUFDakMsWUFBWSxFQUFFLElBQUksUUFBUSxFQUFFO1lBQzVCLGVBQWUsRUFBRSxJQUFJLFFBQVEsRUFBRTtZQUMvQixpQkFBaUIsRUFBRSxJQUFJLFFBQVEsRUFBRTtZQUNqQyxtQkFBbUIsRUFBRSxJQUFJLFFBQVEsRUFBRTtZQUNuQyxvQkFBb0IsRUFBRSxJQUFJLFFBQVEsRUFBRTtZQUNwQyxVQUFVLEVBQUUsSUFBSSxRQUFRLEVBQUU7WUFDMUIsU0FBUyxFQUFFLElBQUksUUFBUSxFQUFFO1lBQ3pCLFNBQVMsRUFBRSxJQUFJLFNBQVMsRUFBRTtZQUMxQixhQUFhLEVBQUU7Z0JBQ2QsS0FBSyxFQUFFLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFO29CQUNuQixJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQzt3QkFDckIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQzt3QkFDNUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUM7NEJBQ3JCLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUk7NEJBQ3JCLEtBQUssRUFBRTtnQ0FDTixRQUFRLEVBQUUsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLO2dDQUNwQyxJQUFJLEVBQUUsSUFBSSxDQUFDLGNBQWM7Z0NBQ3pCLFVBQVUsRUFBRSxXQUFXOzZCQUN2Qjt5QkFDRCxDQUFDLENBQUM7d0JBRUgsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUN4QyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQzt3QkFDckIsbUJBQW1CLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQzt3QkFDN0MsVUFBVSxDQUFDLEdBQUcsRUFBRTs0QkFDZixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dDQUNyQixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7NEJBQ2hCLENBQUM7d0JBQ0YsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO29CQUNULENBQUM7Z0JBQ0YsQ0FBQzthQUNEO1NBQ0QsQ0FBQztRQUVGLG1CQUFtQixDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM3RSxtQkFBbUIsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbEYsbUJBQW1CLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDOUYsbUJBQW1CLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDekYsbUJBQW1CLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3BGLG1CQUFtQixDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN2RixtQkFBbUIsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUN6RixtQkFBbUIsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUMzRixtQkFBbUIsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUM1RixtQkFBbUIsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbEYsbUJBQW1CLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2pGLG1CQUFtQixDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUVoRixtQkFBbUIsQ0FBQyxvQkFBNEIsQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDO1FBRW5FLDBEQUEwRDtRQUN6RCxtQkFBbUIsQ0FBQyxvQkFBNEIsQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUM7UUFDNUUsbUJBQW1CLENBQUMsb0JBQTRCLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQztRQUNwRSxtQkFBbUIsQ0FBQyxvQkFBNEIsQ0FBQyxtQkFBbUIsR0FBRyxLQUFLLENBQUM7UUFFOUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBRXpELEtBQUssQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBRTNELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLG1CQUFtQixDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVNLFdBQVcsQ0FBRSxLQUFZO1FBQy9CLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdkMsOEVBQThFO1lBQzlFLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0IsQ0FBQztRQUVELE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUU3RCxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUMxQixPQUFPO1FBQ1IsQ0FBQztRQUNELEtBQUssQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUV6RCxtQkFBbUIsQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdkMsbUJBQW1CLENBQUMsc0JBQXNCLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbkQsbUJBQW1CLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDOUMsbUJBQW1CLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3pDLG1CQUFtQixDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM1QyxtQkFBbUIsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM5QyxtQkFBbUIsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNoRCxtQkFBbUIsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNqRCxtQkFBbUIsQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdkMsbUJBQW1CLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBRXRDLEtBQUssSUFBSSxHQUFHLEdBQUcsbUJBQW1CLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDO1lBQzFFLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUM3RyxDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUM1RCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUV6QyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDbEUsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLG1CQUFtQixFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzNELENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDbkUsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDOUQsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUNqRCxJQUFJLENBQUMsNEJBQTRCLENBQUMsS0FBSyxFQUFFLG1CQUFtQixFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzFFLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDdkUsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3JCLEtBQUssTUFBTSxLQUFLLElBQUksbUJBQW1CLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUM1RCxLQUFLLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQztnQkFDcEIsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDZCxDQUFDO1FBQ0YsQ0FBQztJQUNGLENBQUM7SUFFTyxhQUFhLENBQUUsS0FBWSxFQUFFLG1CQUF3QyxFQUFFLFNBQWlCLEVBQUUsS0FBYTtRQUM5RyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO1FBQ2hDLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDN0IsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUM3QixNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDO1FBRTdCLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxXQUFXLEdBQUcsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFFL0YsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ2xELE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0QixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUNqQyxNQUFNLEtBQUssR0FBRyxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUN0QyxNQUFNLEtBQUssR0FBRyxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUN0QyxNQUFNLElBQUksR0FBRyxTQUFTLEdBQUcsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDMUQsTUFBTSxJQUFJLEdBQUcsU0FBUyxHQUFHLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1lBRTFELElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssTUFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUM1RCxTQUFTO1lBQ1YsQ0FBQztZQUVELE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDO1lBQ2pDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDO1lBQ2pDLDBCQUEwQjtZQUMxQixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLCtCQUErQjtZQUMxRCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0I7WUFDN0IsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQywrQkFBK0I7WUFDMUQsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0I7WUFDOUMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQywrQkFBK0I7WUFDMUQsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUM7WUFDMUIsK0RBQStEO1lBQy9ELCtEQUErRDtZQUMvRCxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxvQkFBb0I7WUFFNUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ2IsU0FBUztZQUNWLENBQUM7WUFFRCxNQUFNLEVBQUUsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBRTFCLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7WUFFdkMsWUFBWTtZQUNaLE1BQU0sU0FBUyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDO1lBRWpDLEVBQUUsQ0FBQyxPQUFPO2lCQUNSLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLEVBQUUsQ0FBQyxHQUFHLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDdEcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN4QixFQUFFLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztZQUNiLEVBQUUsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO1lBQ2IsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRWYsZ0NBQWdDO1lBQ2hDLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztZQUVqQixJQUFJLEtBQUssR0FBRyxJQUFJLElBQUksS0FBSyxHQUFHLElBQUksRUFBRSxDQUFDO2dCQUNsQyxlQUFlO2dCQUNmLFFBQVEsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztZQUM3QixDQUFDO2lCQUNJLElBQUksS0FBSyxHQUFHLElBQUksSUFBSSxLQUFLLEdBQUcsSUFBSSxFQUFFLENBQUM7Z0JBQ3ZDLGNBQWM7Z0JBQ2QsUUFBUSxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM1QixDQUFDO2lCQUNJLElBQUksS0FBSyxHQUFHLElBQUksSUFBSSxLQUFLLEdBQUcsSUFBSSxFQUFFLENBQUM7Z0JBQ3ZDLFdBQVc7Z0JBQ1gsUUFBUSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ2YsQ0FBQztpQkFDSSxJQUFJLEtBQUssR0FBRyxJQUFJLElBQUksS0FBSyxHQUFHLElBQUksRUFBRSxDQUFDO2dCQUN2QyxjQUFjO2dCQUNkLFFBQVEsR0FBRyxDQUFDLENBQUM7WUFDZCxDQUFDO2lCQUNJLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxLQUFLLEdBQUcsSUFBSSxFQUFFLENBQUM7Z0JBQ3pDLGVBQWU7Z0JBQ2YsUUFBUSxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQUM7WUFDckIsQ0FBQztpQkFDSSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxHQUFHLElBQUksRUFBRSxDQUFDO2dCQUN6QyxVQUFVO2dCQUNWLFFBQVEsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUM7WUFDdEIsQ0FBQztpQkFDSSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxHQUFHLElBQUksRUFBRSxDQUFDO2dCQUN6QyxPQUFPO2dCQUNQLFFBQVEsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO1lBQ3RCLENBQUM7aUJBQ0ksSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssR0FBRyxJQUFJLEVBQUUsQ0FBQztnQkFDekMsS0FBSztnQkFDTCxRQUFRLEdBQUcsQ0FBQyxDQUFDO1lBQ2QsQ0FBQztZQUNELEVBQUUsQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1lBRXZCLCtDQUErQztZQUMvQyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsU0FBUyxHQUFHLEdBQUcsQ0FBQztpQkFDOUIsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUM7aUJBQ3JDLE1BQU0sQ0FBQyxFQUFFLEtBQUssRUFBRSxTQUFTLEdBQUcsU0FBUyxHQUFHLEdBQUcsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7UUFDMUUsQ0FBQztRQUVELDRDQUE0QztRQUM1QyxNQUFNLFlBQVksR0FBRyxTQUFTLEdBQUcsQ0FBQyxDQUFDO1FBRW5DLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxPQUFPO2FBQ3BDLE1BQU0sQ0FBQyxTQUFTLEdBQUcsWUFBWSxFQUFFLFNBQVMsR0FBRyxZQUFZLENBQUM7YUFDMUQsTUFBTSxDQUFDLFNBQVMsR0FBRyxZQUFZLEVBQUUsU0FBUyxHQUFHLFlBQVksQ0FBQzthQUMxRCxNQUFNLENBQUMsU0FBUyxHQUFHLFlBQVksRUFBRSxTQUFTLEdBQUcsWUFBWSxDQUFDO2FBQzFELE1BQU0sQ0FBQyxTQUFTLEdBQUcsWUFBWSxFQUFFLFNBQVMsR0FBRyxZQUFZLENBQUM7YUFDMUQsTUFBTSxFQUFFLENBQUM7SUFDWixDQUFDO0lBRU8seUJBQXlCLENBQUUsS0FBWSxFQUFFLG1CQUF3QyxFQUFFLFNBQWlCO1FBQzNHLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUM7UUFDaEMsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQztRQUU3QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDbEQsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUV4QyxJQUFJLFVBQVUsS0FBSyxJQUFJLElBQUksQ0FBQyxDQUFDLFVBQVUsWUFBWSxnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7Z0JBQ3RFLFNBQVM7WUFDVixDQUFDO1lBRUQsTUFBTSxnQkFBZ0IsR0FBRyxVQUFVLENBQUM7WUFFcEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFckMsZ0JBQWdCLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFNUQsbUJBQW1CLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25GLENBQUM7UUFFRCxtQkFBbUIsQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLENBQUM7WUFDakQsS0FBSyxFQUFFLElBQUksQ0FBQyxzQkFBc0I7WUFDbEMsS0FBSyxFQUFFLFNBQVM7U0FDaEIsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUVPLDRCQUE0QixDQUFFLEtBQVksRUFBRSxtQkFBd0MsRUFBRSxTQUFpQjtRQUM5RyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO1FBQ2hDLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFFN0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ2xELE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUV0QixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDdkIsU0FBUztZQUNWLENBQUM7WUFDRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFFeEMsSUFBSSxVQUFVLEtBQUssSUFBSSxJQUFJLENBQUMsQ0FBQyxVQUFVLFlBQVksY0FBYyxDQUFDLEVBQUUsQ0FBQztnQkFDcEUsU0FBUztZQUNWLENBQUM7WUFFRCxNQUFNLGNBQWMsR0FBRyxVQUFVLENBQUM7WUFFbEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxZQUFZLENBQUMsY0FBYyxDQUFDLG1CQUFtQixDQUFDLENBQUM7WUFDdEUsTUFBTSxTQUFTLEdBQUcsY0FBYyxDQUFDLFNBQVMsQ0FBQztZQUMzQyxJQUFJLFVBQVUsR0FBRyxjQUFjLENBQUMsVUFBVSxDQUFDO1lBRTNDLGNBQWMsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxtQkFBbUIsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ2pHLG1DQUFtQztZQUNuQyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO2dCQUM1QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztvQkFDekQsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDNUIsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ2hDLE1BQU0sRUFBRSxHQUFHLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUVoQyxtQkFBbUIsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPO3lCQUMzQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7eUJBQ3RDLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLEVBQUUsUUFBUSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQzt5QkFDdEMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsRUFBRSxRQUFRLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzFDLENBQUM7WUFDRixDQUFDO1lBRUQsbUJBQW1CO1lBQ25CLElBQUksSUFBSSxDQUFDLFlBQVksSUFBSSxVQUFVLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3pDLFVBQVUsR0FBRyxDQUFDLFVBQVUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ25DLElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ3JDLElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBRXJDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxVQUFVLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQ25ELE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDdEIsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztvQkFFMUIsbUJBQW1CLENBQUMsWUFBWSxDQUFDLE9BQU87eUJBQ3RDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO3lCQUNaLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7b0JBQ3ZCLEtBQUssR0FBRyxDQUFDLENBQUM7b0JBQ1YsS0FBSyxHQUFHLENBQUMsQ0FBQztnQkFDWCxDQUFDO1lBQ0YsQ0FBQztRQUNGLENBQUM7UUFFRCxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUM7UUFDekYsbUJBQW1CLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQztJQUNwRyxDQUFDO0lBRUQsZ0JBQWdCLENBQUUsS0FBWSxFQUFFLG1CQUF3QyxFQUFFLFNBQWlCO1FBQzFGLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUM7UUFDaEMsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQztRQUU3QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDbEQsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRXRCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUN2QixTQUFTO1lBQ1YsQ0FBQztZQUNELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUV4QyxJQUFJLFVBQVUsS0FBSyxJQUFJLElBQUksQ0FBQyxDQUFDLFVBQVUsWUFBWSxrQkFBa0IsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hFLFNBQVM7WUFDVixDQUFDO1lBRUQsTUFBTSxrQkFBa0IsR0FBRyxVQUFVLENBQUM7WUFFdEMsTUFBTSxFQUFFLEdBQUcsa0JBQWtCLENBQUMsbUJBQW1CLENBQUM7WUFDbEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUM7WUFFbkMsa0JBQWtCLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNsRSxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUM3RCxDQUFDO1FBRUQsbUJBQW1CLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQztZQUMxQyxLQUFLLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsS0FBSyxFQUFFLENBQUM7U0FDNUQsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUVELHFCQUFxQixDQUFFLEtBQVksRUFBRSxtQkFBd0MsRUFBRSxTQUFpQjtRQUMvRiw2Q0FBNkM7UUFDN0MsTUFBTSxNQUFNLEdBQUcsSUFBSSxjQUFjLEVBQUUsQ0FBQztRQUNwQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFcEMsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzlCLG1CQUFtQixDQUFDLGlCQUFpQjtpQkFDbkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDO2lCQUNyRSxNQUFNLENBQUMsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO1FBQ2pDLE1BQU0sV0FBVyxHQUFHLENBQUMsZUFBa0MsRUFBRSxPQUFnQixFQUFFLEtBQWEsRUFBUSxFQUFFO1lBQ2pHLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsMENBQTBDLENBQUMsQ0FBQztZQUM3RCxDQUFDO1lBQ0QsTUFBTSxLQUFLLEdBQWEsRUFBRSxDQUFDO1lBQzNCLE1BQU0sT0FBTyxHQUFHLFNBQVMsR0FBRyxDQUFDLENBQUM7WUFFOUIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLGVBQWUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQy9ELE1BQU0sRUFBRSxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDOUIsTUFBTSxFQUFFLEdBQUcsZUFBZSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFFbEMsNkJBQTZCO2dCQUM3QixtQkFBbUIsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLENBQUM7Z0JBQ2pGLG1CQUFtQixDQUFDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUNwRSxtQkFBbUIsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBRWhELG1CQUFtQixDQUFDLG1CQUFtQjtxQkFDckMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsT0FBTyxDQUFDO3FCQUN2QixJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUMsQ0FBQTtnQkFFaEQsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDcEIsQ0FBQztZQUVELDZCQUE2QjtZQUM3QixtQkFBbUIsQ0FBQyxvQkFBb0I7aUJBQ3RDLElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ1gsSUFBSSxDQUFDO2dCQUNMLEtBQUssRUFBRSxJQUFJLENBQUMseUJBQXlCO2dCQUNyQyxLQUFLLEVBQUUsR0FBRzthQUNWLENBQUM7aUJBQ0QsTUFBTSxDQUFDO2dCQUNQLEtBQUssRUFBRSxTQUFTO2dCQUNoQixLQUFLLEVBQUUsSUFBSSxDQUFDLHlCQUF5QjthQUNyQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUM7UUFFRixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDckQsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRTVCLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN6QyxDQUFDO0lBQ0YsQ0FBQztJQUVPLGFBQWEsQ0FBRSxLQUFZLEVBQUUsbUJBQXdDLEVBQUUsU0FBaUI7UUFDL0YsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQztRQUNoQyxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDO1FBRTdCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNsRCxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ3ZCLFNBQVM7WUFDVixDQUFDO1lBQ0QsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBRXhDLElBQUksVUFBVSxLQUFLLElBQUksSUFBSSxDQUFDLENBQUMsVUFBVSxZQUFZLGNBQWMsQ0FBQyxFQUFFLENBQUM7Z0JBQ3BFLFNBQVM7WUFDVixDQUFDO1lBRUQsTUFBTSxjQUFjLEdBQUcsVUFBVSxDQUFDO1lBQ2xDLElBQUksRUFBRSxHQUFHLGNBQWMsQ0FBQyxtQkFBbUIsQ0FBQztZQUM1QyxNQUFNLEtBQUssR0FBRyxJQUFJLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUVuQyxjQUFjLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5RCxJQUFJLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbEIsSUFBSSxFQUFFLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xCLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNYLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztZQUVYLElBQUksY0FBYyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUMzQixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3JCLE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDckIsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDMUIsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFFMUIsRUFBRSxHQUFHLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ25CLEVBQUUsR0FBRyxLQUFLLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUVuQixRQUFRO2dCQUNSLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUM5QyxtQkFBbUIsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBRXpFLFNBQVM7Z0JBQ1QsbUJBQW1CLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQzdDLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUMvQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDN0MsbUJBQW1CLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDaEQsQ0FBQztZQUNELEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDUixLQUFLLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDbkMsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUN0QixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUMxQixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUMxQixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUUxQixFQUFFLEdBQUcsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDbkIsRUFBRSxHQUFHLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ25CLFFBQVE7Z0JBQ1IsbUJBQW1CLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQzlDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFFekUsU0FBUztnQkFDVCxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDN0MsbUJBQW1CLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQy9DLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUM3QyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDL0MsRUFBRSxHQUFHLEVBQUUsQ0FBQztnQkFDUixFQUFFLEdBQUcsRUFBRSxDQUFDO1lBQ1QsQ0FBQztRQUNGLENBQUM7UUFFRCxtQkFBbUIsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUM7UUFDekYsbUJBQW1CLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDO0lBQ3hGLENBQUM7SUFFTSxlQUFlLENBQUUsS0FBWTtRQUNuQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3ZDLE9BQU8sQ0FBQyxJQUFJLENBQUMsb0ZBQW9GLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDM0csQ0FBQztRQUNELE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUU3RCxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUMxQixPQUFPO1FBQ1IsQ0FBQztRQUVELEtBQUssQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBRTlELG1CQUFtQixDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN6RyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3JDLENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiBTcGluZSBSdW50aW1lcyBMaWNlbnNlIEFncmVlbWVudFxuICogTGFzdCB1cGRhdGVkIEp1bHkgMjgsIDIwMjMuIFJlcGxhY2VzIGFsbCBwcmlvciB2ZXJzaW9ucy5cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtMjAyMywgRXNvdGVyaWMgU29mdHdhcmUgTExDXG4gKlxuICogSW50ZWdyYXRpb24gb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3Igb3RoZXJ3aXNlIGNyZWF0aW5nXG4gKiBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpcyBwZXJtaXR0ZWQgdW5kZXIgdGhlIHRlcm1zIGFuZFxuICogY29uZGl0aW9ucyBvZiBTZWN0aW9uIDIgb2YgdGhlIFNwaW5lIEVkaXRvciBMaWNlbnNlIEFncmVlbWVudDpcbiAqIGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1lZGl0b3ItbGljZW5zZVxuICpcbiAqIE90aGVyd2lzZSwgaXQgaXMgcGVybWl0dGVkIHRvIGludGVncmF0ZSB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZSBvclxuICogb3RoZXJ3aXNlIGNyZWF0ZSBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyAoY29sbGVjdGl2ZWx5LFxuICogXCJQcm9kdWN0c1wiKSwgcHJvdmlkZWQgdGhhdCBlYWNoIHVzZXIgb2YgdGhlIFByb2R1Y3RzIG11c3Qgb2J0YWluIHRoZWlyIG93blxuICogU3BpbmUgRWRpdG9yIGxpY2Vuc2UgYW5kIHJlZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9kdWN0cyBpbiBhbnkgZm9ybSBtdXN0XG4gKiBpbmNsdWRlIHRoaXMgbGljZW5zZSBhbmQgY29weXJpZ2h0IG5vdGljZS5cbiAqXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMgQVJFIFBST1ZJREVEIEJZIEVTT1RFUklDIFNPRlRXQVJFIExMQyBcIkFTIElTXCIgQU5EIEFOWVxuICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgRVNPVEVSSUMgU09GVFdBUkUgTExDIEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTLFxuICogQlVTSU5FU1MgSU5URVJSVVBUSU9OLCBPUiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUykgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRIRVxuICogU1BJTkUgUlVOVElNRVMsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB7IENvbnRhaW5lciwgR3JhcGhpY3MsIFRleHQgfSBmcm9tICdwaXhpLmpzJztcbmltcG9ydCB7IFNwaW5lIH0gZnJvbSAnLi9TcGluZS5qcyc7XG5pbXBvcnQge1xuXHRDbGlwcGluZ0F0dGFjaG1lbnQsXG5cdE1lc2hBdHRhY2htZW50LFxuXHRQYXRoQXR0YWNobWVudCxcblx0UmVnaW9uQXR0YWNobWVudCxcblx0U2tlbGV0b25Cb3VuZHNcbn0gZnJvbSAnQGVzb3Rlcmljc29mdHdhcmUvc3BpbmUtY29yZSc7XG5cbmltcG9ydCB0eXBlIHsgQW5pbWF0aW9uU3RhdGVMaXN0ZW5lciB9IGZyb20gJ0Blc290ZXJpY3NvZnR3YXJlL3NwaW5lLWNvcmUnO1xuXG4vKipcbiAqIE1ha2UgYSBjbGFzcyB0aGF0IGV4dGVuZHMgZnJvbSB0aGlzIGludGVyZmFjZSB0byBjcmVhdGUgeW91ciBvd24gZGVidWcgcmVuZGVyZXIuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSVNwaW5lRGVidWdSZW5kZXJlciB7XG5cdC8