@future-grid/fgp-graph
Version:
fgp-graph is a chart lib based on Dygraphs
284 lines (205 loc) • 35.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _DygraphInteraction = _interopRequireDefault(require("./DygraphInteraction"));
var _utils = _interopRequireDefault(require("./utils"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var RangeHandles = function RangeHandles() {
var _this = this;
_classCallCheck(this, RangeHandles);
_defineProperty(this, "g", void 0);
_defineProperty(this, "isMobileDevice", /mobile|android/gi.test(navigator.appVersion));
_defineProperty(this, "graphDiv", void 0);
_defineProperty(this, "singleZoomHandle", void 0);
_defineProperty(this, "rangebarCanvasRect", void 0);
_defineProperty(this, "rangeSize", 0);
_defineProperty(this, "toString", function () {
return "Fgp Range-bar-Handles Plugin";
});
_defineProperty(this, "activate", function (dygraph) {
var _this$g;
_this.g = dygraph;
_this.graphDiv = _this.g.graphDiv;
if ((_this$g = _this.g) === null || _this$g === void 0 ? void 0 : _this$g.getOption('showRangeSelector')) {
_this.createSingleZoomHandle();
_this.initPanInteraction();
}
return {
didDrawChart: _this.placeHandle
};
});
_defineProperty(this, "destory", function () {});
_defineProperty(this, "initPanInteraction", function () {
var isPanning = false;
var clientXLast = 0;
var topElem = document;
var dynamic = !_this.isMobileDevice;
var initGap = -1;
_this.g.attrs_['interactionModel'] = _DygraphInteraction["default"].dragIsPanInteractionModel;
_this.g.attrs_['panEdgeFraction'] = 0.0001;
var toXDataWindow = function toXDataWindow(zoomHandleStatus) {
var _this$g2;
var xDataLimits = (_this$g2 = _this.g) === null || _this$g2 === void 0 ? void 0 : _this$g2.xAxisExtremes();
var xDataMin = 0;
var xDataMax = 0;
if (xDataLimits && _this.rangebarCanvasRect) {
var fact = (xDataLimits[1] - xDataLimits[0]) / _this.rangebarCanvasRect.w;
xDataMin = xDataLimits[0] + (zoomHandleStatus.leftHandlePos - _this.rangebarCanvasRect.x) * fact;
xDataMax = xDataLimits[0] + (zoomHandleStatus.rightHandlePos - _this.rangebarCanvasRect.x) * fact;
}
console.log("new positiong: ", [xDataMin, xDataMax]);
return [xDataMin, xDataMax];
};
var onPanEnd = function onPanEnd(e) {
if (!isPanning) {
return false;
}
isPanning = false;
_utils["default"].removeEvent(topElem, 'mousemove', onPan);
_utils["default"].removeEvent(topElem, 'mouseup', onPanEnd); // If on a slower device, do pan now.
if (!dynamic) {
doPan();
}
return true;
};
var onPanStart = function onPanStart(e) {
if (!isPanning) {
_utils["default"].cancelEvent(e);
isPanning = true;
clientXLast = e.clientX;
if (e.type === 'mousedown') {
// These events are removed manually.
_utils["default"].addEvent(topElem, 'mousemove', onPan);
_utils["default"].addEvent(topElem, 'mouseup', onPanEnd);
}
return true;
}
return false;
};
var doPan = function doPan() {
//get left and right handles position
var halfHandleWidth = _this.singleZoomHandle.width / 2;
if (initGap > 0) {
var leftHandlePos = parseFloat(_this.singleZoomHandle.style.left) + halfHandleWidth;
var dataWindow = toXDataWindow({
leftHandlePos: leftHandlePos,
rightHandlePos: leftHandlePos + initGap
});
_this.g.dateWindow_ = dataWindow;
_this.g.drawGraph_(false);
}
};
var onPan = function onPan(e) {
var _this$graphDiv;
if (!isPanning) {
return false;
}
_utils["default"].cancelEvent(e);
var handles = (_this$graphDiv = _this.graphDiv) === null || _this$graphDiv === void 0 ? void 0 : _this$graphDiv.getElementsByClassName('dygraph-rangesel-zoomhandle');
var halfHandleWidth = _this.singleZoomHandle.width / 2;
if (handles) {
var leftHandlePos = parseFloat(handles[0].style.left) + halfHandleWidth;
var rightHandlePos = parseFloat(handles[1].style.left) + halfHandleWidth;
initGap = rightHandlePos - leftHandlePos;
}
var delX = e.clientX - clientXLast;
if (Math.abs(delX) < 4) {
return true;
}
clientXLast = e.clientX; // get handle position
var handlePos = parseFloat(_this.singleZoomHandle.style.left) + halfHandleWidth; // move handle
if (_this.rangebarCanvasRect && handlePos + delX <= _this.rangebarCanvasRect.x) {
// move outside left
handlePos = _this.rangebarCanvasRect.x;
} else if (_this.rangebarCanvasRect && handlePos + delX >= _this.rangebarCanvasRect.x + _this.rangebarCanvasRect.w) {
// move outside right
handlePos = _this.rangebarCanvasRect.x + _this.rangebarCanvasRect.w;
} else {
handlePos += delX;
} // update position
_this.singleZoomHandle.style.left = handlePos - halfHandleWidth + 'px';
if (dynamic) {
doPan();
}
return true;
};
var onCanvasHover = function onCanvasHover(e) {
console.log("panning.......");
};
_this.g.addAndTrackEvent(_this.singleZoomHandle, 'mousedown', onPanStart);
});
_defineProperty(this, "createSingleZoomHandle", function () {
var _this$graphDiv2;
var img = new Image();
img.className = 'dygraph-rangesel-zoomhandle-single';
img.style.position = 'absolute';
img.style.zIndex = "12";
img.style.visibility = 'hidden'; // Initially hidden so they don't show up in the wrong place.
img.style.cursor = 'move';
img.width = 9;
img.height = 16;
img.src = 'data:image/png;base64,' + 'iVBORw0KGgoAAAANSUhEUgAAAAkAAAAQCAYAAADESFVDAAAAAXNSR0IArs4c6QAAAAZiS0dEANAA' + 'zwDP4Z7KegAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9sHGw0cMqdt1UwAAAAZdEVYdENv' + 'bW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAaElEQVQoz+3SsRFAQBCF4Z9WJM8KCDVwownl' + '6YXsTmCUsyKGkZzcl7zkz3YLkypgAnreFmDEpHkIwVOMfpdi9CEEN2nGpFdwD03yEqDtOgCaun7s' + 'qSTDH32I1pQA2Pb9sZecAxc5r3IAb21d6878xsAAAAAASUVORK5CYII='; // add to bar
if (_this.isMobileDevice) {
img.width *= 2;
img.height *= 2;
}
_this.singleZoomHandle = img;
(_this$graphDiv2 = _this.graphDiv) === null || _this$graphDiv2 === void 0 ? void 0 : _this$graphDiv2.appendChild(_this.singleZoomHandle);
});
_defineProperty(this, "placeHandle", function () {
var _this$g3;
// when rangebar enabled
if ((_this$g3 = _this.g) === null || _this$g3 === void 0 ? void 0 : _this$g3.getOption('showRangeSelector')) {
var _this$g4, _this$graphDiv3;
var plotArea = _this.g.layout_.getPlotArea();
var xAxisLabelHeight = 0;
if ((_this$g4 = _this.g) === null || _this$g4 === void 0 ? void 0 : _this$g4.getOptionForAxis('drawAxis', 'x')) {
var _this$g5, _this$g6, _this$g7;
xAxisLabelHeight = ((_this$g5 = _this.g) === null || _this$g5 === void 0 ? void 0 : _this$g5.getOption('xAxisHeight')) || ((_this$g6 = _this.g) === null || _this$g6 === void 0 ? void 0 : _this$g6.getOption('axisLabelFontSize')) + 2 * ((_this$g7 = _this.g) === null || _this$g7 === void 0 ? void 0 : _this$g7.getOption('axisTickSize'));
}
if (plotArea) {
var _this$g8;
_this.rangebarCanvasRect = {
x: plotArea.x,
y: plotArea.y + plotArea.h + xAxisLabelHeight + 4,
w: plotArea.w,
h: (_this$g8 = _this.g) === null || _this$g8 === void 0 ? void 0 : _this$g8.getOption('rangeSelectorHeight')
};
} // get handles
var handles = (_this$graphDiv3 = _this.graphDiv) === null || _this$graphDiv3 === void 0 ? void 0 : _this$graphDiv3.getElementsByClassName('dygraph-rangesel-zoomhandle');
if (handles && handles.length > 0 && _this.rangebarCanvasRect && _this.singleZoomHandle) {
//
var leftHandle = handles[0];
var rightHandle = handles[1];
if (leftHandle.style.left != "" && rightHandle.style.left != "") {
var leftHandlePos = parseFloat(leftHandle.style.left);
var rightHandlePos = parseFloat(rightHandle.style.left);
if (rightHandlePos - leftHandlePos < 2) {
var _this$g9, _this$g10;
var halfHandleWidth = _this.singleZoomHandle.width / 2;
_this.rangeSize = parseFloat(rightHandle.style.left) + halfHandleWidth - (parseFloat(leftHandle.style.left) + halfHandleWidth); // put the handle to correct spot.
var xExtremes = (_this$g9 = _this.g) === null || _this$g9 === void 0 ? void 0 : _this$g9.xAxisExtremes();
var xWindowLimits = (_this$g10 = _this.g) === null || _this$g10 === void 0 ? void 0 : _this$g10.xAxisRange();
var xRange = xExtremes[1] - xExtremes[0];
var leftPercent = Math.max(0, (xWindowLimits[0] - xExtremes[0]) / xRange);
var leftCoord = _this.rangebarCanvasRect.x + _this.rangebarCanvasRect.w * leftPercent;
var handleTop = Math.max(_this.rangebarCanvasRect.y, _this.rangebarCanvasRect.y + (_this.rangebarCanvasRect.h - _this.singleZoomHandle.height) / 2);
_this.singleZoomHandle.style.left = leftCoord - halfHandleWidth + 'px';
_this.singleZoomHandle.style.top = handleTop + 'px';
_this.singleZoomHandle.style.visibility = 'visible';
} else {
_this.singleZoomHandle.style.visibility = 'hidden';
}
}
} else if (_this.singleZoomHandle) {
_this.singleZoomHandle.style.visibility = 'hidden';
}
}
});
};
exports["default"] = RangeHandles;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9leHRyYXMvUmFuZ2VIYW5kbGVzLnRzIl0sIm5hbWVzIjpbIlJhbmdlSGFuZGxlcyIsInRlc3QiLCJuYXZpZ2F0b3IiLCJhcHBWZXJzaW9uIiwiZHlncmFwaCIsImciLCJncmFwaERpdiIsImdldE9wdGlvbiIsImNyZWF0ZVNpbmdsZVpvb21IYW5kbGUiLCJpbml0UGFuSW50ZXJhY3Rpb24iLCJkaWREcmF3Q2hhcnQiLCJwbGFjZUhhbmRsZSIsImlzUGFubmluZyIsImNsaWVudFhMYXN0IiwidG9wRWxlbSIsImRvY3VtZW50IiwiZHluYW1pYyIsImlzTW9iaWxlRGV2aWNlIiwiaW5pdEdhcCIsImF0dHJzXyIsIkR5Z3JhcGhJbnRlcmFjdGlvbiIsImRyYWdJc1BhbkludGVyYWN0aW9uTW9kZWwiLCJ0b1hEYXRhV2luZG93Iiwiem9vbUhhbmRsZVN0YXR1cyIsInhEYXRhTGltaXRzIiwieEF4aXNFeHRyZW1lcyIsInhEYXRhTWluIiwieERhdGFNYXgiLCJyYW5nZWJhckNhbnZhc1JlY3QiLCJmYWN0IiwidyIsImxlZnRIYW5kbGVQb3MiLCJ4IiwicmlnaHRIYW5kbGVQb3MiLCJjb25zb2xlIiwibG9nIiwib25QYW5FbmQiLCJlIiwidXRpbHMiLCJyZW1vdmVFdmVudCIsIm9uUGFuIiwiZG9QYW4iLCJvblBhblN0YXJ0IiwiY2FuY2VsRXZlbnQiLCJjbGllbnRYIiwidHlwZSIsImFkZEV2ZW50IiwiaGFsZkhhbmRsZVdpZHRoIiwic2luZ2xlWm9vbUhhbmRsZSIsIndpZHRoIiwicGFyc2VGbG9hdCIsInN0eWxlIiwibGVmdCIsImRhdGFXaW5kb3ciLCJkYXRlV2luZG93XyIsImRyYXdHcmFwaF8iLCJoYW5kbGVzIiwiZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSIsImRlbFgiLCJNYXRoIiwiYWJzIiwiaGFuZGxlUG9zIiwib25DYW52YXNIb3ZlciIsImFkZEFuZFRyYWNrRXZlbnQiLCJpbWciLCJJbWFnZSIsImNsYXNzTmFtZSIsInBvc2l0aW9uIiwiekluZGV4IiwidmlzaWJpbGl0eSIsImN1cnNvciIsImhlaWdodCIsInNyYyIsImFwcGVuZENoaWxkIiwicGxvdEFyZWEiLCJsYXlvdXRfIiwiZ2V0UGxvdEFyZWEiLCJ4QXhpc0xhYmVsSGVpZ2h0IiwiZ2V0T3B0aW9uRm9yQXhpcyIsInkiLCJoIiwibGVuZ3RoIiwibGVmdEhhbmRsZSIsInJpZ2h0SGFuZGxlIiwicmFuZ2VTaXplIiwieEV4dHJlbWVzIiwieFdpbmRvd0xpbWl0cyIsInhBeGlzUmFuZ2UiLCJ4UmFuZ2UiLCJsZWZ0UGVyY2VudCIsIm1heCIsImxlZnRDb29yZCIsImhhbmRsZVRvcCIsInRvcCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQUNBOzs7Ozs7OztJQUdxQkEsWSxHQStCakIsd0JBQWM7QUFBQTs7QUFBQTs7QUFBQTs7QUFBQSwwQ0EzQlcsbUJBQW1CQyxJQUFuQixDQUF3QkMsU0FBUyxDQUFDQyxVQUFsQyxDQTJCWDs7QUFBQTs7QUFBQTs7QUFBQTs7QUFBQSxxQ0FuQmMsQ0FtQmQ7O0FBQUEsb0NBakJILFlBQU07QUFDYixXQUFPLDhCQUFQO0FBQ0gsR0FlYTs7QUFBQSxvQ0FiSCxVQUFDQyxPQUFELEVBQXNCO0FBQUE7O0FBQzdCLElBQUEsS0FBSSxDQUFDQyxDQUFMLEdBQVNELE9BQVQ7QUFDQSxJQUFBLEtBQUksQ0FBQ0UsUUFBTCxHQUFzQixLQUFJLENBQUNELENBQVgsQ0FBY0MsUUFBOUI7O0FBQ0EsbUJBQUksS0FBSSxDQUFDRCxDQUFULDRDQUFJLFFBQVFFLFNBQVIsQ0FBa0IsbUJBQWxCLENBQUosRUFBNEM7QUFDeEMsTUFBQSxLQUFJLENBQUNDLHNCQUFMOztBQUNBLE1BQUEsS0FBSSxDQUFDQyxrQkFBTDtBQUNIOztBQUVELFdBQU87QUFDSEMsTUFBQUEsWUFBWSxFQUFFLEtBQUksQ0FBQ0M7QUFEaEIsS0FBUDtBQUdILEdBRWE7O0FBQUEsbUNBSUosWUFBTSxDQUVmLENBTmE7O0FBQUEsOENBV2UsWUFBTTtBQUMvQixRQUFJQyxTQUFTLEdBQUcs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LFVBQTVCLEdBQXlDLFFBQXpDO0FBQ0g7QUFFSjtBQUNKLE9BM0JELE1BMkJPLElBQUksS0FBSSxDQUFDckIsZ0JBQVQsRUFBMkI7QUFDOUIsUUFBQSxLQUFJLENBQUNBLGdCQUFMLENBQXNCRyxLQUF0QixDQUE0QmtCLFVBQTVCLEdBQXlDLFFBQXpDO0FBQ0g7QUFFSjtBQUdKLEdBbk9hO0FBRWIsQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBEeWdyYXBoIGZyb20gJ2R5Z3JhcGhzJztcbmltcG9ydCBEeWdyYXBoSW50ZXJhY3Rpb24gZnJvbSBcIi4vRHlncmFwaEludGVyYWN0aW9uXCI7XG5pbXBvcnQgdXRpbHMgZnJvbSBcIi4vdXRpbHNcIjtcblxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSYW5nZUhhbmRsZXMge1xuXG4gICAgcHJpdmF0ZSBnPzogRHlncmFwaDtcblxuICAgIHByaXZhdGUgaXNNb2JpbGVEZXZpY2UgPSAvbW9iaWxlfGFuZHJvaWQvZ2kudGVzdChuYXZpZ2F0b3IuYXBwVmVyc2lvbik7XG5cbiAgICBwcml2YXRlIGdyYXBoRGl2PzogSFRNTERpdkVsZW1lbnQ7XG5cbiAgICBwcml2YXRlIHNpbmdsZVpvb21IYW5kbGU/OiBhbnk7XG5cbiAgICBwcml2YXRlIHJhbmdlYmFyQ2FudmFzUmVjdD86IHsgeDogbnVtYmVyLCB5OiBudW1iZXIsIHc6IG51bWJlciwgaDogbnVtYmVyIH07XG5cbiAgICBwcml2YXRlIHJhbmdlU2l6ZTogbnVtYmVyID0gMDtcblxuICAgIHRvU3RyaW5nID0gKCkgPT4ge1xuICAgICAgICByZXR1cm4gXCJGZ3AgUmFuZ2UtYmFyLUhhbmRsZXMgUGx1Z2luXCI7XG4gICAgfTtcblxuICAgIGFjdGl2YXRlID0gKGR5Z3JhcGg6IER5Z3JhcGgpID0+IHtcbiAgICAgICAgdGhpcy5nID0gZHlncmFwaDtcbiAgICAgICAgdGhpcy5ncmFwaERpdiA9ICg8YW55PnRoaXMuZykuZ3JhcGhEaXY7XG4gICAgICAgIGlmICh0aGlzLmc/LmdldE9wdGlvbignc2hvd1JhbmdlU2VsZWN0b3InKSkge1xuICAgICAgICAgICAgdGhpcy5jcmVhdGVTaW5nbGVab29tSGFuZGxlKCk7XG4gICAgICAgICAgICB0aGlzLmluaXRQYW5JbnRlcmFjdGlvbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGRpZERyYXdDaGFydDogdGhpcy5wbGFjZUhhbmRsZVxuICAgICAgICB9O1xuICAgIH07XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcblxuICAgIH1cblxuICAgIGRlc3RvcnkgPSAoKSA9PiB7XG5cbiAgICB9O1xuXG5cbiAgICAvLy0tLS0tLS1wcml2YXRlIG1ldGhvZHMtLS0tLS0tLS8vXG5cbiAgICBwcml2YXRlIGluaXRQYW5JbnRlcmFjdGlvbiA9ICgpID0+IHtcbiAgICAgICAgbGV0IGlzUGFubmluZyA9IGZhbHNlO1xuICAgICAgICBsZXQgY2xpZW50WExhc3QgPSAwO1xuICAgICAgICBsZXQgdG9wRWxlbSA9IGRvY3VtZW50O1xuICAgICAgICBsZXQgZHluYW1pYyA9ICF0aGlzLmlzTW9iaWxlRGV2aWNlO1xuICAgICAgICBsZXQgaW5pdEdhcCA9IC0xO1xuXG5cbiAgICAgICAgKDxhbnk+dGhpcy5nKS5hdHRyc19bJ2ludGVyYWN0aW9uTW9kZWwnXSA9IER5Z3JhcGhJbnRlcmFjdGlvbi5kcmFnSXNQYW5JbnRlcmFjdGlvbk1vZGVsO1xuICAgICAgICAoPGFueT50aGlzLmcpLmF0dHJzX1sncGFuRWRnZUZyYWN0aW9uJ10gPSAwLjAwMDE7XG5cblxuICAgICAgICBsZXQgdG9YRGF0YVdpbmRvdyA9ICh6b29tSGFuZGxlU3RhdHVzOiB7IGxlZnRIYW5kbGVQb3M6IG51bWJlciwgcmlnaHRIYW5kbGVQb3M6IG51bWJlciB9KSA9PiB7XG4gICAgICAgICAgICBsZXQgeERhdGFMaW1pdHMgPSB0aGlzLmc/LnhBeGlzRXh0cmVtZXMoKTtcbiAgICAgICAgICAgIGxldCB4RGF0YU1pbiA9IDA7XG4gICAgICAgICAgICBsZXQgeERhdGFNYXggPSAwO1xuXG4gICAgICAgICAgICBpZiAoeERhdGFMaW1pdHMgJiYgdGhpcy5yYW5nZWJhckNhbnZhc1JlY3QpIHtcbiAgICAgICAgICAgICAgICBsZXQgZmFjdCA9ICh4RGF0YUxpbWl0c1sxXSAtIHhEYXRhTGltaXRzWzBdKSAvIHRoaXMucmFuZ2ViYXJDYW52YXNSZWN0Lnc7XG4gICAgICAgICAgICAgICAgeERhdGFNaW4gPSB4RGF0YUxpbWl0c1swXSArICh6b29tSGFuZGxlU3RhdHVzLmxlZnRIYW5kbGVQb3MgLSB0aGlzLnJhbmdlYmFyQ2FudmFzUmVjdC54KSAqIGZhY3Q7XG4gICAgICAgICAgICAgICAgeERhdGFNYXggPSB4RGF0YUxpbWl0c1swXSArICh6b29tSGFuZGxlU3RhdHVzLnJpZ2h0SGFuZGxlUG9zIC0gdGhpcy5yYW5nZWJhckNhbnZhc1JlY3QueCkgKiBmYWN0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc29sZS5sb2coXCJuZXcgcG9zaXRpb25nOiBcIiwgW3hEYXRhTWluLCB4RGF0YU1heF0pO1xuICAgICAgICAgICAgcmV0dXJuIFt4RGF0YU1pbiwgeERhdGFNYXhdO1xuICAgICAgICB9O1xuXG4gICAgICAgIGxldCBvblBhbkVuZCA9IChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoIWlzUGFubmluZykge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlzUGFubmluZyA9IGZhbHNlO1xuICAgICAgICAgICAgdXRpbHMucmVtb3ZlRXZlbnQodG9wRWxlbSwgJ21vdXNlbW92ZScsIG9uUGFuKTtcbiAgICAgICAgICAgIHV0aWxzLnJlbW92ZUV2ZW50KHRvcEVsZW0sICdtb3VzZXVwJywgb25QYW5FbmQpO1xuICAgICAgICAgICAgLy8gSWYgb24gYSBzbG93ZXIgZGV2aWNlLCBkbyBwYW4gbm93LlxuICAgICAgICAgICAgaWYgKCFkeW5hbWljKSB7XG4gICAgICAgICAgICAgICAgZG9QYW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9O1xuXG5cbiAgICAgICAgbGV0IG9uUGFuU3RhcnQgPSAoZTogTW91c2VFdmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFpc1Bhbm5pbmcpIHtcbiAgICAgICAgICAgICAgICB1dGlscy5jYW5jZWxFdmVudChlKTtcbiAgICAgICAgICAgICAgICBpc1Bhbm5pbmcgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGNsaWVudFhMYXN0ID0gZS5jbGllbnRYO1xuICAgICAgICAgICAgICAgIGlmIChlLnR5cGUgPT09ICdtb3VzZWRvd24nKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZXNlIGV2ZW50cyBhcmUgcmVtb3ZlZCBtYW51YWxseS5cbiAgICAgICAgICAgICAgICAgICAgdXRpbHMuYWRkRXZlbnQodG9wRWxlbSwgJ21vdXNlbW92ZScsIG9uUGFuKTtcbiAgICAgICAgICAgICAgICAgICAgdXRpbHMuYWRkRXZlbnQodG9wRWxlbSwgJ21vdXNldXAnLCBvblBhbkVuZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9O1xuXG5cbiAgICAgICAgbGV0IGRvUGFuID0gKCkgPT4ge1xuXG4gICAgICAgICAgICAvL2dldCBsZWZ0IGFuZCByaWdodCBoYW5kbGVzIHBvc2l0aW9uXG4gICAgICAgICAgICBsZXQgaGFsZkhhbmRsZVdpZHRoID0gdGhpcy5zaW5nbGVab29tSGFuZGxlLndpZHRoIC8gMjtcbiAgICAgICAgICAgIGlmIChpbml0R2FwID4gMCkge1xuICAgICAgICAgICAgICAgIGxldCBsZWZ0SGFuZGxlUG9zID0gcGFyc2VGbG9hdCh0aGlzLnNpbmdsZVpvb21IYW5kbGUuc3R5bGUubGVmdCkgKyBoYWxmSGFuZGxlV2lkdGg7XG5cbiAgICAgICAgICAgICAgICBsZXQgZGF0YVdpbmRvdyA9IHRvWERhdGFXaW5kb3coe1xuICAgICAgICAgICAgICAgICAgICBsZWZ0SGFuZGxlUG9zOiBsZWZ0SGFuZGxlUG9zLFxuICAgICAgICAgICAgICAgICAgICByaWdodEhhbmRsZVBvczogbGVmdEhhbmRsZVBvcyArIGluaXRHYXBcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAoPGFueT50aGlzLmcpLmRhdGVXaW5kb3dfID0gZGF0YVdpbmRvdztcbiAgICAgICAgICAgICAgICAoPGFueT50aGlzLmcpLmRyYXdHcmFwaF8oZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGxldCBvblBhbiA9IChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoIWlzUGFubmluZykge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdXRpbHMuY2FuY2VsRXZlbnQoZSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGhhbmRsZXMgPSB0aGlzLmdyYXBoRGl2Py5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdkeWdyYXBoLXJhbmdlc2VsLXpvb21oYW5kbGUnKTtcbiAgICAgICAgICAgIGxldCBoYWxmSGFuZGxlV2lkdGggPSB0aGlzLnNpbmdsZVpvb21IYW5kbGUud2lkdGggLyAyO1xuXG4gICAgICAgICAgICBpZiAoaGFuZGxlcykge1xuICAgICAgICAgICAgICAgIGxldCBsZWZ0SGFuZGxlUG9zID0gcGFyc2VGbG9hdCgoPEhUTUxJbWFnZUVsZW1lbnQ+aGFuZGxlc1swXSkuc3R5bGUubGVmdCkgKyBoYWxmSGFuZGxlV2lkdGg7XG4gICAgICAgICAgICAgICAgbGV0IHJpZ2h0SGFuZGxlUG9zID0gcGFyc2VGbG9hdCgoPEhUTUxJbWFnZUVsZW1lbnQ+aGFuZGxlc1sxXSkuc3R5bGUubGVmdCkgKyBoYWxmSGFuZGxlV2lkdGg7XG4gICAgICAgICAgICAgICAgaW5pdEdhcCA9IHJpZ2h0SGFuZGxlUG9zIC0gbGVmdEhhbmRsZVBvcztcbiAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICBsZXQgZGVsWCA9IGUuY2xpZW50WCAtIGNsaWVudFhMYXN0O1xuXG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMoZGVsWCkgPCA0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNsaWVudFhMYXN0ID0gZS5jbGllbnRYO1xuXG4gICAgICAgICAgICAvLyBnZXQgaGFuZGxlIHBvc2l0aW9uXG5cbiAgICAgICAgICAgIGxldCBoYW5kbGVQb3MgPSBwYXJzZUZsb2F0KHRoaXMuc2luZ2xlWm9vbUhhbmRsZS5zdHlsZS5sZWZ0KSArIGhhbGZIYW5kbGVXaWR0aDtcblxuICAgICAgICAgICAgLy8gbW92ZSBoYW5kbGVcbiAgICAgICAgICAgIGlmICh0aGlzLnJhbmdlYmFyQ2FudmFzUmVjdCAmJiBoYW5kbGVQb3MgKyBkZWxYIDw9IHRoaXMucmFuZ2ViYXJDYW52YXNSZWN0LngpIHtcbiAgICAgICAgICAgICAgICAvLyBtb3ZlIG91dHNpZGUgbGVmdFxuICAgICAgICAgICAgICAgIGhhbmRsZVBvcyA9IHRoaXMucmFuZ2ViYXJDYW52YXNSZWN0Lng7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMucmFuZ2ViYXJDYW52YXNSZWN0ICYmIGhhbmRsZVBvcyArIGRlbFggPj0gKHRoaXMucmFuZ2ViYXJDYW52YXNSZWN0LnggKyB0aGlzLnJhbmdlYmFyQ2FudmFzUmVjdC53KSkge1xuICAgICAgICAgICAgICAgIC8vIG1vdmUgb3V0c2lkZSByaWdodFxuICAgICAgICAgICAgICAgIGhhbmRsZVBvcyA9IHRoaXMucmFuZ2ViYXJDYW52YXNSZWN0LnggKyB0aGlzLnJhbmdlYmFyQ2FudmFzUmVjdC53O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBoYW5kbGVQb3MgKz0gZGVsWDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdXBkYXRlIHBvc2l0aW9uXG4gICAgICAgICAgICB0aGlzLnNpbmdsZVpvb21IYW5kbGUuc3R5bGUubGVmdCA9IGhhbmRsZVBvcyAtIGhhbGZIYW5kbGVXaWR0aCArICdweCc7XG5cbiAgICAgICAgICAgIGlmIChkeW5hbWljKSB7XG4gICAgICAgICAgICAgICAgZG9QYW4oKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG5cblxuICAgICAgICBsZXQgb25DYW52YXNIb3ZlciA9IChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcInBhbm5pbmcuLi4uLi4uXCIpO1xuXG4gICAgICAgIH07XG5cblxuICAgICAgICAoPGFueT50aGlzLmcpLmFkZEFuZFRyYWNrRXZlbnQodGhpcy5zaW5nbGVab29tSGFuZGxlLCAnbW91c2Vkb3duJywgb25QYW5TdGFydCk7XG4gICAgfTtcblxuXG4gICAgcHJpdmF0ZSBjcmVhdGVTaW5nbGVab29tSGFuZGxlID0gKCkgPT4ge1xuICAgICAgICBsZXQgaW1nID0gbmV3IEltYWdlKCk7XG4gICAgICAgIGltZy5jbGFzc05hbWUgPSAnZHlncmFwaC1yYW5nZXNlbC16b29taGFuZGxlLXNpbmdsZSc7XG4gICAgICAgIGltZy5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgICAgIGltZy5zdHlsZS56SW5kZXggPSBcIjEyXCI7XG4gICAgICAgIGltZy5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7IC8vIEluaXRpYWxseSBoaWRkZW4gc28gdGhleSBkb24ndCBzaG93IHVwIGluIHRoZSB3cm9uZyBwbGFjZS5cbiAgICAgICAgaW1nLnN0eWxlLmN1cnNvciA9ICdtb3ZlJztcbiAgICAgICAgaW1nLndpZHRoID0gOTtcbiAgICAgICAgaW1nLmhlaWdodCA9IDE2O1xuICAgICAgICBpbWcuc3JjID0gJ2RhdGE6aW1hZ2UvcG5nO2Jhc2U2NCwnICtcbiAgICAgICAgICAgICdpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQWtBQUFBUUNBWUFBQURFU0ZWREFBQUFBWE5TUjBJQXJzNGM2UUFBQUFaaVMwZEVBTkFBJyArXG4gICAgICAgICAgICAnendEUDRaN0tlZ0FBQUFsd1NGbHpBQUFPeEFBQURzUUJsU3NPR3dBQUFBZDBTVTFGQjlzSEd3MGNNcWR0MVV3QUFBQVpkRVZZZEVOdicgK1xuICAgICAgICAgICAgJ2JXMWxiblFBUTNKbFlYUmxaQ0IzYVhSb0lFZEpUVkJYZ1E0WEFBQUFhRWxFUVZRb3orM1NzUkZBUUJDRjRaOVdKTThLQ0RWd293bmwnICtcbiAgICAgICAgICAgICc2WVhzVG1DVXN5S0drWnpjbDd6a3ozWUxreXBnQW5yZUZtREVwSGtJd1ZPTWZwZGk5Q0VFTjJuR3BGZHdEMDN5RXFEdE9nQ2F1bjdzJyArXG4gICAgICAgICAgICAncVNUREgzMkkxcFFBMlBiOXNaZWNBeGM1cjNJQWIyMWQ2ODc4eHNBQUFBQUFTVVZPUks1Q1lJST0nO1xuICAgICAgICAvLyBhZGQgdG8gYmFyXG4gICAgICAgIGlmICh0aGlzLmlzTW9iaWxlRGV2aWNlKSB7XG4gICAgICAgICAgICBpbWcud2lkdGggKj0gMjtcbiAgICAgICAgICAgIGltZy5oZWlnaHQgKj0gMjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNpbmdsZVpvb21IYW5kbGUgPSBpbWc7XG4gICAgICAgIHRoaXMuZ3JhcGhEaXY/LmFwcGVuZENoaWxkKHRoaXMuc2luZ2xlWm9vbUhhbmRsZSk7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICogbW92ZSBoYW5kbGUgdG8gY29ycmVjdCBzcG90XG4gICAgICovXG4gICAgcHJpdmF0ZSBwbGFjZUhhbmRsZSA9ICgpID0+IHtcblxuICAgICAgICAvLyB3aGVuIHJhbmdlYmFyIGVuYWJsZWRcbiAgICAgICAgaWYgKHRoaXMuZz8uZ2V0T3B0aW9uKCdzaG93UmFuZ2VTZWxlY3RvcicpKSB7XG4gICAgICAgICAgICBsZXQgcGxvdEFyZWEgPSAoPGFueT50aGlzLmcpLmxheW91dF8uZ2V0UGxvdEFyZWEoKTtcbiAgICAgICAgICAgIGxldCB4QXhpc0xhYmVsSGVpZ2h0ID0gMDtcbiAgICAgICAgICAgIGlmICh0aGlzLmc/LmdldE9wdGlvbkZvckF4aXMoJ2RyYXdBeGlzJywgJ3gnKSkge1xuICAgICAgICAgICAgICAgIHhBeGlzTGFiZWxIZWlnaHQgPSB0aGlzLmc/LmdldE9wdGlvbigneEF4aXNIZWlnaHQnKSB8fCAodGhpcy5nPy5nZXRPcHRpb24oJ2F4aXNMYWJlbEZvbnRTaXplJykgKyAyICogdGhpcy5nPy5nZXRPcHRpb24oJ2F4aXNUaWNrU2l6ZScpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwbG90QXJlYSkge1xuICAgICAgICAgICAgICAgIHRoaXMucmFuZ2ViYXJDYW52YXNSZWN0ID0ge1xuICAgICAgICAgICAgICAgICAgICB4OiBwbG90QXJlYS54LFxuICAgICAgICAgICAgICAgICAgICB5OiBwbG90QXJlYS55ICsgcGxvdEFyZWEuaCArIHhBeGlzTGFiZWxIZWlnaHQgKyA0LFxuICAgICAgICAgICAgICAgICAgICB3OiBwbG90QXJlYS53LFxuICAgICAgICAgICAgICAgICAgICBoOiB0aGlzLmc/LmdldE9wdGlvbigncmFuZ2VTZWxlY3RvckhlaWdodCcpXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGdldCBoYW5kbGVzXG4gICAgICAgICAgICBjb25zdCBoYW5kbGVzID0gdGhpcy5ncmFwaERpdj8uZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnZHlncmFwaC1yYW5nZXNlbC16b29taGFuZGxlJyk7XG5cbiAgICAgICAgICAgIGlmIChoYW5kbGVzICYmIGhhbmRsZXMubGVuZ3RoID4gMCAmJiB0aGlzLnJhbmdlYmFyQ2FudmFzUmVjdCAmJiB0aGlzLnNpbmdsZVpvb21IYW5kbGUpIHtcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIGNvbnN0IGxlZnRIYW5kbGUgPSA8SFRNTEltYWdlRWxlbWVudD5oYW5kbGVzWzBdO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJpZ2h0SGFuZGxlID0gPEhUTUxJbWFnZUVsZW1lbnQ+aGFuZGxlc1sxXTtcbiAgICAgICAgICAgICAgICBpZiAobGVmdEhhbmRsZS5zdHlsZS5sZWZ0ICE9IFwiXCIgJiYgcmlnaHRIYW5kbGUuc3R5bGUubGVmdCAhPSBcIlwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBsZWZ0SGFuZGxlUG9zID0gcGFyc2VGbG9hdChsZWZ0SGFuZGxlLnN0eWxlLmxlZnQpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmlnaHRIYW5kbGVQb3MgPSBwYXJzZUZsb2F0KHJpZ2h0SGFuZGxlLnN0eWxlLmxlZnQpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICgocmlnaHRIYW5kbGVQb3MgLSBsZWZ0SGFuZGxlUG9zKSA8IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGhhbGZIYW5kbGVXaWR0aCA9IHRoaXMuc2luZ2xlWm9vbUhhbmRsZS53aWR0aCAvIDI7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJhbmdlU2l6ZSA9IChwYXJzZUZsb2F0KHJpZ2h0SGFuZGxlLnN0eWxlLmxlZnQpICsgaGFsZkhhbmRsZVdpZHRoKSAtIChwYXJzZUZsb2F0KGxlZnRIYW5kbGUuc3R5bGUubGVmdCkgKyBoYWxmSGFuZGxlV2lkdGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHV0IHRoZSBoYW5kbGUgdG8gY29ycmVjdCBzcG90LlxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeEV4dHJlbWVzID0gdGhpcy5nPy54QXhpc0V4dHJlbWVzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4V2luZG93TGltaXRzID0gdGhpcy5nPy54QXhpc1JhbmdlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4UmFuZ2UgPSB4RXh0cmVtZXNbMV0gLSB4RXh0cmVtZXNbMF07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsZWZ0UGVyY2VudCA9IE1hdGgubWF4KDAsICh4V2luZG93TGltaXRzWzBdIC0geEV4dHJlbWVzWzBdKSAvIHhSYW5nZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsZWZ0Q29vcmQgPSB0aGlzLnJhbmdlYmFyQ2FudmFzUmVjdC54ICsgdGhpcy5yYW5nZWJhckNhbnZhc1JlY3QudyAqIGxlZnRQZXJjZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaGFuZGxlVG9wID0gTWF0aC5tYXgodGhpcy5yYW5nZWJhckNhbnZhc1JlY3QueSwgdGhpcy5yYW5nZWJhckNhbnZhc1JlY3QueSArICh0aGlzLnJhbmdlYmFyQ2FudmFzUmVjdC5oIC0gdGhpcy5zaW5nbGVab29tSGFuZGxlLmhlaWdodCkgLyAyKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zaW5nbGVab29tSGFuZGxlLnN0eWxlLmxlZnQgPSAobGVmdENvb3JkIC0gaGFsZkhhbmRsZVdpZHRoKSArICdweCc7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNpbmdsZVpvb21IYW5kbGUuc3R5bGUudG9wID0gaGFuZGxlVG9wICsgJ3B4JztcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2luZ2xlWm9vbUhhbmRsZS5zdHlsZS52aXNpYmlsaXR5ID0gJ3Zpc2libGUnO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zaW5nbGVab29tSGFuZGxlLnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNpbmdsZVpvb21IYW5kbGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNpbmdsZVpvb21IYW5kbGUuc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH1cblxuXG4gICAgfTtcblxuXG59XG4iXX0=