@qogni/dygraphs
Version:
dygraphs is a fast, flexible open source JavaScript charting library.
209 lines (195 loc) • 22.1 kB
JavaScript
/**
* @license
* Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com)
* MIT-licenced: https://opensource.org/licenses/MIT
*/
/**
* @fileoverview This file contains the managment of data handlers
* @author David Eberlein (david.eberlein@ch.sauter-bc.com)
*
* The idea is to define a common, generic data format that works for all data
* structures supported by dygraphs. To make this possible, the DataHandler
* interface is introduced. This makes it possible, that dygraph itself can work
* with the same logic for every data type independent of the actual format and
* the DataHandler takes care of the data format specific jobs.
* DataHandlers are implemented for all data types supported by Dygraphs and
* return Dygraphs compliant formats.
* By default the correct DataHandler is chosen based on the options set.
* Optionally the user may use his own DataHandler (similar to the plugin
* system).
*
*
* The unified data format returend by each handler is defined as so:
* series[n][point] = [x,y,(extras)]
*
* This format contains the common basis that is needed to draw a simple line
* series extended by optional extras for more complex graphing types. It
* contains a primitive x value as first array entry, a primitive y value as
* second array entry and an optional extras object for additional data needed.
*
* x must always be a number.
* y must always be a number, NaN of type number or null.
* extras is optional and must be interpreted by the DataHandler. It may be of
* any type.
*
* In practice this might look something like this:
* default: [x, yVal]
* errorBar / customBar: [x, yVal, [yTopVariance, yBottomVariance] ]
*
*/
/*global Dygraph:false */
/*global DygraphLayout:false */
;
/**
*
* The data handler is responsible for all data specific operations. All of the
* series data it receives and returns is always in the unified data format.
* Initially the unified data is created by the extractSeries method
* @constructor
*/
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var DygraphDataHandler = function DygraphDataHandler() {};
var handler = DygraphDataHandler;
/**
* X-value array index constant for unified data samples.
* @const
* @type {number}
*/
handler.X = 0;
/**
* Y-value array index constant for unified data samples.
* @const
* @type {number}
*/
handler.Y = 1;
/**
* Extras-value array index constant for unified data samples.
* @const
* @type {number}
*/
handler.EXTRAS = 2;
/**
* Extracts one series from the raw data (a 2D array) into an array of the
* unified data format.
* This is where undesirable points (i.e. negative values on log scales and
* missing values through which we wish to connect lines) are dropped.
* TODO(danvk): the "missing values" bit above doesn't seem right.
*
* @param {!Array.<Array>} rawData The raw data passed into dygraphs where
* rawData[i] = [x,ySeries1,...,ySeriesN].
* @param {!number} seriesIndex Index of the series to extract. All other
* series should be ignored.
* @param {!DygraphOptions} options Dygraph options.
* @return {Array.<[!number,?number,?]>} The series in the unified data format
* where series[i] = [x,y,{extras}].
*/
handler.prototype.extractSeries = function (rawData, seriesIndex, options) {};
/**
* Converts a series to a Point array. The resulting point array must be
* returned in increasing order of idx property.
*
* @param {!Array.<[!number,?number,?]>} series The series in the unified
* data format where series[i] = [x,y,{extras}].
* @param {!string} setName Name of the series.
* @param {!number} boundaryIdStart Index offset of the first point, equal to the
* number of skipped points left of the date window minimum (if any).
* @return {!Array.<Dygraph.PointType>} List of points for this series.
*/
handler.prototype.seriesToPoints = function (series, setName, boundaryIdStart) {
// TODO(bhs): these loops are a hot-spot for high-point-count charts. In
// fact,
// on chrome+linux, they are 6 times more expensive than iterating through
// the
// points and drawing the lines. The brunt of the cost comes from allocating
// the |point| structures.
var points = [];
for (var i = 0; i < series.length; ++i) {
var item = series[i];
var yraw = item[1];
var yval = yraw === null ? null : handler.parseFloat(yraw);
var point = {
x: NaN,
y: NaN,
xval: handler.parseFloat(item[0]),
yval: yval,
name: setName,
// TODO(danvk): is this really necessary?
idx: i + boundaryIdStart,
canvasx: NaN,
// add these so we do not alter the structure later, which slows Chrome
canvasy: NaN
};
points.push(point);
}
this.onPointsCreated_(series, points);
return points;
};
/**
* Callback called for each series after the series points have been generated
* which will later be used by the plotters to draw the graph.
* Here data may be added to the seriesPoints which is needed by the plotters.
* The indexes of series and points are in sync meaning the original data
* sample for series[i] is points[i].
*
* @param {!Array.<[!number,?number,?]>} series The series in the unified
* data format where series[i] = [x,y,{extras}].
* @param {!Array.<Dygraph.PointType>} points The corresponding points passed
* to the plotter.
* @protected
*/
handler.prototype.onPointsCreated_ = function (series, points) {};
/**
* Calculates the rolling average of a data set.
*
* @param {!Array.<[!number,?number,?]>} series The series in the unified
* data format where series[i] = [x,y,{extras}].
* @param {!number} rollPeriod The number of points over which to average the data
* @param {!DygraphOptions} options The dygraph options.
* @param {!number} seriesIndex Index of the series this was extracted from.
* @return {!Array.<[!number,?number,?]>} the rolled series.
*/
handler.prototype.rollingAverage = function (series, rollPeriod, options, seriesIndex) {};
/**
* Computes the range of the data series (including confidence intervals).
*
* @param {!Array.<[!number,?number,?]>} series The series in the unified
* data format where series[i] = [x, y, {extras}].
* @param {!Array.<number>} dateWindow The x-value range to display with
* the format: [min, max].
* @param {boolean} stepPlot Whether the stepPlot option is set.
* @return {Array.<number>} The low and high extremes of the series in the
* given window with the format: [low, high].
*/
handler.prototype.getExtremeYValues = function (series, dateWindow, stepPlot) {};
/**
* Callback called for each series after the layouting data has been
* calculated before the series is drawn. Here normalized positioning data
* should be calculated for the extras of each point.
*
* @param {!Array.<Dygraph.PointType>} points The points passed to
* the plotter.
* @param {!Object} axis The axis on which the series will be plotted.
* @param {!boolean} logscale Whether or not to use a logscale.
*/
handler.prototype.onLineEvaluated = function (points, axis, logscale) {};
/**
* Optimized replacement for parseFloat, which was way too slow when almost
* all values were type number, with few edge cases, none of which were strings.
* @param {?number} val
* @return {number}
* @protected
*/
handler.parseFloat = function (val) {
// parseFloat(null) is NaN
if (val === null) {
return NaN;
}
// Assume it's a number or NaN. If it's something else, I'll be shocked.
return val;
};
var _default = exports["default"] = DygraphDataHandler;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImV4cG9ydHMiLCJ2YWx1ZSIsIkR5Z3JhcGhEYXRhSGFuZGxlciIsImhhbmRsZXIiLCJYIiwiWSIsIkVYVFJBUyIsInByb3RvdHlwZSIsImV4dHJhY3RTZXJpZXMiLCJyYXdEYXRhIiwic2VyaWVzSW5kZXgiLCJvcHRpb25zIiwic2VyaWVzVG9Qb2ludHMiLCJzZXJpZXMiLCJzZXROYW1lIiwiYm91bmRhcnlJZFN0YXJ0IiwicG9pbnRzIiwiaSIsImxlbmd0aCIsIml0ZW0iLCJ5cmF3IiwieXZhbCIsInBhcnNlRmxvYXQiLCJwb2ludCIsIngiLCJOYU4iLCJ5IiwieHZhbCIsIm5hbWUiLCJpZHgiLCJjYW52YXN4IiwiY2FudmFzeSIsInB1c2giLCJvblBvaW50c0NyZWF0ZWRfIiwicm9sbGluZ0F2ZXJhZ2UiLCJyb2xsUGVyaW9kIiwiZ2V0RXh0cmVtZVlWYWx1ZXMiLCJkYXRlV2luZG93Iiwic3RlcFBsb3QiLCJvbkxpbmVFdmFsdWF0ZWQiLCJheGlzIiwibG9nc2NhbGUiLCJ2YWwiLCJfZGVmYXVsdCIsIm1vZHVsZSIsImRlZmF1bHQiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvZGF0YWhhbmRsZXIvZGF0YWhhbmRsZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTMgRGF2aWQgRWJlcmxlaW4gKGRhdmlkLmViZXJsZWluQGNoLnNhdXRlci1iYy5jb20pXG4gKiBNSVQtbGljZW5jZWQ6IGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUXG4gKi9cblxuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IFRoaXMgZmlsZSBjb250YWlucyB0aGUgbWFuYWdtZW50IG9mIGRhdGEgaGFuZGxlcnNcbiAqIEBhdXRob3IgRGF2aWQgRWJlcmxlaW4gKGRhdmlkLmViZXJsZWluQGNoLnNhdXRlci1iYy5jb20pXG4gKlxuICogVGhlIGlkZWEgaXMgdG8gZGVmaW5lIGEgY29tbW9uLCBnZW5lcmljIGRhdGEgZm9ybWF0IHRoYXQgd29ya3MgZm9yIGFsbCBkYXRhXG4gKiBzdHJ1Y3R1cmVzIHN1cHBvcnRlZCBieSBkeWdyYXBocy4gVG8gbWFrZSB0aGlzIHBvc3NpYmxlLCB0aGUgRGF0YUhhbmRsZXJcbiAqIGludGVyZmFjZSBpcyBpbnRyb2R1Y2VkLiBUaGlzIG1ha2VzIGl0IHBvc3NpYmxlLCB0aGF0IGR5Z3JhcGggaXRzZWxmIGNhbiB3b3JrXG4gKiB3aXRoIHRoZSBzYW1lIGxvZ2ljIGZvciBldmVyeSBkYXRhIHR5cGUgaW5kZXBlbmRlbnQgb2YgdGhlIGFjdHVhbCBmb3JtYXQgYW5kXG4gKiB0aGUgRGF0YUhhbmRsZXIgdGFrZXMgY2FyZSBvZiB0aGUgZGF0YSBmb3JtYXQgc3BlY2lmaWMgam9icy5cbiAqIERhdGFIYW5kbGVycyBhcmUgaW1wbGVtZW50ZWQgZm9yIGFsbCBkYXRhIHR5cGVzIHN1cHBvcnRlZCBieSBEeWdyYXBocyBhbmRcbiAqIHJldHVybiBEeWdyYXBocyBjb21wbGlhbnQgZm9ybWF0cy5cbiAqIEJ5IGRlZmF1bHQgdGhlIGNvcnJlY3QgRGF0YUhhbmRsZXIgaXMgY2hvc2VuIGJhc2VkIG9uIHRoZSBvcHRpb25zIHNldC5cbiAqIE9wdGlvbmFsbHkgdGhlIHVzZXIgbWF5IHVzZSBoaXMgb3duIERhdGFIYW5kbGVyIChzaW1pbGFyIHRvIHRoZSBwbHVnaW5cbiAqIHN5c3RlbSkuXG4gKlxuICpcbiAqIFRoZSB1bmlmaWVkIGRhdGEgZm9ybWF0IHJldHVyZW5kIGJ5IGVhY2ggaGFuZGxlciBpcyBkZWZpbmVkIGFzIHNvOlxuICogc2VyaWVzW25dW3BvaW50XSA9IFt4LHksKGV4dHJhcyldXG4gKlxuICogVGhpcyBmb3JtYXQgY29udGFpbnMgdGhlIGNvbW1vbiBiYXNpcyB0aGF0IGlzIG5lZWRlZCB0byBkcmF3IGEgc2ltcGxlIGxpbmVcbiAqIHNlcmllcyBleHRlbmRlZCBieSBvcHRpb25hbCBleHRyYXMgZm9yIG1vcmUgY29tcGxleCBncmFwaGluZyB0eXBlcy4gSXRcbiAqIGNvbnRhaW5zIGEgcHJpbWl0aXZlIHggdmFsdWUgYXMgZmlyc3QgYXJyYXkgZW50cnksIGEgcHJpbWl0aXZlIHkgdmFsdWUgYXNcbiAqIHNlY29uZCBhcnJheSBlbnRyeSBhbmQgYW4gb3B0aW9uYWwgZXh0cmFzIG9iamVjdCBmb3IgYWRkaXRpb25hbCBkYXRhIG5lZWRlZC5cbiAqXG4gKiB4IG11c3QgYWx3YXlzIGJlIGEgbnVtYmVyLlxuICogeSBtdXN0IGFsd2F5cyBiZSBhIG51bWJlciwgTmFOIG9mIHR5cGUgbnVtYmVyIG9yIG51bGwuXG4gKiBleHRyYXMgaXMgb3B0aW9uYWwgYW5kIG11c3QgYmUgaW50ZXJwcmV0ZWQgYnkgdGhlIERhdGFIYW5kbGVyLiBJdCBtYXkgYmUgb2ZcbiAqIGFueSB0eXBlLlxuICpcbiAqIEluIHByYWN0aWNlIHRoaXMgbWlnaHQgbG9vayBzb21ldGhpbmcgbGlrZSB0aGlzOlxuICogZGVmYXVsdDogW3gsIHlWYWxdXG4gKiBlcnJvckJhciAvIGN1c3RvbUJhcjogW3gsIHlWYWwsIFt5VG9wVmFyaWFuY2UsIHlCb3R0b21WYXJpYW5jZV0gXVxuICpcbiAqL1xuLypnbG9iYWwgRHlncmFwaDpmYWxzZSAqL1xuLypnbG9iYWwgRHlncmFwaExheW91dDpmYWxzZSAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuLyoqXG4gKlxuICogVGhlIGRhdGEgaGFuZGxlciBpcyByZXNwb25zaWJsZSBmb3IgYWxsIGRhdGEgc3BlY2lmaWMgb3BlcmF0aW9ucy4gQWxsIG9mIHRoZVxuICogc2VyaWVzIGRhdGEgaXQgcmVjZWl2ZXMgYW5kIHJldHVybnMgaXMgYWx3YXlzIGluIHRoZSB1bmlmaWVkIGRhdGEgZm9ybWF0LlxuICogSW5pdGlhbGx5IHRoZSB1bmlmaWVkIGRhdGEgaXMgY3JlYXRlZCBieSB0aGUgZXh0cmFjdFNlcmllcyBtZXRob2RcbiAqIEBjb25zdHJ1Y3RvclxuICovXG52YXIgRHlncmFwaERhdGFIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xufTtcblxudmFyIGhhbmRsZXIgPSBEeWdyYXBoRGF0YUhhbmRsZXI7XG5cbi8qKlxuICogWC12YWx1ZSBhcnJheSBpbmRleCBjb25zdGFudCBmb3IgdW5pZmllZCBkYXRhIHNhbXBsZXMuXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbmhhbmRsZXIuWCA9IDA7XG5cbi8qKlxuICogWS12YWx1ZSBhcnJheSBpbmRleCBjb25zdGFudCBmb3IgdW5pZmllZCBkYXRhIHNhbXBsZXMuXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbmhhbmRsZXIuWSA9IDE7XG5cbi8qKlxuICogRXh0cmFzLXZhbHVlIGFycmF5IGluZGV4IGNvbnN0YW50IGZvciB1bmlmaWVkIGRhdGEgc2FtcGxlcy5cbiAqIEBjb25zdFxuICogQHR5cGUge251bWJlcn1cbiAqL1xuaGFuZGxlci5FWFRSQVMgPSAyO1xuXG4vKipcbiAqIEV4dHJhY3RzIG9uZSBzZXJpZXMgZnJvbSB0aGUgcmF3IGRhdGEgKGEgMkQgYXJyYXkpIGludG8gYW4gYXJyYXkgb2YgdGhlXG4gKiB1bmlmaWVkIGRhdGEgZm9ybWF0LlxuICogVGhpcyBpcyB3aGVyZSB1bmRlc2lyYWJsZSBwb2ludHMgKGkuZS4gbmVnYXRpdmUgdmFsdWVzIG9uIGxvZyBzY2FsZXMgYW5kXG4gKiBtaXNzaW5nIHZhbHVlcyB0aHJvdWdoIHdoaWNoIHdlIHdpc2ggdG8gY29ubmVjdCBsaW5lcykgYXJlIGRyb3BwZWQuXG4gKiBUT0RPKGRhbnZrKTogdGhlIFwibWlzc2luZyB2YWx1ZXNcIiBiaXQgYWJvdmUgZG9lc24ndCBzZWVtIHJpZ2h0LlxuICpcbiAqIEBwYXJhbSB7IUFycmF5LjxBcnJheT59IHJhd0RhdGEgVGhlIHJhdyBkYXRhIHBhc3NlZCBpbnRvIGR5Z3JhcGhzIHdoZXJlXG4gKiAgICAgcmF3RGF0YVtpXSA9IFt4LHlTZXJpZXMxLC4uLix5U2VyaWVzTl0uXG4gKiBAcGFyYW0geyFudW1iZXJ9IHNlcmllc0luZGV4IEluZGV4IG9mIHRoZSBzZXJpZXMgdG8gZXh0cmFjdC4gQWxsIG90aGVyXG4gKiAgICAgc2VyaWVzIHNob3VsZCBiZSBpZ25vcmVkLlxuICogQHBhcmFtIHshRHlncmFwaE9wdGlvbnN9IG9wdGlvbnMgRHlncmFwaCBvcHRpb25zLlxuICogQHJldHVybiB7QXJyYXkuPFshbnVtYmVyLD9udW1iZXIsP10+fSBUaGUgc2VyaWVzIGluIHRoZSB1bmlmaWVkIGRhdGEgZm9ybWF0XG4gKiAgICAgd2hlcmUgc2VyaWVzW2ldID0gW3gseSx7ZXh0cmFzfV0uXG4gKi9cbmhhbmRsZXIucHJvdG90eXBlLmV4dHJhY3RTZXJpZXMgPSBmdW5jdGlvbihyYXdEYXRhLCBzZXJpZXNJbmRleCwgb3B0aW9ucykge1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyBhIHNlcmllcyB0byBhIFBvaW50IGFycmF5LiAgVGhlIHJlc3VsdGluZyBwb2ludCBhcnJheSBtdXN0IGJlXG4gKiByZXR1cm5lZCBpbiBpbmNyZWFzaW5nIG9yZGVyIG9mIGlkeCBwcm9wZXJ0eS5cbiAqXG4gKiBAcGFyYW0geyFBcnJheS48WyFudW1iZXIsP251bWJlciw/XT59IHNlcmllcyBUaGUgc2VyaWVzIGluIHRoZSB1bmlmaWVkXG4gKiAgICAgICAgICBkYXRhIGZvcm1hdCB3aGVyZSBzZXJpZXNbaV0gPSBbeCx5LHtleHRyYXN9XS5cbiAqIEBwYXJhbSB7IXN0cmluZ30gc2V0TmFtZSBOYW1lIG9mIHRoZSBzZXJpZXMuXG4gKiBAcGFyYW0geyFudW1iZXJ9IGJvdW5kYXJ5SWRTdGFydCBJbmRleCBvZmZzZXQgb2YgdGhlIGZpcnN0IHBvaW50LCBlcXVhbCB0byB0aGVcbiAqICAgICAgICAgIG51bWJlciBvZiBza2lwcGVkIHBvaW50cyBsZWZ0IG9mIHRoZSBkYXRlIHdpbmRvdyBtaW5pbXVtIChpZiBhbnkpLlxuICogQHJldHVybiB7IUFycmF5LjxEeWdyYXBoLlBvaW50VHlwZT59IExpc3Qgb2YgcG9pbnRzIGZvciB0aGlzIHNlcmllcy5cbiAqL1xuaGFuZGxlci5wcm90b3R5cGUuc2VyaWVzVG9Qb2ludHMgPSBmdW5jdGlvbihzZXJpZXMsIHNldE5hbWUsIGJvdW5kYXJ5SWRTdGFydCkge1xuICAvLyBUT0RPKGJocyk6IHRoZXNlIGxvb3BzIGFyZSBhIGhvdC1zcG90IGZvciBoaWdoLXBvaW50LWNvdW50IGNoYXJ0cy4gSW5cbiAgLy8gZmFjdCxcbiAgLy8gb24gY2hyb21lK2xpbnV4LCB0aGV5IGFyZSA2IHRpbWVzIG1vcmUgZXhwZW5zaXZlIHRoYW4gaXRlcmF0aW5nIHRocm91Z2hcbiAgLy8gdGhlXG4gIC8vIHBvaW50cyBhbmQgZHJhd2luZyB0aGUgbGluZXMuIFRoZSBicnVudCBvZiB0aGUgY29zdCBjb21lcyBmcm9tIGFsbG9jYXRpbmdcbiAgLy8gdGhlIHxwb2ludHwgc3RydWN0dXJlcy5cbiAgdmFyIHBvaW50cyA9IFtdO1xuICBmb3IgKCB2YXIgaSA9IDA7IGkgPCBzZXJpZXMubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgaXRlbSA9IHNlcmllc1tpXTtcbiAgICB2YXIgeXJhdyA9IGl0ZW1bMV07XG4gICAgdmFyIHl2YWwgPSB5cmF3ID09PSBudWxsID8gbnVsbCA6IGhhbmRsZXIucGFyc2VGbG9hdCh5cmF3KTtcbiAgICB2YXIgcG9pbnQgPSB7XG4gICAgICB4IDogTmFOLFxuICAgICAgeSA6IE5hTixcbiAgICAgIHh2YWwgOiBoYW5kbGVyLnBhcnNlRmxvYXQoaXRlbVswXSksXG4gICAgICB5dmFsIDogeXZhbCxcbiAgICAgIG5hbWUgOiBzZXROYW1lLCAvLyBUT0RPKGRhbnZrKTogaXMgdGhpcyByZWFsbHkgbmVjZXNzYXJ5P1xuICAgICAgaWR4IDogaSArIGJvdW5kYXJ5SWRTdGFydCxcbiAgICAgIGNhbnZhc3g6IE5hTiwgLy8gYWRkIHRoZXNlIHNvIHdlIGRvIG5vdCBhbHRlciB0aGUgc3RydWN0dXJlIGxhdGVyLCB3aGljaCBzbG93cyBDaHJvbWVcbiAgICAgIGNhbnZhc3k6IE5hTixcbiAgICB9O1xuICAgIHBvaW50cy5wdXNoKHBvaW50KTtcbiAgfVxuICB0aGlzLm9uUG9pbnRzQ3JlYXRlZF8oc2VyaWVzLCBwb2ludHMpO1xuICByZXR1cm4gcG9pbnRzO1xufTtcblxuLyoqXG4gKiBDYWxsYmFjayBjYWxsZWQgZm9yIGVhY2ggc2VyaWVzIGFmdGVyIHRoZSBzZXJpZXMgcG9pbnRzIGhhdmUgYmVlbiBnZW5lcmF0ZWRcbiAqIHdoaWNoIHdpbGwgbGF0ZXIgYmUgdXNlZCBieSB0aGUgcGxvdHRlcnMgdG8gZHJhdyB0aGUgZ3JhcGguXG4gKiBIZXJlIGRhdGEgbWF5IGJlIGFkZGVkIHRvIHRoZSBzZXJpZXNQb2ludHMgd2hpY2ggaXMgbmVlZGVkIGJ5IHRoZSBwbG90dGVycy5cbiAqIFRoZSBpbmRleGVzIG9mIHNlcmllcyBhbmQgcG9pbnRzIGFyZSBpbiBzeW5jIG1lYW5pbmcgdGhlIG9yaWdpbmFsIGRhdGFcbiAqIHNhbXBsZSBmb3Igc2VyaWVzW2ldIGlzIHBvaW50c1tpXS5cbiAqXG4gKiBAcGFyYW0geyFBcnJheS48WyFudW1iZXIsP251bWJlciw/XT59IHNlcmllcyBUaGUgc2VyaWVzIGluIHRoZSB1bmlmaWVkXG4gKiAgICAgZGF0YSBmb3JtYXQgd2hlcmUgc2VyaWVzW2ldID0gW3gseSx7ZXh0cmFzfV0uXG4gKiBAcGFyYW0geyFBcnJheS48RHlncmFwaC5Qb2ludFR5cGU+fSBwb2ludHMgVGhlIGNvcnJlc3BvbmRpbmcgcG9pbnRzIHBhc3NlZFxuICogICAgIHRvIHRoZSBwbG90dGVyLlxuICogQHByb3RlY3RlZFxuICovXG5oYW5kbGVyLnByb3RvdHlwZS5vblBvaW50c0NyZWF0ZWRfID0gZnVuY3Rpb24oc2VyaWVzLCBwb2ludHMpIHtcbn07XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgcm9sbGluZyBhdmVyYWdlIG9mIGEgZGF0YSBzZXQuXG4gKlxuICogQHBhcmFtIHshQXJyYXkuPFshbnVtYmVyLD9udW1iZXIsP10+fSBzZXJpZXMgVGhlIHNlcmllcyBpbiB0aGUgdW5pZmllZFxuICogICAgICAgICAgZGF0YSBmb3JtYXQgd2hlcmUgc2VyaWVzW2ldID0gW3gseSx7ZXh0cmFzfV0uXG4gKiBAcGFyYW0geyFudW1iZXJ9IHJvbGxQZXJpb2QgVGhlIG51bWJlciBvZiBwb2ludHMgb3ZlciB3aGljaCB0byBhdmVyYWdlIHRoZSBkYXRhXG4gKiBAcGFyYW0geyFEeWdyYXBoT3B0aW9uc30gb3B0aW9ucyBUaGUgZHlncmFwaCBvcHRpb25zLlxuICogQHBhcmFtIHshbnVtYmVyfSBzZXJpZXNJbmRleCBJbmRleCBvZiB0aGUgc2VyaWVzIHRoaXMgd2FzIGV4dHJhY3RlZCBmcm9tLlxuICogQHJldHVybiB7IUFycmF5LjxbIW51bWJlciw/bnVtYmVyLD9dPn0gdGhlIHJvbGxlZCBzZXJpZXMuXG4gKi9cbmhhbmRsZXIucHJvdG90eXBlLnJvbGxpbmdBdmVyYWdlID0gZnVuY3Rpb24oc2VyaWVzLCByb2xsUGVyaW9kLCBvcHRpb25zLCBzZXJpZXNJbmRleCkge1xufTtcblxuLyoqXG4gKiBDb21wdXRlcyB0aGUgcmFuZ2Ugb2YgdGhlIGRhdGEgc2VyaWVzIChpbmNsdWRpbmcgY29uZmlkZW5jZSBpbnRlcnZhbHMpLlxuICpcbiAqIEBwYXJhbSB7IUFycmF5LjxbIW51bWJlciw/bnVtYmVyLD9dPn0gc2VyaWVzIFRoZSBzZXJpZXMgaW4gdGhlIHVuaWZpZWRcbiAqICAgICBkYXRhIGZvcm1hdCB3aGVyZSBzZXJpZXNbaV0gPSBbeCwgeSwge2V4dHJhc31dLlxuICogQHBhcmFtIHshQXJyYXkuPG51bWJlcj59IGRhdGVXaW5kb3cgVGhlIHgtdmFsdWUgcmFuZ2UgdG8gZGlzcGxheSB3aXRoXG4gKiAgICAgdGhlIGZvcm1hdDogW21pbiwgbWF4XS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gc3RlcFBsb3QgV2hldGhlciB0aGUgc3RlcFBsb3Qgb3B0aW9uIGlzIHNldC5cbiAqIEByZXR1cm4ge0FycmF5LjxudW1iZXI+fSBUaGUgbG93IGFuZCBoaWdoIGV4dHJlbWVzIG9mIHRoZSBzZXJpZXMgaW4gdGhlXG4gKiAgICAgZ2l2ZW4gd2luZG93IHdpdGggdGhlIGZvcm1hdDogW2xvdywgaGlnaF0uXG4gKi9cbmhhbmRsZXIucHJvdG90eXBlLmdldEV4dHJlbWVZVmFsdWVzID0gZnVuY3Rpb24oc2VyaWVzLCBkYXRlV2luZG93LCBzdGVwUGxvdCkge1xufTtcblxuLyoqXG4gKiBDYWxsYmFjayBjYWxsZWQgZm9yIGVhY2ggc2VyaWVzIGFmdGVyIHRoZSBsYXlvdXRpbmcgZGF0YSBoYXMgYmVlblxuICogY2FsY3VsYXRlZCBiZWZvcmUgdGhlIHNlcmllcyBpcyBkcmF3bi4gSGVyZSBub3JtYWxpemVkIHBvc2l0aW9uaW5nIGRhdGFcbiAqIHNob3VsZCBiZSBjYWxjdWxhdGVkIGZvciB0aGUgZXh0cmFzIG9mIGVhY2ggcG9pbnQuXG4gKlxuICogQHBhcmFtIHshQXJyYXkuPER5Z3JhcGguUG9pbnRUeXBlPn0gcG9pbnRzIFRoZSBwb2ludHMgcGFzc2VkIHRvXG4gKiAgICAgICAgICB0aGUgcGxvdHRlci5cbiAqIEBwYXJhbSB7IU9iamVjdH0gYXhpcyBUaGUgYXhpcyBvbiB3aGljaCB0aGUgc2VyaWVzIHdpbGwgYmUgcGxvdHRlZC5cbiAqIEBwYXJhbSB7IWJvb2xlYW59IGxvZ3NjYWxlIFdoZXRoZXIgb3Igbm90IHRvIHVzZSBhIGxvZ3NjYWxlLlxuICovXG5oYW5kbGVyLnByb3RvdHlwZS5vbkxpbmVFdmFsdWF0ZWQgPSBmdW5jdGlvbihwb2ludHMsIGF4aXMsIGxvZ3NjYWxlKSB7XG59O1xuXG4vKipcbiAqIE9wdGltaXplZCByZXBsYWNlbWVudCBmb3IgcGFyc2VGbG9hdCwgd2hpY2ggd2FzIHdheSB0b28gc2xvdyB3aGVuIGFsbW9zdFxuICogYWxsIHZhbHVlcyB3ZXJlIHR5cGUgbnVtYmVyLCB3aXRoIGZldyBlZGdlIGNhc2VzLCBub25lIG9mIHdoaWNoIHdlcmUgc3RyaW5ncy5cbiAqIEBwYXJhbSB7P251bWJlcn0gdmFsXG4gKiBAcmV0dXJuIHtudW1iZXJ9XG4gKiBAcHJvdGVjdGVkXG4gKi9cbmhhbmRsZXIucGFyc2VGbG9hdCA9IGZ1bmN0aW9uKHZhbCkge1xuICAvLyBwYXJzZUZsb2F0KG51bGwpIGlzIE5hTlxuICBpZiAodmFsID09PSBudWxsKSB7XG4gICAgcmV0dXJuIE5hTjtcbiAgfVxuXG4gIC8vIEFzc3VtZSBpdCdzIGEgbnVtYmVyIG9yIE5hTi4gSWYgaXQncyBzb21ldGhpbmcgZWxzZSwgSSdsbCBiZSBzaG9ja2VkLlxuICByZXR1cm4gdmFsO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgRHlncmFwaERhdGFIYW5kbGVyO1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxZQUFZOztBQUVaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTkFBLE1BQUEsQ0FBQUMsY0FBQSxDQUFBQyxPQUFBO0VBQUFDLEtBQUE7QUFBQTtBQUFBRCxPQUFBO0FBT0EsSUFBSUUsa0JBQWtCLEdBQUcsU0FBckJBLGtCQUFrQkEsQ0FBQSxFQUFlLENBQ3JDLENBQUM7QUFFRCxJQUFJQyxPQUFPLEdBQUdELGtCQUFrQjs7QUFFaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBQyxPQUFPLENBQUNDLENBQUMsR0FBRyxDQUFDOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQUQsT0FBTyxDQUFDRSxDQUFDLEdBQUcsQ0FBQzs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0FGLE9BQU8sQ0FBQ0csTUFBTSxHQUFHLENBQUM7O0FBRWxCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBSCxP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