UNPKG

angular-sunburst-radar-chart

Version:
408 lines 65.7 kB
import { __decorate } from "tslib"; import { Component, Input } from '@angular/core'; import { createCircle, createLine, createPath } from './utils/elements'; import { createArcToWriteText, getTextForAngle, writeTextOnArc } from './utils/textelement'; import { createInnerChartBarWithInArc, createOuterChartBarWithInArc } from './utils/arc-bar-charts'; import { calculatePointBetween, getGlobalPositions } from './utils/positions'; import { distanceBetweenTwoPoints, polarToCartesian } from './utils/trignometry'; import { createLegends, createLegendWithOptions } from './utils/legend'; import { formatItems, generateRandomColor, getFormattedAngle, getOptionsOrEmpty, hashCode } from './utils/utils'; import { getAllAnglesBasedOnChild, getAllAnglesBasedOnParent, getPointsOnCircleAtAngels, positionsOnAngles } from './utils/angels'; import { createSvgHandlerWithSelector } from './utils/svg-rotator'; let AngularSunburstRadarChartComponent = class AngularSunburstRadarChartComponent { constructor() { this.componentDisplayed = false; this.showToolTip = false; this.tooltipTopInPx = '0px'; this.tooltipLeftInPx = '0px'; this.tooltipText = ''; this.svgId = null; this.svgGroupId = null; this.svgHandler = null; this.currentRotationAngle = 10; this.svgCursor = 'default'; this.initialized = false; this.innerBorderHeight = 30; this.outerBorderHeight = 30; this.elements = []; this.hasChildren = false; this.outerBorderCircleRef = 'outerBorderCircle'; this.error = null; this.hasError = false; this.startRotation = false; } showError(msg) { this.error = msg; this.hasError = true; } hideError() { this.error = null; this.hasError = false; } appendToSvg(element) { this.elements.push(element); } ngOnChanges(changes) { this.hideError(); const isFirstChange = Object.values(changes).some(c => c.isFirstChange()); this.modifyOnFirstChange(isFirstChange); } modifyOnFirstChange(isFirstChange) { if (!isFirstChange) { this.initialize(); } } ngOnInit() { this.hideError(); this.initialize(); } initialize() { const defaults = { size: 300, maxScore: 100, animateChart: true, splitBasedOnChildren: true, legendAxisLinePosition: 1 }; const options = Object.assign(Object.assign({}, defaults), (getOptionsOrEmpty(this.options))); this.size = options.size; this.maxScore = options.maxScore; this.animateChart = options.animateChart; this.splitBasedOnChildren = options.splitBasedOnChildren; this.legendAxisLinePosition = options.legendAxisLinePosition; if (!this.hasValidParameters()) { this.showError('Input Values not set or Items was improper'); return; } this.initialized = false; this.svgId = 'svg' + hashCode(this.items); this.svgGroupId = 'svg-group' + hashCode(this.items); this.viewBox = '0 0 ' + this.size + ' ' + this.size; this.innerCircleRadius = Math.abs(this.size / 5.33); this.innerBorderHeight = this.innerCircleRadius / 5; this.outerBorderHeight = this.innerCircleRadius / 5; this.globalPosition = getGlobalPositions({ size: this.size, maxScore: this.maxScore, items: this.items }); this.hasChildren = this.items.filter(item => !!item.children).length > 0; this.drawLayout(); const { innerRadius, innerTextRadius, textSize, outerTextSize, outerRadiusBorder, outerTextRadius, center } = this.globalPosition; const [centerX, centerY] = [center.x, center.y]; let items = this.items; let allAngels = []; const hasChildren = this.hasChildren; if (this.splitBasedOnChildren) { // Cannot have no children items = formatItems(items); allAngels = getAllAnglesBasedOnChild(items); } else { allAngels = getAllAnglesBasedOnParent(items); } const angleDifference = 360 / items.length; const angles = allAngels.map(value => value.startDegree); const middleAngles = allAngels.map(value => value.middleDegree); const points = positionsOnAngles(centerX, centerY, this.chartBorder, angles); const lines = []; let elements = []; let nextLevelElements = []; for (let i = 0; i < points.length; i++) { const { x, y } = points[i]; let endAngleIndex = i + 1; if (endAngleIndex >= points.length) { endAngleIndex = 0; } const endAngle = angles[endAngleIndex]; const startAngle = angles[i]; const middleAngle = middleAngles[i]; let item = items[i]; if (!!item.color === false) { const colorDefaults = { color: generateRandomColor() }; item = Object.assign(Object.assign({}, colorDefaults), item); } if (this.hasChildren && item.children && item.children.length > 0) { const childAngels = allAngels[i].children; nextLevelElements = nextLevelElements.concat(this.drawOnLevel({ items: item.children, totalDegrees: angleDifference, childAngels, color: item.color })); } lines.push(createLine({ x1: centerX, y1: centerY, x2: x, y2: y, width: 2 })); // Create Arc for inner values const barWithinArc = createInnerChartBarWithInArc({ startPoint: center, item, radius: innerRadius, startAngle, endAngle, maxScore: this.maxScore }); elements.push(barWithinArc); const innerTextElements = this.addArcText({ arcForTextId: 'arc-text-inner' + this.getUniqueCode() + '-' + i, radius: innerTextRadius, fontSize: textSize, startAngle, endAngle, perAngle: angleDifference, item }); elements = elements.concat(innerTextElements); if (hasChildren) { elements.push(this.drawOuterBackgroundWithMiddle({ item, startAngle, middleAngle, endAngle })); const outerBackgroundTextElements = this.addArcText({ arcForTextId: 'arc-text-outer' + this.getUniqueCode() + '-' + i, radius: outerTextRadius, fontSize: outerTextSize, perAngle: angleDifference, startAngle, endAngle, item }); elements = elements.concat(outerBackgroundTextElements); } } nextLevelElements.forEach(line => { this.appendToSvg(line); }); this.drawInnerBorders(); elements.forEach(line => { this.appendToSvg(line); }); lines.forEach(line => { this.appendToSvg(line); }); const legendAxisIndex = this.getLegendAxisIndex(angles); this.drawLegends(angles[legendAxisIndex]); this.addSmallCirclesAtCenter(centerX, centerY); this.initialized = true; this.currentRotationAngle = 10; this.rotationPoint = getFormattedAngle(this.currentRotationAngle, center); } getLegendAxisIndex(angles) { let legendAxisIndex = this.legendAxisLinePosition - 1; if (legendAxisIndex < 0 || legendAxisIndex >= angles.length) { legendAxisIndex = 0; } return legendAxisIndex; } hasValidParameters() { return this.items && this.items.length > 1; } drawOuterBackgroundWithMiddle({ item, startAngle, middleAngle, endAngle }) { const color = item.color; const { outerTextRadius, center } = this.globalPosition; const [centerX, centerY] = [center.x, center.y]; const middleCircle = calculatePointBetween({ centerX, centerY, startAngle, middleAngle, endAngle, radius: outerTextRadius }); const d = [ 'M', middleCircle.start.x, middleCircle.start.y, 'A', outerTextRadius, outerTextRadius, 0, 0, 1, middleCircle.end.x, middleCircle.end.y ]; const title = item.name + '-' + item.value; const strokeWidth = 0.0775 * this.size; return createPath({ d: d.join(' '), stroke: color, 'stroke-width': strokeWidth, title }); } drawOnLevel({ items, totalDegrees, childAngels, color }) { const { innerRadiusBorder, middleRadius, textSize, middleTextRadius, center } = this.globalPosition; const [centerX, centerY] = [center.x, center.y]; const angles = childAngels.map(item => item.startDegree); const middleAngles = childAngels.map(item => item.middleDegree); const endAngles = childAngels.map(item => item.endDegree); const perAngle = totalDegrees / items.length; const pointsOnInnerRadiusBorder = getPointsOnCircleAtAngels(centerX, centerY, innerRadiusBorder, angles); const pointsOnMiddle = getPointsOnCircleAtAngels(centerX, centerY, middleRadius, angles); let elements = []; const lines = []; let currentDegree = angles[0]; for (let i = 0; i < pointsOnInnerRadiusBorder.length; i++) { const pointOnInnerRadiusBorder = pointsOnInnerRadiusBorder[i]; const pointOnMiddle = pointsOnMiddle[i]; lines.push(createLine({ x1: pointOnInnerRadiusBorder.x, y1: pointOnInnerRadiusBorder.y, x2: pointOnMiddle.x, y2: pointOnMiddle.y, width: 0.5 })); const startAngle = angles[i]; const middleAngle = middleAngles[i]; const endAngle = endAngles[i]; const item = items[i]; const params = { startPoint: pointOnInnerRadiusBorder, item, startAngle, endAngle, middleAngle, middleRadius, innerRadiusBorder, center, maxScore: this.maxScore, color, index: i }; const arcForChart = createOuterChartBarWithInArc(params); elements.push(arcForChart); const middleTextElements = this.addArcText({ arcForTextId: 'arc-text-middle' + this.getUniqueCode() + '-' + startAngle + i, radius: middleTextRadius, fontSize: textSize, perAngle, startAngle, endAngle, item }); elements = elements.concat(middleTextElements); currentDegree = currentDegree + perAngle; } lines.forEach(line => { elements.push(line); }); return elements; } getUniqueCode() { return hashCode(this.items) + '-' + this.size; } drawInnerBorders() { const { innerRadius, innerRadiusBorder, center } = this.globalPosition; const [centerX, centerY] = [center.x, center.y]; const innerContainer = createCircle({ x: centerX, y: centerY, radius: innerRadius, fillColor: 'none' }); const innerBorderContainer = createCircle({ x: centerX, y: centerY, radius: innerRadiusBorder, fillColor: '#FFFFFF' }); this.appendToSvg(innerBorderContainer); this.appendToSvg(innerContainer); } addSmallCirclesAtCenter(centerX, centerY) { const outerRadius = 0.0025 * 2 * this.size; const innerRadius = 0.0005 * 2 * this.size; this.appendToSvg(createCircle({ x: centerX, y: centerY, radius: outerRadius, fillColor: '#FFFFFF' })); this.appendToSvg(createCircle({ x: centerX, y: centerY, radius: innerRadius, fillColor: '#FFFFFF' })); } drawLegends(degreeToBeDrawn) { const { innerRadius, innerRadiusBorder, middleRadius, center } = this.globalPosition; const [centerX, centerY] = [center.x, center.y]; const maxScore = this.maxScore; let legends = createLegends({ startPoint: center, radius: innerRadius, degreeToBeDrawn, maxScore }); const startFrom = polarToCartesian(centerX, centerY, innerRadiusBorder, degreeToBeDrawn); if (this.hasChildren) { const nextLevelLegends = createLegendWithOptions({ startPoint: startFrom, center, startRadius: innerRadiusBorder, endRadius: middleRadius, maxScore, degreeToBeDrawn }); legends = legends.concat(nextLevelLegends); } legends.forEach(elem => { this.appendToSvg(elem); }); } addArcText({ arcForTextId, radius, startAngle, fontSize, endAngle, perAngle, item }) { const elements = []; const { center } = this.globalPosition; const [centerX, centerY] = [center.x, center.y]; const arcForText = createArcToWriteText({ id: arcForTextId, startPoint: center, radius, startAngle, endAngle }); elements.push(arcForText); const distance = distanceBetweenTwoPoints(centerX, centerY, radius, startAngle, endAngle); const label = getTextForAngle(item.name, distance, fontSize); elements.push(writeTextOnArc({ label, text: item.name, pathId: arcForTextId, 'font-size': fontSize + 'px' })); return elements; } drawLayout() { const { innerRadius, innerRadiusBorder, middleRadius, middleRadiusBorder, outerRadius, outerRadiusBorder, center } = this.globalPosition; const [centerX, centerY] = [center.x, center.y]; let innerRadiusEnd = innerRadius; let innerRadiusBorderEnd = innerRadiusBorder; this.chartBorder = innerRadiusBorder; if (this.hasChildren) { const outerBorderCircle = createCircle({ x: centerX, y: centerY, radius: outerRadiusBorder, fillColor: 'none', 'stroke-width': '5', ref: this.outerBorderCircleRef }); this.appendToSvg(outerBorderCircle); const outerCircle = createCircle({ x: centerX, y: centerY, radius: outerRadius, fillColor: 'none' }); this.appendToSvg(outerCircle); innerRadiusEnd = middleRadius; innerRadiusBorderEnd = middleRadiusBorder; this.chartBorder = outerRadiusBorder; } this.appendToSvg(createCircle({ x: centerX, y: centerY, radius: innerRadiusEnd })); this.appendToSvg(createCircle({ x: centerX, y: centerY, radius: innerRadiusBorderEnd })); } hideTooltip() { this.showToolTip = false; } showTooltipText($event, text) { this.tooltipLeftInPx = $event.pageX + 10 + 'px'; this.tooltipTopInPx = $event.pageY + 10 + 'px'; this.tooltipText = text; this.showToolTip = true; } onOutOfComponent() { this.hideTooltip(); this.stopRotate(); } stopRotate() { this.svgCursor = 'default'; this.startRotation = false; } startRotate($event) { this.startRotation = true; this.svgCursor = 'grab'; const { outerRadiusBorder, center } = this.globalPosition; this.svgHandler = createSvgHandlerWithSelector('#' + this.svgId, center); this.svgHandler.startDrag($event, this.currentRotationAngle); $event.preventDefault(); } rotateChart($event) { if (this.startRotation == false) { return; } this.svgCursor = 'grabbing'; const { center } = this.globalPosition; this.currentRotationAngle = this.svgHandler.getRotationAngle($event); this.rotationPoint = getFormattedAngle(Math.round(this.currentRotationAngle), center); } }; __decorate([ Input() ], AngularSunburstRadarChartComponent.prototype, "items", void 0); __decorate([ Input() ], AngularSunburstRadarChartComponent.prototype, "options", void 0); AngularSunburstRadarChartComponent = __decorate([ Component({ selector: 'lib-sunburst-radar-chart', template: "<ng-container (mouseout)=\"onOutOfComponent();\">\n\n\n <div *ngIf=\"hasError\" style=\" color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n margin-top: 5px;\npadding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n\">\n <strong>Error!</strong> {{error}}\n </div>\n\n\n\n<div class=\"app-tooltip\" *ngIf=\"showToolTip\" style=\"position: absolute; display: block;background: cornsilk; border: 1px solid black; border-radius: 5px; padding: 5px; z-index: 1002;\"\n\n [style.left]=\"tooltipLeftInPx\" [style.top]=\"tooltipTopInPx\" >\n {{tooltipText}}\n</div>\n\n<svg [attr.id]=\"svgId\"\n [attr.height]=\"size\"\n [attr.width]=\"size\"\n [attr.viewBox]=\"viewBox\"\n [style.cursor]=\"svgCursor\"\n xmlns=\"http://www.w3.org/2000/svg\">\n\n\n\n\n <animateTransform\n *ngIf=\"animateChart\"\n attributeName=\"transform\"\n begin=\"4s\"\n dur=\"500ms\"\n type=\"rotate\"\n from=\"0\"\n to=\"10\"\n\n additive=\"sum\"\n fill=\"freeze\"\n repeatCount=\"1\"\n />\n\n\n<g\n (mousemove)=\"rotateChart($event);\"\n (mousedown)=\"startRotate($event)\"\n (mouseup)=\"stopRotate()\"\n (touchmove)=\"rotateChart($event);\"\n (touchstart)=\"startRotate($event)\"\n (touchend)=\"stopRotate()\"\n [attr.transform]=\"rotationPoint\"\n [attr.id]=\"svgGroupId\"\n\n\n >\n <ng-container *ngFor=\"let element of elements\" >\n\n\n\n <ng-container [ngSwitch]=\"element.name\" >\n\n\n <circle *ngSwitchCase=\"'circle'\" [attr.cx]=\"element.options.x\" [attr.cy]=[element.options.y]\n [attr.r]=\"element.options.radius\"\n [attr.stroke-width]=\"element.options['stroke-width']\"\n [attr.stroke]=\"element.options['stroke']\"\n [attr.stroke-dasharray]=\"element.options['stroke-dasharray']\"\n [attr.stroke-opacity]=\"element.options['stroke-opacity']\"\n [attr.fill]=\"element.options['fillColor']\"\n >\n\n\n\n\n </circle>\n\n <path *ngSwitchCase=\"'path'\" [attr.d]=\"element.options.d\" [attr.fill]=[element.options.fill]\n\n [attr.stroke]=\"element.options['stroke']\"\n [attr.stroke-width]=\"element.options['stroke-width']\"\n [attr.id]=\"element.options['id']\"\n (mousemove)=\"showTooltipText($event, element.options['title']);\"\n (mouseout)=\"hideTooltip()\" >\n\n\n\n\n\n </path>\n\n<g *ngSwitchCase=\"'path-bar'\" >\n\n\n\n <path [attr.d]=\"element.options.d\"\n [attr.fill]=[element.options.fill]\n\n [attr.stroke]=\"element.options['stroke']\"\n [attr.stroke-width]=\"element.options['stroke-width']\"\n [attr.stroke-opacity]=\"element.options['stroke-opacity']\"\n [attr.fill-opacity]=\"element.options['fill-opacity']\"\n [attr.id]=\"element.options['id']\"\n (mousemove)=\"showTooltipText($event, element.options['title']);\" (mouseout)=\"hideTooltip()\" >\n\n\n\n\n <ng-container\n\n *ngIf=\"animateChart\"\n >\n\n <animate\n attributeName=\"fill\"\n [attr.from]=\"element.options['fill']\"\n to=\"transparent\"\n dur=\"1ms\"\n fill=\"freeze\" />\n <animate\n attributeName=\"stroke\"\n [attr.from]=\"element.options['fill']\"\n [attr.to]=\"element.options['fill']\"\n dur=\"1ms\"\n fill=\"freeze\" />\n <animate\n attributeName=\"stroke-width\"\n from=\"8\"\n to=\"8\"\n dur=\"1ms\"\n fill=\"freeze\" />\n <animate\n attributeName=\"stroke-dasharray\"\n from=\"1000\"\n to=\"1000\"\n dur=\"1ms\"\n fill=\"freeze\" />\n\n\n <animate\n attributeName=\"fill\"\n from=\"#FFFFFF\"\n [attr.to]=\"element.options['fill']\"\n begin=\"2s\"\n dur=\"3s\"\n fill=\"freeze\" />\n\n <animate\n attributeName=\"stroke-dashoffset\"\n from=\"1000\"\n to=\"0\"\n begin=\"1ms\"\n dur=\"3s\"\n fill=\"freeze\" />\n\n <animate\n attributeName=\"stroke-width\"\n from=\"8\"\n [attr.to]=\"element.options['stroke']\"\n begin=\"3s\"\n dur=\"1s\"\n fill=\"freeze\" />\n </ng-container>\n </path>\n\n\n\n\n</g>\n\n <text *ngSwitchCase=\"'text-on-arc'\"\n [attr.font-size]=\"element.options['font-size']\"\n\n >\n <textPath\n [attr.href]=\"element.options.href\"\n [attr.startOffset]=\"element.options.startOffset\"\n [attr.text-anchor]=\"element.options['text-anchor']\"\n >{{element.options['label']}}</textPath>\n <title>{{element.options['title']}}</title>\n\n </text>\n\n\n <line *ngSwitchCase=\"'line'\"\n [attr.x1]=\"element.options.x1\"\n [attr.y1]=\"element.options.y1\"\n [attr.x2]=\"element.options.x2\"\n [attr.y2]=\"element.options.y2\"\n [attr.stroke-width]=\"element.options.width\"\n\n [attr.stroke]=\"element.options['color']\" >\n <title>{{element.options['title']}}</title>\n </line>\n\n\n <text *ngSwitchCase=\"'text'\"\n [attr.x]=\"element.options.x\"\n [attr.y]=\"element.options.y\"\n [attr.stroke]=\"element.options.stroke\"\n [attr.stroke-width]=\"element.options['stroke-width']\"\n [attr.font-size]=\"element.options['font-size']\"\n [attr.text-anchor]=\"element.options['text-anchor']\"\n >{{element.options.content}}\n <title>{{element.options['content']}}</title>\n </text>\n\n </ng-container>\n\n\n\n </ng-container>\n\n\n </g>\n</svg>\n</ng-container>\n", styles: [".app-tooltip{background:#fff8dc;border:1px solid #000;border-radius:5px;padding:5px;z-index:1002}.growAnimation{-moz-transition:transform 2s ease-in-out;-webkit-transition:transform 2s ease-in-out;-o-transition:transform 2s ease-in-out;transform:scale(1)}.growAnimation:active{transform:scale(.5)}"] }) ], AngularSunburstRadarChartComponent); export { AngularSunburstRadarChartComponent }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci1zdW5idXJzdC1yYWRhci1jaGFydC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9hbmd1bGFyLXN1bmJ1cnN0LXJhZGFyLWNoYXJ0LyIsInNvdXJjZXMiOlsibGliL2FuZ3VsYXItc3VuYnVyc3QtcmFkYXItY2hhcnQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQWdCLFNBQVMsRUFBRSxLQUFLLEVBQW1DLE1BQU0sZUFBZSxDQUFDO0FBQ2hHLE9BQU8sRUFBQyxZQUFZLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBQ3RFLE9BQU8sRUFBQyxvQkFBb0IsRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDMUYsT0FBTyxFQUFDLDRCQUE0QixFQUFFLDRCQUE0QixFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFDbEcsT0FBTyxFQUFDLHFCQUFxQixFQUFFLGtCQUFrQixFQUFpQixNQUFNLG1CQUFtQixDQUFDO0FBQzVGLE9BQU8sRUFBQyx3QkFBd0IsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQy9FLE9BQU8sRUFBQyxhQUFhLEVBQUUsdUJBQXVCLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RSxPQUFPLEVBQUMsV0FBVyxFQUFFLG1CQUFtQixFQUFFLGlCQUFpQixFQUFFLGlCQUFpQixFQUFFLFFBQVEsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUMvRyxPQUFPLEVBQUMsd0JBQXdCLEVBQUUseUJBQXlCLEVBQUUseUJBQXlCLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUdqSSxPQUFPLEVBQUMsNEJBQTRCLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQVFqRSxJQUFhLGtDQUFrQyxHQUEvQyxNQUFhLGtDQUFrQztJQUk3QztRQUlBLHVCQUFrQixHQUFDLEtBQUssQ0FBQztRQUN6QixnQkFBVyxHQUFHLEtBQUssQ0FBQztRQUNwQixtQkFBYyxHQUFHLEtBQUssQ0FBQztRQUN2QixvQkFBZSxHQUFHLEtBQUssQ0FBQztRQUN4QixnQkFBVyxHQUFHLEVBQUUsQ0FBQztRQUNqQixVQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ2IsZUFBVSxHQUFHLElBQUksQ0FBQztRQUVsQixlQUFVLEdBQUcsSUFBSSxDQUFDO1FBRWxCLHlCQUFvQixHQUFHLEVBQUUsQ0FBQztRQUUxQixjQUFTLEdBQUcsU0FBUyxDQUFDO1FBc0J0QixnQkFBVyxHQUFHLEtBQUssQ0FBQztRQUdwQixzQkFBaUIsR0FBRyxFQUFFLENBQUM7UUFDdkIsc0JBQWlCLEdBQUcsRUFBRSxDQUFDO1FBR3ZCLGFBQVEsR0FBd0IsRUFBRSxDQUFDO1FBRW5DLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBRXBCLHlCQUFvQixHQUFHLG1CQUFtQixDQUFDO1FBQzNDLFVBQUssR0FBUSxJQUFJLENBQUM7UUFDbEIsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUVqQixrQkFBYSxHQUFHLEtBQUssQ0FBQztJQXBEdEIsQ0FBQztJQXNERCxTQUFTLENBQUMsR0FBRztRQUVYLElBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDO1FBQ2pCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxTQUFTO1FBRVAsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7UUFDbEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7SUFDeEIsQ0FBQztJQUVELFdBQVcsQ0FBQyxPQUEwQjtRQUVwQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBR0QsV0FBVyxDQUFDLE9BQXNCO1FBR2hDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNqQixNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDO1FBQzFFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUcxQyxDQUFDO0lBRUQsbUJBQW1CLENBQUMsYUFBc0I7UUFDeEMsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUVsQixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7U0FDbkI7SUFDSCxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNqQixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDcEIsQ0FBQztJQUdELFVBQVU7UUFHUixNQUFNLFFBQVEsR0FBRyxFQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLG9CQUFvQixFQUFFLElBQUksRUFBRSxzQkFBc0IsRUFBRSxDQUFDLEVBQUMsQ0FBQztRQUN2SCxNQUFNLE9BQU8sbUNBQU8sUUFBUSxHQUFLLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVwRSxJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7UUFDekIsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQztRQUN6QyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsT0FBTyxDQUFDLG9CQUFvQixDQUFDO1FBQ3pELElBQUksQ0FBQyxzQkFBc0IsR0FBRyxPQUFPLENBQUMsc0JBQXNCLENBQUM7UUFHN0QsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxFQUFFO1lBRTlCLElBQUksQ0FBQyxTQUFTLENBQUMsNENBQTRDLENBQUMsQ0FBQztZQUM3RCxPQUFPO1NBQ1I7UUFDRCxJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztRQUN6QixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxVQUFVLEdBQUcsV0FBVyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFHckQsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUdwRCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDO1FBRXBELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxDQUFDO1FBRXBELElBQUksQ0FBQyxjQUFjLEdBQUcsa0JBQWtCLENBQUM7WUFDdkMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO1lBQ2YsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1lBQ3ZCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztTQUVsQixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBR3pFLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUdsQixNQUFNLEVBQUMsV0FBVyxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFLGlCQUFpQixFQUFFLGVBQWUsRUFBRSxNQUFNLEVBQUMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1FBQ2hJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVoRCxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ3ZCLElBQUksU0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNuQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1FBRXJDLElBQUksSUFBSSxDQUFDLG9CQUFvQixFQUFFO1lBRTdCLDBCQUEwQjtZQUMxQixLQUFLLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzNCLFNBQVMsR0FBRyx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUM3QzthQUFNO1lBQ0wsU0FBUyxHQUFHLHlCQUF5QixDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQzlDO1FBR0QsTUFBTSxlQUFlLEdBQUcsR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFFM0MsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUN6RCxNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sTUFBTSxHQUFHLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUU3RSxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7UUFFakIsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ2xCLElBQUksaUJBQWlCLEdBQUcsRUFBRSxDQUFDO1FBRzNCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBRXRDLE1BQU0sRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRXpCLElBQUksYUFBYSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDMUIsSUFBSSxhQUFhLElBQUksTUFBTSxDQUFDLE1BQU0sRUFBRTtnQkFDbEMsYUFBYSxHQUFHLENBQUMsQ0FBQzthQUNuQjtZQUdELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUN2QyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDN0IsTUFBTSxXQUFXLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRXBDLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUdwQixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxLQUFLLEtBQUssRUFBRTtnQkFHMUIsTUFBTSxhQUFhLEdBQUc7b0JBQ3BCLEtBQUssRUFBRSxtQkFBbUIsRUFBRTtpQkFDN0IsQ0FBQztnQkFDRixJQUFJLG1DQUFPLGFBQWEsR0FBSyxJQUFJLENBQUMsQ0FBQzthQUVwQztZQUdELElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtnQkFFakUsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztnQkFHMUMsaUJBQWlCLEdBQUcsaUJBQWlCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7b0JBQzVELEtBQUssRUFBRSxJQUFJLENBQUMsUUFBUTtvQkFDcEIsWUFBWSxFQUFFLGVBQWU7b0JBQzdCLFdBQVc7b0JBQ1gsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO2lCQUNsQixDQUFDLENBQUMsQ0FBQzthQUVMO1lBR0QsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUM7WUFHM0UsOEJBQThCO1lBQzlCLE1BQU0sWUFBWSxHQUFHLDRCQUE0QixDQUFDO2dCQUNoRCxVQUFVLEVBQUUsTUFBTTtnQkFDbEIsSUFBSTtnQkFDSixNQUFNLEVBQUUsV0FBVztnQkFDbkIsVUFBVTtnQkFDVixRQUFRO2dCQUNSLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTthQUN4QixDQUFDLENBQUM7WUFDSCxRQUFRLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRzVCLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztnQkFDeEMsWUFBWSxFQUFFLGdCQUFnQixHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsR0FBRyxHQUFHLEdBQUcsQ0FBQztnQkFDL0QsTUFBTSxFQUFFLGVBQWU7Z0JBQ3ZCLFFBQVEsRUFBRSxRQUFRO2dCQUNsQixVQUFVO2dCQUNWLFFBQVE7Z0JBQ1IsUUFBUSxFQUFFLGVBQWU7Z0JBQ3pCLElBQUk7YUFDTCxDQUFDLENBQUM7WUFDSCxRQUFRLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBRzlDLElBQUksV0FBVyxFQUFFO2dCQUVmLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLDZCQUE2QixDQUFDLEVBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM3RixNQUFNLDJCQUEyQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQ2pEO29CQUNFLFlBQVksRUFBRSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLEdBQUcsR0FBRyxHQUFHLENBQUM7b0JBQy9ELE1BQU0sRUFBRSxlQUFlO29CQUN2QixRQUFRLEVBQUUsYUFBYTtvQkFDdkIsUUFBUSxFQUFFLGVBQWU7b0JBQ3pCLFVBQVU7b0JBQ1YsUUFBUTtvQkFDUixJQUFJO2lCQUNMLENBQUMsQ0FBQztnQkFDTCxRQUFRLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO2FBQ3pEO1NBR0Y7UUFHRCxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDL0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV6QixDQUFDLENBQUMsQ0FBQztRQUdILElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBR3hCLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDdEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV6QixDQUFDLENBQUMsQ0FBQztRQUVILEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDbkIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV6QixDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUV4RCxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFL0MsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFHeEIsSUFBSSxDQUFDLG9CQUFvQixHQUFHLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsYUFBYSxHQUFHLGlCQUFpQixDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUU1RSxDQUFDO0lBTUQsa0JBQWtCLENBQUMsTUFBYTtRQUM5QixJQUFJLGVBQWUsR0FBRyxJQUFJLENBQUMsc0JBQXNCLEdBQUcsQ0FBQyxDQUFDO1FBQ3RELElBQUksZUFBZSxHQUFHLENBQUMsSUFBSSxlQUFlLElBQUksTUFBTSxDQUFDLE1BQU0sRUFBRTtZQUMzRCxlQUFlLEdBQUcsQ0FBQyxDQUFDO1NBQ3JCO1FBQ0QsT0FBTyxlQUFlLENBQUM7SUFDekIsQ0FBQztJQUVELGtCQUFrQjtRQUVoQixPQUFPLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFHRCw2QkFBNkIsQ0FBQyxFQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBQztRQUdyRSxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBRXpCLE1BQU0sRUFBQyxlQUFlLEVBQUUsTUFBTSxFQUFDLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUV0RCxNQUFNLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFHaEQsTUFBTSxZQUFZLEdBQUcscUJBQXFCLENBQUMsRUFBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUMsQ0FBQyxDQUFDO1FBRzNILE1BQU0sQ0FBQyxHQUFHO1lBRVIsR0FBRyxFQUFFLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMvQyxHQUFHLEVBQUUsZUFBZSxFQUFFLGVBQWUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUM7U0FHdkYsQ0FBQztRQUVGLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFFM0MsTUFBTSxXQUFXLEdBQUcsTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDdkMsT0FBTyxVQUFVLENBQUMsRUFBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQztJQUV6RixDQUFDO0lBR0QsV0FBVyxDQUFDLEVBQUMsS0FBSyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFDO1FBR25ELE1BQU0sRUFBQyxpQkFBaUIsRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBQyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDbEcsTUFBTSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBR2hELE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDekQsTUFBTSxZQUFZLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNoRSxNQUFNLFNBQVMsR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzFELE1BQU0sUUFBUSxHQUFHLFlBQVksR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO1FBRTdDLE1BQU0seUJBQXlCLEdBQUcseUJBQXlCLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUd6RyxNQUFNLGNBQWMsR0FBRyx5QkFBeUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUd6RixJQUFJLFFBQVEsR0FBRyxFQUFFLENBQUM7UUFDbEIsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBR2pCLElBQUksYUFBYSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU5QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcseUJBQXlCLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBRXpELE1BQU0sd0JBQXdCLEdBQUcseUJBQXlCLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUQsTUFBTSxhQUFhLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBR3hDLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO2dCQUNwQixFQUFFLEVBQUUsd0JBQXdCLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSx3QkFBd0IsQ0FBQyxDQUFDO2dCQUM5RCxFQUFFLEVBQUUsYUFBYSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsYUFBYSxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRzthQUNyRCxDQUFDLENBQUMsQ0FBQztZQUdKLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM3QixNQUFNLFdBQVcsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEMsTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRzlCLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUd0QixNQUFNLE1BQU0sR0FBRztnQkFDYixVQUFVLEVBQUUsd0JBQXdCO2dCQUNwQyxJQUFJO2dCQUNKLFVBQVU7Z0JBQ1YsUUFBUTtnQkFDUixXQUFXO2dCQUNYLFlBQVk7Z0JBQ1osaUJBQWlCO2dCQUNqQixNQUFNO2dCQUNOLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtnQkFDdkIsS0FBSztnQkFDTCxLQUFLLEVBQUUsQ0FBQzthQUNULENBQUM7WUFHRixNQUFNLFdBQVcsR0FBRyw0QkFBNEIsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUV6RCxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBRzNCLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztnQkFDekMsWUFBWSxFQUFFLGlCQUFpQixHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsR0FBRyxHQUFHLEdBQUcsVUFBVSxHQUFHLENBQUM7Z0JBQzdFLE1BQU0sRUFBRSxnQkFBZ0I7Z0JBQ3hCLFFBQVEsRUFBRSxRQUFRO2dCQUNsQixRQUFRO2dCQUNSLFVBQVU7Z0JBQ1YsUUFBUTtnQkFDUixJQUFJO2FBQ0wsQ0FBQyxDQUFDO1lBRUgsUUFBUSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztZQUcvQyxhQUFhLEdBQUcsYUFBYSxHQUFHLFFBQVEsQ0FBQztTQUUxQztRQUdELEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDbkIsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV0QixDQUFDLENBQUMsQ0FBQztRQUdILE9BQU8sUUFBUSxDQUFDO0lBRWxCLENBQUM7SUFFRCxhQUFhO1FBRVgsT0FBTyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBRWhELENBQUM7SUFFRCxnQkFBZ0I7UUFFZCxNQUFNLEVBQUMsV0FBVyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sRUFBQyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDckUsTUFBTSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWhELE1BQU0sY0FBYyxHQUFHLFlBQVksQ0FBQztZQUNsQyxDQUFDLEVBQUUsT0FBTztZQUNWLENBQUMsRUFBRSxPQUFPO1lBQ1YsTUFBTSxFQUFFLFdBQVc7WUFDbkIsU0FBUyxFQUFFLE1BQU07U0FDbEIsQ0FBQyxDQUFDO1FBR0gsTUFBTSxvQkFBb0IsR0FBRyxZQUFZLENBQUM7WUFDeEMsQ0FBQyxFQUFFLE9BQU87WUFDVixDQUFDLEVBQUUsT0FBTztZQUNWLE1BQU0sRUFBRSxpQkFBaUI7WUFDekIsU0FBUyxFQUFFLFNBQVM7U0FDckIsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFdBQVcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVELHVCQUF1QixDQUFDLE9BQWUsRUFBRSxPQUFlO1FBRXRELE1BQU0sV0FBVyxHQUFHLE1BQU0sR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUMzQyxNQUFNLFdBQVcsR0FBRyxNQUFNLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDM0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUM7WUFDNUIsQ0FBQyxFQUFFLE9BQU87WUFDVixDQUFDLEVBQUUsT0FBTztZQUNWLE1BQU0sRUFBRSxXQUFXO1lBQ25CLFNBQVMsRUFBRSxTQUFTO1NBQ3JCLENBQUMsQ0FBQyxDQUFDO1FBRUosSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUM7WUFDNUIsQ0FBQyxFQUFFLE9BQU87WUFDVixDQUFDLEVBQUUsT0FBTztZQUNWLE1BQU0sRUFBRSxXQUFXO1lBQ25CLFNBQVMsRUFBRSxTQUFTO1NBQ3JCLENBQUMsQ0FBQyxDQUFDO0lBRU4sQ0FBQztJQUVELFdBQVcsQ0FBQyxlQUFlO1FBRXpCLE1BQU0sRUFBQyxXQUFXLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBQyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUM7UUFHbkYsTUFBTSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFFL0IsSUFBSSxPQUFPLEdBQUcsYUFBYSxDQUFDLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFDO1FBR2xHLE1BQU0sU0FBUyxHQUFHLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFFekYsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ3BCLE1BQU0sZ0JBQWdCLEdBQUcsdUJBQXVCLENBQUM7Z0JBQy9DLFVBQVUsRUFBRSxTQUFTO2dCQUNyQixNQUFNO2dCQUNOLFdBQVcsRUFBRSxpQkFBaUI7Z0JBQzlCLFNBQVMsRUFBRSxZQUFZO2dCQUN2QixRQUFRO2dCQUNSLGVBQWU7YUFDaEIsQ0FBQyxDQUFDO1lBRUgsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztTQUM1QztRQUNELE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDckIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QixDQUFDLENBQUMsQ0FBQztJQUVMLENBQUM7SUFHRCxVQUFVLENBQUMsRUFBQyxZQUFZLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUM7UUFDL0UsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ3BCLE1BQU0sRUFBQyxNQUFNLEVBQUMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1FBQ3JDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoRCxNQUFNLFVBQVUsR0FBRyxvQkFBb0IsQ0FBQyxFQUFDLEVBQUUsRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUM7UUFDOUcsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMxQixNQUFNLFFBQVEsR0FBRyx3QkFBd0IsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFHMUYsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzdELFFBQVEsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEVBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLFFBQVEsR0FBRyxJQUFJLEVBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUcsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQUVELFVBQVU7UUFFUixNQUFNLEVBQUMsV0FBVyxFQUFFLGlCQUFpQixFQUFFLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxXQUFXLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFDLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUV2SSxNQUFNLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFHaEQsSUFBSSxjQUFjLEdBQUcsV0FBVyxDQUFDO1FBQ2pDLElBQUksb0JBQW9CLEdBQUcsaUJBQWlCLENBQUM7UUFDN0MsSUFBSSxDQUFDLFdBQVcsR0FBRyxpQkFBaUIsQ0FBQztRQUVyQyxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFFcEIsTUFBTSxpQkFBaUIsR0FBRyxZQUFZLENBQUM7Z0JBQ3JDLENBQUMsRUFBRSxPQUFPO2dCQUNWLENBQUMsRUFBRSxPQUFPO2dCQUNWLE1BQU0sRUFBRSxpQkFBaUI7Z0JBQ3pCLFNBQVMsRUFBRSxNQUFNO2dCQUNqQixjQUFjLEVBQUUsR0FBRztnQkFDbkIsR0FBRyxFQUFFLElBQUksQ0FBQyxvQkFBb0I7YUFFL0IsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLFdBQVcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ3BDLE1BQU0sV0FBVyxHQUFHLFlBQVksQ0FBQztnQkFDL0IsQ0FBQyxFQUFFLE9BQU87Z0JBQ1YsQ0FBQyxFQUFFLE9BQU87Z0JBQ1YsTUFBTSxFQUFFLFdBQVc7Z0JBQ25CLFNBQVMsRUFBRSxNQUFNO2FBQ2xCLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7WUFFOUIsY0FBYyxHQUFHLFlBQVksQ0FBQztZQUM5QixvQkFBb0IsR0FBRyxrQkFBa0IsQ0FBQztZQUMxQyxJQUFJLENBQUMsV0FBVyxHQUFHLGlCQUFpQixDQUFDO1NBQ3RDO1FBRUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsRUFBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBQyxDQUFDLENBQUMsQ0FBQztRQUNqRixJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxFQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsb0JBQW9CLEVBQUMsQ0FBQyxDQUFDLENBQUM7SUFDekYsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztJQUMzQixDQUFDO0lBRUQsZUFBZSxDQUFDLE1BQVcsRUFBRSxJQUFTO1FBQ3BDLElBQUksQ0FBQyxlQUFlLEdBQUcsTUFBTSxDQUFDLEtBQUssR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO1FBQ2hELElBQUksQ0FBQyxjQUFjLEdBQUcsTUFBTSxDQUFDLEtBQUssR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO1FBQy9DLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBRXhCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO0lBRzFCLENBQUM7SUFHRCxnQkFBZ0I7UUFFZCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3BCLENBQUM7SUFFRCxVQUFVO1FBQ1IsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDM0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFDN0IsQ0FBQztJQUVELFdBQVcsQ0FBQyxNQUFXO1FBRXJCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1FBQzFCLElBQUksQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDO1FBQ3hCLE1BQU0sRUFBQyxpQkFBaUIsRUFBRSxNQUFNLEVBQUMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1FBRXhELElBQUksQ0FBQyxVQUFVLEdBQUcsNEJBQTRCLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDekUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBRTdELE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUUxQixDQUFDO0lBR0QsV0FBVyxDQUFDLE1BQVc7UUFHckIsSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLEtBQUssRUFBRTtZQUMvQixPQUFPO1NBQ1I7UUFDRCxJQUFJLENBQUMsU0FBUyxHQUFHLFVBQVUsQ0FBQztRQUM1QixNQUFNLEVBQUMsTUFBTSxFQUFDLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUVyQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUdyRSxJQUFJLENBQUMsYUFBYSxHQUFHLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFHeEYsQ0FBQztDQUVGLENBQUE7QUExbEJDO0lBREMsS0FBSyxFQUFFO2lFQUNGO0FBR047SUFEQyxLQUFLLEVBQUU7bUVBQ0E7QUEzQkcsa0NBQWtDO0lBTDlDLFNBQVMsQ0FBQztRQUNULFFBQVEsRUFBRSwwQkFBMEI7UUFDcEMscW1NQUE0RDs7S0FFN0QsQ0FBQztHQUNXLGtDQUFrQyxDQWtuQjlDO1NBbG5CWSxrQ0FBa0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0FmdGVyVmlld0luaXQsIENvbXBvbmVudCwgSW5wdXQsIE9uQ2hhbmdlcywgT25Jbml0LCBTaW1wbGVDaGFuZ2VzfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Y3JlYXRlQ2lyY2xlLCBjcmVhdGVMaW5lLCBjcmVhdGVQYXRofSBmcm9tICcuL3V0aWxzL2VsZW1lbnRzJztcbmltcG9ydCB7Y3JlYXRlQXJjVG9Xcml0ZVRleHQsIGdldFRleHRGb3JBbmdsZSwgd3JpdGVUZXh0T25BcmN9IGZyb20gJy4vdXRpbHMvdGV4dGVsZW1lbnQnO1xuaW1wb3J0IHtjcmVhdGVJbm5lckNoYXJ0QmFyV2l0aEluQXJjLCBjcmVhdGVPdXRlckNoYXJ0QmFyV2l0aEluQXJjfSBmcm9tICcuL3V0aWxzL2FyYy1iYXItY2hhcnRzJztcbmltcG9ydCB7Y2FsY3VsYXRlUG9pbnRCZXR3ZWVuLCBnZXRHbG9iYWxQb3NpdGlvbnMsIEdsb2JhbFBvc2l0aW9ufSBmcm9tICcuL3V0aWxzL3Bvc2l0aW9ucyc7XG5pbXBvcnQge2Rpc3RhbmNlQmV0d2VlblR3b1BvaW50cywgcG9sYXJUb0NhcnRlc2lhbn0gZnJvbSAnLi91dGlscy90cmlnbm9tZXRyeSc7XG5pbXBvcnQge2NyZWF0ZUxlZ2VuZHMsIGNyZWF0ZUxlZ2VuZFdpdGhPcHRpb25zfSBmcm9tICcuL3V0aWxzL2xlZ2VuZCc7XG5pbXBvcnQge2Zvcm1hdEl0ZW1zLCBnZW5lcmF0ZVJhbmRvbUNvbG9yLCBnZXRGb3JtYXR0ZWRBbmdsZSwgZ2V0T3B0aW9uc09yRW1wdHksIGhhc2hDb2RlfSBmcm9tICcuL3V0aWxzL3V0aWxzJztcbmltcG9ydCB7Z2V0QWxsQW5nbGVzQmFzZWRPbkNoaWxkLCBnZXRBbGxBbmdsZXNCYXNlZE9uUGFyZW50LCBnZXRQb2ludHNPbkNpcmNsZUF0QW5nZWxzLCBwb3NpdGlvbnNPbkFuZ2xlc30gZnJvbSAnLi91dGlscy9hbmdlbHMnO1xuaW1wb3J0IHtBbmd1bGFyU3ZnRWxlbWVudH0gZnJvbSAnLi91dGlscy9tb2RlbHMnO1xuXG5pbXBvcnQge2NyZWF0ZVN2Z0hhbmRsZXJXaXRoU2VsZWN0b3J9IGZyb20gJy4vdXRpbHMvc3ZnLXJvdGF0b3InO1xuXG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2xpYi1zdW5idXJzdC1yYWRhci1jaGFydCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9hbmd1bGFyLXN1bmJ1cnN0LXJhZGFyLWNoYXJ0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vYW5ndWxhci1zdW5idXJzdC1yYWRhci1jaGFydC5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIEFuZ3VsYXJTdW5idXJzdFJhZGFyQ2hhcnRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG5cblxuXG4gIGNvbnN0cnVjdG9yKCkge1xuICB9XG5cblxuICBjb21wb25lbnREaXNwbGF5ZWQ9ZmFsc2U7XG4gIHNob3dUb29sVGlwID0gZmFsc2U7XG4gIHRvb2x0aXBUb3BJblB4ID0gJzBweCc7XG4gIHRvb2x0aXBMZWZ0SW5QeCA9ICcwcHgnO1xuICB0b29sdGlwVGV4dCA9ICcnO1xuICBzdmdJZCA9IG51bGw7XG4gIHN2Z0dyb3VwSWQgPSBudWxsO1xuXG4gIHN2Z0hhbmRsZXIgPSBudWxsO1xuXG4gIGN1cnJlbnRSb3RhdGlvbkFuZ2xlID0gMTA7XG4gIHJvdGF0aW9uUG9pbnQ7XG4gIHN2Z0N1cnNvciA9ICdkZWZhdWx0JztcblxuXG4gIEBJbnB1dCgpXG4gIGl0ZW1zO1xuXG4gIEBJbnB1dCgpXG4gIG9wdGlvbnM7XG5cbiAgc2l6ZTogbnVtYmVyO1xuXG5cbiAgbWF4U2NvcmU6IG51bWJlcjtcblxuICBsZWdlbmRBeGlzTGluZVBvc2l0aW9uOiBudW1iZXI7XG5cbiAgYW5pbWF0ZUNoYXJ0O1xuXG4gIHNwbGl0QmFzZWRPbkNoaWxkcmVuO1xuXG4gIHZpZXdCb3g7XG5cbiAgaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgaW5uZXJDaXJjbGVSYWRpdXM7XG5cbiAgaW5uZXJCb3JkZXJIZWlnaHQgPSAzMDtcbiAgb3V0ZXJCb3JkZXJIZWlnaHQgPSAzMDtcblxuXG4gIGVsZW1lbnRzOiBBbmd1bGFyU3ZnRWxlbWVudFtdID0gW107XG4gIGdsb2JhbFBvc2l0aW9uOiBHbG9iYWxQb3NpdGlvbjtcbiAgaGFzQ2hpbGRyZW4gPSBmYWxzZTtcbiAgY2hhcnRCb3JkZXI7XG4gIG91dGVyQm9yZGVyQ2lyY2xlUmVmID0gJ291dGVyQm9yZGVyQ2lyY2xlJztcbiAgZXJyb3I6IGFueSA9IG51bGw7XG4gIGhhc0Vycm9yID0gZmFsc2U7XG5cbiAgc3RhcnRSb3RhdGlvbiA9IGZhbHNlO1xuXG4gIHNob3dFcnJvcihtc2cpIHtcblxuICAgIHRoaXMuZXJyb3IgPSBtc2c7XG4gICAgdGhpcy5oYXNFcnJvciA9IHRydWU7XG4gIH1cblxuICBoaWRlRXJyb3IoKSB7XG5cbiAgICB0aGlzLmVycm9yID0gbnVsbDtcbiAgICB0aGlzLmhhc0Vycm9yID0gZmFsc2U7XG4gIH1cblxuICBhcHBlbmRUb1N2ZyhlbGVtZW50OiBBbmd1bGFyU3ZnRWxlbWVudCkge1xuXG4gICAgdGhpcy5lbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICB9XG5cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG5cblxuICAgIHRoaXMuaGlkZUVycm9yKCk7XG4gICAgY29uc3QgaXNGaXJzdENoYW5nZSA9IE9iamVjdC52YWx1ZXMoY2hhbmdlcykuc29tZShjID0+IGMuaXNGaXJzdENoYW5nZSgpKTtcbiAgICB0aGlzLm1vZGlmeU9uRmlyc3RDaGFuZ2UoaXNGaXJzdENoYW5nZSk7XG5cblxuICB9XG5cbiAgbW9kaWZ5T25GaXJzdENoYW5nZShpc0ZpcnN0Q2hhbmdlOiBib29sZWFuKSB7XG4gICAgaWYgKCFpc0ZpcnN0Q2hhbmdlKSB7XG5cbiAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuaGlkZUVycm9yKCk7XG4gICAgdGhpcy5pbml0aWFsaXplKCk7XG4gIH1cblxuXG4gIGluaXRpYWxpemUoKTogdm9pZCB7XG5cblxuICAgIGNvbnN0IGRlZmF1bHRzID0ge3NpemU6IDMwMCwgbWF4U2NvcmU6IDEwMCwgYW5pbWF0ZUNoYXJ0OiB0cnVlLCBzcGxpdEJhc2VkT25DaGlsZHJlbjogdHJ1ZSwgbGVnZW5kQXhpc0xpbmVQb3NpdGlvbjogMX07XG4gICAgY29uc3Qgb3B0aW9ucyA9IHsuLi5kZWZhdWx0cywgLi4uKGdldE9wdGlvbnNPckVtcHR5KHRoaXMub3B0aW9ucykpfTtcblxuICAgIHRoaXMuc2l6ZSA9IG9wdGlvbnMuc2l6ZTtcbiAgICB0aGlzLm1heFNjb3JlID0gb3B0aW9ucy5tYXhTY29yZTtcbiAgICB0aGlzLmFuaW1hdGVDaGFydCA9IG9wdGlvbnMuYW5pbWF0ZUNoYXJ0O1xuICAgIHRoaXMuc3BsaXRCYXNlZE9uQ2hpbGRyZW4gPSBvcHRpb25zLnNwbGl0QmFzZWRPbkNoaWxkcmVuO1xuICAgIHRoaXMubGVnZW5kQXhpc0xpbmVQb3NpdGlvbiA9IG9wdGlvbnMubGVnZW5kQXhpc0xpbmVQb3NpdGlvbjtcblxuXG4gICAgaWYgKCF0aGlzLmhhc1ZhbGlkUGFyYW1ldGVycygpKSB7XG5cbiAgICAgIHRoaXMuc2hvd0Vycm9yKCdJbnB1dCBWYWx1ZXMgbm90IHNldCBvciBJdGVtcyB3YXMgaW1wcm9wZXInKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgIHRoaXMuc3ZnSWQgPSAnc3ZnJyArIGhhc2hDb2RlKHRoaXMuaXRlbXMpO1xuICAgIHRoaXMuc3ZnR3JvdXBJZCA9ICdzdmctZ3JvdXAnICsgaGFzaENvZGUodGhpcy5pdGVtcyk7XG5cblxuICAgIHRoaXMudmlld0JveCA9ICcwIDAgJyArIHRoaXMuc2l6ZSArICcgJyArIHRoaXMuc2l6ZTtcblxuXG4gICAgdGhpcy5pbm5lckNpcmNsZVJhZGl1cyA9IE1hdGguYWJzKHRoaXMuc2l6ZSAvIDUuMzMpO1xuXG4gICAgdGhpcy5pbm5lckJvcmRlckhlaWdodCA9IHRoaXMuaW5uZXJDaXJjbGVSYWRpdXMgLyA1O1xuICAgIHRoaXMub3V0ZXJCb3JkZXJIZWlnaHQgPSB0aGlzLmlubmVyQ2lyY2xlUmFkaXVzIC8gNTtcblxuICAgIHRoaXMuZ2xvYmFsUG9zaXRpb24gPSBnZXRHbG9iYWxQb3NpdGlvbnMoe1xuICAgICAgc2l6ZTogdGhpcy5zaXplLFxuICAgICAgbWF4U2NvcmU6IHRoaXMubWF4U2NvcmUsXG4gICAgICBpdGVtczogdGhpcy5pdGVtc1xuXG4gICAgfSk7XG5cbiAgICB0aGlzLmhhc0NoaWxkcmVuID0gdGhpcy5pdGVtcy5maWx0ZXIoaXRlbSA9PiAhIWl0ZW0uY2hpbGRyZW4pLmxlbmd0aCA+IDA7XG5cblxuICAgIHRoaXMuZHJhd0xheW91dCgpO1xuXG5cbiAgICBjb25zdCB7aW5uZXJSYWRpdXMsIGlubmVyVGV4dFJhZGl1cywgdGV4dFNpemUsIG91dGVyVGV4dFNpemUsIG91dGVyUmFkaXVzQm9yZGVyLCBvdXRlclRleHRSYWRpdXMsIGNlbnRlcn0gPSB0aGlzLmdsb2JhbFBvc2l0aW9uO1xuICAgIGNvbnN0IFtjZW50ZXJYLCBjZW50ZXJZXSA9IFtjZW50ZXIueCwgY2VudGVy