UNPKG

kepler.gl

Version:

kepler.gl is a webgl based application to visualize large scale location data in the browser

330 lines (318 loc) 41.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.datasetColorMaker = exports.addTimeLabel = void 0; exports.findDefaultColorField = findDefaultColorField; exports.getFieldFormatLabels = getFieldFormatLabels; exports.getFormatLabels = void 0; exports.validateInputData = validateInputData; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _constants = require("@kepler.gl/constants"); var _commonUtils = require("@kepler.gl/common-utils"); var _typeAnalyzer = require("type-analyzer"); var _assert = _interopRequireDefault(require("assert")); var _utils = require("./utils"); var _dataUtils = require("./data-utils"); var _format = require("./format"); var _colorUtils = require("./color-utils"); function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var _marked = /*#__PURE__*/_regenerator["default"].mark(generateColor); // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project // apply a color for each dataset // to use as label colors var datasetColors = ['#8F2FBF', '#005CFF', '#C06C84', '#F8B195', '#547A82', '#3EACA8', '#A2D4AB'].map(_colorUtils.hexToRgb); /** * Random color generator */ function generateColor() { var index; return _regenerator["default"].wrap(function generateColor$(_context) { while (1) switch (_context.prev = _context.next) { case 0: index = 0; case 1: if (!(index < datasetColors.length + 1)) { _context.next = 7; break; } if (index === datasetColors.length) { index = 0; } _context.next = 5; return datasetColors[index++]; case 5: _context.next = 1; break; case 7: case "end": return _context.stop(); } }, _marked); } var datasetColorMaker = exports.datasetColorMaker = generateColor(); /** * Field name prefixes and suffixes which should not be considered * as metrics. Fields will still be included if a 'metric word' * is found on the field name, however. */ var EXCLUDED_DEFAULT_FIELDS = [ // Serial numbers and identification numbers '_id', 'id', 'index', 'uuid', 'guid', 'uid', 'gid', 'serial', // Geographic IDs are unlikely to be interesting to color 'zip', 'code', 'post', 'region', 'fips', 'cbgs', 'h3', 's2', // Geographic coords (but not z/elevation/altitude // since that might be a metric) 'lat', 'lon', 'lng', 'latitude', 'longitude', '_x', '_y']; /** * Prefixes and suffixes that indicate a field is a metric. * * Note that these are in order of preference, first being * most preferred. */ var METRIC_DEFAULT_FIELDS = ['metric', 'value', 'sum', 'count', 'unique', 'mean', 'mode', 'median', 'max', 'min', 'deviation', 'variance', 'p99', 'p95', 'p75', 'p50', 'p25', 'p05', // Abbreviations are less preferred 'cnt', 'val']; /** * Choose a field to use as the default color field of a layer. * * The heuristic is: * * First, exclude fields that are on the exclusion list and don't * have names that suggest they contain metrics. Also exclude * field names that are blank. * * Next, look for a field that is of real type and contains one * of the preferred names (in order of the preferred names). * * Next, look for a field that is of integer type and contains * one of the preferred names (in order of the preferred names). * * Next, look for the first field that is of real type (in order * of field index). * * Next, look for the first field that is of integer type (in * order of field index). * * It's possible no field will be chosen (i.e. because all fields * are strings.) * * @param dataset */ function findDefaultColorField(_ref) { var fields = _ref.fields, _ref$fieldPairs = _ref.fieldPairs, fieldPairs = _ref$fieldPairs === void 0 ? [] : _ref$fieldPairs; var fieldsWithoutExcluded = fields.filter(function (field) { if (field.type !== _constants.ALL_FIELD_TYPES.real) { // Only select numeric fields. return false; } if (fieldPairs.find(function (pair) { return pair.pair.lat.value === field.name || pair.pair.lng.value === field.name; })) { // Do not permit lat, lon fields return false; } var normalizedFieldName = field.name.toLowerCase(); if (normalizedFieldName === '') { // Special case excluded name when the name is blank. return false; } var hasExcluded = EXCLUDED_DEFAULT_FIELDS.find(function (f) { return normalizedFieldName.startsWith(f) || normalizedFieldName.endsWith(f); }); var hasInclusion = METRIC_DEFAULT_FIELDS.find(function (f) { return normalizedFieldName.startsWith(f) || normalizedFieldName.endsWith(f); }); return !hasExcluded || hasInclusion; }); var sortedFields = fieldsWithoutExcluded.sort(function (left, right) { var normalizedLeft = left.name.toLowerCase(); var normalizedRight = right.name.toLowerCase(); var leftHasInclusion = METRIC_DEFAULT_FIELDS.findIndex(function (f) { return normalizedLeft.startsWith(f) || normalizedLeft.endsWith(f); }); var rightHasInclusion = METRIC_DEFAULT_FIELDS.findIndex(function (f) { return normalizedRight.startsWith(f) || normalizedRight.endsWith(f); }); if (leftHasInclusion !== rightHasInclusion) { if (leftHasInclusion === -1) { // Elements that do not have the inclusion list should go after those that do. return 1; } else if (rightHasInclusion === -1) { // Elements that do have the inclusion list should go before those that don't. return -1; } // Compare based on order in the inclusion list return leftHasInclusion - rightHasInclusion; } // Compare based on type if (left.type !== right.type) { if (left.type === _constants.ALL_FIELD_TYPES.real) { return -1; } // left is an integer and right is not // and reals come before integers return 1; } // Finally, order based on the order in the datasets columns // @ts-expect-error return left.index - right.index; }); if (sortedFields.length) { // There was a best match return sortedFields[0]; } // No matches return null; } /** * Validate input data, adding missing field types, rename duplicate columns */ function validateInputData(data) { if (!(0, _utils.isPlainObject)(data)) { (0, _assert["default"])('addDataToMap Error: dataset.data cannot be null'); return null; } else if (!Array.isArray(data.fields)) { (0, _assert["default"])('addDataToMap Error: expect dataset.data.fields to be an array'); return null; } else if (!Array.isArray(data.rows) && !Array.isArray(data.cols)) { (0, _assert["default"])('addDataToMap Error: expect dataset.data.rows or cols to be an array'); return null; } var fields = data.fields, rows = data.rows, cols = data.cols; // check if all fields has name, format and type var allValid = fields.every(function (f, i) { if (!(0, _utils.isPlainObject)(f)) { (0, _assert["default"])("fields needs to be an array of object, but find ".concat((0, _typeof2["default"])(f))); fields[i] = { name: "column_".concat(i), type: _constants.ALL_FIELD_TYPES.string }; } if (!f.name) { (0, _assert["default"])("field.name is required but missing in ".concat(JSON.stringify(f))); // assign a name fields[i].name = "column_".concat(i); } if (!f.type || !_constants.ALL_FIELD_TYPES[f.type]) { (0, _assert["default"])("unknown field type ".concat(f.type)); return false; } if (!f.analyzerType) { (0, _assert["default"])("field ".concat(i, " missing analyzerType")); return false; } // check time format is correct based on first 10 not empty element if (f.type === _constants.ALL_FIELD_TYPES.timestamp) { var sample = (cols ? findNonEmptyRowsAtFieldArrow(cols, i, 10) : findNonEmptyRowsAtField(rows, i, 10)).map(function (r) { return { ts: r[i] }; }); var analyzedType = _typeAnalyzer.Analyzer.computeColMeta(sample)[0]; return analyzedType && analyzedType.category === 'TIME' && analyzedType.format === f.format; } // check existing string field is H3 type if (f.type === _constants.ALL_FIELD_TYPES.string) { var _sample = (cols ? findNonEmptyRowsAtFieldArrow(cols, i, 10) : findNonEmptyRowsAtField(rows, i, 10)).map(function (r) { return r[i]; }); return _sample.every(function (item) { return !(0, _commonUtils.h3IsValid)(item); }); } return true; }); if (allValid) { return { rows: rows, fields: fields, cols: cols }; } // if any field has missing type, recalculate it for everyone // because we simply lost faith in humanity var sampleData = cols ? (0, _commonUtils.getSampleForTypeAnalyzeArrow)(cols, fields.map(function (f) { return f.name; })) : (0, _commonUtils.getSampleForTypeAnalyze)({ fields: fields.map(function (f) { return f.name; }), rows: rows }); var fieldOrder = fields.map(function (f) { return f.name; }); var meta = (0, _commonUtils.getFieldsFromData)(sampleData, fieldOrder); var updatedFields = fields.map(function (f, i) { return _objectSpread(_objectSpread({}, f), {}, { type: meta[i].type, format: meta[i].format, analyzerType: meta[i].analyzerType }); }); return _objectSpread({ fields: updatedFields, rows: rows }, cols ? { cols: cols } : {}); } function findNonEmptyRowsAtField(rows, fieldIdx, total) { var sample = []; var i = 0; while (sample.length < total && i < rows.length) { var _rows$i; if ((0, _commonUtils.notNullorUndefined)((_rows$i = rows[i]) === null || _rows$i === void 0 ? void 0 : _rows$i[fieldIdx])) { sample.push(rows[i]); } i++; } return sample; } function findNonEmptyRowsAtFieldArrow(cols, fieldIdx, total) { var sample = []; var numRows = cols[fieldIdx].length; var i = 0; while (sample.length < total && i < numRows) { if ((0, _commonUtils.notNullorUndefined)(cols[fieldIdx].get(i))) { var row = cols.map(function (col) { return col.get(i); }); sample.push(row); } i++; } return sample; } var TIME_DISPLAY = '2020-05-11 14:00'; var addTimeLabel = exports.addTimeLabel = function addTimeLabel(formats) { return formats.map(function (f) { return _objectSpread(_objectSpread({}, f), {}, { label: f.type === _constants.TOOLTIP_FORMAT_TYPES.DATE_TIME || f.type === _constants.TOOLTIP_FORMAT_TYPES.DATE ? (0, _dataUtils.getFormatter)((0, _format.getFormatValue)(f))(TIME_DISPLAY) : f.label }); }); }; function getFieldFormatLabels(fieldType) { var tooltipTypes = fieldType && _constants.FIELD_OPTS[fieldType].format.tooltip || []; var formatLabels = Object.values(_constants.TOOLTIP_FORMATS).filter(function (t) { return tooltipTypes.includes(t.type); }); return addTimeLabel(formatLabels); } var getFormatLabels = exports.getFormatLabels = function getFormatLabels(fields, fieldName) { var _fields$find; var fieldType = (_fields$find = fields.find(function (f) { return f.name === fieldName; })) === null || _fields$find === void 0 ? void 0 : _fields$find.type; return getFieldFormatLabels(fieldType); }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29uc3RhbnRzIiwicmVxdWlyZSIsIl9jb21tb25VdGlscyIsIl90eXBlQW5hbHl6ZXIiLCJfYXNzZXJ0IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl91dGlscyIsIl9kYXRhVXRpbHMiLCJfZm9ybWF0IiwiX2NvbG9yVXRpbHMiLCJvd25LZXlzIiwiZSIsInIiLCJ0IiwiT2JqZWN0Iiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsIm8iLCJmaWx0ZXIiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJlbnVtZXJhYmxlIiwicHVzaCIsImFwcGx5IiwiX29iamVjdFNwcmVhZCIsImFyZ3VtZW50cyIsImxlbmd0aCIsImZvckVhY2giLCJfZGVmaW5lUHJvcGVydHkyIiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJkZWZpbmVQcm9wZXJ0eSIsIl9tYXJrZWQiLCJfcmVnZW5lcmF0b3IiLCJtYXJrIiwiZ2VuZXJhdGVDb2xvciIsImRhdGFzZXRDb2xvcnMiLCJtYXAiLCJoZXhUb1JnYiIsImluZGV4Iiwid3JhcCIsImdlbmVyYXRlQ29sb3IkIiwiX2NvbnRleHQiLCJwcmV2IiwibmV4dCIsInN0b3AiLCJkYXRhc2V0Q29sb3JNYWtlciIsImV4cG9ydHMiLCJFWENMVURFRF9ERUZBVUxUX0ZJRUxEUyIsIk1FVFJJQ19ERUZBVUxUX0ZJRUxEUyIsImZpbmREZWZhdWx0Q29sb3JGaWVsZCIsIl9yZWYiLCJmaWVsZHMiLCJfcmVmJGZpZWxkUGFpcnMiLCJmaWVsZFBhaXJzIiwiZmllbGRzV2l0aG91dEV4Y2x1ZGVkIiwiZmllbGQiLCJ0eXBlIiwiQUxMX0ZJRUxEX1RZUEVTIiwicmVhbCIsImZpbmQiLCJwYWlyIiwibGF0IiwidmFsdWUiLCJuYW1lIiwibG5nIiwibm9ybWFsaXplZEZpZWxkTmFtZSIsInRvTG93ZXJDYXNlIiwiaGFzRXhjbHVkZWQiLCJmIiwic3RhcnRzV2l0aCIsImVuZHNXaXRoIiwiaGFzSW5jbHVzaW9uIiwic29ydGVkRmllbGRzIiwic29ydCIsImxlZnQiLCJyaWdodCIsIm5vcm1hbGl6ZWRMZWZ0Iiwibm9ybWFsaXplZFJpZ2h0IiwibGVmdEhhc0luY2x1c2lvbiIsImZpbmRJbmRleCIsInJpZ2h0SGFzSW5jbHVzaW9uIiwidmFsaWRhdGVJbnB1dERhdGEiLCJkYXRhIiwiaXNQbGFpbk9iamVjdCIsImFzc2VydCIsIkFycmF5IiwiaXNBcnJheSIsInJvd3MiLCJjb2xzIiwiYWxsVmFsaWQiLCJldmVyeSIsImkiLCJjb25jYXQiLCJfdHlwZW9mMiIsInN0cmluZyIsIkpTT04iLCJzdHJpbmdpZnkiLCJhbmFseXplclR5cGUiLCJ0aW1lc3RhbXAiLCJzYW1wbGUiLCJmaW5kTm9uRW1wdHlSb3dzQXRGaWVsZEFycm93IiwiZmluZE5vbkVtcHR5Um93c0F0RmllbGQiLCJ0cyIsImFuYWx5emVkVHlwZSIsIkFuYWx5emVyIiwiY29tcHV0ZUNvbE1ldGEiLCJjYXRlZ29yeSIsImZvcm1hdCIsIml0ZW0iLCJoM0lzVmFsaWQiLCJzYW1wbGVEYXRhIiwiZ2V0U2FtcGxlRm9yVHlwZUFuYWx5emVBcnJvdyIsImdldFNhbXBsZUZvclR5cGVBbmFseXplIiwiZmllbGRPcmRlciIsIm1ldGEiLCJnZXRGaWVsZHNGcm9tRGF0YSIsInVwZGF0ZWRGaWVsZHMiLCJmaWVsZElkeCIsInRvdGFsIiwiX3Jvd3MkaSIsIm5vdE51bGxvclVuZGVmaW5lZCIsIm51bVJvd3MiLCJnZXQiLCJyb3ciLCJjb2wiLCJUSU1FX0RJU1BMQVkiLCJhZGRUaW1lTGFiZWwiLCJmb3JtYXRzIiwibGFiZWwiLCJUT09MVElQX0ZPUk1BVF9UWVBFUyIsIkRBVEVfVElNRSIsIkRBVEUiLCJnZXRGb3JtYXR0ZXIiLCJnZXRGb3JtYXRWYWx1ZSIsImdldEZpZWxkRm9ybWF0TGFiZWxzIiwiZmllbGRUeXBlIiwidG9vbHRpcFR5cGVzIiwiRklFTERfT1BUUyIsInRvb2x0aXAiLCJmb3JtYXRMYWJlbHMiLCJ2YWx1ZXMiLCJUT09MVElQX0ZPUk1BVFMiLCJpbmNsdWRlcyIsImdldEZvcm1hdExhYmVscyIsImZpZWxkTmFtZSIsIl9maWVsZHMkZmluZCJdLCJzb3VyY2VzIjpbIi4uL3NyYy9kYXRhc2V0LXV0aWxzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbmltcG9ydCAqIGFzIGFycm93IGZyb20gJ2FwYWNoZS1hcnJvdyc7XG5pbXBvcnQge1xuICBBTExfRklFTERfVFlQRVMsXG4gIEZJRUxEX09QVFMsXG4gIFRPT0xUSVBfRk9STUFUUyxcbiAgVE9PTFRJUF9GT1JNQVRfVFlQRVNcbn0gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IHtcbiAgZ2V0U2FtcGxlRm9yVHlwZUFuYWx5emUsXG4gIGdldFNhbXBsZUZvclR5cGVBbmFseXplQXJyb3csXG4gIGdldEZpZWxkc0Zyb21EYXRhXG59IGZyb20gJ0BrZXBsZXIuZ2wvY29tbW9uLXV0aWxzJztcbmltcG9ydCB7QW5hbHl6ZXJ9IGZyb20gJ3R5cGUtYW5hbHl6ZXInO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5pbXBvcnQge1xuICBQcm9jZXNzb3JSZXN1bHQsXG4gIFJHQkNvbG9yLFxuICBGaWVsZCxcbiAgRmllbGRQYWlyLFxuICBUaW1lTGFiZWxGb3JtYXQsXG4gIFRvb2x0aXBGaWVsZHMsXG4gIFByb3RvRGF0YXNldFxufSBmcm9tICdAa2VwbGVyLmdsL3R5cGVzJztcbmltcG9ydCB7VG9vbHRpcEZvcm1hdH0gZnJvbSAnQGtlcGxlci5nbC9jb25zdGFudHMnO1xuaW1wb3J0IHtub3ROdWxsb3JVbmRlZmluZWQsIGgzSXNWYWxpZH0gZnJvbSAnQGtlcGxlci5nbC9jb21tb24tdXRpbHMnO1xuXG5pbXBvcnQge2lzUGxhaW5PYmplY3R9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHtnZXRGb3JtYXR0ZXJ9IGZyb20gJy4vZGF0YS11dGlscyc7XG5pbXBvcnQge2dldEZvcm1hdFZhbHVlfSBmcm9tICcuL2Zvcm1hdCc7XG5pbXBvcnQge2hleFRvUmdifSBmcm9tICcuL2NvbG9yLXV0aWxzJztcblxuLy8gYXBwbHkgYSBjb2xvciBmb3IgZWFjaCBkYXRhc2V0XG4vLyB0byB1c2UgYXMgbGFiZWwgY29sb3JzXG5jb25zdCBkYXRhc2V0Q29sb3JzID0gW1xuICAnIzhGMkZCRicsXG4gICcjMDA1Q0ZGJyxcbiAgJyNDMDZDODQnLFxuICAnI0Y4QjE5NScsXG4gICcjNTQ3QTgyJyxcbiAgJyMzRUFDQTgnLFxuICAnI0EyRDRBQidcbl0ubWFwKGhleFRvUmdiKTtcblxuLyoqXG4gKiBSYW5kb20gY29sb3IgZ2VuZXJhdG9yXG4gKi9cbmZ1bmN0aW9uKiBnZW5lcmF0ZUNvbG9yKCk6IEdlbmVyYXRvcjxSR0JDb2xvcj4ge1xuICBsZXQgaW5kZXggPSAwO1xuICB3aGlsZSAoaW5kZXggPCBkYXRhc2V0Q29sb3JzLmxlbmd0aCArIDEpIHtcbiAgICBpZiAoaW5kZXggPT09IGRhdGFzZXRDb2xvcnMubGVuZ3RoKSB7XG4gICAgICBpbmRleCA9IDA7XG4gICAgfVxuICAgIHlpZWxkIGRhdGFzZXRDb2xvcnNbaW5kZXgrK107XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGRhdGFzZXRDb2xvck1ha2VyID0gZ2VuZXJhdGVDb2xvcigpO1xuXG4vKipcbiAqIEZpZWxkIG5hbWUgcHJlZml4ZXMgYW5kIHN1ZmZpeGVzIHdoaWNoIHNob3VsZCBub3QgYmUgY29uc2lkZXJlZFxuICogYXMgbWV0cmljcy4gRmllbGRzIHdpbGwgc3RpbGwgYmUgaW5jbHVkZWQgaWYgYSAnbWV0cmljIHdvcmQnXG4gKiBpcyBmb3VuZCBvbiB0aGUgZmllbGQgbmFtZSwgaG93ZXZlci5cbiAqL1xuY29uc3QgRVhDTFVERURfREVGQVVMVF9GSUVMRFMgPSBbXG4gIC8vIFNlcmlhbCBudW1iZXJzIGFuZCBpZGVudGlmaWNhdGlvbiBudW1iZXJzXG4gICdfaWQnLFxuICAnaWQnLFxuICAnaW5kZXgnLFxuICAndXVpZCcsXG4gICdndWlkJyxcbiAgJ3VpZCcsXG4gICdnaWQnLFxuICAnc2VyaWFsJyxcbiAgLy8gR2VvZ3JhcGhpYyBJRHMgYXJlIHVubGlrZWx5IHRvIGJlIGludGVyZXN0aW5nIHRvIGNvbG9yXG4gICd6aXAnLFxuICAnY29kZScsXG4gICdwb3N0JyxcbiAgJ3JlZ2lvbicsXG4gICdmaXBzJyxcbiAgJ2NiZ3MnLFxuICAnaDMnLFxuICAnczInLFxuICAvLyBHZW9ncmFwaGljIGNvb3JkcyAoYnV0IG5vdCB6L2VsZXZhdGlvbi9hbHRpdHVkZVxuICAvLyBzaW5jZSB0aGF0IG1pZ2h0IGJlIGEgbWV0cmljKVxuICAnbGF0JyxcbiAgJ2xvbicsXG4gICdsbmcnLFxuICAnbGF0aXR1ZGUnLFxuICAnbG9uZ2l0dWRlJyxcbiAgJ194JyxcbiAgJ195J1xuXTtcblxuLyoqXG4gKiBQcmVmaXhlcyBhbmQgc3VmZml4ZXMgdGhhdCBpbmRpY2F0ZSBhIGZpZWxkIGlzIGEgbWV0cmljLlxuICpcbiAqIE5vdGUgdGhhdCB0aGVzZSBhcmUgaW4gb3JkZXIgb2YgcHJlZmVyZW5jZSwgZmlyc3QgYmVpbmdcbiAqIG1vc3QgcHJlZmVycmVkLlxuICovXG5jb25zdCBNRVRSSUNfREVGQVVMVF9GSUVMRFMgPSBbXG4gICdtZXRyaWMnLFxuICAndmFsdWUnLFxuICAnc3VtJyxcbiAgJ2NvdW50JyxcbiAgJ3VuaXF1ZScsXG4gICdtZWFuJyxcbiAgJ21vZGUnLFxuICAnbWVkaWFuJyxcbiAgJ21heCcsXG4gICdtaW4nLFxuICAnZGV2aWF0aW9uJyxcbiAgJ3ZhcmlhbmNlJyxcbiAgJ3A5OScsXG4gICdwOTUnLFxuICAncDc1JyxcbiAgJ3A1MCcsXG4gICdwMjUnLFxuICAncDA1JyxcbiAgLy8gQWJicmV2aWF0aW9ucyBhcmUgbGVzcyBwcmVmZXJyZWRcbiAgJ2NudCcsXG4gICd2YWwnXG5dO1xuXG4vKipcbiAqIENob29zZSBhIGZpZWxkIHRvIHVzZSBhcyB0aGUgZGVmYXVsdCBjb2xvciBmaWVsZCBvZiBhIGxheWVyLlxuICpcbiAqIFRoZSBoZXVyaXN0aWMgaXM6XG4gKlxuICogRmlyc3QsIGV4Y2x1ZGUgZmllbGRzIHRoYXQgYXJlIG9uIHRoZSBleGNsdXNpb24gbGlzdCBhbmQgZG9uJ3RcbiAqIGhhdmUgbmFtZXMgdGhhdCBzdWdnZXN0IHRoZXkgY29udGFpbiBtZXRyaWNzLiBBbHNvIGV4Y2x1ZGVcbiAqIGZpZWxkIG5hbWVzIHRoYXQgYXJlIGJsYW5rLlxuICpcbiAqIE5leHQsIGxvb2sgZm9yIGEgZmllbGQgdGhhdCBpcyBvZiByZWFsIHR5cGUgYW5kIGNvbnRhaW5zIG9uZVxuICogb2YgdGhlIHByZWZlcnJlZCBuYW1lcyAoaW4gb3JkZXIgb2YgdGhlIHByZWZlcnJlZCBuYW1lcykuXG4gKlxuICogTmV4dCwgbG9vayBmb3IgYSBmaWVsZCB0aGF0IGlzIG9mIGludGVnZXIgdHlwZSBhbmQgY29udGFpbnNcbiAqIG9uZSBvZiB0aGUgcHJlZmVycmVkIG5hbWVzIChpbiBvcmRlciBvZiB0aGUgcHJlZmVycmVkIG5hbWVzKS5cbiAqXG4gKiBOZXh0LCBsb29rIGZvciB0aGUgZmlyc3QgZmllbGQgdGhhdCBpcyBvZiByZWFsIHR5cGUgKGluIG9yZGVyXG4gKiBvZiBmaWVsZCBpbmRleCkuXG4gKlxuICogTmV4dCwgbG9vayBmb3IgdGhlIGZpcnN0IGZpZWxkIHRoYXQgaXMgb2YgaW50ZWdlciB0eXBlIChpblxuICogb3JkZXIgb2YgZmllbGQgaW5kZXgpLlxuICpcbiAqIEl0J3MgcG9zc2libGUgbm8gZmllbGQgd2lsbCBiZSBjaG9zZW4gKGkuZS4gYmVjYXVzZSBhbGwgZmllbGRzXG4gKiBhcmUgc3RyaW5ncy4pXG4gKlxuICogQHBhcmFtIGRhdGFzZXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmREZWZhdWx0Q29sb3JGaWVsZCh7XG4gIGZpZWxkcyxcbiAgZmllbGRQYWlycyA9IFtdXG59OiB7XG4gIGZpZWxkczogRmllbGRbXTtcbiAgZmllbGRQYWlyczogRmllbGRQYWlyW107XG59KTogbnVsbCB8IEZpZWxkIHtcbiAgY29uc3QgZmllbGRzV2l0aG91dEV4Y2x1ZGVkID0gZmllbGRzLmZpbHRlcihmaWVsZCA9PiB7XG4gICAgaWYgKGZpZWxkLnR5cGUgIT09IEFMTF9GSUVMRF9UWVBFUy5yZWFsKSB7XG4gICAgICAvLyBPbmx5IHNlbGVjdCBudW1lcmljIGZpZWxkcy5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgZmllbGRQYWlycy5maW5kKFxuICAgICAgICBwYWlyID0+IHBhaXIucGFpci5sYXQudmFsdWUgPT09IGZpZWxkLm5hbWUgfHwgcGFpci5wYWlyLmxuZy52YWx1ZSA9PT0gZmllbGQubmFtZVxuICAgICAgKVxuICAgICkge1xuICAgICAgLy8gRG8gbm90IHBlcm1pdCBsYXQsIGxvbiBmaWVsZHNcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBub3JtYWxpemVkRmllbGROYW1lID0gZmllbGQubmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChub3JtYWxpemVkRmllbGROYW1lID09PSAnJykge1xuICAgICAgLy8gU3BlY2lhbCBjYXNlIGV4Y2x1ZGVkIG5hbWUgd2hlbiB0aGUgbmFtZSBpcyBibGFuay5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgaGFzRXhjbHVkZWQgPSBFWENMVURFRF9ERUZBVUxUX0ZJRUxEUy5maW5kKFxuICAgICAgZiA9PiBub3JtYWxpemVkRmllbGROYW1lLnN0YXJ0c1dpdGgoZikgfHwgbm9ybWFsaXplZEZpZWxkTmFtZS5lbmRzV2l0aChmKVxuICAgICk7XG4gICAgY29uc3QgaGFzSW5jbHVzaW9uID0gTUVUUklDX0RFRkFVTFRfRklFTERTLmZpbmQoXG4gICAgICBmID0+IG5vcm1hbGl6ZWRGaWVsZE5hbWUuc3RhcnRzV2l0aChmKSB8fCBub3JtYWxpemVkRmllbGROYW1lLmVuZHNXaXRoKGYpXG4gICAgKTtcbiAgICByZXR1cm4gIWhhc0V4Y2x1ZGVkIHx8IGhhc0luY2x1c2lvbjtcbiAgfSk7XG5cbiAgY29uc3Qgc29ydGVkRmllbGRzID0gZmllbGRzV2l0aG91dEV4Y2x1ZGVkLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiB7XG4gICAgY29uc3Qgbm9ybWFsaXplZExlZnQgPSBsZWZ0Lm5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICBjb25zdCBub3JtYWxpemVkUmlnaHQgPSByaWdodC5uYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3QgbGVmdEhhc0luY2x1c2lvbiA9IE1FVFJJQ19ERUZBVUxUX0ZJRUxEUy5maW5kSW5kZXgoXG4gICAgICBmID0+IG5vcm1hbGl6ZWRMZWZ0LnN0YXJ0c1dpdGgoZikgfHwgbm9ybWFsaXplZExlZnQuZW5kc1dpdGgoZilcbiAgICApO1xuICAgIGNvbnN0IHJpZ2h0SGFzSW5jbHVzaW9uID0gTUVUUklDX0RFRkFVTFRfRklFTERTLmZpbmRJbmRleChcbiAgICAgIGYgPT4gbm9ybWFsaXplZFJpZ2h0LnN0YXJ0c1dpdGgoZikgfHwgbm9ybWFsaXplZFJpZ2h0LmVuZHNXaXRoKGYpXG4gICAgKTtcbiAgICBpZiAobGVmdEhhc0luY2x1c2lvbiAhPT0gcmlnaHRIYXNJbmNsdXNpb24pIHtcbiAgICAgIGlmIChsZWZ0SGFzSW5jbHVzaW9uID09PSAtMSkge1xuICAgICAgICAvLyBFbGVtZW50cyB0aGF0IGRvIG5vdCBoYXZlIHRoZSBpbmNsdXNpb24gbGlzdCBzaG91bGQgZ28gYWZ0ZXIgdGhvc2UgdGhhdCBkby5cbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICB9IGVsc2UgaWYgKHJpZ2h0SGFzSW5jbHVzaW9uID09PSAtMSkge1xuICAgICAgICAvLyBFbGVtZW50cyB0aGF0IGRvIGhhdmUgdGhlIGluY2x1c2lvbiBsaXN0IHNob3VsZCBnbyBiZWZvcmUgdGhvc2UgdGhhdCBkb24ndC5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgLy8gQ29tcGFyZSBiYXNlZCBvbiBvcmRlciBpbiB0aGUgaW5jbHVzaW9uIGxpc3RcbiAgICAgIHJldHVybiBsZWZ0SGFzSW5jbHVzaW9uIC0gcmlnaHRIYXNJbmNsdXNpb247XG4gICAgfVxuXG4gICAgLy8gQ29tcGFyZSBiYXNlZCBvbiB0eXBlXG4gICAgaWYgKGxlZnQudHlwZSAhPT0gcmlnaHQudHlwZSkge1xuICAgICAgaWYgKGxlZnQudHlwZSA9PT0gQUxMX0ZJRUxEX1RZUEVTLnJlYWwpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgLy8gbGVmdCBpcyBhbiBpbnRlZ2VyIGFuZCByaWdodCBpcyBub3RcbiAgICAgIC8vIGFuZCByZWFscyBjb21lIGJlZm9yZSBpbnRlZ2Vyc1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuXG4gICAgLy8gRmluYWxseSwgb3JkZXIgYmFzZWQgb24gdGhlIG9yZGVyIGluIHRoZSBkYXRhc2V0cyBjb2x1bW5zXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgIHJldHVybiBsZWZ0LmluZGV4IC0gcmlnaHQuaW5kZXg7XG4gIH0pO1xuXG4gIGlmIChzb3J0ZWRGaWVsZHMubGVuZ3RoKSB7XG4gICAgLy8gVGhlcmUgd2FzIGEgYmVzdCBtYXRjaFxuICAgIHJldHVybiBzb3J0ZWRGaWVsZHNbMF07XG4gIH1cbiAgLy8gTm8gbWF0Y2hlc1xuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBpbnB1dCBkYXRhLCBhZGRpbmcgbWlzc2luZyBmaWVsZCB0eXBlcywgcmVuYW1lIGR1cGxpY2F0ZSBjb2x1bW5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUlucHV0RGF0YShkYXRhOiBQcm90b0RhdGFzZXRbJ2RhdGEnXSk6IFByb2Nlc3NvclJlc3VsdCB7XG4gIGlmICghaXNQbGFpbk9iamVjdChkYXRhKSkge1xuICAgIGFzc2VydCgnYWRkRGF0YVRvTWFwIEVycm9yOiBkYXRhc2V0LmRhdGEgY2Fubm90IGJlIG51bGwnKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfSBlbHNlIGlmICghQXJyYXkuaXNBcnJheShkYXRhLmZpZWxkcykpIHtcbiAgICBhc3NlcnQoJ2FkZERhdGFUb01hcCBFcnJvcjogZXhwZWN0IGRhdGFzZXQuZGF0YS5maWVsZHMgdG8gYmUgYW4gYXJyYXknKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfSBlbHNlIGlmICghQXJyYXkuaXNBcnJheShkYXRhLnJvd3MpICYmICFBcnJheS5pc0FycmF5KGRhdGEuY29scykpIHtcbiAgICBhc3NlcnQoJ2FkZERhdGFUb01hcCBFcnJvcjogZXhwZWN0IGRhdGFzZXQuZGF0YS5yb3dzIG9yIGNvbHMgdG8gYmUgYW4gYXJyYXknKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHtmaWVsZHMsIHJvd3MsIGNvbHN9ID0gZGF0YTtcblxuICAvLyBjaGVjayBpZiBhbGwgZmllbGRzIGhhcyBuYW1lLCBmb3JtYXQgYW5kIHR5cGVcbiAgY29uc3QgYWxsVmFsaWQgPSBmaWVsZHMuZXZlcnkoKGYsIGkpID0+IHtcbiAgICBpZiAoIWlzUGxhaW5PYmplY3QoZikpIHtcbiAgICAgIGFzc2VydChgZmllbGRzIG5lZWRzIHRvIGJlIGFuIGFycmF5IG9mIG9iamVjdCwgYnV0IGZpbmQgJHt0eXBlb2YgZn1gKTtcbiAgICAgIGZpZWxkc1tpXSA9IHtuYW1lOiBgY29sdW1uXyR7aX1gLCB0eXBlOiBBTExfRklFTERfVFlQRVMuc3RyaW5nfTtcbiAgICB9XG5cbiAgICBpZiAoIWYubmFtZSkge1xuICAgICAgYXNzZXJ0KGBmaWVsZC5uYW1lIGlzIHJlcXVpcmVkIGJ1dCBtaXNzaW5nIGluICR7SlNPTi5zdHJpbmdpZnkoZil9YCk7XG4gICAgICAvLyBhc3NpZ24gYSBuYW1lXG4gICAgICBmaWVsZHNbaV0ubmFtZSA9IGBjb2x1bW5fJHtpfWA7XG4gICAgfVxuXG4gICAgaWYgKCFmLnR5cGUgfHwgIUFMTF9GSUVMRF9UWVBFU1tmLnR5cGVdKSB7XG4gICAgICBhc3NlcnQoYHVua25vd24gZmllbGQgdHlwZSAke2YudHlwZX1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoIWYuYW5hbHl6ZXJUeXBlKSB7XG4gICAgICBhc3NlcnQoYGZpZWxkICR7aX0gbWlzc2luZyBhbmFseXplclR5cGVgKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBjaGVjayB0aW1lIGZvcm1hdCBpcyBjb3JyZWN0IGJhc2VkIG9uIGZpcnN0IDEwIG5vdCBlbXB0eSBlbGVtZW50XG4gICAgaWYgKGYudHlwZSA9PT0gQUxMX0ZJRUxEX1RZUEVTLnRpbWVzdGFtcCkge1xuICAgICAgY29uc3Qgc2FtcGxlID0gKFxuICAgICAgICBjb2xzID8gZmluZE5vbkVtcHR5Um93c0F0RmllbGRBcnJvdyhjb2xzLCBpLCAxMCkgOiBmaW5kTm9uRW1wdHlSb3dzQXRGaWVsZChyb3dzLCBpLCAxMClcbiAgICAgICkubWFwKHIgPT4gKHt0czogcltpXX0pKTtcbiAgICAgIGNvbnN0IGFuYWx5emVkVHlwZSA9IEFuYWx5emVyLmNvbXB1dGVDb2xNZXRhKHNhbXBsZSlbMF07XG4gICAgICByZXR1cm4gYW5hbHl6ZWRUeXBlICYmIGFuYWx5emVkVHlwZS5jYXRlZ29yeSA9PT0gJ1RJTUUnICYmIGFuYWx5emVkVHlwZS5mb3JtYXQgPT09IGYuZm9ybWF0O1xuICAgIH1cblxuICAgIC8vIGNoZWNrIGV4aXN0aW5nIHN0cmluZyBmaWVsZCBpcyBIMyB0eXBlXG4gICAgaWYgKGYudHlwZSA9PT0gQUxMX0ZJRUxEX1RZUEVTLnN0cmluZykge1xuICAgICAgY29uc3Qgc2FtcGxlID0gKFxuICAgICAgICBjb2xzID8gZmluZE5vbkVtcHR5Um93c0F0RmllbGRBcnJvdyhjb2xzLCBpLCAxMCkgOiBmaW5kTm9uRW1wdHlSb3dzQXRGaWVsZChyb3dzLCBpLCAxMClcbiAgICAgICkubWFwKHIgPT4gcltpXSk7XG4gICAgICByZXR1cm4gc2FtcGxlLmV2ZXJ5KGl0ZW0gPT4gIWgzSXNWYWxpZChpdGVtKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0pO1xuXG4gIGlmIChhbGxWYWxpZCkge1xuICAgIHJldHVybiB7cm93cywgZmllbGRzLCBjb2xzfTtcbiAgfVxuXG4gIC8vIGlmIGFueSBmaWVsZCBoYXMgbWlzc2luZyB0eXBlLCByZWNhbGN1bGF0ZSBpdCBmb3IgZXZlcnlvbmVcbiAgLy8gYmVjYXVzZSB3ZSBzaW1wbHkgbG9zdCBmYWl0aCBpbiBodW1hbml0eVxuICBjb25zdCBzYW1wbGVEYXRhID0gY29sc1xuICAgID8gZ2V0U2FtcGxlRm9yVHlwZUFuYWx5emVBcnJvdyhcbiAgICAgICAgY29scyxcbiAgICAgICAgZmllbGRzLm1hcChmID0+IGYubmFtZSlcbiAgICAgIClcbiAgICA6IGdldFNhbXBsZUZvclR5cGVBbmFseXplKHtcbiAgICAgICAgZmllbGRzOiBmaWVsZHMubWFwKGYgPT4gZi5uYW1lKSxcbiAgICAgICAgcm93c1xuICAgICAgfSk7XG4gIGNvbnN0IGZpZWxkT3JkZXIgPSBmaWVsZHMubWFwKGYgPT4gZi5uYW1lKTtcbiAgY29uc3QgbWV0YSA9IGdldEZpZWxkc0Zyb21EYXRhKHNhbXBsZURhdGEsIGZpZWxkT3JkZXIpO1xuICBjb25zdCB1cGRhdGVkRmllbGRzID0gZmllbGRzLm1hcCgoZiwgaSkgPT4gKHtcbiAgICAuLi5mLFxuICAgIHR5cGU6IG1ldGFbaV0udHlwZSxcbiAgICBmb3JtYXQ6IG1ldGFbaV0uZm9ybWF0LFxuICAgIGFuYWx5emVyVHlwZTogbWV0YVtpXS5hbmFseXplclR5cGVcbiAgfSkpO1xuXG4gIHJldHVybiB7ZmllbGRzOiB1cGRhdGVkRmllbGRzLCByb3dzLCAuLi4oY29scyA/IHtjb2xzfSA6IHt9KX07XG59XG5cbmZ1bmN0aW9uIGZpbmROb25FbXB0eVJvd3NBdEZpZWxkKHJvd3M6IHVua25vd25bXVtdLCBmaWVsZElkeDogbnVtYmVyLCB0b3RhbDogbnVtYmVyKTogYW55W10ge1xuICBjb25zdCBzYW1wbGU6IGFueVtdID0gW107XG4gIGxldCBpID0gMDtcbiAgd2hpbGUgKHNhbXBsZS5sZW5ndGggPCB0b3RhbCAmJiBpIDwgcm93cy5sZW5ndGgpIHtcbiAgICBpZiAobm90TnVsbG9yVW5kZWZpbmVkKHJvd3NbaV0/LltmaWVsZElkeF0pKSB7XG4gICAgICBzYW1wbGUucHVzaChyb3dzW2ldKTtcbiAgICB9XG4gICAgaSsrO1xuICB9XG4gIHJldHVybiBzYW1wbGU7XG59XG5cbmZ1bmN0aW9uIGZpbmROb25FbXB0eVJvd3NBdEZpZWxkQXJyb3coXG4gIGNvbHM6IGFycm93LlZlY3RvcltdLFxuICBmaWVsZElkeDogbnVtYmVyLFxuICB0b3RhbDogbnVtYmVyXG4pOiBhbnlbXSB7XG4gIGNvbnN0IHNhbXBsZTogYW55W10gPSBbXTtcbiAgY29uc3QgbnVtUm93cyA9IGNvbHNbZmllbGRJZHhdLmxlbmd0aDtcbiAgbGV0IGkgPSAwO1xuICB3aGlsZSAoc2FtcGxlLmxlbmd0aCA8IHRvdGFsICYmIGkgPCBudW1Sb3dzKSB7XG4gICAgaWYgKG5vdE51bGxvclVuZGVmaW5lZChjb2xzW2ZpZWxkSWR4XS5nZXQoaSkpKSB7XG4gICAgICBjb25zdCByb3cgPSBjb2xzLm1hcChjb2wgPT4gY29sLmdldChpKSk7XG4gICAgICBzYW1wbGUucHVzaChyb3cpO1xuICAgIH1cbiAgICBpKys7XG4gIH1cbiAgcmV0dXJuIHNhbXBsZTtcbn1cblxuY29uc3QgVElNRV9ESVNQTEFZID0gJzIwMjAtMDUtMTEgMTQ6MDAnO1xuXG5leHBvcnQgY29uc3QgYWRkVGltZUxhYmVsID0gKGZvcm1hdHM6IFRpbWVMYWJlbEZvcm1hdFtdKSA9PlxuICBmb3JtYXRzLm1hcChmID0+ICh7XG4gICAgLi4uZixcbiAgICBsYWJlbDpcbiAgICAgIGYudHlwZSA9PT0gVE9PTFRJUF9GT1JNQVRfVFlQRVMuREFURV9USU1FIHx8IGYudHlwZSA9PT0gVE9PTFRJUF9GT1JNQVRfVFlQRVMuREFURVxuICAgICAgICA/IGdldEZvcm1hdHRlcihnZXRGb3JtYXRWYWx1ZShmKSkoVElNRV9ESVNQTEFZKVxuICAgICAgICA6IGYubGFiZWxcbiAgfSkpO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmllbGRGb3JtYXRMYWJlbHMoZmllbGRUeXBlPzogc3RyaW5nKTogVG9vbHRpcEZvcm1hdFtdIHtcbiAgY29uc3QgdG9vbHRpcFR5cGVzID0gKGZpZWxkVHlwZSAmJiBGSUVMRF9PUFRTW2ZpZWxkVHlwZV0uZm9ybWF0LnRvb2x0aXApIHx8IFtdO1xuICBjb25zdCBmb3JtYXRMYWJlbHM6IFRpbWVMYWJlbEZvcm1hdFtdID0gT2JqZWN0LnZhbHVlcyhUT09MVElQX0ZPUk1BVFMpLmZpbHRlcih0ID0+XG4gICAgdG9vbHRpcFR5cGVzLmluY2x1ZGVzKHQudHlwZSlcbiAgKTtcbiAgcmV0dXJuIGFkZFRpbWVMYWJlbChmb3JtYXRMYWJlbHMpO1xufVxuXG5leHBvcnQgY29uc3QgZ2V0Rm9ybWF0TGFiZWxzID0gKGZpZWxkczogVG9vbHRpcEZpZWxkc1tdLCBmaWVsZE5hbWU6IHN0cmluZyk6IFRvb2x0aXBGb3JtYXRbXSA9PiB7XG4gIGNvbnN0IGZpZWxkVHlwZSA9IGZpZWxkcy5maW5kKGYgPT4gZi5uYW1lID09PSBmaWVsZE5hbWUpPy50eXBlO1xuICByZXR1cm4gZ2V0RmllbGRGb3JtYXRMYWJlbHMoZmllbGRUeXBlKTtcbn07XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O0FBSUEsSUFBQUEsVUFBQSxHQUFBQyxPQUFBO0FBTUEsSUFBQUMsWUFBQSxHQUFBRCxPQUFBO0FBS0EsSUFBQUUsYUFBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcsT0FBQSxHQUFBQyxzQkFBQSxDQUFBSixPQUFBO0FBY0EsSUFBQUssTUFBQSxHQUFBTCxPQUFBO0FBQ0EsSUFBQU0sVUFBQSxHQUFBTixPQUFBO0FBQ0EsSUFBQU8sT0FBQSxHQUFBUCxPQUFBO0FBQ0EsSUFBQVEsV0FBQSxHQUFBUixPQUFBO0FBQXVDLFNBQUFTLFFBQUFDLENBQUEsRUFBQUMsQ0FBQSxRQUFBQyxDQUFBLEdBQUFDLE1BQUEsQ0FBQUMsSUFBQSxDQUFBSixDQUFBLE9BQUFHLE1BQUEsQ0FBQUUscUJBQUEsUUFBQUMsQ0FBQSxHQUFBSCxNQUFBLENBQUFFLHFCQUFBLENBQUFMLENBQUEsR0FBQUMsQ0FBQSxLQUFBSyxDQUFBLEdBQUFBLENBQUEsQ0FBQUMsTUFBQSxXQUFBTixDQUFBLFdBQUFFLE1BQUEsQ0FBQUssd0JBQUEsQ0FBQVIsQ0FBQSxFQUFBQyxDQUFBLEVBQUFRLFVBQUEsT0FBQVAsQ0FBQSxDQUFBUSxJQUFBLENBQUFDLEtBQUEsQ0FBQVQsQ0FBQSxFQUFBSSxDQUFBLFlBQUFKLENBQUE7QUFBQSxTQUFBVSxjQUFBWixDQUFBLGFBQUFDLENBQUEsTUFBQUEsQ0FBQSxHQUFBWSxTQUFBLENBQUFDLE1BQUEsRUFBQWIsQ0FBQSxVQUFBQyxDQUFBLFdBQUFXLFNBQUEsQ0FBQVosQ0FBQSxJQUFBWSxTQUFBLENBQUFaLENBQUEsUUFBQUEsQ0FBQSxPQUFBRixPQUFBLENBQUFJLE1BQUEsQ0FBQUQsQ0FBQSxPQUFBYSxPQUFBLFdBQUFkLENBQUEsUUFBQWUsZ0JBQUEsYUFBQWhCLENBQUEsRUFBQUMsQ0FBQSxFQUFBQyxDQUFBLENBQUFELENBQUEsU0FBQUUsTUFBQSxDQUFBYyx5QkFBQSxHQUFBZCxNQUFBLENBQUFlLGdCQUFBLENBQUFsQixDQUFBLEVBQUFHLE1BQUEsQ0FBQWMseUJBQUEsQ0FBQWYsQ0FBQSxLQUFBSCxPQUFBLENBQUFJLE1BQUEsQ0FBQUQsQ0FBQSxHQUFBYSxPQUFBLFdBQUFkLENBQUEsSUFBQUUsTUFBQSxDQUFBZ0IsY0FBQSxDQUFBbkIsQ0FBQSxFQUFBQyxDQUFBLEVBQUFFLE1BQUEsQ0FBQUssd0JBQUEsQ0FBQU4sQ0FBQSxFQUFBRCxDQUFBLGlCQUFBRCxDQUFBO0FBQUEsSUFBQW9CLE9BQUEsZ0JBQUFDLFlBQUEsWUFBQUMsSUFBQSxDQWlCN0JDLGFBQWEsR0FsRHZCO0FBQ0E7QUFrQ0E7QUFDQTtBQUNBLElBQU1DLGFBQWEsR0FBRyxDQUNwQixTQUFTLEVBQ1QsU0FBUyxFQUNULFNBQVMsRUFDVCxTQUFTLEVBQ1QsU0FBUyxFQUNULFNBQVMsRUFDVCxTQUFTLENBQ1YsQ0FBQ0MsR0FBRyxDQUFDQyxvQkFBUSxDQUFDOztBQUVmO0FBQ0E7QUFDQTtBQUNBLFNBQVVILGFBQWFBLENBQUE7RUFBQSxJQUFBSSxLQUFBO0VBQUEsT0FBQU4sWUFBQSxZQUFBTyxJQUFBLFVBQUFDLGVBQUFDLFFBQUE7SUFBQSxrQkFBQUEsUUFBQSxDQUFBQyxJQUFBLEdBQUFELFFBQUEsQ0FBQUUsSUFBQTtNQUFBO1FBQ2pCTCxLQUFLLEdBQUcsQ0FBQztNQUFBO1FBQUEsTUFDTkEsS0FBSyxHQUFHSCxhQUFhLENBQUNWLE1BQU0sR0FBRyxDQUFDO1VBQUFnQixRQUFBLENBQUFFLElBQUE7VUFBQTtRQUFBO1FBQ3JDLElBQUlMLEtBQUssS0FBS0gsYUFBYSxDQUFDVixNQUFNLEVBQUU7VUFDbENhLEtBQUssR0FBRyxDQUFDO1FBQ1g7UUFBQ0csUUFBQSxDQUFBRSxJQUFBO1FBQ0QsT0FBTVIsYUFBYSxDQUFDRyxLQUFLLEVBQUUsQ0FBQztNQUFBO1FBQUFHLFFBQUEsQ0FBQUUsSUFBQTtRQUFBO01BQUE7TUFBQTtRQUFBLE9BQUFGLFFBQUEsQ0FBQUcsSUFBQTtJQUFBO0VBQUEsR0FBQWIsT0FBQTtBQUFBO0FBSXpCLElBQU1jLGlCQUFpQixHQUFBQyxPQUFBLENBQUFELGlCQUFBLEdBQUdYLGFBQWEsQ0FBQyxDQUFDOztBQUVoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBTWEsdUJBQXVCLEdBQUc7QUFDOUI7QUFDQSxLQUFLLEVBQ0wsSUFBSSxFQUNKLE9BQU8sRUFDUCxNQUFNLEVBQ04sTUFBTSxFQUNOLEtBQUssRUFDTCxLQUFLLEVBQ0wsUUFBUTtBQUNSO0FBQ0EsS0FBSyxFQUNMLE1BQU0sRUFDTixNQUFNLEVBQ04sUUFBUSxFQUNSLE1BQU0sRUFDTixNQUFNLEVBQ04sSUFBSSxFQUNKLElBQUk7QUFDSjtBQUNBO0FBQ0EsS0FBSyxFQUNMLEtBQUssRUFDTCxLQUFLLEVBQ0wsVUFBVSxFQUNWLFdBQVcsRUFDWCxJQUFJLEVBQ0osSUFBSSxDQUNMOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQU1DLHFCQUFxQixHQUFHLENBQzVCLFFBQVEsRUFDUixPQUFPLEVBQ1AsS0FBSyxFQUNMLE9BQU8sRUFDUCxRQUFRLEVBQ1IsTUFBTSxFQUNOLE1BQU0sRUFDTixRQUFRLEVBQ1IsS0FBSyxFQUNMLEtBQUssRUFDTCxXQUFXLEVBQ1gsVUFBVSxFQUNWLEtBQUssRUFDTCxLQUFLLEVBQ0wsS0FBSyxFQUNMLEtBQUssRUFDTCxLQUFLLEVBQ0wsS0FBSztBQUNMO0FBQ0EsS0FBSyxFQUNMLEtBQUssQ0FDTjs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0MscUJBQXFCQSxDQUFBQyxJQUFBLEVBTXBCO0VBQUEsSUFMZkMsTUFBTSxHQUFBRCxJQUFBLENBQU5DLE1BQU07SUFBQUMsZUFBQSxHQUFBRixJQUFBLENBQ05HLFVBQVU7SUFBVkEsVUFBVSxHQUFBRCxlQUFBLGNBQUcsRUFBRSxHQUFBQSxlQUFBO0VBS2YsSUFBTUUscUJBQXFCLEdBQUdILE1BQU0sQ0FBQ2pDLE1BQU0sQ0FBQyxVQUFBcUMsS0FBSyxFQUFJO0lBQ25ELElBQUlBLEtBQUssQ0FBQ0MsSUFBSSxLQUFLQywwQkFBZSxDQUFDQyxJQUFJLEVBQUU7TUFDdkM7TUFDQSxPQUFPLEtBQUs7SUFDZDtJQUNBLElBQ0VMLFVBQVUsQ0FBQ00sSUFBSSxDQUNiLFVBQUFDLElBQUk7TUFBQSxPQUFJQSxJQUFJLENBQUNBLElBQUksQ0FBQ0MsR0FBRyxDQUFDQyxLQUFLLEtBQUtQLEtBQUssQ0FBQ1EsSUFBSSxJQUFJSCxJQUFJLENBQUNBLElBQUksQ0FBQ0ksR0FBRyxDQUFDRixLQUFLLEtBQUtQLEtBQUssQ0FBQ1EsSUFBSTtJQUFBLENBQ2xGLENBQUMsRUFDRDtNQUNBO01BQ0EsT0FBTyxLQUFLO0lBQ2Q7SUFFQSxJQUFNRSxtQkFBbUIsR0FBR1YsS0FBSyxDQUFDUSxJQUFJLENBQUNHLFdBQVcsQ0FBQyxDQUFDO0lBQ3BELElBQUlELG1CQUFtQixLQUFLLEVBQUUsRUFBRTtNQUM5QjtNQUNBLE9BQU8sS0FBSztJQUNkO0lBQ0EsSUFBTUUsV0FBVyxHQUFHcEIsdUJBQXVCLENBQUNZLElBQUksQ0FDOUMsVUFBQVMsQ0FBQztNQUFBLE9BQUlILG1CQUFtQixDQUFDSSxVQUFVLENBQUNELENBQUMsQ0FBQyxJQUFJSCxtQkFBbUIsQ0FBQ0ssUUFBUSxDQUFDRixDQUFDLENBQUM7SUFBQSxDQUMzRSxDQUFDO0lBQ0QsSUFBTUcsWUFBWSxHQUFHdkIscUJBQXFCLENBQUNXLElBQUksQ0FDN0MsVUFBQVMsQ0FBQztNQUFBLE9BQUlILG1CQUFtQixDQUFDSSxVQUFVLENBQUNELENBQUMsQ0FBQyxJQUFJSCxtQkFBbUIsQ0FBQ0ssUUFBUSxDQUFDRixDQUFDLENBQUM7SUFBQSxDQUMzRSxDQUFDO0lBQ0QsT0FBTyxDQUFDRCxXQUFXLElBQUlJLFlBQVk7RUFDckMsQ0FBQyxDQUFDO0VBRUYsSUFBTUMsWUFBWSxHQUFHbEIscUJBQXFCLENBQUNtQixJQUFJLENBQUMsVUFBQ0MsSUFBSSxFQUFFQyxLQUFLLEVBQUs7SUFDL0QsSUFBTUMsY0FBYyxHQUFHRixJQUFJLENBQUNYLElBQUksQ0FBQ0csV0FBVyxDQUFDLENBQUM7SUFDOUMsSUFBTVcsZUFBZSxHQUFHRixLQUFLLENBQUNaLElBQUksQ0FBQ0csV0FBVyxDQUFDLENBQUM7SUFDaEQsSUFBTVksZ0JBQWdCLEdBQUc5QixxQkFBcUIsQ0FBQytCLFNBQVMsQ0FDdEQsVUFBQVgsQ0FBQztNQUFBLE9BQUlRLGNBQWMsQ0FBQ1AsVUFBVSxDQUFDRCxDQUFDLENBQUMsSUFBSVEsY0FBYyxDQUFDTixRQUFRLENBQUNGLENBQUMsQ0FBQztJQUFBLENBQ2pFLENBQUM7SUFDRCxJQUFNWSxpQkFBaUIsR0FBR2hDLHFCQUFxQixDQUFDK0IsU0FBUyxDQUN2RCxVQUFBWCxDQUFDO01BQUEsT0FBSVMsZUFBZSxDQUFDUixVQUFVLENBQUNELENBQUMsQ0FBQyxJQUFJUyxlQUFlLENBQUNQLFFBQVEsQ0FBQ0YsQ0FBQyxDQUFDO0lBQUEsQ0FDbkUsQ0FBQztJQUNELElBQUlVLGdCQUFnQixLQUFLRSxpQkFBaUIsRUFBRTtNQUMxQyxJQUFJRixnQkFBZ0IsS0FBSyxDQUFDLENBQUMsRUFBRTtRQUMzQjtRQUNBLE9BQU8sQ0FBQztNQUNWLENBQUMsTUFBTSxJQUFJRSxpQkFBaUIsS0FBSyxDQUFDLENBQUMsRUFBRTtRQUNuQztRQUNBLE9BQU8sQ0FBQyxDQUFDO01BQ1g7TUFDQTtNQUNBLE9BQU9GLGdCQUFnQixHQUFHRSxpQkFBaUI7SUFDN0M7O0lBRUE7SUFDQSxJQUFJTixJQUFJLENBQUNsQixJQUFJLEtBQUttQixLQUFLLENBQUNuQixJQUFJLEVBQUU7TUFDNUIsSUFBSWtCLElBQUksQ0FBQ2xCLElBQUksS0FBS0MsMEJBQWUsQ0FBQ0MsSUFBSSxFQUFFO1FBQ3RDLE9BQU8sQ0FBQyxDQUFDO01BQ1g7TUFDQTtNQUNBO01BQ0EsT0FBTyxDQUFDO0lBQ1Y7O0lBRUE7SUFDQTtJQUNBLE9BQU9nQixJQUFJLENBQUNwQyxLQUFLLEdBQUdxQyxLQUFLLENBQUNyQyxLQUFLO0VBQ2pDLENBQUMsQ0FBQztFQUVGLElBQUlrQyxZQUFZLENBQUMvQyxNQUFNLEVBQUU7SUFDdkI7SUFDQSxPQUFPK0MsWUFBWSxDQUFDLENBQUMsQ0FBQztFQUN4QjtFQUNBO0VBQ0EsT0FBTyxJQUFJO0FBQ2I7O0FBRUE7QUFDQTtBQUNBO0FBQ08sU0FBU1MsaUJBQWlCQSxDQUFDQyxJQUEwQixFQUFtQjtFQUM3RSxJQUFJLENBQUMsSUFBQUMsb0JBQWEsRUFBQ0QsSUFBSSxDQUFDLEVBQUU7SUFDeEIsSUFBQUUsa0JBQU0sRUFBQyxpREFBaUQsQ0FBQztJQUN6RCxPQUFPLElBQUk7RUFDYixDQUFDLE1BQU0sSUFBSSxDQUFDQyxLQUFLLENBQUNDLE9BQU8sQ0FBQ0osSUFBSSxDQUFDL0IsTUFBTSxDQUFDLEVBQUU7SUFDdEMsSUFBQWlDLGtCQUFNLEVBQUMsK0RBQStELENBQUM7SUFDdkUsT0FBTyxJQUFJO0VBQ2IsQ0FBQyxNQUFNLElBQUksQ0FBQ0MsS0FBSyxDQUFDQyxPQUFPLENBQUNKLElBQUksQ0FBQ0ssSUFBSSxDQUFDLElBQUksQ0FBQ0YsS0FBSyxDQUFDQyxPQUFPLENBQUNKLElBQUksQ0FBQ00sSUFBSSxDQUFDLEVBQUU7SUFDakUsSUFBQUosa0JBQU0sRUFBQyxxRUFBcUUsQ0FBQztJQUM3RSxPQUFPLElBQUk7RUFDYjtFQUVBLElBQU9qQyxNQUFNLEdBQWdCK0IsSUFBSSxDQUExQi9CLE1BQU07SUFBRW9DLElBQUksR0FBVUwsSUFBSSxDQUFsQkssSUFBSTtJQUFFQyxJQUFJLEdBQUlOLElBQUksQ0FBWk0sSUFBSTs7RUFFekI7RUFDQSxJQUFNQyxRQUFRLEdBQUd0QyxNQUFNLENBQUN1QyxLQUFLLENBQUMsVUFBQ3RCLENBQUMsRUFBRXVCLENBQUMsRUFBSztJQUN0QyxJQUFJLENBQUMsSUFBQVIsb0JBQWEsRUFBQ2YsQ0FBQyxDQUFDLEVBQUU7TUFDckIsSUFBQWdCLGtCQUFNLHFEQUFBUSxNQUFBLEtBQUFDLFFBQUEsYUFBMkR6QixDQUFDLEVBQUUsQ0FBQztNQUNyRWpCLE1BQU0sQ0FBQ3dDLENBQUMsQ0FBQyxHQUFHO1FBQUM1QixJQUFJLFlBQUE2QixNQUFBLENBQVlELENBQUMsQ0FBRTtRQUFFbkMsSUFBSSxFQUFFQywwQkFBZSxDQUFDcUM7TUFBTSxDQUFDO0lBQ2pFO0lBRUEsSUFBSSxDQUFDMUIsQ0FBQyxDQUFDTCxJQUFJLEVBQUU7TUFDWCxJQUFBcUIsa0JBQU0sMkNBQUFRLE1BQUEsQ0FBMENHLElBQUksQ0FBQ0MsU0FBUyxDQUFDNUIsQ0FBQyxDQUFDLENBQUUsQ0FBQztNQUNwRTtNQUNBakIsTUFBTSxDQUFDd0MsQ0FBQyxDQUFDLENBQUM1QixJQUFJLGFBQUE2QixNQUFBLENBQWFELENBQUMsQ0FBRTtJQUNoQztJQUVBLElBQUksQ0FBQ3ZCLENBQUMsQ0FBQ1osSUFBSSxJQUFJLENBQUNDLDBCQUFlLENBQUNXLENBQUMsQ0FBQ1osSUFBSSxDQUFDLEVBQUU7TUFDdkMsSUFBQTRCLGtCQUFNLHdCQUFBUSxNQUFBLENBQXVCeEIsQ0FBQyxDQUFDWixJQUFJLENBQUUsQ0FBQztNQUN0QyxPQUFPLEtBQUs7SUFDZDtJQUVBLElBQUksQ0FBQ1ksQ0FBQyxDQUFDNkIsWUFBWSxFQUFFO01BQ25CLElBQUFiLGtCQUFNLFdBQUFRLE1BQUEsQ0FBVUQsQ0FBQywwQkFBdUIsQ0FBQztNQUN6QyxPQUFPLEtBQUs7SUFDZDs7SUFFQTtJQUNBLElBQUl2QixDQUFDLENBQUNaLElBQUksS0FBS0MsMEJBQWUsQ0FBQ3lDLFNBQVMsRUFBRTtNQUN4QyxJQUFNQyxNQUFNLEdBQUcsQ0FDYlgsSUFBSSxHQUFHWSw0QkFBNEIsQ0FBQ1osSUFBSSxFQUFFRyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUdVLHVCQUF1QixDQUFDZCxJQUFJLEVBQUVJLENBQUMsRUFBRSxFQUFFLENBQUMsRUFDdkZ2RCxHQUFHLENBQUMsVUFBQXhCLENBQUM7UUFBQSxPQUFLO1VBQUMwRixFQUFFLEVBQUUxRixDQUFDLENBQUMrRSxDQUFDO1FBQUMsQ0FBQztNQUFBLENBQUMsQ0FBQztNQUN4QixJQUFNWSxZQUFZLEdBQUdDLHNCQUFRLENBQUNDLGNBQWMsQ0FBQ04sTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO01BQ3ZELE9BQU9JLFlBQVksSUFBSUEsWUFBWSxDQUFDRyxRQUFRLEtBQUssTUFBTSxJQUFJSCxZQUFZLENBQUNJLE1BQU0sS0FBS3ZDLENBQUMsQ0FBQ3VDLE1BQU07SUFDN0Y7O0lBRUE7SUFDQSxJQUFJdkMsQ0FBQyxDQUFDWixJQUFJLEtBQUtDLDBCQUFlLENBQUNxQyxNQUFNLEVBQUU7TUFDckMsSUFBTUssT0FBTSxHQUFHLENBQ2JYLElBQUksR0FBR1ksNEJBQTRCLENBQUNaLElBQUksRUFBRUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHVSx1QkFBdUIsQ0FBQ2QsSUFBSSxFQUFFSSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQ3ZGdkQsR0FBRyxDQUFDLFVBQUF4QixDQUFDO1FBQUEsT0FBSUEsQ0FBQyxDQUFDK0UsQ0FBQyxDQUFDO01BQUEsRUFBQztNQUNoQixPQUFPUSxPQUFNLENBQUNULEtBQUssQ0FBQyxVQUFBa0IsSUFBSTtRQUFBLE9BQUksQ0FBQyxJQUFBQyxzQkFBUyxFQUFDRCxJQUFJLENBQUM7TUFBQSxFQUFDO0lBQy9DO0lBRUEsT0FBTyxJQUFJO0VBQ2IsQ0FBQyxDQUFDO0VBRUYsSUFBSW5CLFFBQVEsRUFBRTtJQUNaLE9BQU87TUFBQ0YsSUFBSSxFQUFKQSxJQUFJO01BQUVwQyxNQUFNLEVBQU5BLE1BQU07TUFBRXFDLElBQUksRUFBSkE7SUFBSSxDQUFDO0VBQzdCOztFQUVBO0VBQ0E7RUFDQSxJQUFNc0IsVUFBVSxHQUFHdEIsSUFBSSxHQUNuQixJQUFBdUIseUNBQTRCLEVBQzFCdkIsSUFBSSxFQUNKckMsTUFBTSxDQUFDZixHQUFHLENBQUMsVUFBQWdDLENBQUM7SUFBQSxPQUFJQSxDQUFDLENBQUNMLElBQUk7RUFBQSxFQUN4QixDQUFDLEdBQ0QsSUFBQWlELG9DQUF1QixFQUFDO0lBQ3RCN0QsTUFBTSxFQUFFQSxNQUFNLENBQUNmLEdBQUcsQ0FBQyxVQUFBZ0MsQ0FBQztNQUFBLE9BQUlBLENBQUMsQ0FBQ0wsSUFBSTtJQUFBLEVBQUM7SUFDL0J3QixJQUFJLEVBQUpBO0VBQ0YsQ0FBQyxDQUFDO0VBQ04sSUFBTTBCLFVBQVUsR0FBRzlELE1BQU0sQ0FBQ2YsR0FBRyxDQUFDLFVBQUFnQyxDQUFDO0lBQUEsT0FBSUEsQ0FBQyxDQUFDTCxJQUFJO0VBQUEsRUFBQztFQUMxQyxJQUFNbUQsSUFBSSxHQUFHLElBQUFDLDhCQUFpQixFQUFDTCxVQUFVLEVBQUVHLFVBQVUsQ0FBQztFQUN0RCxJQUFNRyxhQUFhLEdBQUdqRSxNQUFNLENBQUNmLEdBQUcsQ0FBQyxVQUFDZ0MsQ0FBQyxFQUFFdUIsQ0FBQztJQUFBLE9BQUFwRSxhQUFBLENBQUFBLGFBQUEsS0FDakM2QyxDQUFDO01BQ0paLElBQUksRUFBRTBELElBQUksQ0FBQ3ZCLENBQUMsQ0FBQyxDQUFDbkMsSUFBSTtNQUNsQm1ELE1BQU0sRUFBRU8sSUFBSSxDQUFDdkIsQ0FBQyxDQUFDLENBQUNnQixNQUFNO01BQ3RCVixZQUFZLEVBQUVpQixJQUFJLENBQUN2QixDQUFDLENBQUMsQ0FBQ007SUFBWTtFQUFBLENBQ2xDLENBQUM7RUFFSCxPQUFBMUUsYUFBQTtJQUFRNEIsTUFBTSxFQUFFaUUsYUFBYTtJQUFFN0IsSUFBSSxFQUFKQTtFQUFJLEdBQU1DLElBQUksR0FBRztJQUFDQSxJQUFJLEVBQUpBO0VBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUM3RDtBQUVBLFNBQVNhLHVCQUF1QkEsQ0FBQ2QsSUFBaUIsRUFBRThCLFFBQWdCLEVBQUVDLEtBQWEsRUFBUztFQUMxRixJQUFNbkIsTUFBYSxHQUFHLEVBQUU7RUFDeEIsSUFBSVIsQ0FBQyxHQUFHLENBQUM7RUFDVCxPQUFPUSxNQUFNLENBQUMxRSxNQUFNLEdBQUc2RixLQUFLLElBQUkzQixDQUFDLEdBQUdKLElBQUksQ0FBQzlELE1BQU0sRUFBRTtJQUFBLElBQUE4RixPQUFBO0lBQy9DLElBQUksSUFBQUMsK0JBQWtCLEdBQUFELE9BQUEsR0FBQ2hDLElBQUksQ0FBQ0ksQ0FBQyxDQUFDLGNBQUE0QixPQUFBLHVCQUFQQSxPQUFBLENBQVVGLFFBQVEsQ0FBQyxDQUFDLEVBQUU7TUFDM0NsQixNQUFNLENBQUM5RSxJQUFJLENBQUNrRSxJQUFJLENBQUNJLENBQUMsQ0FBQyxDQUFDO0lBQ3RCO0lBQ0FBLENBQUMsRUFBRTtFQUNMO0VBQ0EsT0FBT1EsTUFBTTtBQUNmO0FBRUEsU0FBU0MsNEJBQTRCQSxDQUNuQ1osSUFBb0IsRUFDcEI2QixRQUFnQixFQUNoQkMsS0FBYSxFQUNOO0VBQ1AsSUFBTW5CLE1BQWEsR0FBRyxFQUFFO0VBQ3hCLElBQU1zQixPQUFPLEdBQUdqQyxJQUFJLENBQUM2QixRQUFRLENBQUMsQ0FBQzVGLE1BQU07RUFDckMsSUFBSWtFLENBQUMsR0FBRyxDQUFDO0VBQ1QsT0FBT1EsTUFBTSxDQUFDMUUsTUFBTSxHQUFHNkYsS0FBSyxJQUFJM0IsQ0FBQyxHQUFHOEIsT0FBTyxFQUFFO0lBQzNDLElBQUksSUFBQUQsK0JBQWtCLEVBQUNoQyxJQUFJLENBQUM2QixRQUFRLENBQUMsQ0FBQ0ssR0FBRyxDQUFDL0IsQ0FBQyxDQUFDLENBQUMsRUFBRTtNQUM3QyxJQUFNZ0MsR0FBRyxHQUFHbkMsSUFBSSxDQUFDcEQsR0FBRyxDQUFDLFVBQUF3RixHQUFHO1FBQUEsT0FBSUEsR0FBRyxDQUFDRixHQUFHLENBQUMvQixDQUFDLENBQUM7TUFBQSxFQUFDO01BQ3ZDUSxNQUFNLENBQUM5RSxJQUFJLENBQUNzRyxHQUFHLENBQUM7SUFDbEI7SUFDQWhDLENBQUMsRUFBRTtFQUNMO0VBQ0EsT0FBT1EsTUFBTTtBQUNmO0FBRUEsSUFBTTBCLFlBQVksR0FBRyxrQkFBa0I7QUFFaEMsSUFBTUMsWUFBWSxHQUFBaEYsT0FBQSxDQUFBZ0YsWUFBQSxHQUFHLFNBQWZBLFlBQVlBLENBQUlDLE9BQTBCO0VBQUEsT0FDckRBLE9BQU8sQ0FBQzNGLEdBQUcsQ0FBQyxVQUFBZ0MsQ0FBQztJQUFBLE9BQUE3QyxhQUFBLENBQUFBLGFBQUEsS0FDUjZDLENBQUM7TUFDSjRELEtBQUssRUFDSDVELENBQUMsQ0FBQ1osSUFBSSxLQUFLeUUsK0JBQW9CLENBQUNDLFNBQVMsSUFBSTlELENBQUMsQ0FBQ1osSUFBSSxLQUFLeUUsK0JBQW9CLENBQUNFLElBQUksR0FDN0UsSUFBQUMsdUJBQVksRUFBQyxJQUFBQyxzQkFBYyxFQUFDakUsQ0FBQyxDQUFDLENBQUMsQ0FBQ3lELFlBQVksQ0FBQyxHQUM3Q3pELENBQUMsQ0FBQzREO0lBQUs7RUFBQSxDQUNiLENBQUM7QUFBQTtBQUVFLFNBQVNNLG9CQUFvQkEsQ0FBQ0MsU0FBa0IsRUFBbUI7RUFDeEUsSUFBTUMsWUFBWSxHQUFJRCxTQUFTLElBQUlFLHFCQUFVLENBQUNGLFNBQVMsQ0FBQyxDQUFDNUIsTUFBTSxDQUFDK0IsT0FBTyxJQUFLLEVBQUU7RUFDOUUsSUFBTUMsWUFBK0IsR0FBRzdILE1BQU0sQ0FBQzhILE1BQU0sQ0FBQ0MsMEJBQWUsQ0FBQyxDQUFDM0gsTUFBTSxDQUFDLFVBQUFMLENBQUM7SUFBQSxPQUM3RTJILFlBQVksQ0FBQ00sUUFBUSxDQUFDakksQ0FBQyxDQUFDMkMsSUFBSSxDQUFDO0VBQUEsQ0FDL0IsQ0FBQztFQUNELE9BQU9zRSxZQUFZLENBQUNhLFlBQVksQ0FBQztBQUNuQztBQUVPLElBQU1JLGVBQWUsR0FBQWpHLE9BQUEsQ0FBQWlHLGVBQUEsR0FBRyxTQUFsQkEsZUFBZUEsQ0FBSTVGLE1BQXVCLEVBQUU2RixTQUFpQixFQUFzQjtFQUFBLElBQUFDLFlBQUE7RUFDOUYsSUFBTVYsU0FBUyxJQUFBVSxZQUFBLEdBQUc5RixNQUFNLENBQUNRLElBQUksQ0FBQyxVQUFBUyxDQUFDO0lBQUEsT0FBSUEsQ0FBQyxDQUFDTCxJQUFJLEtBQUtpRixTQUFTO0VBQUEsRUFBQyxjQUFBQyxZQUFBLHVCQUF0Q0EsWUFBQSxDQUF3Q3pGLElBQUk7RUFDOUQsT0FBTzhFLG9CQUFvQixDQUFDQyxTQUFTLENBQUM7QUFDeEMsQ0FBQyIsImlnbm9yZUxpc3QiOltdfQ==