UNPKG

41 kBJavaScriptView Raw
1var __extends = (this && this.__extends) || (function () {
2 var extendStatics = function (d, b) {
3 extendStatics = Object.setPrototypeOf ||
4 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6 return extendStatics(d, b);
7 };
8 return function (d, b) {
9 extendStatics(d, b);
10 function __() { this.constructor = d; }
11 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
12 };
13})();
14var __assign = (this && this.__assign) || function () {
15 __assign = Object.assign || function(t) {
16 for (var s, i = 1, n = arguments.length; i < n; i++) {
17 s = arguments[i];
18 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
19 t[p] = s[p];
20 }
21 return t;
22 };
23 return __assign.apply(this, arguments);
24};
25import _ from "lodash";
26import React from "react";
27import { View } from "react-native";
28import { G, Rect, Svg, Text } from "react-native-svg";
29import AbstractChart from "../AbstractChart";
30import { mapValue } from "../Utils";
31import { convertToDate, getBeginningTimeForDate, shiftDate } from "./DateHelpers";
32import { DAYS_IN_WEEK, MILLISECONDS_IN_ONE_DAY, MONTH_LABELS } from "./constants";
33var SQUARE_SIZE = 20;
34var MONTH_LABEL_GUTTER_SIZE = 8;
35var paddingLeft = 32;
36var ContributionGraph = /** @class */ (function (_super) {
37 __extends(ContributionGraph, _super);
38 function ContributionGraph(props) {
39 var _this = _super.call(this, props) || this;
40 var _a = _this.getValueCache(props.values), maxValue = _a.maxValue, minValue = _a.minValue, valueCache = _a.valueCache;
41 _this.state = {
42 maxValue: maxValue,
43 minValue: minValue,
44 valueCache: valueCache
45 };
46 return _this;
47 }
48 ContributionGraph.prototype.UNSAFE_componentWillReceiveProps = function (nextProps) {
49 var _a = this.getValueCache(nextProps.values), maxValue = _a.maxValue, minValue = _a.minValue, valueCache = _a.valueCache;
50 this.setState({
51 maxValue: maxValue,
52 minValue: minValue,
53 valueCache: valueCache
54 });
55 };
56 ContributionGraph.prototype.getSquareSizeWithGutter = function () {
57 return (this.props.squareSize || SQUARE_SIZE) + this.props.gutterSize;
58 };
59 ContributionGraph.prototype.getMonthLabelSize = function () {
60 var _a = this.props.squareSize, squareSize = _a === void 0 ? SQUARE_SIZE : _a;
61 if (!this.props.showMonthLabels) {
62 return 0;
63 }
64 if (this.props.horizontal) {
65 return squareSize + MONTH_LABEL_GUTTER_SIZE;
66 }
67 return 2 * (squareSize + MONTH_LABEL_GUTTER_SIZE);
68 };
69 ContributionGraph.prototype.getStartDate = function () {
70 return shiftDate(this.getEndDate(), -this.props.numDays + 1); // +1 because endDate is inclusive
71 };
72 ContributionGraph.prototype.getEndDate = function () {
73 return getBeginningTimeForDate(convertToDate(this.props.endDate));
74 };
75 ContributionGraph.prototype.getStartDateWithEmptyDays = function () {
76 return shiftDate(this.getStartDate(), -this.getNumEmptyDaysAtStart());
77 };
78 ContributionGraph.prototype.getNumEmptyDaysAtStart = function () {
79 return this.getStartDate().getDay();
80 };
81 ContributionGraph.prototype.getNumEmptyDaysAtEnd = function () {
82 return DAYS_IN_WEEK - 1 - this.getEndDate().getDay();
83 };
84 ContributionGraph.prototype.getWeekCount = function () {
85 var numDaysRoundedToWeek = this.props.numDays +
86 this.getNumEmptyDaysAtStart() +
87 this.getNumEmptyDaysAtEnd();
88 return Math.ceil(numDaysRoundedToWeek / DAYS_IN_WEEK);
89 };
90 ContributionGraph.prototype.getWeekWidth = function () {
91 return DAYS_IN_WEEK * this.getSquareSizeWithGutter();
92 };
93 ContributionGraph.prototype.getWidth = function () {
94 return (this.getWeekCount() * this.getSquareSizeWithGutter() -
95 this.props.gutterSize);
96 };
97 ContributionGraph.prototype.getHeight = function () {
98 return (this.getWeekWidth() + (this.getMonthLabelSize() - this.props.gutterSize));
99 };
100 ContributionGraph.prototype.getValueCache = function (values) {
101 var _this = this;
102 var minValue = Infinity, maxValue = -Infinity;
103 return {
104 valueCache: values.reduce(function (memo, value) {
105 var date = convertToDate(value.date);
106 var index = Math.floor((date.valueOf() - _this.getStartDateWithEmptyDays().valueOf()) /
107 MILLISECONDS_IN_ONE_DAY);
108 minValue = Math.min(value[_this.props.accessor], minValue);
109 maxValue = Math.max(value[_this.props.accessor], maxValue);
110 memo[index] = {
111 value: value,
112 title: _this.props.titleForValue
113 ? _this.props.titleForValue(value)
114 : null,
115 tooltipDataAttrs: _this.getTooltipDataAttrsForValue(value)
116 };
117 return memo;
118 }, {}),
119 minValue: minValue,
120 maxValue: maxValue
121 };
122 };
123 ContributionGraph.prototype.getValueForIndex = function (index) {
124 if (this.state.valueCache[index]) {
125 return this.state.valueCache[index].value;
126 }
127 return null;
128 };
129 ContributionGraph.prototype.getClassNameForIndex = function (index) {
130 if (this.state.valueCache[index]) {
131 if (this.state.valueCache[index].value) {
132 var count = this.state.valueCache[index].value[this.props.accessor];
133 if (count) {
134 var opacity = mapValue(count, this.state.minValue, this.state.maxValue, 0.15 + 0.05, // + 0.05 to make smaller values a bit more visible
135 1);
136 return this.props.chartConfig.color(opacity);
137 }
138 }
139 }
140 return this.props.chartConfig.color(0.15);
141 };
142 ContributionGraph.prototype.getTitleForIndex = function (index) {
143 if (this.state.valueCache[index]) {
144 return this.state.valueCache[index].title;
145 }
146 return this.props.titleForValue ? this.props.titleForValue(null) : null;
147 };
148 ContributionGraph.prototype.getTooltipDataAttrsForIndex = function (index) {
149 var _a;
150 if (this.state.valueCache[index]) {
151 return this.state.valueCache[index].tooltipDataAttrs;
152 }
153 return this.getTooltipDataAttrsForValue((_a = {
154 date: null
155 },
156 _a[this.props.accessor] = null,
157 _a));
158 };
159 ContributionGraph.prototype.getTooltipDataAttrsForValue = function (value) {
160 var tooltipDataAttrs = this.props.tooltipDataAttrs;
161 if (typeof tooltipDataAttrs === "function") {
162 return tooltipDataAttrs(value);
163 }
164 return tooltipDataAttrs;
165 };
166 ContributionGraph.prototype.getTransformForWeek = function (weekIndex) {
167 if (this.props.horizontal) {
168 return [weekIndex * this.getSquareSizeWithGutter(), 50];
169 }
170 return [10, weekIndex * this.getSquareSizeWithGutter()];
171 };
172 ContributionGraph.prototype.getTransformForMonthLabels = function () {
173 if (this.props.horizontal) {
174 return null;
175 }
176 return this.getWeekWidth() + MONTH_LABEL_GUTTER_SIZE + ", 0";
177 };
178 ContributionGraph.prototype.getTransformForAllWeeks = function () {
179 if (this.props.horizontal) {
180 return "0, " + (this.getMonthLabelSize() - 100);
181 }
182 return null;
183 };
184 ContributionGraph.prototype.getViewBox = function () {
185 if (this.props.horizontal) {
186 return this.getWidth() + " " + this.getHeight();
187 }
188 return this.getHeight() + " " + this.getWidth();
189 };
190 ContributionGraph.prototype.getSquareCoordinates = function (dayIndex) {
191 if (this.props.horizontal) {
192 return [0, dayIndex * this.getSquareSizeWithGutter()];
193 }
194 return [dayIndex * this.getSquareSizeWithGutter(), 0];
195 };
196 ContributionGraph.prototype.getMonthLabelCoordinates = function (weekIndex) {
197 if (this.props.horizontal) {
198 return [
199 weekIndex * this.getSquareSizeWithGutter(),
200 this.getMonthLabelSize() - MONTH_LABEL_GUTTER_SIZE
201 ];
202 }
203 var verticalOffset = -2;
204 return [
205 0,
206 (weekIndex + 1) * this.getSquareSizeWithGutter() + verticalOffset
207 ];
208 };
209 ContributionGraph.prototype.renderSquare = function (dayIndex, index) {
210 var _this = this;
211 var indexOutOfRange = index < this.getNumEmptyDaysAtStart() ||
212 index >= this.getNumEmptyDaysAtStart() + this.props.numDays;
213 if (indexOutOfRange && !this.props.showOutOfRangeDays) {
214 return null;
215 }
216 var _a = this.getSquareCoordinates(dayIndex), x = _a[0], y = _a[1];
217 var _b = this.props.squareSize, squareSize = _b === void 0 ? SQUARE_SIZE : _b;
218 return (<Rect key={index} width={squareSize} height={squareSize} x={x + paddingLeft} y={y} title={this.getTitleForIndex(index)} fill={this.getClassNameForIndex(index)} onPress={function () {
219 _this.handleDayPress(index);
220 }} {...this.getTooltipDataAttrsForIndex(index)}/>);
221 };
222 ContributionGraph.prototype.handleDayPress = function (index) {
223 var _a;
224 if (!this.props.onDayPress) {
225 return;
226 }
227 this.props.onDayPress(this.state.valueCache[index] && this.state.valueCache[index].value
228 ? this.state.valueCache[index].value
229 : (_a = {},
230 _a[this.props.accessor] = 0,
231 _a.date = new Date(this.getStartDate().valueOf() + index * MILLISECONDS_IN_ONE_DAY),
232 _a));
233 };
234 ContributionGraph.prototype.renderWeek = function (weekIndex) {
235 var _this = this;
236 var _a = this.getTransformForWeek(weekIndex), x = _a[0], y = _a[1];
237 return (<G key={weekIndex} x={x} y={y}>
238 {_.range(DAYS_IN_WEEK).map(function (dayIndex) {
239 return _this.renderSquare(dayIndex, weekIndex * DAYS_IN_WEEK + dayIndex);
240 })}
241 </G>);
242 };
243 ContributionGraph.prototype.renderAllWeeks = function () {
244 var _this = this;
245 return _.range(this.getWeekCount()).map(function (weekIndex) {
246 return _this.renderWeek(weekIndex);
247 });
248 };
249 ContributionGraph.prototype.renderMonthLabels = function () {
250 var _this = this;
251 if (!this.props.showMonthLabels) {
252 return null;
253 }
254 var weekRange = _.range(this.getWeekCount() - 1); // don't render for last week, because label will be cut off
255 return weekRange.map(function (weekIndex) {
256 var endOfWeek = shiftDate(_this.getStartDateWithEmptyDays(), (weekIndex + 1) * DAYS_IN_WEEK);
257 var _a = _this.getMonthLabelCoordinates(weekIndex), x = _a[0], y = _a[1];
258 return endOfWeek.getDate() >= 1 && endOfWeek.getDate() <= DAYS_IN_WEEK ? (<Text key={weekIndex} x={x + paddingLeft} y={y + 8} {..._this.getPropsForLabels()}>
259 {_this.props.getMonthLabel
260 ? _this.props.getMonthLabel(endOfWeek.getMonth())
261 : MONTH_LABELS[endOfWeek.getMonth()]}
262 </Text>) : null;
263 });
264 };
265 ContributionGraph.prototype.render = function () {
266 var style = this.props.style;
267 var _a = style.borderRadius, borderRadius = _a === void 0 ? 0 : _a;
268 if (!borderRadius && this.props.chartConfig.style) {
269 var stupidXo = this.props.chartConfig.style.borderRadius;
270 borderRadius = stupidXo;
271 }
272 return (<View style={style}>
273 <Svg height={this.props.height} width={this.props.width}>
274 {this.renderDefs(__assign({ width: this.props.width, height: this.props.height }, this.props.chartConfig))}
275 <Rect width="100%" height={this.props.height} rx={borderRadius} ry={borderRadius} fill="url(#backgroundGradient)"/>
276 <G>{this.renderMonthLabels()}</G>
277 <G>{this.renderAllWeeks()}</G>
278 </Svg>
279 </View>);
280 };
281 ContributionGraph.defaultProps = {
282 numDays: 200,
283 endDate: new Date(),
284 gutterSize: 1,
285 squareSize: SQUARE_SIZE,
286 horizontal: true,
287 showMonthLabels: true,
288 showOutOfRangeDays: false,
289 accessor: "count",
290 classForValue: function (value) { return (value ? "black" : "#8cc665"); },
291 style: {}
292 };
293 return ContributionGraph;
294}(AbstractChart));
295export default ContributionGraph;
296//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29udHJpYnV0aW9uR3JhcGguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29udHJpYnV0aW9uLWdyYXBoL0NvbnRyaWJ1dGlvbkdyYXBoLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLENBQUMsTUFBTSxRQUFRLENBQUM7QUFDdkIsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQzFCLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDcEMsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQWEsR0FBRyxFQUFFLElBQUksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRWpFLE9BQU8sYUFBYSxNQUFNLGtCQUFrQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDcEMsT0FBTyxFQUNMLGFBQWEsRUFDYix1QkFBdUIsRUFDdkIsU0FBUyxFQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFDTCxZQUFZLEVBQ1osdUJBQXVCLEVBQ3ZCLFlBQVksRUFDYixNQUFNLGFBQWEsQ0FBQztBQUdyQixJQUFNLFdBQVcsR0FBRyxFQUFFLENBQUM7QUFDdkIsSUFBTSx1QkFBdUIsR0FBRyxDQUFDLENBQUM7QUFDbEMsSUFBTSxXQUFXLEdBQUcsRUFBRSxDQUFDO0FBYXZCO0lBQWdDLHFDQUcvQjtJQUNDLDJCQUFZLEtBQTZCO1FBQXpDLFlBQ0Usa0JBQU0sS0FBSyxDQUFDLFNBU2I7UUFQSyxJQUFBLEtBQXFDLEtBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFuRSxRQUFRLGNBQUEsRUFBRSxRQUFRLGNBQUEsRUFBRSxVQUFVLGdCQUFxQyxDQUFDO1FBRTFFLEtBQUksQ0FBQyxLQUFLLEdBQUc7WUFDWCxRQUFRLFVBQUE7WUFDUixRQUFRLFVBQUE7WUFDUixVQUFVLFlBQUE7U0FDWCxDQUFD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QUssQ0FBQyxNQUFNLENBQUMsQ0FDMUIsRUFBRSxDQUFDLENBQUMsWUFBWSxDQUFDLENBQ2pCLEVBQUUsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUNqQixJQUFJLENBQUMsMEJBQTBCLEVBRWpDO1VBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FDaEM7VUFBQSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FDL0I7UUFBQSxFQUFFLEdBQUcsQ0FDUDtNQUFBLEVBQUUsSUFBSSxDQUFDLENBQ1IsQ0FBQztJQUNKLENBQUM7SUEzQ2EsOEJBQVksR0FBRztRQUMzQixPQUFPLEVBQUUsR0FBRztRQUNaLE9BQU8sRUFBRSxJQUFJLElBQUksRUFBRTtRQUNuQixVQUFVLEVBQUUsQ0FBQztRQUNiLFVBQVUsRUFBRSxXQUFXO1FBQ3ZCLFVBQVUsRUFBRSxJQUFJO1FBQ2hCLGVBQWUsRUFBRSxJQUFJO1FBQ3JCLGtCQUFrQixFQUFFLEtBQUs7UUFDekIsUUFBUSxFQUFFLE9BQU87UUFDakIsYUFBYSxFQUFFLFVBQUEsS0FBSyxJQUFJLE9BQUEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEVBQTdCLENBQTZCO1FBQ3JELEtBQUssRUFBRSxFQUFFO0tBQ1YsQ0FBQztJQWlDSix3QkFBQztDQUFBLEFBM1dELENBQWdDLGFBQWEsR0EyVzVDO0FBRUQsZUFBZSxpQkFBaUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBfIGZyb20gXCJsb2Rhc2hcIjtcbmltcG9ydCBSZWFjdCBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IFZpZXcgfSBmcm9tIFwicmVhY3QtbmF0aXZlXCI7XG5pbXBvcnQgeyBHLCBSZWN0LCBSZWN0UHJvcHMsIFN2ZywgVGV4dCB9IGZyb20gXCJyZWFjdC1uYXRpdmUtc3ZnXCI7XG5cbmltcG9ydCBBYnN0cmFjdENoYXJ0IGZyb20gXCIuLi9BYnN0cmFjdENoYXJ0XCI7XG5pbXBvcnQgeyBtYXBWYWx1ZSB9IGZyb20gXCIuLi9VdGlsc1wiO1xuaW1wb3J0IHtcbiAgY29udmVydFRvRGF0ZSxcbiAgZ2V0QmVnaW5uaW5nVGltZUZvckRhdGUsXG4gIHNoaWZ0RGF0ZVxufSBmcm9tIFwiLi9EYXRlSGVscGVyc1wiO1xuaW1wb3J0IHtcbiAgREFZU19JTl9XRUVLLFxuICBNSUxMSVNFQ09ORFNfSU5fT05FX0RBWSxcbiAgTU9OVEhfTEFCRUxTXG59IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQ29udHJpYnV0aW9uR3JhcGhQcm9wcywgQ29udHJpYnV0aW9uR3JhcGhTdGF0ZSB9IGZyb20gXCIuXCI7XG5cbmNvbnN0IFNRVUFSRV9TSVpFID0gMjA7XG5jb25zdCBNT05USF9MQUJFTF9HVVRURVJfU0laRSA9IDg7XG5jb25zdCBwYWRkaW5nTGVmdCA9IDMyO1xuXG5leHBvcnQgdHlwZSBDb250cmlidXRpb25DaGFydFZhbHVlID0ge1xuICB2YWx1ZTogbnVtYmVyO1xuICB0aXRsZTogc3RyaW5nO1xuICB0b29sdGlwRGF0YUF0dHJzOiBUb29sdGlwRGF0YUF0dHJzO1xuICBkYXRlOiBEYXRlO1xufTtcblxuZXhwb3J0IHR5cGUgVG9vbHRpcERhdGFBdHRycyA9IChcbiAgdmFsdWU6IENvbnRyaWJ1dGlvbkNoYXJ0VmFsdWVcbikgPT4gUGFydGlhbDxSZWN0UHJvcHM+IHwgUGFydGlhbDxSZWN0UHJvcHM+O1xuXG5jbGFzcyBDb250cmlidXRpb25HcmFwaCBleHRlbmRzIEFic3RyYWN0Q2hhcnQ8XG4gIENvbnRyaWJ1dGlvbkdyYXBoUHJvcHMsXG4gIENvbnRyaWJ1dGlvbkdyYXBoU3RhdGVcbj4ge1xuICBjb25zdHJ1Y3Rvcihwcm9wczogQ29udHJpYnV0aW9uR3JhcGhQcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcblxuICAgIGxldCB7IG1heFZhbHVlLCBtaW5WYWx1ZSwgdmFsdWVDYWNoZSB9ID0gdGhpcy5nZXRWYWx1ZUNhY2hlKHByb3BzLnZhbHVlcyk7XG5cbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgbWF4VmFsdWUsXG4gICAgICBtaW5WYWx1ZSxcbiAgICAgIHZhbHVlQ2FjaGVcbiAgICB9O1xuICB9XG5cbiAgVU5TQUZFX2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzOiBDb250cmlidXRpb25HcmFwaFByb3BzKSB7XG4gICAgbGV0IHsgbWF4VmFsdWUsIG1pblZhbHVlLCB2YWx1ZUNhY2hlIH0gPSB0aGlzLmdldFZhbHVlQ2FjaGUoXG4gICAgICBuZXh0UHJvcHMudmFsdWVzXG4gICAgKTtcblxuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgbWF4VmFsdWUsXG4gICAgICBtaW5WYWx1ZSxcbiAgICAgIHZhbHVlQ2FjaGVcbiAgICB9KTtcbiAgfVxuXG4gIGdldFNxdWFyZVNpemVXaXRoR3V0dGVyKCkge1xuICAgIHJldHVybiAodGhpcy5wcm9wcy5zcXVhcmVTaXplIHx8IFNRVUFSRV9TSVpFKSArIHRoaXMucHJvcHMuZ3V0dGVyU2l6ZTtcbiAgfVxuXG4gIGdldE1vbnRoTGFiZWxTaXplKCkge1xuICAgIGxldCB7IHNxdWFyZVNpemUgPSBTUVVBUkVfU0laRSB9ID0gdGhpcy5wcm9wcztcbiAgICBpZiAoIXRoaXMucHJvcHMuc2hvd01vbnRoTGFiZWxzKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgaWYgKHRoaXMucHJvcHMuaG9yaXpvbnRhbCkge1xuICAgICAgcmV0dXJuIHNxdWFyZVNpemUgKyBNT05USF9MQUJFTF9HVVRURVJfU0laRTtcbiAgICB9XG4gICAgcmV0dXJuIDIgKiAoc3F1YXJlU2l6ZSArIE1PTlRIX0xBQkVMX0dVVFRFUl9TSVpFKTtcbiAgfVxuXG4gIGdldFN0YXJ0RGF0ZSgpIHtcbiAgICByZXR1cm4gc2hpZnREYXRlKHRoaXMuZ2V0RW5kRGF0ZSgpLCAtdGhpcy5wcm9wcy5udW1EYXlzICsgMSk7IC8vICsxIGJlY2F1c2UgZW5kRGF0ZSBpcyBpbmNsdXNpdmVcbiAgfVxuXG4gIGdldEVuZERhdGUoKSB7XG4gICAgcmV0dXJuIGdldEJlZ2lubmluZ1RpbWVGb3JEYXRlKGNvbnZlcnRUb0RhdGUodGhpcy5wcm9wcy5lbmREYXRlKSk7XG4gIH1cblxuICBnZXRTdGFydERhdGVXaXRoRW1wdHlEYXlzKCkge1xuICAgIHJldHVybiBzaGlmdERhdGUodGhpcy5nZXRTdGFydERhdGUoKSwgLXRoaXMuZ2V0TnVtRW1wdHlEYXlzQXRTdGFydCgpKTtcbiAgfVxuXG4gIGdldE51bUVtcHR5RGF5c0F0U3RhcnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0U3RhcnREYXRlKCkuZ2V0RGF5KCk7XG4gIH1cblxuICBnZXROdW1FbXB0eURheXNBdEVuZCgpIHtcbiAgICByZXR1cm4gREFZU19JTl9XRUVLIC0gMSAtIHRoaXMuZ2V0RW5kRGF0ZSgpLmdldERheSgpO1xuICB9XG5cbiAgZ2V0V2Vla0NvdW50KCkge1xuICAgIGNvbnN0IG51bURheXNSb3VuZGVkVG9XZWVrID1cbiAgICAgIHRoaXMucHJvcHMubnVtRGF5cyArXG4gICAgICB0aGlzLmdldE51bUVtcHR5RGF5c0F0U3RhcnQoKSArXG4gICAgICB0aGlzLmdldE51bUVtcHR5RGF5c0F0RW5kKCk7XG4gICAgcmV0dXJuIE1hdGguY2VpbChudW1EYXlzUm91bmRlZFRvV2VlayAvIERBWVNfSU5fV0VFSyk7XG4gIH1cblxuICBnZXRXZWVrV2lkdGgoKSB7XG4gICAgcmV0dXJuIERBWVNfSU5fV0VFSyAqIHRoaXMuZ2V0U3F1YXJlU2l6ZVdpdGhHdXR0ZXIoKTtcbiAgfVxuXG4gIGdldFdpZHRoKCkge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmdldFdlZWtDb3VudCgpICogdGhpcy5nZXRTcXVhcmVTaXplV2l0aEd1dHRlcigpIC1cbiAgICAgIHRoaXMucHJvcHMuZ3V0dGVyU2l6ZVxuICAgICk7XG4gIH1cblxuICBnZXRIZWlnaHQoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuZ2V0V2Vla1dpZHRoKCkgKyAodGhpcy5nZXRNb250aExhYmVsU2l6ZSgpIC0gdGhpcy5wcm9wcy5ndXR0ZXJTaXplKVxuICAgICk7XG4gIH1cblxuICBnZXRWYWx1ZUNhY2hlKHZhbHVlczogQ29udHJpYnV0aW9uQ2hhcnRWYWx1ZVtdKSB7XG4gICAgbGV0IG1pblZhbHVlID0gSW5maW5pdHksXG4gICAgICBtYXhWYWx1ZSA9IC1JbmZpbml0eTtcblxuICAgIHJldHVybiB7XG4gICAgICB2YWx1ZUNhY2hlOiB2YWx1ZXMucmVkdWNlKChtZW1vLCB2YWx1ZSkgPT4ge1xuICAgICAgICBjb25zdCBkYXRlID0gY29udmVydFRvRGF0ZSh2YWx1ZS5kYXRlKTtcblxuICAgICAgICBjb25zdCBpbmRleCA9IE1hdGguZmxvb3IoXG4gICAgICAgICAgKGRhdGUudmFsdWVPZigpIC0gdGhpcy5nZXRTdGFydERhdGVXaXRoRW1wdHlEYXlzKCkudmFsdWVPZigpKSAvXG4gICAgICAgICAgICBNSUxMSVNFQ09ORFNfSU5fT05FX0RBWVxuICAgICAgICApO1xuXG4gICAgICAgIG1pblZhbHVlID0gTWF0aC5taW4odmFsdWVbdGhpcy5wcm9wcy5hY2Nlc3Nvcl0sIG1pblZhbHVlKTtcbiAgICAgICAgbWF4VmFsdWUgPSBNYXRoLm1heCh2YWx1ZVt0aGlzLnByb3BzLmFjY2Vzc29yXSwgbWF4VmFsdWUpO1xuXG4gICAgICAgIG1lbW9baW5kZXhdID0ge1xuICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgIHRpdGxlOiB0aGlzLnByb3BzLnRpdGxlRm9yVmFsdWVcbiAgICAgICAgICAgID8gdGhpcy5wcm9wcy50aXRsZUZvclZhbHVlKHZhbHVlKVxuICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICAgIHRvb2x0aXBEYXRhQXR0cnM6IHRoaXMuZ2V0VG9vbHRpcERhdGFBdHRyc0ZvclZhbHVlKHZhbHVlKVxuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBtZW1vO1xuICAgICAgfSwge30pLFxuICAgICAgbWluVmFsdWUsXG4gICAgICBtYXhWYWx1ZVxuICAgIH07XG4gIH1cblxuICBnZXRWYWx1ZUZvckluZGV4KGluZGV4OiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5zdGF0ZS52YWx1ZUNhY2hlW2luZGV4XSkge1xuICAgICAgcmV0dXJuIHRoaXMuc3RhdGUudmFsdWVDYWNoZVtpbmRleF0udmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZ2V0Q2xhc3NOYW1lRm9ySW5kZXgoaW5kZXg6IG51bWJlcikge1xuICAgIGlmICh0aGlzLnN0YXRlLnZhbHVlQ2FjaGVbaW5kZXhdKSB7XG4gICAgICBpZiAodGhpcy5zdGF0ZS52YWx1ZUNhY2hlW2luZGV4XS52YWx1ZSkge1xuICAgICAgICBjb25zdCBjb3VudCA9IHRoaXMuc3RhdGUudmFsdWVDYWNoZVtpbmRleF0udmFsdWVbdGhpcy5wcm9wcy5hY2Nlc3Nvcl07XG5cbiAgICAgICAgaWYgKGNvdW50KSB7XG4gICAgICAgICAgY29uc3Qgb3BhY2l0eSA9IG1hcFZhbHVlKFxuICAgICAgICAgICAgY291bnQsXG4gICAgICAgICAgICB0aGlzLnN0YXRlLm1pblZhbHVlLFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5tYXhWYWx1ZSxcbiAgICAgICAgICAgIDAuMTUgKyAwLjA1LCAvLyArIDAuMDUgdG8gbWFrZSBzbWFsbGVyIHZhbHVlcyBhIGJpdCBtb3JlIHZpc2libGVcbiAgICAgICAgICAgIDFcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgcmV0dXJuIHRoaXMucHJvcHMuY2hhcnRDb25maWcuY29sb3Iob3BhY2l0eSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5wcm9wcy5jaGFydENvbmZpZy5jb2xvcigwLjE1KTtcbiAgfVxuXG4gIGdldFRpdGxlRm9ySW5kZXgoaW5kZXg6IG51bWJlcikge1xuICAgIGlmICh0aGlzLnN0YXRlLnZhbHVlQ2FjaGVbaW5kZXhdKSB7XG4gICAgICByZXR1cm4gdGhpcy5zdGF0ZS52YWx1ZUNhY2hlW2luZGV4XS50aXRsZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5wcm9wcy50aXRsZUZvclZhbHVlID8gdGhpcy5wcm9wcy50aXRsZUZvclZhbHVlKG51bGwpIDogbnVsbDtcbiAgfVxuXG4gIGdldFRvb2x0aXBEYXRhQXR0cnNGb3JJbmRleChpbmRleDogbnVtYmVyKSB7XG4gICAgaWYgKHRoaXMuc3RhdGUudmFsdWVDYWNoZVtpbmRleF0pIHtcbiAgICAgIHJldHVybiB0aGlzLnN0YXRlLnZhbHVlQ2FjaGVbaW5kZXhdLnRvb2x0aXBEYXRhQXR0cnM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZ2V0VG9vbHRpcERhdGFBdHRyc0ZvclZhbHVlKHtcbiAgICAgIGRhdGU6IG51bGwsXG4gICAgICBbdGhpcy5wcm9wcy5hY2Nlc3Nvcl06IG51bGxcbiAgICB9IGFzIENvbnRyaWJ1dGlvbkNoYXJ0VmFsdWUpO1xuICB9XG5cbiAgZ2V0VG9vbHRpcERhdGFBdHRyc0ZvclZhbHVlKHZhbHVlOiBDb250cmlidXRpb25DaGFydFZhbHVlKSB7XG4gICAgY29uc3QgeyB0b29sdGlwRGF0YUF0dHJzIH0gPSB0aGlzLnByb3BzO1xuXG4gICAgaWYgKHR5cGVvZiB0b29sdGlwRGF0YUF0dHJzID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHJldHVybiB0b29sdGlwRGF0YUF0dHJzKHZhbHVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdG9vbHRpcERhdGFBdHRycztcbiAgfVxuXG4gIGdldFRyYW5zZm9ybUZvcldlZWsod2Vla0luZGV4OiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5wcm9wcy5ob3Jpem9udGFsKSB7XG4gICAgICByZXR1cm4gW3dlZWtJbmRleCAqIHRoaXMuZ2V0U3F1YXJlU2l6ZVdpdGhHdXR0ZXIoKSwgNTBdO1xuICAgIH1cbiAgICByZXR1cm4gWzEwLCB3ZWVrSW5kZXggKiB0aGlzLmdldFNxdWFyZVNpemVXaXRoR3V0dGVyKCldO1xuICB9XG5cbiAgZ2V0VHJhbnNmb3JtRm9yTW9udGhMYWJlbHMoKSB7XG4gICAgaWYgKHRoaXMucHJvcHMuaG9yaXpvbnRhbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBgJHt0aGlzLmdldFdlZWtXaWR0aCgpICsgTU9OVEhfTEFCRUxfR1VUVEVSX1NJWkV9LCAwYDtcbiAgfVxuXG4gIGdldFRyYW5zZm9ybUZvckFsbFdlZWtzKCkge1xuICAgIGlmICh0aGlzLnByb3BzLmhvcml6b250YWwpIHtcbiAgICAgIHJldHVybiBgMCwgJHt0aGlzLmdldE1vbnRoTGFiZWxTaXplKCkgLSAxMDB9YDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBnZXRWaWV3Qm94KCkge1xuICAgIGlmICh0aGlzLnByb3BzLmhvcml6b250YWwpIHtcbiAgICAgIHJldHVybiBgJHt0aGlzLmdldFdpZHRoKCl9ICR7dGhpcy5nZXRIZWlnaHQoKX1gO1xuICAgIH1cbiAgICByZXR1cm4gYCR7dGhpcy5nZXRIZWlnaHQoKX0gJHt0aGlzLmdldFdpZHRoKCl9YDtcbiAgfVxuXG4gIGdldFNxdWFyZUNvb3JkaW5hdGVzKGRheUluZGV4OiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5wcm9wcy5ob3Jpem9udGFsKSB7XG4gICAgICByZXR1cm4gWzAsIGRheUluZGV4ICogdGhpcy5nZXRTcXVhcmVTaXplV2l0aEd1dHRlcigpXTtcbiAgICB9XG4gICAgcmV0dXJuIFtkYXlJbmRleCAqIHRoaXMuZ2V0U3F1YXJlU2l6ZVdpdGhHdXR0ZXIoKSwgMF07XG4gIH1cblxuICBnZXRNb250aExhYmVsQ29vcmRpbmF0ZXMod2Vla0luZGV4OiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5wcm9wcy5ob3Jpem9udGFsKSB7XG4gICAgICByZXR1cm4gW1xuICAgICAgICB3ZWVrSW5kZXggKiB0aGlzLmdldFNxdWFyZVNpemVXaXRoR3V0dGVyKCksXG4gICAgICAgIHRoaXMuZ2V0TW9udGhMYWJlbFNpemUoKSAtIE1PTlRIX0xBQkVMX0dVVFRFUl9TSVpFXG4gICAgICBdO1xuICAgIH1cbiAgICBjb25zdCB2ZXJ0aWNhbE9mZnNldCA9IC0yO1xuICAgIHJldHVybiBbXG4gICAgICAwLFxuICAgICAgKHdlZWtJbmRleCArIDEpICogdGhpcy5nZXRTcXVhcmVTaXplV2l0aEd1dHRlcigpICsgdmVydGljYWxPZmZzZXRcbiAgICBdO1xuICB9XG5cbiAgcmVuZGVyU3F1YXJlKGRheUluZGV4OiBudW1iZXIsIGluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBpbmRleE91dE9mUmFuZ2UgPVxuICAgICAgaW5kZXggPCB0aGlzLmdldE51bUVtcHR5RGF5c0F0U3RhcnQoKSB8fFxuICAgICAgaW5kZXggPj0gdGhpcy5nZXROdW1FbXB0eURheXNBdFN0YXJ0KCkgKyB0aGlzLnByb3BzLm51bURheXM7XG5cbiAgICBpZiAoaW5kZXhPdXRPZlJhbmdlICYmICF0aGlzLnByb3BzLnNob3dPdXRPZlJhbmdlRGF5cykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgW3gsIHldID0gdGhpcy5nZXRTcXVhcmVDb29yZGluYXRlcyhkYXlJbmRleCk7XG4gICAgY29uc3QgeyBzcXVhcmVTaXplID0gU1FVQVJFX1NJWkUgfSA9IHRoaXMucHJvcHM7XG5cbiAgICByZXR1cm4gKFxuICAgICAgPFJlY3RcbiAgICAgICAga2V5PXtpbmRleH1cbiAgICAgICAgd2lkdGg9e3NxdWFyZVNpemV9XG4gICAgICAgIGhlaWdodD17c3F1YXJlU2l6ZX1cbiAgICAgICAgeD17eCArIHBhZGRpbmdMZWZ0fVxuICAgICAgICB5PXt5fVxuICAgICAgICB0aXRsZT17dGhpcy5nZXRUaXRsZUZvckluZGV4KGluZGV4KX1cbiAgICAgICAgZmlsbD17dGhpcy5nZXRDbGFzc05hbWVGb3JJbmRleChpbmRleCl9XG4gICAgICAgIG9uUHJlc3M9eygpID0+IHtcbiAgICAgICAgICB0aGlzLmhhbmRsZURheVByZXNzKGluZGV4KTtcbiAgICAgICAgfX1cbiAgICAgICAgey4uLnRoaXMuZ2V0VG9vbHRpcERhdGFBdHRyc0ZvckluZGV4KGluZGV4KX1cbiAgICAgIC8+XG4gICAgKTtcbiAgfVxuXG4gIGhhbmRsZURheVByZXNzKGluZGV4OiBudW1iZXIpIHtcbiAgICBpZiAoIXRoaXMucHJvcHMub25EYXlQcmVzcykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMucHJvcHMub25EYXlQcmVzcyhcbiAgICAgIHRoaXMuc3RhdGUudmFsdWVDYWNoZVtpbmRleF0gJiYgdGhpcy5zdGF0ZS52YWx1ZUNhY2hlW2luZGV4XS52YWx1ZVxuICAgICAgICA/IHRoaXMuc3RhdGUudmFsdWVDYWNoZVtpbmRleF0udmFsdWVcbiAgICAgICAgOiB7XG4gICAgICAgICAgICBbdGhpcy5wcm9wcy5hY2Nlc3Nvcl06IDAsXG4gICAgICAgICAgICBkYXRlOiBuZXcgRGF0ZShcbiAgICAgICAgICAgICAgdGhpcy5nZXRTdGFydERhdGUoKS52YWx1ZU9mKCkgKyBpbmRleCAqIE1JTExJU0VDT05EU19JTl9PTkVfREFZXG4gICAgICAgICAgICApXG4gICAgICAgICAgfVxuICAgICk7XG4gIH1cblxuICByZW5kZXJXZWVrKHdlZWtJbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3QgW3gsIHldID0gdGhpcy5nZXRUcmFuc2Zvcm1Gb3JXZWVrKHdlZWtJbmRleCk7XG4gICAgcmV0dXJuIChcbiAgICAgIDxHIGtleT17d2Vla0luZGV4fSB4PXt4fSB5PXt5fT5cbiAgICAgICAge18ucmFuZ2UoREFZU19JTl9XRUVLKS5tYXAoZGF5SW5kZXggPT5cbiAgICAgICAgICB0aGlzLnJlbmRlclNxdWFyZShkYXlJbmRleCwgd2Vla0luZGV4ICogREFZU19JTl9XRUVLICsgZGF5SW5kZXgpXG4gICAgICAgICl9XG4gICAgICA8L0c+XG4gICAgKTtcbiAgfVxuXG4gIHJlbmRlckFsbFdlZWtzKCkge1xuICAgIHJldHVybiBfLnJhbmdlKHRoaXMuZ2V0V2Vla0NvdW50KCkpLm1hcCh3ZWVrSW5kZXggPT5cbiAgICAgIHRoaXMucmVuZGVyV2Vlayh3ZWVrSW5kZXgpXG4gICAgKTtcbiAgfVxuXG4gIHJlbmRlck1vbnRoTGFiZWxzKCkge1xuICAgIGlmICghdGhpcy5wcm9wcy5zaG93TW9udGhMYWJlbHMpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHdlZWtSYW5nZSA9IF8ucmFuZ2UodGhpcy5nZXRXZWVrQ291bnQoKSAtIDEpOyAvLyBkb24ndCByZW5kZXIgZm9yIGxhc3Qgd2VlaywgYmVjYXVzZSBsYWJlbCB3aWxsIGJlIGN1dCBvZmZcblxuICAgIHJldHVybiB3ZWVrUmFuZ2UubWFwKHdlZWtJbmRleCA9PiB7XG4gICAgICBjb25zdCBlbmRPZldlZWsgPSBzaGlmdERhdGUoXG4gICAgICAgIHRoaXMuZ2V0U3RhcnREYXRlV2l0aEVtcHR5RGF5cygpLFxuICAgICAgICAod2Vla0luZGV4ICsgMSkgKiBEQVlTX0lOX1dFRUtcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IFt4LCB5XSA9IHRoaXMuZ2V0TW9udGhMYWJlbENvb3JkaW5hdGVzKHdlZWtJbmRleCk7XG5cbiAgICAgIHJldHVybiBlbmRPZldlZWsuZ2V0RGF0ZSgpID49IDEgJiYgZW5kT2ZXZWVrLmdldERhdGUoKSA8PSBEQVlTX0lOX1dFRUsgPyAoXG4gICAgICAgIDxUZXh0XG4gICAgICAgICAga2V5PXt3ZWVrSW5kZXh9XG4gICAgICAgICAgeD17eCArIHBhZGRpbmdMZWZ0fVxuICAgICAgICAgIHk9e3kgKyA4fVxuICAgICAgICAgIHsuLi50aGlzLmdldFByb3BzRm9yTGFiZWxzKCl9XG4gICAgICAgID5cbiAgICAgICAgICB7dGhpcy5wcm9wcy5nZXRNb250aExhYmVsXG4gICAgICAgICAgICA/IHRoaXMucHJvcHMuZ2V0TW9udGhMYWJlbChlbmRPZldlZWsuZ2V0TW9udGgoKSlcbiAgICAgICAgICAgIDogTU9OVEhfTEFCRUxTW2VuZE9mV2Vlay5nZXRNb250aCgpXX1cbiAgICAgICAgPC9UZXh0PlxuICAgICAgKSA6IG51bGw7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGRlZmF1bHRQcm9wcyA9IHtcbiAgICBudW1EYXlzOiAyMDAsXG4gICAgZW5kRGF0ZTogbmV3IERhdGUoKSxcbiAgICBndXR0ZXJTaXplOiAxLFxuICAgIHNxdWFyZVNpemU6IFNRVUFSRV9TSVpFLFxuICAgIGhvcml6b250YWw6IHRydWUsXG4gICAgc2hvd01vbnRoTGFiZWxzOiB0cnVlLFxuICAgIHNob3dPdXRPZlJhbmdlRGF5czogZmFsc2UsXG4gICAgYWNjZXNzb3I6IFwiY291bnRcIixcbiAgICBjbGFzc0ZvclZhbHVlOiB2YWx1ZSA9PiAodmFsdWUgPyBcImJsYWNrXCIgOiBcIiM4Y2M2NjVcIiksXG4gICAgc3R5bGU6IHt9XG4gIH07XG5cbiAgcmVuZGVyKCkge1xuICAgIGNvbnN0IHsgc3R5bGUgfSA9IHRoaXMucHJvcHM7XG5cbiAgICBsZXQgeyBib3JkZXJSYWRpdXMgPSAwIH0gPSBzdHlsZTtcblxuICAgIGlmICghYm9yZGVyUmFkaXVzICYmIHRoaXMucHJvcHMuY2hhcnRDb25maWcuc3R5bGUpIHtcbiAgICAgIGNvbnN0IHN0dXBpZFhvID0gdGhpcy5wcm9wcy5jaGFydENvbmZpZy5zdHlsZS5ib3JkZXJSYWRpdXM7XG4gICAgICBib3JkZXJSYWRpdXMgPSBzdHVwaWRYbztcbiAgICB9XG5cbiAgICByZXR1cm4gKFxuICAgICAgPFZpZXcgc3R5bGU9e3N0eWxlfT5cbiAgICAgICAgPFN2ZyBoZWlnaHQ9e3RoaXMucHJvcHMuaGVpZ2h0fSB3aWR0aD17dGhpcy5wcm9wcy53aWR0aH0+XG4gICAgICAgICAge3RoaXMucmVuZGVyRGVmcyh7XG4gICAgICAgICAgICB3aWR0aDogdGhpcy5wcm9wcy53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogdGhpcy5wcm9wcy5oZWlnaHQsXG4gICAgICAgICAgICAuLi50aGlzLnByb3BzLmNoYXJ0Q29uZmlnXG4gICAgICAgICAgfSl9XG4gICAgICAgICAgPFJlY3RcbiAgICAgICAgICAgIHdpZHRoPVwiMTAwJVwiXG4gICAgICAgICAgICBoZWlnaHQ9e3RoaXMucHJvcHMuaGVpZ2h0fVxuICAgICAgICAgICAgcng9e2JvcmRlclJhZGl1c31cbiAgICAgICAgICAgIHJ5PXtib3JkZXJSYWRpdXN9XG4gICAgICAgICAgICBmaWxsPVwidXJsKCNiYWNrZ3JvdW5kR3JhZGllbnQpXCJcbiAgICAgICAgICAvPlxuICAgICAgICAgIDxHPnt0aGlzLnJlbmRlck1vbnRoTGFiZWxzKCl9PC9HPlxuICAgICAgICAgIDxHPnt0aGlzLnJlbmRlckFsbFdlZWtzKCl9PC9HPlxuICAgICAgICA8L1N2Zz5cbiAgICAgIDwvVmlldz5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IENvbnRyaWJ1dGlvbkdyYXBoO1xuIl19
\No newline at end of file