From 959e9750f3071f027a4a4ead5554d7cb3711e11b Mon Sep 17 00:00:00 2001 From: blair2004 Date: Mon, 15 Mar 2021 02:30:00 +0100 Subject: [PATCH] Update --- public/js/app.js | 12 ------------ public/js/pos-init.js | 9 --------- public/js/pos.js | 4 ---- public/js/vendor.js | 7 ------- 4 files changed, 32 deletions(-) diff --git a/public/js/app.js b/public/js/app.js index 0ddf07d1a..0438e4772 100755 --- a/public/js/app.js +++ b/public/js/app.js @@ -128,11 +128,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _lib /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -<<<<<<< HEAD -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _libraries_form_validation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/libraries/form-validation */ \"./resources/ts/libraries/form-validation.ts\");\n/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/bootstrap */ \"./resources/ts/bootstrap.ts\");\n/* harmony import */ var _popups_ns_pos_confirm_popup_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/popups/ns-pos-confirm-popup.vue */ \"./resources/ts/popups/ns-pos-confirm-popup.vue\");\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _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; }\n\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n data: function data() {\n return {\n formValidation: new _libraries_form_validation__WEBPACK_IMPORTED_MODULE_0__[\"default\"](),\n nsSnackBar: _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"],\n nsHttpClient: _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"],\n _sampleVariation: null,\n form: ''\n };\n },\n computed: {\n defaultVariation: function defaultVariation() {\n var newVariation = new Object();\n\n for (var tabIndex in this._sampleVariation.tabs) {\n newVariation[tabIndex] = new Object();\n newVariation[tabIndex].label = this._sampleVariation.tabs[tabIndex].label;\n newVariation[tabIndex].active = this._sampleVariation.tabs[tabIndex].active;\n newVariation[tabIndex].fields = this._sampleVariation.tabs[tabIndex].fields.filter(function (field) {\n console.log(field);\n return !['category_id', 'product_type', 'stock_management', 'expires'].includes(field.name);\n }).map(function (field) {\n field.value = '';\n return field;\n });\n }\n\n return {\n id: '',\n tabs: newVariation\n };\n }\n },\n props: ['submit-method', 'submit-url', 'return-url', 'src', 'units-url'],\n methods: {\n getUnitQuantity: function getUnitQuantity(fields) {\n var quantity = fields.filter(function (f) {\n return f.name === 'quantity';\n }).map(function (f) {\n return f.value;\n });\n return quantity.length > 0 ? quantity[0] : 0;\n },\n\n /**\r\n * The user want to remove a group\r\n * we might need confirmation before proceeding.\r\n */\n removeUnitPriceGroup: function removeUnitPriceGroup(group_fields, group) {\n var _this = this;\n\n var hasIdField = group_fields.filter(function (field) {\n return field.name === 'id';\n });\n Popup.show(_popups_ns_pos_confirm_popup_vue__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n title: 'Confirm Your Action',\n message: 'Would you like to delete this group ?',\n onAction: function onAction(action) {\n if (action) {\n if (hasIdField.length > 0) {\n _this.confirmUnitQuantityDeletion({\n group_fields: group_fields,\n group: group\n });\n } else {\n var index = group.indexOf(group_fields);\n group.splice(index, 1);\n }\n }\n }\n });\n },\n confirmUnitQuantityDeletion: function confirmUnitQuantityDeletion(_ref) {\n var group_fields = _ref.group_fields,\n group = _ref.group;\n Popup.show(_popups_ns_pos_confirm_popup_vue__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n title: 'Your Attention Is Required',\n size: 'w-3/4-screen h-2/5-screen',\n message: 'The current unit you\\'re about to delete has a reference on the database and it might have already procured stock. Deleting that reference will remove procured stock. Would you proceed ?',\n onAction: function onAction(action) {\n if (action) {\n var id = group_fields.filter(function (f) {\n return f.name === 'id';\n }).map(function (f) {\n return f.value;\n })[0];\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"][\"delete\"](\"/api/nexopos/v4/products/units/quantity/\".concat(id)).subscribe(function (result) {\n var index = group.indexOf(group_fields);\n group.splice(index, 1);\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].success(result.message).subscribe();\n }, function (error) {\n nsSnackbar.error(error.message).subscribe();\n });\n }\n }\n });\n },\n\n /**\r\n * When the user click on \"New Group\", \r\n * this check if there is not enough options as there is groups\r\n */\n addUnitGroup: function addUnitGroup(field) {\n if (field.options.length === 0) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error('Please select at least one unit group before you proceed.').subscribe();\n }\n\n if (field.options.length > field.groups.length) {\n field.groups.push(JSON.parse(JSON.stringify(field.fields)));\n } else {\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error('There shoulnd\\'t be more option than there are units.').subscribe();\n }\n },\n\n /**\r\n * When a change is made on unit group\r\n * we need to pull units attached to and make them available\r\n * for every groups. Validation should prevent duplicated units.\r\n */\n loadAvailableUnits: function loadAvailableUnits(unit_section) {\n var _this2 = this;\n\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"].get(this.unitsUrl.replace('{id}', unit_section.fields[0].value)).subscribe(function (result) {\n /**\r\n * For each group, we'll loop to find\r\n * the field that allow to choose the unit\r\n * in order to change the options available\r\n */\n unit_section.fields.forEach(function (field) {\n if (field.type === 'group') {\n field.options = result;\n field.fields.forEach(function (_field) {\n if (_field.name === 'unit_id') {\n console.log(_field);\n _field.options = result.map(function (option) {\n return {\n label: option.name,\n value: option.id\n };\n });\n }\n });\n }\n });\n\n _this2.$forceUpdate();\n });\n },\n\n /**\r\n * @deprecated\r\n */\n loadOptionsFor: function loadOptionsFor(fieldName, value, variation_index) {\n var _this3 = this;\n\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"].get(this.unitsUrl.replace('{id}', value)).subscribe(function (result) {\n _this3.form.variations[variation_index].tabs.units.fields.forEach(function (_field) {\n if (_field.name === fieldName) {\n _field.options = result.map(function (option) {\n return {\n label: option.name,\n value: option.id,\n selected: false\n };\n });\n }\n });\n\n _this3.$forceUpdate();\n });\n },\n submit: function submit() {\n var _this4 = this;\n\n var formValidGlobally = true;\n this.formValidation.validateFields([this.form.main]);\n var validity = this.form.variations.map(function (variation) {\n return _this4.formValidation.validateForm(variation);\n }).filter(function (v) {\n return v.length > 0;\n });\n\n if (validity.length > 0 || Object.values(this.form.main.errors).length > 0) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error(this.$slots['error-form-invalid'] ? this.$slots['error-form-invalid'][0].text : 'No error has been provided for the slot \"error-form-invalid\"').subscribe();\n }\n /**\r\n * If there are more than one\r\n * primary image, we'll block the process\r\n */\n\n\n var images = this.form.variations.map(function (v, i) {\n return v.tabs.images.groups.filter(function (fields) {\n return fields.filter(function (f) {\n return f.name === 'primary' && f.value === 1;\n }).length > 0;\n });\n });\n\n if (images[0] && images[0].length > 1) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error(this.$slots['error-multiple-primary'] ? this.$slots['error-multiple-primary'][0].text : 'No error has been provided for the slot \"error-multiple-primary\"').subscribe();\n }\n\n var validation = [];\n this.form.variations.map(function (v, i) {\n return v.tabs.units.fields.filter(function (field) {\n return field.type === 'group';\n }).forEach(function (fields_groups) {\n var uniqueness = new Object();\n fields_groups.groups.forEach(function (fields) {\n validation.push(_this4.formValidation.validateFields(fields));\n });\n });\n });\n\n if (validation.length === 0) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error(this.$slots['error-no-units-groups'] ? this.$slots['error-no-units-groups'][0].text : 'Either Selling or Purchase unit isn\\'t defined. Unable to proceed.').subscribe();\n }\n\n if (validation.filter(function (v) {\n return v === false;\n }).length > 0) {\n this.$forceUpdate();\n return _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error(this.$slots['error-invalid-unit-group'] ? this.$slots['error-invalid-unit-group'][0].text : 'Unable to proceed as one of the unit group field is invalid').subscribe();\n }\n /**\r\n * let's correctly extract \r\n * the form before submitting that\r\n */\n\n\n var data = _objectSpread(_objectSpread({}, this.formValidation.extractForm(this.form)), {}, {\n variations: this.form.variations.map(function (v, i) {\n var data = _this4.formValidation.extractForm(v);\n\n if (i === 0) {\n data['$primary'] = true;\n }\n\n data['images'] = v.tabs.images.groups.map(function (fields) {\n return _this4.formValidation.extractFields(fields);\n });\n var groups = new Object();\n v.tabs.units.fields.filter(function (field) {\n return field.type === 'group';\n }).forEach(function (field) {\n groups[field.name] = field.groups.map(function (fields) {\n return _this4.formValidation.extractFields(fields);\n });\n });\n data['units'] = _objectSpread(_objectSpread({}, data['units']), groups);\n return data;\n })\n });\n\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"][this.submitMethod ? this.submitMethod.toLowerCase() : 'post'](this.submitUrl, data).subscribe(function (data) {\n if (data.status === 'success') {\n if (_this4.returnUrl !== false) {\n return document.location = _this4.returnUrl;\n }\n\n _this4.$emit('save');\n }\n\n _this4.formValidation.enableForm(_this4.form);\n }, function (error) {\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error(error.message, undefined, {\n duration: 5000\n }).subscribe();\n\n _this4.formValidation.triggerError(_this4.form, error.response.data);\n\n _this4.formValidation.enableForm(_this4.form);\n });\n },\n deleteVariation: function deleteVariation(index) {\n if (confirm(this.$slots['delete-variation'] ? this.$slots['delete-variation'][0].text : 'No error message provided with code \"delete-variation\"')) {\n this.form.variations.splice(index, 1);\n }\n },\n setTabActive: function setTabActive(activeIndex, tabs) {\n for (var _index in tabs) {\n if (_index !== activeIndex) {\n tabs[_index].active = false;\n }\n }\n\n tabs[activeIndex].active = true;\n /**\r\n * If the loaded tab is \"units\", we'll\r\n * load sub units based on the selection.\r\n */\n\n if (activeIndex === 'units') {\n this.loadAvailableUnits(tabs[activeIndex]);\n }\n },\n duplicate: function duplicate(variation) {\n this.form.variations.push(Object.assign({}, variation));\n },\n newVariation: function newVariation() {\n this.form.variations.push(this.defaultVariation);\n },\n getActiveTab: function getActiveTab(tabs) {\n for (var key in tabs) {\n if (tabs[key].active) {\n return tabs[key];\n }\n }\n\n return false;\n },\n getActiveTabKey: function getActiveTabKey(tabs) {\n for (var key in tabs) {\n if (tabs[key].active) {\n return key;\n }\n }\n\n return false;\n },\n parseForm: function parseForm(form) {\n var _this5 = this;\n\n form.main.value = form.main.value === undefined ? '' : form.main.value;\n form.main = this.formValidation.createFields([form.main])[0];\n form.variations.forEach(function (variation, _index) {\n var index = 0;\n\n for (var key in variation.tabs) {\n /**\r\n * here we need to explicitely remove the\r\n * name field as this is replaced by the top field.\r\n * We also save the default variation as that's used for variations\r\n */\n if (index === 0 && variation.tabs[key].active === undefined) {\n variation.tabs[key].active = true;\n _this5._sampleVariation = Object.assign({}, variation);\n\n if (variation.tabs[key].fields) {\n variation.tabs[key].fields = _this5.formValidation.createFields(variation.tabs[key].fields.filter(function (f) {\n return f.name !== 'name';\n }));\n }\n } else {\n if (variation.tabs[key].fields) {\n variation.tabs[key].fields = _this5.formValidation.createFields(variation.tabs[key].fields);\n }\n }\n\n variation.tabs[key].active = variation.tabs[key].active === undefined ? false : variation.tabs[key].active;\n index++;\n }\n });\n return form;\n },\n loadForm: function loadForm() {\n var _this6 = this;\n\n var request = _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"].get(\"\".concat(this.src));\n request.subscribe(function (f) {\n _this6.form = _this6.parseForm(f.form);\n });\n },\n addImage: function addImage(variation) {\n variation.tabs.images.groups.push(this.formValidation.createFields(JSON.parse(JSON.stringify(variation.tabs.images.fields))));\n }\n },\n mounted: function mounted() {\n this.loadForm();\n },\n name: 'ns-manage-products'\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcmVzb3VyY2VzL3RzL3BhZ2VzL2Rhc2hib2FyZC9wcm9jdXJlbWVudHMvbWFuYWdlLXByb2R1Y3RzLnZ1ZT80OTkxIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0lBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBLDhGQURBO0FBRUEsdUVBRkE7QUFHQSwyRUFIQTtBQUlBLDRCQUpBO0FBS0E7QUFMQTtBQU9BLEdBVEE7QUFVQTtBQUNBLG9CQURBLDhCQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvRkFDQSxNQURBLENBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FKQSxFQUtBLEdBTEEsQ0FLQTtBQUNBO0FBQ0E7QUFDQSxTQVJBO0FBU0E7O0FBRUE7QUFDQSxjQURBO0FBRUE7QUFGQTtBQUlBO0FBdkJBLEdBVkE7QUFtQ0EsMEVBbkNBO0FBb0NBO0FBQ0EsbUJBREEsMkJBQ0EsTUFEQSxFQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0EsS0FKQTs7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQVZBLGdDQVVBLFlBVkEsRUFVQSxLQVZBLEVBVUE7QUFBQTs7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBLG9DQURBO0FBRUEsd0RBRkE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBLGFBRkEsTUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFaQTtBQWNBLEtBMUJBO0FBNEJBLCtCQTVCQSw2Q0E0QkE7QUFBQTtBQUFBO0FBQ0E7QUFDQSwyQ0FEQTtBQUVBLHlDQUZBO0FBR0EsNk1BSEE7QUFJQTtBQUNBO0FBQ0E7QUFB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LElBM1FBLEVBMlFBO0FBQUE7O0FBQ0E7QUFDQTtBQUVBO0FBQ0E7O0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQSxXQU5BLE1BTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUVBO0FBQ0E7QUFDQSxPQXpCQTtBQTJCQTtBQUNBLEtBM1NBO0FBNFNBLFlBNVNBLHNCQTRTQTtBQUFBOztBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BRkE7QUFHQSxLQWpUQTtBQWtUQSxZQWxUQSxvQkFrVEEsU0FsVEEsRUFrVEE7QUFDQSx3Q0FDQSwwRkFEQTtBQUdBO0FBdFRBLEdBcENBO0FBNFZBLFNBNVZBLHFCQTRWQTtBQUNBO0FBQ0EsR0E5VkE7QUErVkE7QUEvVkEiLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYmFiZWwtbG9hZGVyL2xpYi9pbmRleC5qcz8hLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvaW5kZXguanM/IS4vcmVzb3VyY2VzL3RzL3BhZ2VzL2Rhc2hib2FyZC9wcm9jdXJlbWVudHMvbWFuYWdlLXByb2R1Y3RzLnZ1ZT92dWUmdHlwZT1zY3JpcHQmbGFuZz1qcyYuanMiLCJzb3VyY2VzQ29udGVudCI6WyJcclxuPHRlbXBsYXRlPlxyXG4gICAgPGRpdiBjbGFzcz1cImZvcm0gZmxleC1hdXRvXCIgaWQ9XCJjcnVkLWZvcm1cIj5cclxuICAgICAgICA8ZGl2IHYtaWY9XCJPYmplY3QudmFsdWVzKCBmb3JtICkubGVuZ3RoID09PSAwXCIgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBoLWZ1bGwganVzdGlmeS1jZW50ZXIgZmxleC1hdXRvXCI+XHJcbiAgICAgICAgICAgIDxucy1zcGlubmVyLz5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8dGVtcGxhdGUgdi1pZj1cIk9iamVjdC52YWx1ZXMoIGZvcm0gKS5sZW5ndGggPiAwXCI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBqdXN0aWZ5LWJldHdlZW4gaXRlbXMtY2VudGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGZvcj1cInRpdGxlXCIgY2xhc3M9XCJmb250LWJvbGQgbXktMiB0ZXh0LWdyYXktNzAwXCI+e3sgZm9ybS5tYWluLmxhYmVsIH19PC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGZvcj1cInRpdGxlXCIgY2xhc3M9XCJ0ZXh0LXNtIG15LTIgdGV4dC1ncmF5LTcwMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8YSB2LWlmPVwicmV0dXJuVXJsXCIgOmhyZWY9XCJyZXR1cm5VcmxcIiBjbGFzcz1cInJvdW5kZWQtZnVsbCBib3JkZXIgYm9yZGVyLWdyYXktNDAwIGhvdmVyOmJnLXJlZC02MDAgaG92ZXI6dGV4dC13aGl0ZSBiZy13aGl0ZSBweC0yIHB5LTFcIj5SZXR1cm48L2E+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDxkaXYgOmNsYXNzPVwiZm9ybS5tYWluLmRpc2FibGVkID8gJ2JvcmRlci1ncmF5LTUwMCcgOiBmb3JtLm1haW4uZXJyb3JzLmxlbmd0aCA+IDAgPyAnYm9yZGVyLXJlZC02MDAnIDogJ2JvcmRlci1ibHVlLTUwMCdcIiBjbGFzcz1cImZsZXggYm9yZGVyLTIgcm91bmRlZCBvdmVyZmxvdy1oaWRkZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdi1tb2RlbD1cImZvcm0ubWFpbi52YWx1ZVwiIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBAYmx1cj1cImZvcm1WYWxpZGF0aW9uLmNoZWNrRmllbGQoIGZvcm0ubWFpbiApXCIgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEBjaGFuZ2U9XCJmb3JtVmFsaWRhdGlvbi5jaGVja0ZpZWxkKCBmb3JtLm1haW4gKVwiIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6ZGlzYWJsZWQ9XCJmb3JtLm1haW4uZGlzYWJsZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6Y2xhc3M9XCJmb3JtLm1haW4uZGlzYWJsZWQgPyAnYmctZ3JheS00MDAnIDogJydcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXgtYXV0byB0ZXh0LWdyYXktNzAwIG91dGxpbmUtbm9uZSBoLTEwIHB4LTJcIj5cclxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIDpkaXNhYmxlZD1cImZvcm0ubWFpbi5kaXNhYmxlZFwiIDpjbGFzcz1cImZvcm0ubWFpbi5kaXNhYmxlZCA/ICdiZy1ncmF5LTUwMCcgOiBmb3JtLm1haW4uZXJyb3JzLmxlbmd0aCA+IDAgPyAnYmctcmVkLTUwMCcgOiAnYmctYmx1ZS01MDAnXCIgQGNsaWNrPVwic3VibWl0KClcIiBjbGFzcz1cIm91dGxpbmUtbm9uZSBweC00IGgtMTAgdGV4dC13aGl0ZSBib3JkZXItbCBib3JkZXItZ3JheS00MDBcIj48c2xvdCBuYW1lPVwic2F2ZVwiPlNhdmU8L3Nsb3Q+PC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC14cyB0ZXh0LWdyYXktNjAwIHB5LTFcIiB2LWlmPVwiZm9ybS5tYWluLmRlc2NyaXB0aW9uICYmIGZvcm0ubWFpbi5lcnJvcnMubGVuZ3RoID09PSAwXCI+e3sgZm9ybS5tYWluLmRlc2NyaXB0aW9uIH19PC9wPlxyXG4gICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LXhzIHB5LTEgdGV4dC1yZWQtNTAwXCIgdi1iaW5kOmtleT1cImluZGV4XCIgdi1mb3I9XCIoZXJyb3IsIGluZGV4KSBvZiBmb3JtLm1haW4uZXJyb3JzXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+PHNsb3QgbmFtZT1cImVycm9yLXJlcXVpcmVkXCI+e3sgZXJyb3IuaWRlbnRpZmllciB9fTwvc2xvdD48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICA8L3A+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGlkPVwiZm9ybS1jb250YWluZXJcIiBjbGFzcz1cIi1teC00IGZsZXggZmxleC13cmFwIG10LTRcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC00IHctZnVsbFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9XCJ0YWJiZWQtY2FyZFwiIGNsYXNzPVwibWItOFwiIDprZXk9XCJ2YXJpYXRpb25faW5kZXhcIiB2LWZvcj1cIih2YXJpYXRpb24sIHZhcmlhdGlvbl9pbmRleCkgb2YgZm9ybS52YXJpYXRpb25zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9XCJjYXJkLWhlYWRlclwiIGNsYXNzPVwiZmxleCBmbGV4LXdyYXAganVzdGlmeS1iZXR3ZWVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LXdyYXBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IEBjbGljaz1cInNldFRhYkFjdGl2ZSggaW5kZXgsIHZhcmlhdGlvbi50YWJzIClcIiA6Y2xhc3M9XCJ0YWIuYWN0aXZlID8gJ2JnLXdoaXRlJyA6ICdiZy1ncmF5LTEwMCdcIiB2LWZvcj1cIiggdGFiLCBpbmRleCApIGluIHZhcmlhdGlvbi50YWJzXCIgdi1iaW5kOmtleT1cImluZGV4XCIgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciB0ZXh0LWdyYXktNzAwIHB4LTQgcHktMiByb3VuZGVkLXRsLWxnIHJvdW5kZWQtdHItbGcgZmxleCBqdXN0aWZ5LWJldHdlZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJibG9jayBtci0yXCI+e3sgdGFiLmxhYmVsIH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiB2LWlmPVwidGFiLmVycm9ycyAmJiB0YWIuZXJyb3JzLmxlbmd0aCA+IDBcIiBjbGFzcz1cInJvdW5kZWQtZnVsbCBiZy1yZWQtNDAwIHRleHQtd2hpdGUgaC02IHctNiBmbGV4IGZvbnQtc2VtaWJvbGQgaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCI+e3sgdGFiLmVycm9ycy5sZW5ndGggfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciAtbXgtMVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGRpdiBjbGFzcz1cInB4LTFcIiB2LWlmPVwiZm9ybS52YXJpYXRpb25zLmxlbmd0aCA+IDEgJiYgdmFyaWF0aW9uX2luZGV4ID4gMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIEBjbGljaz1cImRlbGV0ZVZhcmlhdGlvbiggdmFyaWF0aW9uX2luZGV4IClcIiBjbGFzcz1cInJvdW5kZWQtZnVsbCBoLTggdy04IGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIGJnLXJlZC00MDAgdGV4dC13aGl0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJsYXMgbGEtdGltZXNcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gQGNsaWNrPVwibmV3VmFyaWF0aW9uKClcIiBjbGFzcz1cInJvdW5kZWQtZnVsbCBoLTggdy04IGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIGJnLWdyZWVuLTQwMCB0ZXh0LXdoaXRlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImxhcyBsYS1wbHVzXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIEBjbGljaz1cImR1cGxpY2F0ZSggdmFyaWF0aW9uIClcIiBjbGFzcz1cInJvdW5kZWQtZnVsbCBoLTggdy04IGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIGJnLWJsdWUtNDAwIHRleHQtd2hpdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGFzIGxhLWNvcHlcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PiAtLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtYm9keSBiZy13aGl0ZSByb3VuZGVkLWJyLWxnIHJvdW5kZWQtYmwtbGcgc2hhZG93IHAtMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIi1teC00IGZsZXggZmxleC13cmFwXCIgdi1pZj1cIiEgWyAnaW1hZ2VzJywgJ3VuaXRzJyBdLmluY2x1ZGVzKCBnZXRBY3RpdmVUYWJLZXkoIHZhcmlhdGlvbi50YWJzICkgKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZW1wbGF0ZSB2LWZvcj1cIiggZmllbGQsIGluZGV4ICkgb2YgZ2V0QWN0aXZlVGFiKCB2YXJpYXRpb24udGFicyApLmZpZWxkc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IDprZXk9XCJpbmRleFwiIGNsYXNzPVwiZmxleCBmbGV4LWNvbCBweC00IHctZnVsbCBtZDp3LTEvMiBsZzp3LTEvM1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5zLWZpZWxkIDpmaWVsZD1cImZpZWxkXCI+PC9ucy1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIi1teC00IGZsZXggZmxleC13cmFwXCIgdi1pZj1cImdldEFjdGl2ZVRhYktleSggdmFyaWF0aW9uLnRhYnMgKSA9PT0gJ2ltYWdlcydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBweC00IHctZnVsbCBtZDp3LTEvMiBsZzp3LTEvM1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm91bmRlZCBib3JkZXIgZmxleCBiZy13aGl0ZSBqdXN0aWZ5LWJldHdlZW4gcC0yIGl0ZW1zLWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+QWRkIEltYWdlczwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gQGNsaWNrPVwiYWRkSW1hZ2UoIHZhcmlhdGlvbiApXCIgY2xhc3M9XCJyb3VuZGVkLWZ1bGwgYm9yZGVyIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHctOCBoLTggYmctd2hpdGUgaG92ZXI6YmctYmx1ZS00MDAgaG92ZXI6dGV4dC13aGl0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGFzIGxhLXBsdXMtY2lyY2xlXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXZcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOmtleT1cImluZGV4XCIgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHYtZm9yPVwiKCBncm91cCwgaW5kZXggKSBvZiBnZXRBY3RpdmVUYWIoIHZhcmlhdGlvbi50YWJzICkuZ3JvdXBzXCIgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxleCBmbGV4LWNvbCBweC00IHctZnVsbCBtZDp3LTEvMiBsZzp3LTEvMyBtYi00XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3VuZGVkIGJvcmRlciBmbGV4IGZsZXgtY29sIGJnLXdoaXRlIHAtMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5zLWZpZWxkIDprZXk9XCJpbmRleFwiIHYtZm9yPVwiKGZpZWxkLCBpbmRleCkgb2YgZ3JvdXBcIiA6ZmllbGQ9XCJmaWVsZFwiPjwvbnMtZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiLW14LTQgZmxleCBmbGV4LXdyYXBcIiB2LWlmPVwiZ2V0QWN0aXZlVGFiS2V5KCB2YXJpYXRpb24udGFicyApID09PSAndW5pdHMnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTQgdy1mdWxsIG1kOnctMS8yIGxnOnctMS8zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxucy1maWVsZCBAY2hhbmdlPVwibG9hZEF2YWlsYWJsZVVuaXRzKCBnZXRBY3RpdmVUYWIoIHZhcmlhdGlvbi50YWJzICkgKVwiIDpmaWVsZD1cImdldEFjdGl2ZVRhYiggdmFyaWF0aW9uLnRhYnMgKS5maWVsZHNbMF1cIj48L25zLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZW1wbGF0ZSB2LWZvcj1cIihmaWVsZCxpbmRleCkgb2YgZ2V0QWN0aXZlVGFiKCB2YXJpYXRpb24udGFicyApLmZpZWxkc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHYtaWY9XCJmaWVsZC50eXBlID09PSAnZ3JvdXAnXCIgY2xhc3M9XCJweC00IHctZnVsbCBsZzp3LTIvM1wiIDprZXk9XCJpbmRleFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb250LW1lZGl1bSB0ZXh0LWdyYXktNzAwXCI+e3sgZmllbGQubGFiZWwgfX08L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwicHktMSB0ZXh0LXNtIHRleHQtZ3JheS02MDBcIj57eyBmaWVsZC5kZXNjcmlwdGlvbiB9fTwvcD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IEBjbGljaz1cImFkZFVuaXRHcm91cCggZmllbGQgKVwiIGNsYXNzPVwiYm9yZGVyLWRhc2hlZCBib3JkZXItMiBib3JkZXItZ3JheS0yMDAgcC0xIGJnLWdyYXktMTAwIGZsZXgganVzdGlmeS1iZXR3ZWVuIGl0ZW1zLWNlbnRlciB0ZXh0LWdyYXktNzAwIGN1cnNvci1wb2ludGVyIHJvdW5kZWQtbGdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyb3VuZGVkLWZ1bGwgYm9yZGVyLTIgYm9yZGVyLWdyYXktMzAwIGJnLXdoaXRlIGgtOCB3LTggZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGFzIGxhLXBsdXMtY2lyY2xlXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPk5ldyBHcm91cDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIi1teC00IGZsZXggZmxleC13cmFwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTQgdy1mdWxsIG1kOnctMS8yIG1iLTRcIiA6a2V5PVwiaW5kZXhcIiB2LWZvcj1cIihncm91cF9maWVsZHMsaW5kZXgpIG9mIGZpZWxkLmdyb3Vwc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2hhZG93IHJvdW5kZWQgb3ZlcmZsb3ctaGlkZGVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm9yZGVyLWIgdGV4dC1zbSBiZy1ibHVlLTQwMCB0ZXh0LXdoaXRlICBib3JkZXItYmx1ZS0zMDAgcC0yIGZsZXgganVzdGlmeS1iZXR3ZWVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+QXZhaWxhYmxlIFF1YW50aXR5PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IGdldFVuaXRRdWFudGl0eSggZ3JvdXBfZmllbGRzICkgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLTIgbWItMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxucy1maWVsZCA6ZmllbGQ9XCJmaWVsZFwiIHYtZm9yPVwiKGZpZWxkLGluZGV4KSBvZiBncm91cF9maWVsZHNcIiA6a2V5PVwiaW5kZXhcIj48L25zLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IEBjbGljaz1cInJlbW92ZVVuaXRQcmljZUdyb3VwKCBncm91cF9maWVsZHMsIGZpZWxkLmdyb3VwcyApXCIgY2xhc3M9XCJwLTEgdGV4dC1yZWQtODAwIGhvdmVyOmJnLXJlZC0yMDAgYm9yZGVyLXQgYm9yZGVyLXJlZC0yMDAgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgY3Vyc29yLXBvaW50ZXIgZm9udC1tZWRpdW1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWxldGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvdGVtcGxhdGU+XHJcbiAgICA8L2Rpdj5cclxuPC90ZW1wbGF0ZT5cclxuPHNjcmlwdD5cclxuaW1wb3J0IEZvcm1WYWxpZGF0aW9uIGZyb20gJ0AvbGlicmFyaWVzL2Zvcm0tdmFsaWRhdGlvbidcclxuaW1wb3J0IHsgbnNTbmFja0JhciwgbnNIdHRwQ2xpZW50IH0gZnJvbSAnQC9ib290c3RyYXAnO1xyXG5pbXBvcnQgbnNQb3NDb25maXJtUG9wdXBWdWUgZnJvbSAnQC9wb3B1cHMvbnMtcG9zLWNvbmZpcm0tcG9wdXAudnVlJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIGRhdGE6ICgpID0+IHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBmb3JtVmFsaWRhdGlvbjogbmV3IEZvcm1WYWxpZGF0aW9uLFxyXG4gICAgICAgICAgICBuc1NuYWNrQmFyLFxyXG4gICAgICAgICAgICBuc0h0dHBDbGllbnQsXHJcbiAgICAgICAgICAgIF9zYW1wbGVWYXJpYXRpb246IG51bGwsXHJcbiAgICAgICAgICAgIGZvcm06ICcnLFxyXG4gICAgICAgIH1cclxuICAgIH0sXHJcbiAgICBjb21wdXRlZDoge1xyXG4gICAgICAgIGRlZmF1bHRWYXJpYXRpb24oKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG5ld1ZhcmlhdGlvbiAgICAgPSAgIG5ldyBPYmplY3Q7XHJcblxyXG4gICAgICAgICAgICBmb3IoIGxldCB0YWJJbmRleCBpbiB0aGlzLl9zYW1wbGVWYXJpYXRpb24udGFicyApIHtcclxuICAgICAgICAgICAgICAgIG5ld1ZhcmlhdGlvblsgdGFiSW5kZXggXSAgICAgICAgICAgID0gICBuZXcgT2JqZWN0O1xyXG4gICAgICAgICAgICAgICAgbmV3VmFyaWF0aW9uWyB0YWJJbmRleCBdLmxhYmVsICAgICAgPSAgIHRoaXMuX3NhbXBsZVZhcmlhdGlvbi50YWJzWyB0YWJJbmRleCBdLmxhYmVsO1xyXG4gICAgICAgICAgICAgICAgbmV3VmFyaWF0aW9uWyB0YWJJbmRleCBdLmFjdGl2ZSAgICAgPSAgIHRoaXMuX3NhbXBsZVZhcmlhdGlvbi50YWJzWyB0YWJJbmRleCBdLmFjdGl2ZTtcclxuICAgICAgICAgICAgICAgIG5ld1ZhcmlhdGlvblsgdGFiSW5kZXggXS5maWVsZHMgICAgID0gICB0aGlzLl9zYW1wbGVWYXJpYXRpb24udGFic1sgdGFiSW5kZXggXS5maWVsZHNcclxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKCBmaWVsZCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCBmaWVsZCApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gISBbICdjYXRlZ29yeV9pZCcsICdwcm9kdWN0X3R5cGUnLCAnc3RvY2tfbWFuYWdlbWVudCcsICdleHBpcmVzJyBdLmluY2x1ZGVzKCBmaWVsZC5uYW1lICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAubWFwKCBmaWVsZCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZmllbGQudmFsdWUgICAgID0gICAnJztcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmllbGQ7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGlkOiAnJyxcclxuICAgICAgICAgICAgICAgIHRhYnM6IG5ld1ZhcmlhdGlvblxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgIH0sICBcclxuICAgIHByb3BzOiBbICdzdWJtaXQtbWV0aG9kJywgJ3N1Ym1pdC11cmwnLCAncmV0dXJuLXVybCcsICdzcmMnLCAndW5pdHMtdXJsJyBdLFxyXG4gICAgbWV0aG9kczoge1xyXG4gICAgICAgIGdldFVuaXRRdWFudGl0eSggZmllbGRzICkge1xyXG4gICAgICAgICAgICBjb25zdCBxdWFudGl0eSAgPSAgIGZpZWxkcy5maWx0ZXIoIGYgPT4gZi5uYW1lID09PSAncXVhbnRpdHknICkubWFwKCBmID0+IGYudmFsdWUgKTtcclxuICAgICAgICAgICAgcmV0dXJuIHF1YW50aXR5Lmxlbmd0aCA+IDAgPyBxdWFudGl0eVswXSA6IDA7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVGhlIHVzZXIgd2FudCB0byByZW1vdmUgYSBncm91cFxyXG4gICAgICAgICAqIHdlIG1pZ2h0IG5lZWQgY29uZmlybWF0aW9uIGJlZm9yZSBwcm9jZWVkaW5nLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHJlbW92ZVVuaXRQcmljZUdyb3VwKCBncm91cF9maWVsZHMsIGdyb3VwICkge1xyXG4gICAgICAgICAgICBjb25zdCBoYXNJZEZpZWxkICAgID0gICBncm91cF9maWVsZHMuZmlsdGVyKCBmaWVsZCA9PiBmaWVsZC5uYW1lID09PSAnaWQnICk7XHJcbiAgICAgICAgICAgICAgICBQb3B1cC5zaG93KCBuc1Bvc0NvbmZpcm1Qb3B1cFZ1ZSwge1xyXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnQ29uZmlybSBZb3VyIEFjdGlvbicsXHJcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ1dvdWxkIHlvdSBsaWtlIHRvIGRlbGV0ZSB0aGlzIGdyb3VwID8nLFxyXG4gICAgICAgICAgICAgICAgICAgIG9uQWN0aW9uOiAoIGFjdGlvbiApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBhY3Rpb24gKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGhhc0lkRmllbGQubGVuZ3RoID4gMCApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpcm1Vbml0UXVhbnRpdHlEZWxldGlvbih7IGdyb3VwX2ZpZWxkcywgZ3JvdXAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ICAgICA9ICAgZ3JvdXAuaW5kZXhPZiggZ3JvdXBfZmllbGRzICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAuc3BsaWNlKCBpbmRleCwgMSApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgY29uZmlybVVuaXRRdWFudGl0eURlbGV0aW9uKHsgZ3JvdXBfZmllbGRzLCBncm91cCB9KSB7XHJcbiAgICAgICAgICAgIFBvcHVwLnNob3coIG5zUG9zQ29uZmlybVBvcHVwVnVlLCB7XHJcbiAgICAgICAgICAgICAgICB0aXRsZTogJ1lvdXIgQXR0ZW50aW9uIElzIFJlcXVpcmVkJyxcclxuICAgICAgICAgICAgICAgIHNpemU6ICd3LTMvNC1zY3JlZW4gaC0yLzUtc2NyZWVuJyxcclxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdUaGUgY3VycmVudCB1bml0IHlvdVxcJ3JlIGFib3V0IHRvIGRlbGV0ZSBoYXMgYSByZWZlcmVuY2Ugb24gdGhlIGRhdGFiYXNlIGFuZCBpdCBtaWdodCBoYXZlIGFscmVhZHkgcHJvY3VyZWQgc3RvY2suIERlbGV0aW5nIHRoYXQgcmVmZXJlbmNlIHdpbGwgcmVtb3ZlIHByb2N1cmVkIHN0b2NrLiBXb3VsZCB5b3UgcHJvY2VlZCA/JyxcclxuICAgICAgICAgICAgICAgIG9uQWN0aW9uOiAoIGFjdGlvbiApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIGFjdGlvbiApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaWQgICAgPSAgIGdyb3VwX2ZpZWxkcy5maWx0ZXIoIGYgPT4gZi5uYW1lID09PSAnaWQnIClcclxuICAgICAgICAgICAgICAgICAgICAgICAgLm1hcCggZiA9PiBmLnZhbHVlIClbMF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuc0h0dHBDbGllbnQuZGVsZXRlKCBgL2FwaS9uZXhvcG9zL3Y0L3Byb2R1Y3RzL3VuaXRzL3F1YW50aXR5LyR7aWR9YClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoIHJlc3VsdCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggICAgID0gICBncm91cC5pbmRleE9mKCBncm91cF9maWVsZHMgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cC5zcGxpY2UoIGluZGV4LCAxICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnNTbmFja0Jhci5zdWNjZXNzKCByZXN1bHQubWVzc2FnZSApLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgKCBlcnJvciApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuc1NuYWNrYmFyLmVycm9yKCBlcnJvci5tZXNzYWdlICkuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdoZW4gdGhlIHVzZXIgY2xpY2sgb24gXCJOZXcgR3JvdXBcIiwgXHJcbiAgICAgICAgICogdGhpcyBjaGVjayBpZiB0aGVyZSBpcyBub3QgZW5vdWdoIG9wdGlvbnMgYXMgdGhlcmUgaXMgZ3JvdXBzXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgYWRkVW5pdEdyb3VwKCBmaWVsZCApIHtcclxuICAgICAgICAgICAgaWYgKCBmaWVsZC5vcHRpb25zLmxlbmd0aCA9PT0gMCApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuc1NuYWNrQmFyLmVycm9yKCAnUGxlYXNlIHNlbGVjdCBhdCBsZWFzdCBvbmUgdW5pdCBncm91cCBiZWZvcmUgeW91IHByb2NlZWQuJyApLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiggZmllbGQub3B0aW9ucy5sZW5ndGggPiBmaWVsZC5ncm91cHMubGVuZ3RoICkge1xyXG4gICAgICAgICAgICAgICAgZmllbGQuZ3JvdXBzLnB1c2goSlNPTi5wYXJzZSggSlNPTi5zdHJpbmdpZnkoIGZpZWxkLmZpZWxkcyApICkgKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIG5zU25hY2tCYXIuZXJyb3IoICdUaGVyZSBzaG91bG5kXFwndCBiZSBtb3JlIG9wdGlvbiB0aGFuIHRoZXJlIGFyZSB1bml0cy4nICkuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBXaGVuIGEgY2hhbmdlIGlzIG1hZGUgb24gdW5pdCBncm91cFxyXG4gICAgICAgICAqIHdlIG5lZWQgdG8gcHVsbCB1bml0cyBhdHRhY2hlZCB0byBhbmQgbWFrZSB0aGVtIGF2YWlsYWJsZVxyXG4gICAgICAgICAqIGZvciBldmVyeSBncm91cHMuIFZhbGlkYXRpb24gc2hvdWxkIHByZXZlbnQgZHVwbGljYXRlZCB1bml0cy5cclxuICAgICAgICAgKi9cclxuICAgICAgICBsb2FkQXZhaWxhYmxlVW5pdHMoIHVuaXRfc2VjdGlvbiApIHtcclxuICAgICAgICAgICAgbnNIdHRwQ2xpZW50LmdldCggdGhpcy51bml0c1VybC5yZXBsYWNlKCAne2lkfScsIHVuaXRfc2VjdGlvbi5maWVsZHNbMF0udmFsdWUgKSApXHJcbiAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCByZXN1bHQgPT4ge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAgICAgKiBGb3IgZWFjaCBncm91cCwgd2UnbGwgbG9vcCB0byBmaW5kXHJcbiAgICAgICAgICAgICAgICAgICAgICogdGhlIGZpZWxkIHRoYXQgYWxsb3cgdG8gY2hvb3NlIHRoZSB1bml0XHJcbiAgICAgICAgICAgICAgICAgICAgICogaW4gb3JkZXIgdG8gY2hhbmdlIHRoZSBvcHRpb25zIGF2YWlsYWJsZVxyXG4gICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgIHVuaXRfc2VjdGlvbi5maWVsZHMuZm9yRWFjaCggZmllbGQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGZpZWxkLnR5cGUgPT09ICdncm91cCcgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC5vcHRpb25zICAgPSAgIHJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLmZpZWxkcy5mb3JFYWNoKCBfZmllbGQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggX2ZpZWxkLm5hbWUgPT09ICd1bml0X2lkJyApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coIF9maWVsZCApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZmllbGQub3B0aW9ucyAgPSAgIHJlc3VsdC5tYXAoIG9wdGlvbiA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBvcHRpb24ubmFtZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogb3B0aW9uLmlkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZm9yY2VVcGRhdGUoKTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGRlcHJlY2F0ZWRcclxuICAgICAgICAgKi9cclxuICAgICAgICBsb2FkT3B0aW9uc0ZvciggZmllbGROYW1lLCB2YWx1ZSwgdmFyaWF0aW9uX2luZGV4ICkge1xyXG4gICAgICAgICAgICBuc0h0dHBDbGllbnQuZ2V0KCB0aGlzLnVuaXRzVXJsLnJlcGxhY2UoICd7aWR9JywgdmFsdWUgKSApXHJcbiAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCByZXN1bHQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZm9ybS52YXJpYXRpb25zWyB2YXJpYXRpb25faW5kZXggXS50YWJzLnVuaXRzLmZpZWxkcy5mb3JFYWNoKCBfZmllbGQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIF9maWVsZC5uYW1lID09PSBmaWVsZE5hbWUgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZmllbGQub3B0aW9ucyAgICA9ICAgcmVzdWx0Lm1hcCggb3B0aW9uID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogb3B0aW9uLm5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBvcHRpb24uaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGZvcmNlVXBkYXRlKCk7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgc3VibWl0KCkge1xyXG4gICAgICAgICAgICBsZXQgZm9ybVZhbGlkR2xvYmFsbHkgICA9ICAgdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5mb3JtVmFsaWRhdGlvbi52YWxpZGF0ZUZpZWxkcyhbIHRoaXMuZm9ybS5tYWluIF0pOyBcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHZhbGlkaXR5ICA9ICAgdGhpcy5mb3JtLnZhcmlhdGlvbnMubWFwKCB2YXJpYXRpb24gPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm9ybVZhbGlkYXRpb24udmFsaWRhdGVGb3JtKCB2YXJpYXRpb24gKTtcclxuICAgICAgICAgICAgfSkuZmlsdGVyKCB2ID0+IHYubGVuZ3RoID4gMCApO1xyXG5cclxuICAgICAgICAgICAgaWYgKCB2YWxpZGl0eS5sZW5ndGggPiAwIHx8IE9iamVjdC52YWx1ZXMoIHRoaXMuZm9ybS5tYWluLmVycm9ycyApLmxlbmd0aCA+IDAgKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnNTbmFja0Jhci5lcnJvciggdGhpcy4kc2xvdHNbICdlcnJvci1mb3JtLWludmFsaWQnIF0gPyB0aGlzLiRzbG90c1sgJ2Vycm9yLWZvcm0taW52YWxpZCcgXVswXS50ZXh0IDogJ05vIGVycm9yIGhhcyBiZWVuIHByb3ZpZGVkIGZvciB0aGUgc2xvdCBcImVycm9yLWZvcm0taW52YWxpZFwiJyApLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogSWYgdGhlcmUgYXJlIG1vcmUgdGhhbiBvbmVcclxuICAgICAgICAgICAgICogcHJpbWFyeSBpbWFnZSwgd2UnbGwgYmxvY2sgdGhlIHByb2Nlc3NcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGNvbnN0IGltYWdlcyAgICA9ICAgdGhpcy5mb3JtLnZhcmlhdGlvbnMubWFwKCAodixpKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdi50YWJzLmltYWdlcy5ncm91cHMuZmlsdGVyKCBmaWVsZHMgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWVsZHMuZmlsdGVyKCBmID0+IGYubmFtZSA9PT0gJ3ByaW1hcnknICYmIGYudmFsdWUgPT09IDEgKS5sZW5ndGggPiAwO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pXHJcblxyXG4gICAgICAgICAgICBpZiAoIGltYWdlc1swXSAmJiBpbWFnZXNbMF0ubGVuZ3RoID4gMSApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuc1NuYWNrQmFyLmVycm9yKCB0aGlzLiRzbG90c1sgJ2Vycm9yLW11bHRpcGxlLXByaW1hcnknIF0gPyB0aGlzLiRzbG90c1sgJ2Vycm9yLW11bHRpcGxlLXByaW1hcnknIF1bMF0udGV4dCA6ICdObyBlcnJvciBoYXMgYmVlbiBwcm92aWRlZCBmb3IgdGhlIHNsb3QgXCJlcnJvci1tdWx0aXBsZS1wcmltYXJ5XCInICkuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHZhbGlkYXRpb24gICAgICAgID0gICBbXTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZm9ybS52YXJpYXRpb25zLm1hcCggKCB2LCBpICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHYudGFicy51bml0cy5maWVsZHNcclxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKCBmaWVsZCA9PiBmaWVsZC50eXBlID09PSAnZ3JvdXAnIClcclxuICAgICAgICAgICAgICAgICAgICAuZm9yRWFjaCggZmllbGRzX2dyb3VwcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuaXF1ZW5lc3MgICAgPSAgIG5ldyBPYmplY3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkc19ncm91cHMuZ3JvdXBzLmZvckVhY2goIGZpZWxkcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uLnB1c2goIHRoaXMuZm9ybVZhbGlkYXRpb24udmFsaWRhdGVGaWVsZHMoIGZpZWxkcyApICk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIGlmICggdmFsaWRhdGlvbi5sZW5ndGggPT09IDAgKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnNTbmFja0Jhci5lcnJvciggdGhpcy4kc2xvdHNbICdlcnJvci1uby11bml0cy1ncm91cHMnIF0gPyB0aGlzLiRzbG90c1sgJ2Vycm9yLW5vLXVuaXRzLWdyb3VwcycgXVswXS50ZXh0IDogJ0VpdGhlciBTZWxsaW5nIG9yIFB1cmNoYXNlIHVuaXQgaXNuXFwndCBkZWZpbmVkLiBVbmFibGUgdG8gcHJvY2VlZC4nICkuc3Vic2NyaWJlKCk7IFxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIHZhbGlkYXRpb24uZmlsdGVyKCB2ID0+IHYgPT09IGZhbHNlICkubGVuZ3RoID4gMCApIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuJGZvcmNlVXBkYXRlKCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnNTbmFja0Jhci5lcnJvciggdGhpcy4kc2xvdHNbICdlcnJvci1pbnZhbGlkLXVuaXQtZ3JvdXAnIF0gPyB0aGlzLiRzbG90c1sgJ2Vycm9yLWludmFsaWQtdW5pdC1ncm91cCcgXVswXS50ZXh0IDogJ1VuYWJsZSB0byBwcm9jZWVkIGFzIG9uZSBvZiB0aGUgdW5pdCBncm91cCBmaWVsZCBpcyBpbnZhbGlkJyApLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogbGV0J3MgY29ycmVjdGx5IGV4dHJhY3QgXHJcbiAgICAgICAgICAgICAqIHRoZSBmb3JtIGJlZm9yZSBzdWJtaXR0aW5nIHRoYXRcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgID0gICB7XHJcbiAgICAgICAgICAgICAgICAuLi50aGlzLmZvcm1WYWxpZGF0aW9uLmV4dHJhY3RGb3JtKCB0aGlzLmZvcm0gKSxcclxuICAgICAgICAgICAgICAgIHZhcmlhdGlvbnM6IHRoaXMuZm9ybS52YXJpYXRpb25zLm1hcCggKHYsaSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgID0gICB0aGlzLmZvcm1WYWxpZGF0aW9uLmV4dHJhY3RGb3JtKCB2ICk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCBpID09PSAwICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhWyAnJHByaW1hcnknIF0gID0gICB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZGF0YVsgJ2ltYWdlcycgXSAgICA9ICAgdi50YWJzLmltYWdlcy5ncm91cHMubWFwKCBmaWVsZHMgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtVmFsaWRhdGlvbi5leHRyYWN0RmllbGRzKCBmaWVsZHMgKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZ3JvdXBzICAgID0gICBuZXcgT2JqZWN0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2LnRhYnMudW5pdHMuZmllbGRzLmZpbHRlciggZmllbGQgPT4gZmllbGQudHlwZSA9PT0gJ2dyb3VwJyApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5mb3JFYWNoKCBmaWVsZCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cHNbIGZpZWxkLm5hbWUgXSAgICA9ICAgZmllbGQuZ3JvdXBzLm1hcCggZmllbGRzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtVmFsaWRhdGlvbi5leHRyYWN0RmllbGRzKCBmaWVsZHMgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBkYXRhWyAndW5pdHMnIF0gICAgICAgICA9ICAgeyBcclxuICAgICAgICAgICAgICAgICAgICAgICAgLi4uZGF0YVsgJ3VuaXRzJyBdLCBcclxuICAgICAgICAgICAgICAgICAgICAgICAgLi4uZ3JvdXBzXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGE7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBuc0h0dHBDbGllbnRbIHRoaXMuc3VibWl0TWV0aG9kID8gdGhpcy5zdWJtaXRNZXRob2QudG9Mb3dlckNhc2UoKSA6ICdwb3N0JyBdKCB0aGlzLnN1Ym1pdFVybCwgZGF0YSApXHJcbiAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCBkYXRhID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIGRhdGEuc3RhdHVzID09PSAnc3VjY2VzcycgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggdGhpcy5yZXR1cm5VcmwgIT09IGZhbHNlICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50LmxvY2F0aW9uICAgPSAgIHRoaXMucmV0dXJuVXJsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGVtaXQoICdzYXZlJyApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm1WYWxpZGF0aW9uLmVuYWJsZUZvcm0oIHRoaXMuZm9ybSApO1xyXG4gICAgICAgICAgICAgICAgfSwgKCBlcnJvciApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBuc1NuYWNrQmFyLmVycm9yKCBlcnJvci5tZXNzYWdlLCB1bmRlZmluZWQsIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IDUwMDBcclxuICAgICAgICAgICAgICAgICAgICB9KS5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm1WYWxpZGF0aW9uLnRyaWdnZXJFcnJvciggdGhpcy5mb3JtLCBlcnJvci5yZXNwb25zZS5kYXRhICk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtVmFsaWRhdGlvbi5lbmFibGVGb3JtKCB0aGlzLmZvcm0gKTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgfSxcclxuICAgICAgICBkZWxldGVWYXJpYXRpb24oIGluZGV4ICkge1xyXG4gICAgICAgICAgICBpZiAoIGNvbmZpcm0oIHRoaXMuJHNsb3RzWyAnZGVsZXRlLXZhcmlhdGlvbicgXSA/IHRoaXMuJHNsb3RzWyAnZGVsZXRlLXZhcmlhdGlvbicgXVswXS50ZXh0IDogJ05vIGVycm9yIG1lc3NhZ2UgcHJvdmlkZWQgd2l0aCBjb2RlIFwiZGVsZXRlLXZhcmlhdGlvblwiJyApICkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtLnZhcmlhdGlvbnMuc3BsaWNlKCBpbmRleCwgMSApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBzZXRUYWJBY3RpdmUoIGFjdGl2ZUluZGV4LCB0YWJzICkge1xyXG4gICAgICAgICAgICBmb3IoIGxldCBfaW5kZXggaW4gdGFicyApIHtcclxuICAgICAgICAgICAgICAgIGlmICggX2luZGV4ICE9PSBhY3RpdmVJbmRleCApIHtcclxuICAgICAgICAgICAgICAgICAgICB0YWJzWyBfaW5kZXggXS5hY3RpdmUgICAgPSAgIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0YWJzWyBhY3RpdmVJbmRleCBdLmFjdGl2ZSAgPSAgIHRydWU7XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogSWYgdGhlIGxvYWRlZCB0YWIgaXMgXCJ1bml0c1wiLCB3ZSdsbFxyXG4gICAgICAgICAgICAgKiBsb2FkIHN1YiB1bml0cyBiYXNlZCBvbiB0aGUgc2VsZWN0aW9uLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgaWYgKCBhY3RpdmVJbmRleCA9PT0gJ3VuaXRzJyApIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubG9hZEF2YWlsYWJsZVVuaXRzKCB0YWJzWyBhY3RpdmVJbmRleCBdICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LCAgXHJcbiAgICAgICAgZHVwbGljYXRlKCB2YXJpYXRpb24gKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZm9ybS52YXJpYXRpb25zLnB1c2goIE9iamVjdC5hc3NpZ24oe30sIHZhcmlhdGlvbiApKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIG5ld1ZhcmlhdGlvbigpIHtcclxuICAgICAgICAgICAgdGhpcy5mb3JtLnZhcmlhdGlvbnMucHVzaCggdGhpcy5kZWZhdWx0VmFyaWF0aW9uICk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBnZXRBY3RpdmVUYWIoIHRhYnMgKSB7XHJcbiAgICAgICAgICAgIGZvciggbGV0IGtleSBpbiB0YWJzICkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCB0YWJzWyBrZXkgXS5hY3RpdmUgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRhYnNbIGtleSBdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfSwgXHJcbiAgICAgICAgZ2V0QWN0aXZlVGFiS2V5KCB0YWJzICkge1xyXG4gICAgICAgICAgICBmb3IoIGxldCBrZXkgaW4gdGFicyApIHtcclxuICAgICAgICAgICAgICAgIGlmICggdGFic1sga2V5IF0uYWN0aXZlICkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBrZXk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIHBhcnNlRm9ybSggZm9ybSApIHtcclxuICAgICAgICAgICAgZm9ybS5tYWluLnZhbHVlICAgICA9ICAgZm9ybS5tYWluLnZhbHVlID09PSB1bmRlZmluZWQgPyAnJyA6IGZvcm0ubWFpbi52YWx1ZTtcclxuICAgICAgICAgICAgZm9ybS5tYWluICAgICAgICAgICA9ICAgdGhpcy5mb3JtVmFsaWRhdGlvbi5jcmVhdGVGaWVsZHMoWyBmb3JtLm1haW4gXSlbMF07XHJcblxyXG4gICAgICAgICAgICBmb3JtLnZhcmlhdGlvbnMuZm9yRWFjaCggKCB2YXJpYXRpb24sIF9pbmRleCApID0+IHtcclxuICAgICAgICAgICAgICAgIGxldCBpbmRleCAgICAgICAgICAgPSAgIDA7XHJcbiAgICAgICAgICAgICAgICBmb3IoIGxldCBrZXkgaW4gdmFyaWF0aW9uLnRhYnMgKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICAgICAqIGhlcmUgd2UgbmVlZCB0byBleHBsaWNpdGVseSByZW1vdmUgdGhlXHJcbiAgICAgICAgICAgICAgICAgICAgICogbmFtZSBmaWVsZCBhcyB0aGlzIGlzIHJlcGxhY2VkIGJ5IHRoZSB0b3AgZmllbGQuXHJcbiAgICAgICAgICAgICAgICAgICAgICogV2UgYWxzbyBzYXZlIHRoZSBkZWZhdWx0IHZhcmlhdGlvbiBhcyB0aGF0J3MgdXNlZCBmb3IgdmFyaWF0aW9uc1xyXG4gICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICggaW5kZXggPT09IDAgJiYgdmFyaWF0aW9uLnRhYnNbIGtleSBdLmFjdGl2ZSA9PT0gdW5kZWZpbmVkICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXJpYXRpb24udGFic1sga2V5IF0uYWN0aXZlICAgID0gICB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zYW1wbGVWYXJpYXRpb24gICAgICAgICAgID0gICBPYmplY3QuYXNzaWduKHt9LCB2YXJpYXRpb24gKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCB2YXJpYXRpb24udGFic1sga2V5IF0uZmllbGRzICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWF0aW9uLnRhYnNbIGtleSBdLmZpZWxkcyAgICA9ICAgdGhpcy5mb3JtVmFsaWRhdGlvbi5jcmVhdGVGaWVsZHMoIHZhcmlhdGlvbi50YWJzWyBrZXkgXS5maWVsZHMuZmlsdGVyKCBmID0+IGYubmFtZSAhPT0gJ25hbWUnICkgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggdmFyaWF0aW9uLnRhYnNbIGtleSBdLmZpZWxkcyApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhdGlvbi50YWJzWyBrZXkgXS5maWVsZHMgICAgPSAgIHRoaXMuZm9ybVZhbGlkYXRpb24uY3JlYXRlRmllbGRzKCB2YXJpYXRpb24udGFic1sga2V5IF0uZmllbGRzICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhcmlhdGlvbi50YWJzWyBrZXkgXS5hY3RpdmUgICAgPSAgIHZhcmlhdGlvbi50YWJzWyBrZXkgXS5hY3RpdmUgPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogdmFyaWF0aW9uLnRhYnNbIGtleSBdLmFjdGl2ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaW5kZXgrKztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gZm9ybTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGxvYWRGb3JtKCkge1xyXG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ICAgPSAgIG5zSHR0cENsaWVudC5nZXQoIGAke3RoaXMuc3JjfWAgKTtcclxuICAgICAgICAgICAgcmVxdWVzdC5zdWJzY3JpYmUoIGYgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtICAgID0gICB0aGlzLnBhcnNlRm9ybSggZi5mb3JtICk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgYWRkSW1hZ2UoIHZhcmlhdGlvbiApIHtcclxuICAgICAgICAgICAgdmFyaWF0aW9uLnRhYnMuaW1hZ2VzLmdyb3Vwcy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtVmFsaWRhdGlvbi5jcmVhdGVGaWVsZHMoIEpTT04ucGFyc2UoIEpTT04uc3RyaW5naWZ5KCB2YXJpYXRpb24udGFicy5pbWFnZXMuZmllbGRzICkgKSApXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIG1vdW50ZWQoKSB7XHJcbiAgICAgICAgdGhpcy5sb2FkRm9ybSgpO1xyXG4gICAgfSxcclxuICAgIG5hbWU6ICducy1tYW5hZ2UtcHJvZHVjdHMnLFxyXG59XHJcbjwvc2NyaXB0PiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/ts/pages/dashboard/procurements/manage-products.vue?vue&type=script&lang=js&\n"); -======= eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _libraries_form_validation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/libraries/form-validation */ \"./resources/ts/libraries/form-validation.ts\");\n/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/bootstrap */ \"./resources/ts/bootstrap.ts\");\n/* harmony import */ var _popups_ns_pos_confirm_popup_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/popups/ns-pos-confirm-popup.vue */ \"./resources/ts/popups/ns-pos-confirm-popup.vue\");\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _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; }\n\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n data: function data() {\n return {\n formValidation: new _libraries_form_validation__WEBPACK_IMPORTED_MODULE_0__[\"default\"](),\n nsSnackBar: _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"],\n nsHttpClient: _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"],\n _sampleVariation: null,\n form: ''\n };\n },\n computed: {\n defaultVariation: function defaultVariation() {\n var newVariation = new Object();\n\n for (var tabIndex in this._sampleVariation.tabs) {\n newVariation[tabIndex] = new Object();\n newVariation[tabIndex].label = this._sampleVariation.tabs[tabIndex].label;\n newVariation[tabIndex].active = this._sampleVariation.tabs[tabIndex].active;\n newVariation[tabIndex].fields = this._sampleVariation.tabs[tabIndex].fields.filter(function (field) {\n console.log(field);\n return !['category_id', 'product_type', 'stock_management', 'expires'].includes(field.name);\n }).map(function (field) {\n field.value = '';\n return field;\n });\n }\n\n return {\n id: '',\n tabs: newVariation\n };\n }\n },\n props: ['submit-method', 'submit-url', 'return-url', 'src', 'units-url'],\n methods: {\n getUnitQuantity: function getUnitQuantity(fields) {\n var quantity = fields.filter(function (f) {\n return f.name === 'quantity';\n }).map(function (f) {\n return f.value;\n });\n return quantity.length > 0 ? quantity[0] : 0;\n },\n\n /**\r\n * The user want to remove a group\r\n * we might need confirmation before proceeding.\r\n */\n removeUnitPriceGroup: function removeUnitPriceGroup(group_fields, group) {\n var _this = this;\n\n var hasIdField = group_fields.filter(function (field) {\n return field.name === 'id' && field.value !== undefined;\n });\n Popup.show(_popups_ns_pos_confirm_popup_vue__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n title: 'Confirm Your Action',\n message: 'Would you like to delete this group ?',\n onAction: function onAction(action) {\n if (action) {\n if (hasIdField.length > 0) {\n _this.confirmUnitQuantityDeletion({\n group_fields: group_fields,\n group: group\n });\n } else {\n var index = group.indexOf(group_fields);\n group.splice(index, 1);\n }\n }\n }\n });\n },\n confirmUnitQuantityDeletion: function confirmUnitQuantityDeletion(_ref) {\n var group_fields = _ref.group_fields,\n group = _ref.group;\n Popup.show(_popups_ns_pos_confirm_popup_vue__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n title: 'Your Attention Is Required',\n size: 'w-3/4-screen h-2/5-screen',\n message: 'The current unit you\\'re about to delete has a reference on the database and it might have already procured stock. Deleting that reference will remove procured stock. Would you proceed ?',\n onAction: function onAction(action) {\n if (action) {\n var id = group_fields.filter(function (f) {\n return f.name === 'id';\n }).map(function (f) {\n return f.value;\n })[0];\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"][\"delete\"](\"/api/nexopos/v4/products/units/quantity/\".concat(id)).subscribe(function (result) {\n var index = group.indexOf(group_fields);\n group.splice(index, 1);\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].success(result.message).subscribe();\n }, function (error) {\n nsSnackbar.error(error.message).subscribe();\n });\n }\n }\n });\n },\n\n /**\r\n * When the user click on \"New Group\", \r\n * this check if there is not enough options as there is groups\r\n */\n addUnitGroup: function addUnitGroup(field) {\n if (field.options.length === 0) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error('Please select at least one unit group before you proceed.').subscribe();\n }\n\n if (field.options.length > field.groups.length) {\n field.groups.push(JSON.parse(JSON.stringify(field.fields)));\n } else {\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error('There shoulnd\\'t be more option than there are units.').subscribe();\n }\n },\n\n /**\r\n * When a change is made on unit group\r\n * we need to pull units attached to and make them available\r\n * for every groups. Validation should prevent duplicated units.\r\n */\n loadAvailableUnits: function loadAvailableUnits(unit_section) {\n var _this2 = this;\n\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"].get(this.unitsUrl.replace('{id}', unit_section.fields.filter(function (f) {\n return f.name === 'unit_group';\n })[0].value)).subscribe(function (result) {\n /**\r\n * For each group, we'll loop to find\r\n * the field that allow to choose the unit\r\n * in order to change the options available\r\n */\n unit_section.fields.forEach(function (field) {\n if (field.type === 'group') {\n field.options = result;\n field.fields.forEach(function (_field) {\n if (_field.name === 'unit_id') {\n console.log(_field);\n _field.options = result.map(function (option) {\n return {\n label: option.name,\n value: option.id\n };\n });\n }\n });\n }\n });\n\n _this2.$forceUpdate();\n });\n },\n\n /**\r\n * @deprecated\r\n */\n loadOptionsFor: function loadOptionsFor(fieldName, value, variation_index) {\n var _this3 = this;\n\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"].get(this.unitsUrl.replace('{id}', value)).subscribe(function (result) {\n _this3.form.variations[variation_index].tabs.units.fields.forEach(function (_field) {\n if (_field.name === fieldName) {\n _field.options = result.map(function (option) {\n return {\n label: option.name,\n value: option.id,\n selected: false\n };\n });\n }\n });\n\n _this3.$forceUpdate();\n });\n },\n submit: function submit() {\n var _this4 = this;\n\n var formValidGlobally = true;\n this.formValidation.validateFields([this.form.main]);\n var validity = this.form.variations.map(function (variation) {\n return _this4.formValidation.validateForm(variation);\n }).filter(function (v) {\n return v.length > 0;\n });\n\n if (validity.length > 0 || Object.values(this.form.main.errors).length > 0) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error(this.$slots['error-form-invalid'] ? this.$slots['error-form-invalid'][0].text : 'No error has been provided for the slot \"error-form-invalid\"').subscribe();\n }\n /**\r\n * If there are more than one\r\n * primary image, we'll block the process\r\n */\n\n\n var images = this.form.variations.map(function (v, i) {\n return v.tabs.images.groups.filter(function (fields) {\n return fields.filter(function (f) {\n return f.name === 'primary' && f.value === 1;\n }).length > 0;\n });\n });\n\n if (images[0] && images[0].length > 1) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error(this.$slots['error-multiple-primary'] ? this.$slots['error-multiple-primary'][0].text : 'No error has been provided for the slot \"error-multiple-primary\"').subscribe();\n }\n\n var validation = [];\n this.form.variations.map(function (v, i) {\n return v.tabs.units.fields.filter(function (field) {\n return field.type === 'group';\n }).forEach(function (fields_groups) {\n var uniqueness = new Object();\n fields_groups.groups.forEach(function (fields) {\n validation.push(_this4.formValidation.validateFields(fields));\n });\n });\n });\n\n if (validation.length === 0) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error(this.$slots['error-no-units-groups'] ? this.$slots['error-no-units-groups'][0].text : 'Either Selling or Purchase unit isn\\'t defined. Unable to proceed.').subscribe();\n }\n\n if (validation.filter(function (v) {\n return v === false;\n }).length > 0) {\n this.$forceUpdate();\n return _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error(this.$slots['error-invalid-unit-group'] ? this.$slots['error-invalid-unit-group'][0].text : 'Unable to proceed as one of the unit group field is invalid').subscribe();\n }\n /**\r\n * let's correctly extract \r\n * the form before submitting that\r\n */\n\n\n var data = _objectSpread(_objectSpread({}, this.formValidation.extractForm(this.form)), {}, {\n variations: this.form.variations.map(function (v, i) {\n var data = _this4.formValidation.extractForm(v);\n\n if (i === 0) {\n data['$primary'] = true;\n }\n\n data['images'] = v.tabs.images.groups.map(function (fields) {\n return _this4.formValidation.extractFields(fields);\n });\n var groups = new Object();\n v.tabs.units.fields.filter(function (field) {\n return field.type === 'group';\n }).forEach(function (field) {\n groups[field.name] = field.groups.map(function (fields) {\n return _this4.formValidation.extractFields(fields);\n });\n });\n data['units'] = _objectSpread(_objectSpread({}, data['units']), groups);\n return data;\n })\n });\n\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"][this.submitMethod ? this.submitMethod.toLowerCase() : 'post'](this.submitUrl, data).subscribe(function (data) {\n if (data.status === 'success') {\n if (_this4.returnUrl !== false) {\n return document.location = _this4.returnUrl;\n }\n\n _this4.$emit('save');\n }\n\n _this4.formValidation.enableForm(_this4.form);\n }, function (error) {\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error(error.message, undefined, {\n duration: 5000\n }).subscribe();\n\n _this4.formValidation.triggerError(_this4.form, error.response.data);\n\n _this4.formValidation.enableForm(_this4.form);\n });\n },\n deleteVariation: function deleteVariation(index) {\n if (confirm(this.$slots['delete-variation'] ? this.$slots['delete-variation'][0].text : 'No error message provided with code \"delete-variation\"')) {\n this.form.variations.splice(index, 1);\n }\n },\n setTabActive: function setTabActive(activeIndex, tabs) {\n for (var _index in tabs) {\n if (_index !== activeIndex) {\n tabs[_index].active = false;\n }\n }\n\n tabs[activeIndex].active = true;\n /**\r\n * If the loaded tab is \"units\", we'll\r\n * load sub units based on the selection.\r\n */\n\n if (activeIndex === 'units') {\n this.loadAvailableUnits(tabs[activeIndex]);\n }\n },\n duplicate: function duplicate(variation) {\n this.form.variations.push(Object.assign({}, variation));\n },\n newVariation: function newVariation() {\n this.form.variations.push(this.defaultVariation);\n },\n getActiveTab: function getActiveTab(tabs) {\n for (var key in tabs) {\n if (tabs[key].active) {\n return tabs[key];\n }\n }\n\n return false;\n },\n getActiveTabKey: function getActiveTabKey(tabs) {\n for (var key in tabs) {\n if (tabs[key].active) {\n return key;\n }\n }\n\n return false;\n },\n parseForm: function parseForm(form) {\n var _this5 = this;\n\n form.main.value = form.main.value === undefined ? '' : form.main.value;\n form.main = this.formValidation.createFields([form.main])[0];\n form.variations.forEach(function (variation, _index) {\n var index = 0;\n\n for (var key in variation.tabs) {\n /**\r\n * here we need to explicitely remove the\r\n * name field as this is replaced by the top field.\r\n * We also save the default variation as that's used for variations\r\n */\n if (index === 0 && variation.tabs[key].active === undefined) {\n variation.tabs[key].active = true;\n _this5._sampleVariation = Object.assign({}, variation);\n\n if (variation.tabs[key].fields) {\n variation.tabs[key].fields = _this5.formValidation.createFields(variation.tabs[key].fields.filter(function (f) {\n return f.name !== 'name';\n }));\n }\n } else {\n if (variation.tabs[key].fields) {\n variation.tabs[key].fields = _this5.formValidation.createFields(variation.tabs[key].fields);\n }\n }\n\n variation.tabs[key].active = variation.tabs[key].active === undefined ? false : variation.tabs[key].active;\n index++;\n }\n });\n return form;\n },\n loadForm: function loadForm() {\n var _this6 = this;\n\n var request = _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"].get(\"\".concat(this.src));\n request.subscribe(function (f) {\n _this6.form = _this6.parseForm(f.form);\n });\n },\n addImage: function addImage(variation) {\n variation.tabs.images.groups.push(this.formValidation.createFields(JSON.parse(JSON.stringify(variation.tabs.images.fields))));\n }\n },\n mounted: function mounted() {\n this.loadForm();\n },\n name: 'ns-manage-products'\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcmVzb3VyY2VzL3RzL3BhZ2VzL2Rhc2hib2FyZC9wcm9jdXJlbWVudHMvbWFuYWdlLXByb2R1Y3RzLnZ1ZT80OTkxIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWlJQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQSw4RkFEQTtBQUVBLHVFQUZBO0FBR0EsMkVBSEE7QUFJQSw0QkFKQTtBQUtBO0FBTEE7QUFPQSxHQVRBO0FBVUE7QUFDQSxvQkFEQSw4QkFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0ZBQ0EsTUFEQSxDQUNBO0FBQ0E7QUFDQTtBQUNBLFNBSkEsRUFLQSxHQUxBLENBS0E7QUFDQTtBQUNBO0FBQ0EsU0FSQTtBQVNBOztBQUVBO0FBQ0EsY0FEQTtBQUVBO0FBRkE7QUFJQTtBQXZCQSxHQVZBO0FBbUNBLDBFQW5DQTtBQW9DQTtBQUNBLG1CQURBLDJCQUNBLE1BREEsRUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBLEtBSkE7O0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFWQSxnQ0FVQSxZQVZBLEVBVUEsS0FWQSxFQVVBO0FBQUE7O0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQSxvQ0FEQTtBQUVBLHdEQUZBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQSxhQUZBLE1BRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBWkE7QUFjQSxLQTFCQTtBQTRCQSwrQkE1QkEsNkNBNEJBO0FBQUE7QUFBQTtBQUNBO0FBQ0EsMkNBREE7QUFFQSx5Q0FGQTtBQUdBLDZNQUhBO0FBSUE7QUFDQTtBQUNBO0FBQUE7QUFBQSxlQUNBLEdBREEsQ0FDQTtBQUFBO0FBQUEsYUFEQSxFQUNBLENBREE7QUFHQSxxSUFDQSxTQURBLENBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUxBLEVBS0E7QUFDQTtBQUNBLGFBUEE7QUFRQTtBQUNBO0FBbEJBO0FBb0JBLEtBakRBOztBQW1EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQXZEQSx3QkF1REEsS0F2REEsRUF1REE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BRkEsTUFFQTtBQUNBO0FBQ0E7QUFDQSxLQWpFQTs7QUFtRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQXhFQSw4QkF3RUEsWUF4RUEsRUF3RUE7QUFBQTs7QUFDQTtBQUFBO0FBQUEsb0JBQ0EsU0FEQSxDQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FEQTtBQUVBO0FBRkE7QUFJQSxpQkFMQTtBQU1BO0FBQ0EsYUFWQTtBQVdBO0FBQ0EsU0FmQTs7QUFpQkE7QUFDQSxPQTFCQTtBQTJCQSxLQXBHQTs7QUFzR0E7QUFDQTtBQUNBO0FBQ0Esa0JBekdBLDBCQXlHQSxTQXpHQSxFQXlHQSxLQXpHQSxFQXlHQSxlQXpHQSxFQXlHQTtBQUFBOztBQUNBLHdHQUNBLFNBREEsQ0FDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBREE7QUFFQSxnQ0FGQTtBQUdBO0FBSEE7QUFLQSxhQU5BO0FBT0E7QUFDQSxTQVZBOztBQVdBO0FBQ0EsT0FkQTtBQWVBLEtBekhBO0FBMEhBLFVBMUhBLG9CQTBIQTtBQUFBOztBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0EsT0FGQSxFQUVBLE1BRkEsQ0FFQTtBQUFBO0FBQUEsT0FGQTs7QUFJQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBLFNBRkE7QUFHQSxPQUpBOztBQU1BO0FBQ0E7QUFDQTs7QUFFQTtBQUVBO0FBQ0EsbUNBQ0EsTUFEQSxDQUNBO0FBQUE7QUFBQSxTQURBLEVBRUEsT0FGQSxDQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FGQTtBQUdBLFNBUEE7QUFRQSxPQVRBOztBQVdBO0FBQ0E7QUFDQTs7QUFFQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsaURBQ0EsMENBREE7QUFFQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FGQTtBQUlBO0FBRUE7QUFBQTtBQUFBLGFBQ0EsT0FEQSxDQUNBO0FBQ0E7QUFDQTtBQUNBLGFBRkE7QUFHQSxXQUxBO0FBT0EsMERBQ0EsYUFEQSxHQUVBLE1BRkE7QUFLQTtBQUNBLFNBekJBO0FBRkE7O0FBOEJBLGtKQUNBLFNBREEsQ0FDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUNBO0FBQ0E7O0FBQ0E7QUFDQSxPQVRBLEVBU0E7QUFDQTtBQUNBO0FBREEsV0FFQSxTQUZBOztBQUdBOztBQUNBO0FBQ0EsT0FmQTtBQWdCQSxLQTVOQTtBQTZOQSxtQkE3TkEsMkJBNk5BLEtBN05BLEVBNk5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FqT0E7QUFrT0EsZ0JBbE9BLHdCQWtPQSxXQWxPQSxFQWtPQSxJQWxPQSxFQWtPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQWxQQTtBQW1QQSxhQW5QQSxxQkFtUEEsU0FuUEEsRUFtUEE7QUFDQTtBQUNBLEtBclBBO0FBc1BBLGdCQXRQQSwwQkFzUEE7QUFDQTtBQUNBLEtBeFBBO0FBeVBBLGdCQXpQQSx3QkF5UEEsSUF6UEEsRUF5UEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FqUUE7QUFrUUEsbUJBbFFBLDJCQWtRQSxJQWxRQSxFQWtRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQTFRQTtBQTJRQSxhQTNRQSxxQkEyUUEsSUEzUUEsRUEyUUE7QUFBQTs7QUFDQTtBQUNBO0FBRUE7QUFDQTs7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBLFdBTkEsTUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBRUE7QUFDQTtBQUNBLE9BekJBO0FBMkJBO0FBQ0EsS0EzU0E7QUE0U0EsWUE1U0Esc0JBNFNBO0FBQUE7O0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FGQTtBQUdBLEtBalRBO0FBa1RBLFlBbFRBLG9CQWtUQSxTQWxUQSxFQWtUQTtBQUNBLHdDQUNBLDBGQURBO0FBR0E7QUF0VEEsR0FwQ0E7QUE0VkEsU0E1VkEscUJBNFZBO0FBQ0E7QUFDQSxHQTlWQTtBQStWQTtBQS9WQSIsImZpbGUiOiIuL25vZGVfbW9kdWxlcy9iYWJlbC1sb2FkZXIvbGliL2luZGV4LmpzPyEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9pbmRleC5qcz8hLi9yZXNvdXJjZXMvdHMvcGFnZXMvZGFzaGJvYXJkL3Byb2N1cmVtZW50cy9tYW5hZ2UtcHJvZHVjdHMudnVlP3Z1ZSZ0eXBlPXNjcmlwdCZsYW5nPWpzJi5qcyIsInNvdXJjZXNDb250ZW50IjpbIlxyXG48dGVtcGxhdGU+XHJcbiAgICA8ZGl2IGNsYXNzPVwiZm9ybSBmbGV4LWF1dG9cIiBpZD1cImNydWQtZm9ybVwiPlxyXG4gICAgICAgIDxkaXYgdi1pZj1cIk9iamVjdC52YWx1ZXMoIGZvcm0gKS5sZW5ndGggPT09IDBcIiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGgtZnVsbCBqdXN0aWZ5LWNlbnRlciBmbGV4LWF1dG9cIj5cclxuICAgICAgICAgICAgPG5zLXNwaW5uZXIvPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDx0ZW1wbGF0ZSB2LWlmPVwiT2JqZWN0LnZhbHVlcyggZm9ybSApLmxlbmd0aCA+IDBcIj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2xcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktYmV0d2VlbiBpdGVtcy1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgZm9yPVwidGl0bGVcIiBjbGFzcz1cImZvbnQtYm9sZCBteS0yIHRleHQtZ3JheS03MDBcIj57eyBmb3JtLm1haW4ubGFiZWwgfX08L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgZm9yPVwidGl0bGVcIiBjbGFzcz1cInRleHQtc20gbXktMiB0ZXh0LWdyYXktNzAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxhIHYtaWY9XCJyZXR1cm5VcmxcIiA6aHJlZj1cInJldHVyblVybFwiIGNsYXNzPVwicm91bmRlZC1mdWxsIGJvcmRlciBib3JkZXItZ3JheS00MDAgaG92ZXI6YmctcmVkLTYwMCBob3Zlcjp0ZXh0LXdoaXRlIGJnLXdoaXRlIHB4LTIgcHktMVwiPlJldHVybjwvYT5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPGRpdiA6Y2xhc3M9XCJmb3JtLm1haW4uZGlzYWJsZWQgPyAnYm9yZGVyLWdyYXktNTAwJyA6IGZvcm0ubWFpbi5lcnJvcnMubGVuZ3RoID4gMCA/ICdib3JkZXItcmVkLTYwMCcgOiAnYm9yZGVyLWJsdWUtNTAwJ1wiIGNsYXNzPVwiZmxleCBib3JkZXItMiByb3VuZGVkIG92ZXJmbG93LWhpZGRlblwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB2LW1vZGVsPVwiZm9ybS5tYWluLnZhbHVlXCIgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEBibHVyPVwiZm9ybVZhbGlkYXRpb24uY2hlY2tGaWVsZCggZm9ybS5tYWluIClcIiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgQGNoYW5nZT1cImZvcm1WYWxpZGF0aW9uLmNoZWNrRmllbGQoIGZvcm0ubWFpbiApXCIgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDpkaXNhYmxlZD1cImZvcm0ubWFpbi5kaXNhYmxlZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCIgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDpjbGFzcz1cImZvcm0ubWFpbi5kaXNhYmxlZCA/ICdiZy1ncmF5LTQwMCcgOiAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxleC1hdXRvIHRleHQtZ3JheS03MDAgb3V0bGluZS1ub25lIGgtMTAgcHgtMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gOmRpc2FibGVkPVwiZm9ybS5tYWluLmRpc2FibGVkXCIgOmNsYXNzPVwiZm9ybS5tYWluLmRpc2FibGVkID8gJ2JnLWdyYXktNTAwJyA6IGZvcm0ubWFpbi5lcnJvcnMubGVuZ3RoID4gMCA/ICdiZy1yZWQtNTAwJyA6ICdiZy1ibHVlLTUwMCdcIiBAY2xpY2s9XCJzdWJtaXQoKVwiIGNsYXNzPVwib3V0bGluZS1ub25lIHB4LTQgaC0xMCB0ZXh0LXdoaXRlIGJvcmRlci1sIGJvcmRlci1ncmF5LTQwMFwiPjxzbG90IG5hbWU9XCJzYXZlXCI+U2F2ZTwvc2xvdD48L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LXhzIHRleHQtZ3JheS02MDAgcHktMVwiIHYtaWY9XCJmb3JtLm1haW4uZGVzY3JpcHRpb24gJiYgZm9ybS5tYWluLmVycm9ycy5sZW5ndGggPT09IDBcIj57eyBmb3JtLm1haW4uZGVzY3JpcHRpb24gfX08L3A+XHJcbiAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQteHMgcHktMSB0ZXh0LXJlZC01MDBcIiB2LWJpbmQ6a2V5PVwiaW5kZXhcIiB2LWZvcj1cIihlcnJvciwgaW5kZXgpIG9mIGZvcm0ubWFpbi5lcnJvcnNcIj5cclxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj48c2xvdCBuYW1lPVwiZXJyb3ItcmVxdWlyZWRcIj57eyBlcnJvci5pZGVudGlmaWVyIH19PC9zbG90Pjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgIDwvcD5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgaWQ9XCJmb3JtLWNvbnRhaW5lclwiIGNsYXNzPVwiLW14LTQgZmxleCBmbGV4LXdyYXAgbXQtNFwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTQgdy1mdWxsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD1cInRhYmJlZC1jYXJkXCIgY2xhc3M9XCJtYi04XCIgOmtleT1cInZhcmlhdGlvbl9pbmRleFwiIHYtZm9yPVwiKHZhcmlhdGlvbiwgdmFyaWF0aW9uX2luZGV4KSBvZiBmb3JtLnZhcmlhdGlvbnNcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD1cImNhcmQtaGVhZGVyXCIgY2xhc3M9XCJmbGV4IGZsZXgtd3JhcCBqdXN0aWZ5LWJldHdlZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtd3JhcFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgQGNsaWNrPVwic2V0VGFiQWN0aXZlKCBpbmRleCwgdmFyaWF0aW9uLnRhYnMgKVwiIDpjbGFzcz1cInRhYi5hY3RpdmUgPyAnYmctd2hpdGUnIDogJ2JnLWdyYXktMTAwJ1wiIHYtZm9yPVwiKCB0YWIsIGluZGV4ICkgaW4gdmFyaWF0aW9uLnRhYnNcIiB2LWJpbmQ6a2V5PVwiaW5kZXhcIiBjbGFzcz1cImN1cnNvci1wb2ludGVyIHRleHQtZ3JheS03MDAgcHgtNCBweS0yIHJvdW5kZWQtdGwtbGcgcm91bmRlZC10ci1sZyBmbGV4IGp1c3RpZnktYmV0d2VlblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJsb2NrIG1yLTJcIj57eyB0YWIubGFiZWwgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIHYtaWY9XCJ0YWIuZXJyb3JzICYmIHRhYi5lcnJvcnMubGVuZ3RoID4gMFwiIGNsYXNzPVwicm91bmRlZC1mdWxsIGJnLXJlZC00MDAgdGV4dC13aGl0ZSBoLTYgdy02IGZsZXggZm9udC1zZW1pYm9sZCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIj57eyB0YWIuZXJyb3JzLmxlbmd0aCB9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIC1teC0xXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSA8ZGl2IGNsYXNzPVwicHgtMVwiIHYtaWY9XCJmb3JtLnZhcmlhdGlvbnMubGVuZ3RoID4gMSAmJiB2YXJpYXRpb25faW5kZXggPiAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gQGNsaWNrPVwiZGVsZXRlVmFyaWF0aW9uKCB2YXJpYXRpb25faW5kZXggKVwiIGNsYXNzPVwicm91bmRlZC1mdWxsIGgtOCB3LTggZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgYmctcmVkLTQwMCB0ZXh0LXdoaXRlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImxhcyBsYS10aW1lc1wiPjwvaT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTFcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBAY2xpY2s9XCJuZXdWYXJpYXRpb24oKVwiIGNsYXNzPVwicm91bmRlZC1mdWxsIGgtOCB3LTggZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgYmctZ3JlZW4tNDAwIHRleHQtd2hpdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGFzIGxhLXBsdXNcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gQGNsaWNrPVwiZHVwbGljYXRlKCB2YXJpYXRpb24gKVwiIGNsYXNzPVwicm91bmRlZC1mdWxsIGgtOCB3LTggZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgYmctYmx1ZS00MDAgdGV4dC13aGl0ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJsYXMgbGEtY29weVwiPjwvaT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1ib2R5IGJnLXdoaXRlIHJvdW5kZWQtYnItbGcgcm91bmRlZC1ibC1sZyBzaGFkb3cgcC0yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiLW14LTQgZmxleCBmbGV4LXdyYXBcIiB2LWlmPVwiISBbICdpbWFnZXMnLCAndW5pdHMnIF0uaW5jbHVkZXMoIGdldEFjdGl2ZVRhYktleSggdmFyaWF0aW9uLnRhYnMgKSApXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRlbXBsYXRlIHYtZm9yPVwiKCBmaWVsZCwgaW5kZXggKSBvZiBnZXRBY3RpdmVUYWIoIHZhcmlhdGlvbi50YWJzICkuZmllbGRzXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgOmtleT1cImluZGV4XCIgY2xhc3M9XCJmbGV4IGZsZXgtY29sIHB4LTQgdy1mdWxsIG1kOnctMS8yIGxnOnctMS8zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bnMtZmllbGQgOmZpZWxkPVwiZmllbGRcIj48L25zLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiLW14LTQgZmxleCBmbGV4LXdyYXBcIiB2LWlmPVwiZ2V0QWN0aXZlVGFiS2V5KCB2YXJpYXRpb24udGFicyApID09PSAnaW1hZ2VzJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIHB4LTQgdy1mdWxsIG1kOnctMS8yIGxnOnctMS8zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3VuZGVkIGJvcmRlciBmbGV4IGJnLXdoaXRlIGp1c3RpZnktYmV0d2VlbiBwLTIgaXRlbXMtY2VudGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5BZGQgSW1hZ2VzPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBAY2xpY2s9XCJhZGRJbWFnZSggdmFyaWF0aW9uIClcIiBjbGFzcz1cInJvdW5kZWQtZnVsbCBib3JkZXIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgdy04IGgtOCBiZy13aGl0ZSBob3ZlcjpiZy1ibHVlLTQwMCBob3Zlcjp0ZXh0LXdoaXRlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJsYXMgbGEtcGx1cy1jaXJjbGVcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6a2V5PVwiaW5kZXhcIiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdi1mb3I9XCIoIGdyb3VwLCBpbmRleCApIG9mIGdldEFjdGl2ZVRhYiggdmFyaWF0aW9uLnRhYnMgKS5ncm91cHNcIiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbGV4IGZsZXgtY29sIHB4LTQgdy1mdWxsIG1kOnctMS8yIGxnOnctMS8zIG1iLTRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvdW5kZWQgYm9yZGVyIGZsZXggZmxleC1jb2wgYmctd2hpdGUgcC0yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bnMtZmllbGQgOmtleT1cImluZGV4XCIgdi1mb3I9XCIoZmllbGQsIGluZGV4KSBvZiBncm91cFwiIDpmaWVsZD1cImZpZWxkXCI+PC9ucy1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCItbXgtNCBmbGV4IGZsZXgtd3JhcFwiIHYtaWY9XCJnZXRBY3RpdmVUYWJLZXkoIHZhcmlhdGlvbi50YWJzICkgPT09ICd1bml0cydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtNCB3LWZ1bGwgbWQ6dy0xLzIgbGc6dy0xLzNcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5zLWZpZWxkIEBjaGFuZ2U9XCJsb2FkQXZhaWxhYmxlVW5pdHMoIGdldEFjdGl2ZVRhYiggdmFyaWF0aW9uLnRhYnMgKSApXCIgOmZpZWxkPVwiZ2V0QWN0aXZlVGFiKCB2YXJpYXRpb24udGFicyApLmZpZWxkc1swXVwiPjwvbnMtZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxucy1maWVsZCBAY2hhbmdlPVwibG9hZEF2YWlsYWJsZVVuaXRzKCBnZXRBY3RpdmVUYWIoIHZhcmlhdGlvbi50YWJzICkgKVwiIDpmaWVsZD1cImdldEFjdGl2ZVRhYiggdmFyaWF0aW9uLnRhYnMgKS5maWVsZHNbMV1cIj48L25zLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZW1wbGF0ZSB2LWZvcj1cIihmaWVsZCxpbmRleCkgb2YgZ2V0QWN0aXZlVGFiKCB2YXJpYXRpb24udGFicyApLmZpZWxkc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHYtaWY9XCJmaWVsZC50eXBlID09PSAnZ3JvdXAnXCIgY2xhc3M9XCJweC00IHctZnVsbCBsZzp3LTIvM1wiIDprZXk9XCJpbmRleFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb250LW1lZGl1bSB0ZXh0LWdyYXktNzAwXCI+e3sgZmllbGQubGFiZWwgfX08L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwicHktMSB0ZXh0LXNtIHRleHQtZ3JheS02MDBcIj57eyBmaWVsZC5kZXNjcmlwdGlvbiB9fTwvcD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IEBjbGljaz1cImFkZFVuaXRHcm91cCggZmllbGQgKVwiIGNsYXNzPVwiYm9yZGVyLWRhc2hlZCBib3JkZXItMiBib3JkZXItZ3JheS0yMDAgcC0xIGJnLWdyYXktMTAwIGZsZXgganVzdGlmeS1iZXR3ZWVuIGl0ZW1zLWNlbnRlciB0ZXh0LWdyYXktNzAwIGN1cnNvci1wb2ludGVyIHJvdW5kZWQtbGdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyb3VuZGVkLWZ1bGwgYm9yZGVyLTIgYm9yZGVyLWdyYXktMzAwIGJnLXdoaXRlIGgtOCB3LTggZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGFzIGxhLXBsdXMtY2lyY2xlXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPk5ldyBHcm91cDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIi1teC00IGZsZXggZmxleC13cmFwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTQgdy1mdWxsIG1kOnctMS8yIG1iLTRcIiA6a2V5PVwiaW5kZXhcIiB2LWZvcj1cIihncm91cF9maWVsZHMsaW5kZXgpIG9mIGZpZWxkLmdyb3Vwc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2hhZG93IHJvdW5kZWQgb3ZlcmZsb3ctaGlkZGVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm9yZGVyLWIgdGV4dC1zbSBiZy1ibHVlLTQwMCB0ZXh0LXdoaXRlICBib3JkZXItYmx1ZS0zMDAgcC0yIGZsZXgganVzdGlmeS1iZXR3ZWVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+QXZhaWxhYmxlIFF1YW50aXR5PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IGdldFVuaXRRdWFudGl0eSggZ3JvdXBfZmllbGRzICkgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLTIgbWItMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxucy1maWVsZCA6ZmllbGQ9XCJmaWVsZFwiIHYtZm9yPVwiKGZpZWxkLGluZGV4KSBvZiBncm91cF9maWVsZHNcIiA6a2V5PVwiaW5kZXhcIj48L25zLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IEBjbGljaz1cInJlbW92ZVVuaXRQcmljZUdyb3VwKCBncm91cF9maWVsZHMsIGZpZWxkLmdyb3VwcyApXCIgY2xhc3M9XCJwLTEgdGV4dC1yZWQtODAwIGhvdmVyOmJnLXJlZC0yMDAgYm9yZGVyLXQgYm9yZGVyLXJlZC0yMDAgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgY3Vyc29yLXBvaW50ZXIgZm9udC1tZWRpdW1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWxldGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvdGVtcGxhdGU+XHJcbiAgICA8L2Rpdj5cclxuPC90ZW1wbGF0ZT5cclxuPHNjcmlwdD5cclxuaW1wb3J0IEZvcm1WYWxpZGF0aW9uIGZyb20gJ0AvbGlicmFyaWVzL2Zvcm0tdmFsaWRhdGlvbidcclxuaW1wb3J0IHsgbnNTbmFja0JhciwgbnNIdHRwQ2xpZW50IH0gZnJvbSAnQC9ib290c3RyYXAnO1xyXG5pbXBvcnQgbnNQb3NDb25maXJtUG9wdXBWdWUgZnJvbSAnQC9wb3B1cHMvbnMtcG9zLWNvbmZpcm0tcG9wdXAudnVlJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIGRhdGE6ICgpID0+IHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBmb3JtVmFsaWRhdGlvbjogbmV3IEZvcm1WYWxpZGF0aW9uLFxyXG4gICAgICAgICAgICBuc1NuYWNrQmFyLFxyXG4gICAgICAgICAgICBuc0h0dHBDbGllbnQsXHJcbiAgICAgICAgICAgIF9zYW1wbGVWYXJpYXRpb246IG51bGwsXHJcbiAgICAgICAgICAgIGZvcm06ICcnLFxyXG4gICAgICAgIH1cclxuICAgIH0sXHJcbiAgICBjb21wdXRlZDoge1xyXG4gICAgICAgIGRlZmF1bHRWYXJpYXRpb24oKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG5ld1ZhcmlhdGlvbiAgICAgPSAgIG5ldyBPYmplY3Q7XHJcblxyXG4gICAgICAgICAgICBmb3IoIGxldCB0YWJJbmRleCBpbiB0aGlzLl9zYW1wbGVWYXJpYXRpb24udGFicyApIHtcclxuICAgICAgICAgICAgICAgIG5ld1ZhcmlhdGlvblsgdGFiSW5kZXggXSAgICAgICAgICAgID0gICBuZXcgT2JqZWN0O1xyXG4gICAgICAgICAgICAgICAgbmV3VmFyaWF0aW9uWyB0YWJJbmRleCBdLmxhYmVsICAgICAgPSAgIHRoaXMuX3NhbXBsZVZhcmlhdGlvbi50YWJzWyB0YWJJbmRleCBdLmxhYmVsO1xyXG4gICAgICAgICAgICAgICAgbmV3VmFyaWF0aW9uWyB0YWJJbmRleCBdLmFjdGl2ZSAgICAgPSAgIHRoaXMuX3NhbXBsZVZhcmlhdGlvbi50YWJzWyB0YWJJbmRleCBdLmFjdGl2ZTtcclxuICAgICAgICAgICAgICAgIG5ld1ZhcmlhdGlvblsgdGFiSW5kZXggXS5maWVsZHMgICAgID0gICB0aGlzLl9zYW1wbGVWYXJpYXRpb24udGFic1sgdGFiSW5kZXggXS5maWVsZHNcclxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKCBmaWVsZCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCBmaWVsZCApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gISBbICdjYXRlZ29yeV9pZCcsICdwcm9kdWN0X3R5cGUnLCAnc3RvY2tfbWFuYWdlbWVudCcsICdleHBpcmVzJyBdLmluY2x1ZGVzKCBmaWVsZC5uYW1lICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAubWFwKCBmaWVsZCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZmllbGQudmFsdWUgICAgID0gICAnJztcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmllbGQ7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGlkOiAnJyxcclxuICAgICAgICAgICAgICAgIHRhYnM6IG5ld1ZhcmlhdGlvblxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgIH0sICBcclxuICAgIHByb3BzOiBbICdzdWJtaXQtbWV0aG9kJywgJ3N1Ym1pdC11cmwnLCAncmV0dXJuLXVybCcsICdzcmMnLCAndW5pdHMtdXJsJyBdLFxyXG4gICAgbWV0aG9kczoge1xyXG4gICAgICAgIGdldFVuaXRRdWFudGl0eSggZmllbGRzICkge1xyXG4gICAgICAgICAgICBjb25zdCBxdWFudGl0eSAgPSAgIGZpZWxkcy5maWx0ZXIoIGYgPT4gZi5uYW1lID09PSAncXVhbnRpdHknICkubWFwKCBmID0+IGYudmFsdWUgKTtcclxuICAgICAgICAgICAgcmV0dXJuIHF1YW50aXR5Lmxlbmd0aCA+IDAgPyBxdWFudGl0eVswXSA6IDA7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVGhlIHVzZXIgd2FudCB0byByZW1vdmUgYSBncm91cFxyXG4gICAgICAgICAqIHdlIG1pZ2h0IG5lZWQgY29uZmlybWF0aW9uIGJlZm9yZSBwcm9jZWVkaW5nLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHJlbW92ZVVuaXRQcmljZUdyb3VwKCBncm91cF9maWVsZHMsIGdyb3VwICkge1xyXG4gICAgICAgICAgICBjb25zdCBoYXNJZEZpZWxkICAgID0gICBncm91cF9maWVsZHMuZmlsdGVyKCBmaWVsZCA9PiBmaWVsZC5uYW1lID09PSAnaWQnICYmIGZpZWxkLnZhbHVlICE9PSB1bmRlZmluZWQgKTtcclxuICAgICAgICAgICAgICAgIFBvcHVwLnNob3coIG5zUG9zQ29uZmlybVBvcHVwVnVlLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdDb25maXJtIFlvdXIgQWN0aW9uJyxcclxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiAnV291bGQgeW91IGxpa2UgdG8gZGVsZXRlIHRoaXMgZ3JvdXAgPycsXHJcbiAgICAgICAgICAgICAgICAgICAgb25BY3Rpb246ICggYWN0aW9uICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGFjdGlvbiApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggaGFzSWRGaWVsZC5sZW5ndGggPiAwICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlybVVuaXRRdWFudGl0eURlbGV0aW9uKHsgZ3JvdXBfZmllbGRzLCBncm91cCB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggICAgID0gICBncm91cC5pbmRleE9mKCBncm91cF9maWVsZHMgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cC5zcGxpY2UoIGluZGV4LCAxICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBjb25maXJtVW5pdFF1YW50aXR5RGVsZXRpb24oeyBncm91cF9maWVsZHMsIGdyb3VwIH0pIHtcclxuICAgICAgICAgICAgUG9wdXAuc2hvdyggbnNQb3NDb25maXJtUG9wdXBWdWUsIHtcclxuICAgICAgICAgICAgICAgIHRpdGxlOiAnWW91ciBBdHRlbnRpb24gSXMgUmVxdWlyZWQnLFxyXG4gICAgICAgICAgICAgICAgc2l6ZTogJ3ctMy80LXNjcmVlbiBoLTIvNS1zY3JlZW4nLFxyXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ1RoZSBjdXJyZW50IHVuaXQgeW91XFwncmUgYWJvdXQgdG8gZGVsZXRlIGhhcyBhIHJlZmVyZW5jZSBvbiB0aGUgZGF0YWJhc2UgYW5kIGl0IG1pZ2h0IGhhdmUgYWxyZWFkeSBwcm9jdXJlZCBzdG9jay4gRGVsZXRpbmcgdGhhdCByZWZlcmVuY2Ugd2lsbCByZW1vdmUgcHJvY3VyZWQgc3RvY2suIFdvdWxkIHlvdSBwcm9jZWVkID8nLFxyXG4gICAgICAgICAgICAgICAgb25BY3Rpb246ICggYWN0aW9uICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICggYWN0aW9uICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpZCAgICA9ICAgZ3JvdXBfZmllbGRzLmZpbHRlciggZiA9PiBmLm5hbWUgPT09ICdpZCcgKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAubWFwKCBmID0+IGYudmFsdWUgKVswXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5zSHR0cENsaWVudC5kZWxldGUoIGAvYXBpL25leG9wb3MvdjQvcHJvZHVjdHMvdW5pdHMvcXVhbnRpdHkvJHtpZH1gKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZSggcmVzdWx0ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleCAgICAgPSAgIGdyb3VwLmluZGV4T2YoIGdyb3VwX2ZpZWxkcyApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwLnNwbGljZSggaW5kZXgsIDEgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuc1NuYWNrQmFyLnN1Y2Nlc3MoIHJlc3VsdC5tZXNzYWdlICkuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCAoIGVycm9yICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zU25hY2tiYXIuZXJyb3IoIGVycm9yLm1lc3NhZ2UgKS5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV2hlbiB0aGUgdXNlciBjbGljayBvbiBcIk5ldyBHcm91cFwiLCBcclxuICAgICAgICAgKiB0aGlzIGNoZWNrIGlmIHRoZXJlIGlzIG5vdCBlbm91Z2ggb3B0aW9ucyBhcyB0aGVyZSBpcyBncm91cHNcclxuICAgICAgICAgKi9cclxuICAgICAgICBhZGRVbml0R3JvdXAoIGZpZWxkICkge1xyXG4gICAgICAgICAgICBpZiAoIGZpZWxkLm9wdGlvbnMubGVuZ3RoID09PSAwICkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5zU25hY2tCYXIuZXJyb3IoICdQbGVhc2Ugc2VsZWN0IGF0IGxlYXN0IG9uZSB1bml0IGdyb3VwIGJlZm9yZSB5b3UgcHJvY2VlZC4nICkuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmKCBmaWVsZC5vcHRpb25zLmxlbmd0aCA+IGZpZWxkLmdyb3Vwcy5sZW5ndGggKSB7XHJcbiAgICAgICAgICAgICAgICBmaWVsZC5ncm91cHMucHVzaChKU09OLnBhcnNlKCBKU09OLnN0cmluZ2lmeSggZmllbGQuZmllbGRzICkgKSApO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgbnNTbmFja0Jhci5lcnJvciggJ1RoZXJlIHNob3VsbmRcXCd0IGJlIG1vcmUgb3B0aW9uIHRoYW4gdGhlcmUgYXJlIHVuaXRzLicgKS5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdoZW4gYSBjaGFuZ2UgaXMgbWFkZSBvbiB1bml0IGdyb3VwXHJcbiAgICAgICAgICogd2UgbmVlZCB0byBwdWxsIHVuaXRzIGF0dGFjaGVkIHRvIGFuZCBtYWtlIHRoZW0gYXZhaWxhYmxlXHJcbiAgICAgICAgICogZm9yIGV2ZXJ5IGdyb3Vwcy4gVmFsaWRhdGlvbiBzaG91bGQgcHJldmVudCBkdXBsaWNhdGVkIHVuaXRzLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGxvYWRBdmFpbGFibGVVbml0cyggdW5pdF9zZWN0aW9uICkge1xyXG4gICAgICAgICAgICBuc0h0dHBDbGllbnQuZ2V0KCB0aGlzLnVuaXRzVXJsLnJlcGxhY2UoICd7aWR9JywgdW5pdF9zZWN0aW9uLmZpZWxkcy5maWx0ZXIoIGYgPT4gZi5uYW1lID09PSAndW5pdF9ncm91cCcgKVswXS52YWx1ZSApIClcclxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoIHJlc3VsdCA9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICAgICAqIEZvciBlYWNoIGdyb3VwLCB3ZSdsbCBsb29wIHRvIGZpbmRcclxuICAgICAgICAgICAgICAgICAgICAgKiB0aGUgZmllbGQgdGhhdCBhbGxvdyB0byBjaG9vc2UgdGhlIHVuaXRcclxuICAgICAgICAgICAgICAgICAgICAgKiBpbiBvcmRlciB0byBjaGFuZ2UgdGhlIG9wdGlvbnMgYXZhaWxhYmxlXHJcbiAgICAgICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICAgICAgdW5pdF9zZWN0aW9uLmZpZWxkcy5mb3JFYWNoKCBmaWVsZCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggZmllbGQudHlwZSA9PT0gJ2dyb3VwJyApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLm9wdGlvbnMgICA9ICAgcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQuZmllbGRzLmZvckVhY2goIF9maWVsZCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBfZmllbGQubmFtZSA9PT0gJ3VuaXRfaWQnICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyggX2ZpZWxkICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9maWVsZC5vcHRpb25zICA9ICAgcmVzdWx0Lm1hcCggb3B0aW9uID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IG9wdGlvbi5uYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBvcHRpb24uaWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRmb3JjZVVwZGF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAZGVwcmVjYXRlZFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGxvYWRPcHRpb25zRm9yKCBmaWVsZE5hbWUsIHZhbHVlLCB2YXJpYXRpb25faW5kZXggKSB7XHJcbiAgICAgICAgICAgIG5zSHR0cENsaWVudC5nZXQoIHRoaXMudW5pdHNVcmwucmVwbGFjZSggJ3tpZH0nLCB2YWx1ZSApIClcclxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoIHJlc3VsdCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLnZhcmlhdGlvbnNbIHZhcmlhdGlvbl9pbmRleCBdLnRhYnMudW5pdHMuZmllbGRzLmZvckVhY2goIF9maWVsZCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggX2ZpZWxkLm5hbWUgPT09IGZpZWxkTmFtZSApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9maWVsZC5vcHRpb25zICAgID0gICByZXN1bHQubWFwKCBvcHRpb24gPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBvcHRpb24ubmFtZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IG9wdGlvbi5pZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZm9yY2VVcGRhdGUoKTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgfSxcclxuICAgICAgICBzdWJtaXQoKSB7XHJcbiAgICAgICAgICAgIGxldCBmb3JtVmFsaWRHbG9iYWxseSAgID0gICB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1WYWxpZGF0aW9uLnZhbGlkYXRlRmllbGRzKFsgdGhpcy5mb3JtLm1haW4gXSk7IFxyXG5cclxuICAgICAgICAgICAgY29uc3QgdmFsaWRpdHkgID0gICB0aGlzLmZvcm0udmFyaWF0aW9ucy5tYXAoIHZhcmlhdGlvbiA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtVmFsaWRhdGlvbi52YWxpZGF0ZUZvcm0oIHZhcmlhdGlvbiApO1xyXG4gICAgICAgICAgICB9KS5maWx0ZXIoIHYgPT4gdi5sZW5ndGggPiAwICk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIHZhbGlkaXR5Lmxlbmd0aCA+IDAgfHwgT2JqZWN0LnZhbHVlcyggdGhpcy5mb3JtLm1haW4uZXJyb3JzICkubGVuZ3RoID4gMCApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuc1NuYWNrQmFyLmVycm9yKCB0aGlzLiRzbG90c1sgJ2Vycm9yLWZvcm0taW52YWxpZCcgXSA/IHRoaXMuJHNsb3RzWyAnZXJyb3ItZm9ybS1pbnZhbGlkJyBdWzBdLnRleHQgOiAnTm8gZXJyb3IgaGFzIGJlZW4gcHJvdmlkZWQgZm9yIHRoZSBzbG90IFwiZXJyb3ItZm9ybS1pbnZhbGlkXCInICkuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBJZiB0aGVyZSBhcmUgbW9yZSB0aGFuIG9uZVxyXG4gICAgICAgICAgICAgKiBwcmltYXJ5IGltYWdlLCB3ZSdsbCBibG9jayB0aGUgcHJvY2Vzc1xyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgY29uc3QgaW1hZ2VzICAgID0gICB0aGlzLmZvcm0udmFyaWF0aW9ucy5tYXAoICh2LGkpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB2LnRhYnMuaW1hZ2VzLmdyb3Vwcy5maWx0ZXIoIGZpZWxkcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpZWxkcy5maWx0ZXIoIGYgPT4gZi5uYW1lID09PSAncHJpbWFyeScgJiYgZi52YWx1ZSA9PT0gMSApLmxlbmd0aCA+IDA7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSlcclxuXHJcbiAgICAgICAgICAgIGlmICggaW1hZ2VzWzBdICYmIGltYWdlc1swXS5sZW5ndGggPiAxICkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5zU25hY2tCYXIuZXJyb3IoIHRoaXMuJHNsb3RzWyAnZXJyb3ItbXVsdGlwbGUtcHJpbWFyeScgXSA/IHRoaXMuJHNsb3RzWyAnZXJyb3ItbXVsdGlwbGUtcHJpbWFyeScgXVswXS50ZXh0IDogJ05vIGVycm9yIGhhcyBiZWVuIHByb3ZpZGVkIGZvciB0aGUgc2xvdCBcImVycm9yLW11bHRpcGxlLXByaW1hcnlcIicgKS5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgdmFsaWRhdGlvbiAgICAgICAgPSAgIFtdO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5mb3JtLnZhcmlhdGlvbnMubWFwKCAoIHYsIGkgKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdi50YWJzLnVuaXRzLmZpZWxkc1xyXG4gICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoIGZpZWxkID0+IGZpZWxkLnR5cGUgPT09ICdncm91cCcgKVxyXG4gICAgICAgICAgICAgICAgICAgIC5mb3JFYWNoKCBmaWVsZHNfZ3JvdXBzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5pcXVlbmVzcyAgICA9ICAgbmV3IE9iamVjdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRzX2dyb3Vwcy5ncm91cHMuZm9yRWFjaCggZmllbGRzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb24ucHVzaCggdGhpcy5mb3JtVmFsaWRhdGlvbi52YWxpZGF0ZUZpZWxkcyggZmllbGRzICkgKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgaWYgKCB2YWxpZGF0aW9uLmxlbmd0aCA9PT0gMCApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuc1NuYWNrQmFyLmVycm9yKCB0aGlzLiRzbG90c1sgJ2Vycm9yLW5vLXVuaXRzLWdyb3VwcycgXSA/IHRoaXMuJHNsb3RzWyAnZXJyb3Itbm8tdW5pdHMtZ3JvdXBzJyBdWzBdLnRleHQgOiAnRWl0aGVyIFNlbGxpbmcgb3IgUHVyY2hhc2UgdW5pdCBpc25cXCd0IGRlZmluZWQuIFVuYWJsZSB0byBwcm9jZWVkLicgKS5zdWJzY3JpYmUoKTsgXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICggdmFsaWRhdGlvbi5maWx0ZXIoIHYgPT4gdiA9PT0gZmFsc2UgKS5sZW5ndGggPiAwICkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy4kZm9yY2VVcGRhdGUoKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuc1NuYWNrQmFyLmVycm9yKCB0aGlzLiRzbG90c1sgJ2Vycm9yLWludmFsaWQtdW5pdC1ncm91cCcgXSA/IHRoaXMuJHNsb3RzWyAnZXJyb3ItaW52YWxpZC11bml0LWdyb3VwJyBdWzBdLnRleHQgOiAnVW5hYmxlIHRvIHByb2NlZWQgYXMgb25lIG9mIHRoZSB1bml0IGdyb3VwIGZpZWxkIGlzIGludmFsaWQnICkuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBsZXQncyBjb3JyZWN0bHkgZXh0cmFjdCBcclxuICAgICAgICAgICAgICogdGhlIGZvcm0gYmVmb3JlIHN1Ym1pdHRpbmcgdGhhdFxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgY29uc3QgZGF0YSAgPSAgIHtcclxuICAgICAgICAgICAgICAgIC4uLnRoaXMuZm9ybVZhbGlkYXRpb24uZXh0cmFjdEZvcm0oIHRoaXMuZm9ybSApLFxyXG4gICAgICAgICAgICAgICAgdmFyaWF0aW9uczogdGhpcy5mb3JtLnZhcmlhdGlvbnMubWFwKCAodixpKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGF0YSAgPSAgIHRoaXMuZm9ybVZhbGlkYXRpb24uZXh0cmFjdEZvcm0oIHYgKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIGkgPT09IDAgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFbICckcHJpbWFyeScgXSAgPSAgIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBkYXRhWyAnaW1hZ2VzJyBdICAgID0gICB2LnRhYnMuaW1hZ2VzLmdyb3Vwcy5tYXAoIGZpZWxkcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1WYWxpZGF0aW9uLmV4dHJhY3RGaWVsZHMoIGZpZWxkcyApO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBncm91cHMgICAgPSAgIG5ldyBPYmplY3Q7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHYudGFicy51bml0cy5maWVsZHMuZmlsdGVyKCBmaWVsZCA9PiBmaWVsZC50eXBlID09PSAnZ3JvdXAnIClcclxuICAgICAgICAgICAgICAgICAgICAgICAgLmZvckVhY2goIGZpZWxkID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3Vwc1sgZmllbGQubmFtZSBdICAgID0gICBmaWVsZC5ncm91cHMubWFwKCBmaWVsZHMgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1WYWxpZGF0aW9uLmV4dHJhY3RGaWVsZHMoIGZpZWxkcyApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGRhdGFbICd1bml0cycgXSAgICAgICAgID0gICB7IFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5kYXRhWyAndW5pdHMnIF0sIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5ncm91cHNcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIG5zSHR0cENsaWVudFsgdGhpcy5zdWJtaXRNZXRob2QgPyB0aGlzLnN1Ym1pdE1ldGhvZC50b0xvd2VyQ2FzZSgpIDogJ3Bvc3QnIF0oIHRoaXMuc3VibWl0VXJsLCBkYXRhIClcclxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoIGRhdGEgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICggZGF0YS5zdGF0dXMgPT09ICdzdWNjZXNzJyApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCB0aGlzLnJldHVyblVybCAhPT0gZmFsc2UgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9jdW1lbnQubG9jYXRpb24gICA9ICAgdGhpcy5yZXR1cm5Vcmw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kZW1pdCggJ3NhdmUnICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZm9ybVZhbGlkYXRpb24uZW5hYmxlRm9ybSggdGhpcy5mb3JtICk7XHJcbiAgICAgICAgICAgICAgICB9LCAoIGVycm9yICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIG5zU25hY2tCYXIuZXJyb3IoIGVycm9yLm1lc3NhZ2UsIHVuZGVmaW5lZCwge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbjogNTAwMFxyXG4gICAgICAgICAgICAgICAgICAgIH0pLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZm9ybVZhbGlkYXRpb24udHJpZ2dlckVycm9yKCB0aGlzLmZvcm0sIGVycm9yLnJlc3BvbnNlLmRhdGEgKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm1WYWxpZGF0aW9uLmVuYWJsZUZvcm0oIHRoaXMuZm9ybSApO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICB9LFxyXG4gICAgICAgIGRlbGV0ZVZhcmlhdGlvbiggaW5kZXggKSB7XHJcbiAgICAgICAgICAgIGlmICggY29uZmlybSggdGhpcy4kc2xvdHNbICdkZWxldGUtdmFyaWF0aW9uJyBdID8gdGhpcy4kc2xvdHNbICdkZWxldGUtdmFyaWF0aW9uJyBdWzBdLnRleHQgOiAnTm8gZXJyb3IgbWVzc2FnZSBwcm92aWRlZCB3aXRoIGNvZGUgXCJkZWxldGUtdmFyaWF0aW9uXCInICkgKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm0udmFyaWF0aW9ucy5zcGxpY2UoIGluZGV4LCAxICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIHNldFRhYkFjdGl2ZSggYWN0aXZlSW5kZXgsIHRhYnMgKSB7XHJcbiAgICAgICAgICAgIGZvciggbGV0IF9pbmRleCBpbiB0YWJzICkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCBfaW5kZXggIT09IGFjdGl2ZUluZGV4ICkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRhYnNbIF9pbmRleCBdLmFjdGl2ZSAgICA9ICAgZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRhYnNbIGFjdGl2ZUluZGV4IF0uYWN0aXZlICA9ICAgdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBJZiB0aGUgbG9hZGVkIHRhYiBpcyBcInVuaXRzXCIsIHdlJ2xsXHJcbiAgICAgICAgICAgICAqIGxvYWQgc3ViIHVuaXRzIGJhc2VkIG9uIHRoZSBzZWxlY3Rpb24uXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBpZiAoIGFjdGl2ZUluZGV4ID09PSAndW5pdHMnICkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkQXZhaWxhYmxlVW5pdHMoIHRhYnNbIGFjdGl2ZUluZGV4IF0gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sICBcclxuICAgICAgICBkdXBsaWNhdGUoIHZhcmlhdGlvbiApIHtcclxuICAgICAgICAgICAgdGhpcy5mb3JtLnZhcmlhdGlvbnMucHVzaCggT2JqZWN0LmFzc2lnbih7fSwgdmFyaWF0aW9uICkpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgbmV3VmFyaWF0aW9uKCkge1xyXG4gICAgICAgICAgICB0aGlzLmZvcm0udmFyaWF0aW9ucy5wdXNoKCB0aGlzLmRlZmF1bHRWYXJpYXRpb24gKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGdldEFjdGl2ZVRhYiggdGFicyApIHtcclxuICAgICAgICAgICAgZm9yKCBsZXQga2V5IGluIHRhYnMgKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIHRhYnNbIGtleSBdLmFjdGl2ZSApIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFic1sga2V5IF07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9LCBcclxuICAgICAgICBnZXRBY3RpdmVUYWJLZXkoIHRhYnMgKSB7XHJcbiAgICAgICAgICAgIGZvciggbGV0IGtleSBpbiB0YWJzICkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCB0YWJzWyBrZXkgXS5hY3RpdmUgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGtleTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgcGFyc2VGb3JtKCBmb3JtICkge1xyXG4gICAgICAgICAgICBmb3JtLm1haW4udmFsdWUgICAgID0gICBmb3JtLm1haW4udmFsdWUgPT09IHVuZGVmaW5lZCA/ICcnIDogZm9ybS5tYWluLnZhbHVlO1xyXG4gICAgICAgICAgICBmb3JtLm1haW4gICAgICAgICAgID0gICB0aGlzLmZvcm1WYWxpZGF0aW9uLmNyZWF0ZUZpZWxkcyhbIGZvcm0ubWFpbiBdKVswXTtcclxuXHJcbiAgICAgICAgICAgIGZvcm0udmFyaWF0aW9ucy5mb3JFYWNoKCAoIHZhcmlhdGlvbiwgX2luZGV4ICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgbGV0IGluZGV4ICAgICAgICAgICA9ICAgMDtcclxuICAgICAgICAgICAgICAgIGZvciggbGV0IGtleSBpbiB2YXJpYXRpb24udGFicyApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgICAgICogaGVyZSB3ZSBuZWVkIHRvIGV4cGxpY2l0ZWx5IHJlbW92ZSB0aGVcclxuICAgICAgICAgICAgICAgICAgICAgKiBuYW1lIGZpZWxkIGFzIHRoaXMgaXMgcmVwbGFjZWQgYnkgdGhlIHRvcCBmaWVsZC5cclxuICAgICAgICAgICAgICAgICAgICAgKiBXZSBhbHNvIHNhdmUgdGhlIGRlZmF1bHQgdmFyaWF0aW9uIGFzIHRoYXQncyB1c2VkIGZvciB2YXJpYXRpb25zXHJcbiAgICAgICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCBpbmRleCA9PT0gMCAmJiB2YXJpYXRpb24udGFic1sga2V5IF0uYWN0aXZlID09PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhdGlvbi50YWJzWyBrZXkgXS5hY3RpdmUgICAgPSAgIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NhbXBsZVZhcmlhdGlvbiAgICAgICAgICAgPSAgIE9iamVjdC5hc3NpZ24oe30sIHZhcmlhdGlvbiApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHZhcmlhdGlvbi50YWJzWyBrZXkgXS5maWVsZHMgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJpYXRpb24udGFic1sga2V5IF0uZmllbGRzICAgID0gICB0aGlzLmZvcm1WYWxpZGF0aW9uLmNyZWF0ZUZpZWxkcyggdmFyaWF0aW9uLnRhYnNbIGtleSBdLmZpZWxkcy5maWx0ZXIoIGYgPT4gZi5uYW1lICE9PSAnbmFtZScgKSApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCB2YXJpYXRpb24udGFic1sga2V5IF0uZmllbGRzICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWF0aW9uLnRhYnNbIGtleSBdLmZpZWxkcyAgICA9ICAgdGhpcy5mb3JtVmFsaWRhdGlvbi5jcmVhdGVGaWVsZHMoIHZhcmlhdGlvbi50YWJzWyBrZXkgXS5maWVsZHMgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyaWF0aW9uLnRhYnNbIGtleSBdLmFjdGl2ZSAgICA9ICAgdmFyaWF0aW9uLnRhYnNbIGtleSBdLmFjdGl2ZSA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiB2YXJpYXRpb24udGFic1sga2V5IF0uYWN0aXZlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpbmRleCsrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBmb3JtO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgbG9hZEZvcm0oKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3QgICA9ICAgbnNIdHRwQ2xpZW50LmdldCggYCR7dGhpcy5zcmN9YCApO1xyXG4gICAgICAgICAgICByZXF1ZXN0LnN1YnNjcmliZSggZiA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm0gICAgPSAgIHRoaXMucGFyc2VGb3JtKCBmLmZvcm0gKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBhZGRJbWFnZSggdmFyaWF0aW9uICkge1xyXG4gICAgICAgICAgICB2YXJpYXRpb24udGFicy5pbWFnZXMuZ3JvdXBzLnB1c2goXHJcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1WYWxpZGF0aW9uLmNyZWF0ZUZpZWxkcyggSlNPTi5wYXJzZSggSlNPTi5zdHJpbmdpZnkoIHZhcmlhdGlvbi50YWJzLmltYWdlcy5maWVsZHMgKSApIClcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG4gICAgbW91bnRlZCgpIHtcclxuICAgICAgICB0aGlzLmxvYWRGb3JtKCk7XHJcbiAgICB9LFxyXG4gICAgbmFtZTogJ25zLW1hbmFnZS1wcm9kdWN0cycsXHJcbn1cclxuPC9zY3JpcHQ+Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/ts/pages/dashboard/procurements/manage-products.vue?vue&type=script&lang=js&\n"); ->>>>>>> 3313f0bf34ae3b3550ee3b8ff27748899eebc41e /***/ }), @@ -156,11 +152,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -<<<<<<< HEAD -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _libraries_form_validation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/libraries/form-validation */ \"./resources/ts/libraries/form-validation.ts\");\n/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs */ \"./node_modules/rxjs/_esm5/index.js\");\n/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs/operators */ \"./node_modules/rxjs/_esm5/operators/index.js\");\n/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/bootstrap */ \"./resources/ts/bootstrap.ts\");\n/* harmony import */ var _manage_products__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./manage-products */ \"./resources/ts/pages/dashboard/procurements/manage-products.vue\");\n/* harmony import */ var _libraries_tax__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @/libraries/tax */ \"./resources/ts/libraries/tax.ts\");\n/* harmony import */ var _popups_ns_procurement_product_options_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @/popups/ns-procurement-product-options.vue */ \"./resources/ts/popups/ns-procurement-product-options.vue\");\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _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; }\n\n\n\n\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n name: 'ns-procurement',\n mounted: function mounted() {\n this.reloadEntities();\n },\n computed: {\n activeTab: function activeTab() {\n return this.validTabs.filter(function (tab) {\n return tab.active;\n }).length > 0 ? this.validTabs.filter(function (tab) {\n return tab.active;\n })[0] : false;\n }\n },\n data: function data() {\n return {\n /**\r\n * Is the total taxes\r\n * computed on all the supplied products\r\n */\n totalTaxValues: 0,\n\n /**\r\n * is the total purchase price of\r\n * all the products\r\n */\n totalPurchasePrice: 0,\n\n /**\r\n * Creating an instance of the form validation\r\n * to proceed with basic form validation\r\n */\n formValidation: new _libraries_form_validation__WEBPACK_IMPORTED_MODULE_0__[\"default\"](),\n\n /**\r\n * Reference to the form. Contains\r\n * all the values and that's what is submitted\r\n * to the server\r\n */\n form: {},\n\n /**\r\n * Reference to the nsSnackBar object\r\n */\n nsSnackBar: _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsSnackBar\"],\n\n /**\r\n * Is the array that contains the various \r\n * procurement informations\r\n */\n fields: [],\n\n /**\r\n * Is the array that contains the result\r\n * from the search.\r\n */\n searchResult: [],\n\n /**\r\n * Search value.\r\n */\n searchValue: '',\n\n /**\r\n * Debounce reference,used for searching\r\n * product using the search bar\r\n */\n debounceSearch: null,\n\n /**\r\n * A reference to the nsHttpClient object\r\n */\n nsHttpClient: _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsHttpClient\"],\n\n /**\r\n * Must contain the \r\n * available taxes group\r\n */\n taxes: [],\n\n /**\r\n * Define the available tabs on\r\n * the actual uI\r\n */\n validTabs: [{\n label: 'Details',\n identifier: 'details',\n active: true\n }, {\n label: 'Products',\n identifier: 'products',\n active: false\n }],\n\n /**\r\n * control the state of the reloading\r\n * spinner\r\n */\n reloading: false\n };\n },\n watch: {\n searchValue: function searchValue(value) {\n var _this = this;\n\n if (value) {\n clearTimeout(this.debounceSearch);\n this.debounceSearch = setTimeout(function () {\n _this.doSearch(value);\n }, 500);\n }\n }\n },\n components: {\n NsManageProducts: _manage_products__WEBPACK_IMPORTED_MODULE_4__[\"default\"]\n },\n props: ['submit-method', 'submit-url', 'return-url', 'src', 'rules'],\n methods: {\n computeTotal: function computeTotal() {\n this.totalTaxValues = 0;\n\n if (this.form.products.length > 0) {\n this.totalTaxValues = this.form.products.map(function (p) {\n return p.procurement.tax_value;\n }).reduce(function (b, a) {\n return b + a;\n });\n }\n\n this.totalPurchasePrice = 0;\n\n if (this.form.products.length > 0) {\n this.totalPurchasePrice = this.form.products.map(function (p) {\n return parseFloat(p.procurement.total_purchase_price);\n }).reduce(function (b, a) {\n return b + a;\n });\n }\n },\n\n /**\r\n * Ensure a line is being updated after\r\n * some field has been changed.\r\n * @param {integer} product index\r\n * @return {void}\r\n */\n updateLine: function updateLine(index) {\n var product = this.form.products[index];\n var taxGroup = this.taxes.filter(function (taxGroup) {\n return taxGroup.id === product.procurement.tax_group_id;\n });\n\n if (parseFloat(product.procurement.purchase_price_edit) > 0 && parseFloat(product.procurement.quantity) > 0) {\n /**\r\n * if some tax group is provided\r\n * then let's compute all the grouped taxes\r\n */\n if (taxGroup.length > 0) {\n var totalTaxes = taxGroup[0].taxes.map(function (tax) {\n return _libraries_tax__WEBPACK_IMPORTED_MODULE_5__[\"Tax\"].getTaxValue(product.procurement.tax_type, product.procurement.purchase_price_edit, parseFloat(tax.rate));\n });\n product.procurement.tax_value = totalTaxes.reduce(function (b, a) {\n return b + a;\n });\n\n if (product.procurement.tax_type === 'inclusive') {\n product.procurement.net_purchase_price = parseFloat(product.procurement.purchase_price_edit) - product.procurement.tax_value;\n product.procurement.gross_purchase_price = parseFloat(product.procurement.purchase_price_edit);\n product.procurement.purchase_price = parseFloat(product.procurement.gross_purchase_price);\n } else {\n product.procurement.gross_purchase_price = parseFloat(product.procurement.purchase_price_edit) + product.procurement.tax_value;\n product.procurement.net_purchase_price = parseFloat(product.procurement.purchase_price_edit);\n product.procurement.purchase_price = parseFloat(product.procurement.gross_purchase_price);\n }\n } else {\n product.procurement.gross_purchase_price = parseFloat(product.procurement.purchase_price_edit);\n product.procurement.purchase_price = parseFloat(product.procurement.purchase_price_edit);\n product.procurement.net_purchase_price = parseFloat(product.procurement.purchase_price_edit);\n product.procurement.tax_value = 0;\n }\n\n product.procurement.tax_value = product.procurement.tax_value * parseFloat(product.procurement.quantity);\n product.procurement.total_purchase_price = product.procurement.purchase_price * parseFloat(product.procurement.quantity);\n }\n\n this.computeTotal();\n this.$forceUpdate();\n },\n\n /**\r\n * Switch the tax type applied \r\n * on the current product.\r\n */\n switchTaxType: function switchTaxType(product, index) {\n product.procurement.tax_type = product.procurement.tax_type === 'inclusive' ? 'exclusive' : 'inclusive';\n this.updateLine(index);\n },\n\n /**\r\n * Perform a seach and populate\r\n * the search result array\r\n * @param string\r\n * @return void\r\n */\n doSearch: function doSearch(search) {\n var _this2 = this;\n\n _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsHttpClient\"].post('/api/nexopos/v4/products/search', {\n search: search\n }).subscribe(function (result) {\n if (result.length === 1) {\n _this2.addProductList(result[0]);\n } else {\n _this2.searchResult = result;\n }\n });\n },\n\n /**\r\n * Reload the value from the server.\r\n * Useful to reload data after having created a new\r\n * entity\r\n * @return void\r\n */\n reloadEntities: function reloadEntities() {\n var _this3 = this;\n\n this.reloading = true;\n Object(rxjs__WEBPACK_IMPORTED_MODULE_1__[\"forkJoin\"])([_bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsHttpClient\"].get('/api/nexopos/v4/categories'), _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsHttpClient\"].get('/api/nexopos/v4/products'), _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsHttpClient\"].get(this.src), _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsHttpClient\"].get('/api/nexopos/v4/taxes/groups')]).subscribe(function (result) {\n _this3.reloading = false;\n _this3.categories = result[0];\n _this3.products = result[1];\n _this3.taxes = result[3];\n\n if (_this3.form.general) {\n result[2].tabs.general.fieds.forEach(function (field, index) {\n field.value = _this3.form.tabs.general.fields[index].value || '';\n });\n }\n\n _this3.form = Object.assign(_this3.form, result[2]);\n _this3.form = _this3.formValidation.createForm(_this3.form);\n\n if (_this3.form.products === undefined) {\n _this3.form.products = [];\n } else {\n /**\r\n * if the product has been provided by the\r\n * server we need to format it.\r\n */\n _this3.form.products = _this3.form.products.map(function (product) {\n ['gross_purchase_price', 'purchase_price_edit', 'tax_value', 'net_purchase_price', 'purchase_price', 'total_price', 'total_purchase_price', 'quantity', 'tax_group_id'].forEach(function (field) {\n if (product[field] === undefined) {\n product[field] = 0;\n }\n });\n product.$invalid = product.$invalid || false;\n product.purchase_price_edit = product.purchase_price;\n return {\n name: product.name,\n purchase_units: product.purchase_units,\n procurement: product,\n unit_quantities: product.unit_quantities || []\n };\n });\n console.log(_this3.form.products);\n }\n\n _this3.$forceUpdate();\n });\n },\n setTabActive: function setTabActive(tab) {\n this.validTabs.forEach(function (tab) {\n return tab.active = false;\n });\n this.$forceUpdate();\n this.$nextTick().then(function () {\n tab.active = true;\n });\n },\n addProductList: function addProductList(product) {\n if (product.unit_quantities === undefined) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsSnackBar\"].error('Unable to add product which doesn\\'t unit quantities defined.').subscribe();\n }\n\n product.procurement = new Object();\n product.procurement.gross_purchase_price = 0;\n product.procurement.purchase_price_edit = 0;\n product.procurement.tax_value = 0;\n product.procurement.net_purchase_price = 0;\n product.procurement.purchase_price = 0;\n product.procurement.total_price = 0;\n product.procurement.total_purchase_price = 0;\n product.procurement.quantity = 1;\n product.procurement.expiration = null;\n product.procurement.tax_group_id = 0;\n product.procurement.tax_type = 'inclusive';\n product.procurement.unit_id = 0;\n product.procurement.product_id = product.id;\n product.procurement.procurement_id = null;\n product.procurement.$invalid = false;\n this.searchResult = [];\n this.searchValue = '';\n this.form.products.push(product);\n },\n submit: function submit() {\n var _this4 = this;\n\n if (this.form.products.length === 0) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsSnackBar\"].error(this.$slots['error-no-products'] ? this.$slots['error-no-products'][0].text : 'No error message provided on the slot \"error-no-products\".', this.$slots['okay'] ? this.$slots['okay'][0].text : 'OK').subscribe();\n }\n\n this.form.products.forEach(function (product) {\n if (!parseFloat(product.procurement.quantity) >= 1) {\n product.procurement.$invalid = true;\n } else if (product.unit_id === 0) {\n product.procurement.$invalid = true;\n } else {\n product.procurement.$invalid = false;\n }\n });\n var invalidProducts = this.form.products.filter(function (product) {\n return product.procurement.$invalid;\n });\n\n if (invalidProducts.length > 0) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsSnackBar\"].error(this.$slots['error-invalid-products'] ? this.$slots['error-invalid-products'][0].text : 'No error message provided on the slot \"error-invalid-products\".', this.$slots['okay'] ? this.$slots['okay'][0].text : 'OK').subscribe();\n }\n\n if (this.formValidation.validateForm(this.form).length > 0) {\n /**\r\n * hack to force rerendering\r\n * there might be a better solutin here.\r\n */\n this.setTabActive(this.activeTab);\n return _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsSnackBar\"].error(this.$slots['error-invalid-form'] ? this.$slots['error-invalid-form'][0].text : 'No error message provided for having an invalid form.', this.$slots['okay'] ? this.$slots['okay'][0].text : 'OK').subscribe();\n }\n\n if (this.submitUrl === undefined) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsSnackBar\"].error(this.$slots['error-no-submit-url'] ? this.$slots['error-no-submit-url'][0].text : 'No error message provided for not having a valid submit url.', this.$slots['okay'] ? this.$slots['okay'][0].text : 'OK').subscribe();\n }\n\n this.formValidation.disableForm(this.form);\n\n var data = _objectSpread(_objectSpread({}, this.formValidation.extractForm(this.form)), {\n products: this.form.products.map(function (product) {\n return product.procurement;\n })\n });\n\n _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsHttpClient\"][this.submitMethod ? this.submitMethod.toLowerCase() : 'post'](this.submitUrl, data).subscribe(function (data) {\n if (data.status === 'success') {\n return document.location = _this4.returnUrl;\n }\n\n _this4.formValidation.enableForm(_this4.form);\n }, function (error) {\n _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsSnackBar\"].error(error.message, undefined, {\n duration: 5000\n }).subscribe();\n\n _this4.formValidation.enableForm(_this4.form);\n\n if (error.errors) {\n _this4.formValidation.triggerError(_this4.form, error.errors);\n }\n });\n },\n deleteProduct: function deleteProduct(index) {\n this.form.products.splice(index, 1);\n this.$forceUpdate();\n },\n handleGlobalChange: function handleGlobalChange(event) {\n this.globallyChecked = event;\n this.rows.forEach(function (r) {\n return r.$checked = event;\n });\n },\n setProductOptions: function setProductOptions(index) {\n var _this5 = this;\n\n var promise = new Promise(function (resolve, reject) {\n Popup.show(_popups_ns_procurement_product_options_vue__WEBPACK_IMPORTED_MODULE_6__[\"default\"], {\n product: _this5.form.products[index],\n resolve: resolve,\n reject: reject\n });\n });\n promise.then(function (value) {\n for (var key in value) {\n _this5.form.products[index].procurement[key] = value[key];\n }\n\n _this5.updateLine(index);\n });\n }\n }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcmVzb3VyY2VzL3RzL3BhZ2VzL2Rhc2hib2FyZC9wcm9jdXJlbWVudHMvbnMtcHJvY3VyZW1lbnQudnVlP2E4MzciXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0Esd0JBREE7QUFFQSxTQUZBLHFCQUVBO0FBQ0E7QUFDQSxHQUpBO0FBS0E7QUFDQSxhQURBLHVCQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBSEEsR0FMQTtBQVVBLE1BVkEsa0JBVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBTEE7O0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFYQTs7QUFjQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhGQWxCQTs7QUFvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBekJBOztBQTJCQTtBQUNBO0FBQ0E7QUFDQSx1RUE5QkE7O0FBZ0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBcENBOztBQXNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQTFDQTs7QUE0Q0E7QUFDQTtBQUNBO0FBQ0EscUJBL0NBOztBQWlEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQXJEQTs7QUF1REE7QUFDQTtBQUNBO0FBQ0EsMkVBMURBOztBQTREQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBaEVBOztBQWtFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUNBO0FBQ0Esd0JBREE7QUFFQSw2QkFGQTtBQUdBO0FBSEEsT0FEQSxFQUtBO0FBQ0EseUJBREE7QUFFQSw4QkFGQTtBQUdBO0FBSEEsT0FMQSxDQXRFQTs7QUFrRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQXRGQTtBQXdGQSxHQW5HQTtBQW9HQTtBQUNBLGVBREEsdUJBQ0EsS0FEQSxFQUNBO0FBQUE7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUZBLEVBRUEsR0FGQTtBQUdBO0FBQ0E7QUFSQSxHQXBHQTtBQThHQTtBQUNBO0FBREEsR0E5R0E7QUFpSEEsc0VBakhBO0FBa0hBO0FBQ0EsZ0JBREEsMEJBQ0E7QUFFQTs7QUFFQTtBQUNBO0FBQUE7QUFBQSxXQUNBLE1BREEsQ0FDQTtBQUFBO0FBQUEsU0FEQTtBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFBQTtBQUFBLFdBQ0EsTUFEQSxDQUNBO0FBQUE7QUFBQSxTQURBO0FBRUE7QUFDQSxLQWhCQTs7QUFrQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0F4QkEsc0JBd0JBLEtBeEJBLEVBd0JBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7O0FBRUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRkFDQSw0QkFEQSxFQUVBLHVDQUZBLEVBR0Esb0JBSEE7QUFLQSxXQU5BO0FBUUE7QUFBQTtBQUFBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FKQSxNQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQSxTQXJCQSxNQXFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQXBFQTs7QUFzRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkExRUEseUJBMEVBLE9BMUVBLEVBMEVBLEtBMUVBLEVBMEVBO0FBQ0E7QUFDQTtBQUNBLEtBN0VBOztBQStFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQXJGQSxvQkFxRkEsTUFyRkEsRUFxRkE7QUFBQTs7QUFDQTtBQUFBO0FBQUEsU0FDQSxTQURBLENBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FGQSxNQUVBO0FBQ0E7QUFDQTtBQUNBLE9BUEE7QUFRQSxLQTlGQTs7QUFnR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBdEdBLDRCQXNHQTtBQUFBOztBQUNBO0FBQ0EsNkRBQ0EseUZBREEsRUFFQSx1RkFGQSxFQUdBLHFFQUhBLEVBSUEsMkZBSkEsR0FLQSxTQUxBLENBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUZBO0FBR0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FGQSxNQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQ0Esc0JBREEsRUFFQSxxQkFGQSxFQUdBLFdBSEEsRUFJQSxvQkFKQSxFQUtBLGdCQUxBLEVBTUEsYUFOQSxFQU9BLHNCQVBBLEVBUUEsVUFSQSxFQVNBLGNBVEEsRUFVQSxPQVZBLENBVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQWRBO0FBZ0JBO0FBQ0E7QUFFQTtBQUNBLGdDQURBO0FBRUEsb0RBRkE7QUFHQSxrQ0FIQTtBQUlBO0FBSkE7QUFNQSxXQTFCQTtBQTRCQTtBQUNBOztBQUVBO0FBQ0EsT0EzREE7QUE0REEsS0FwS0E7QUFxS0EsZ0JBcktBLHdCQXFLQSxHQXJLQSxFQXFLQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BRkE7QUFHQSxLQTNLQTtBQTRLQSxrQkE1S0EsMEJBNEtBLE9BNUtBLEVBNEtBO0FBRUE7QUFDQSw0SUFDQSxTQURBO0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBRUE7QUFDQSxLQXhNQTtBQXlNQSxVQXpNQSxvQkF5TUE7QUFBQTs7QUFFQTtBQUNBLGlSQUNBLFNBREE7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUZBLE1BRUE7QUFDQTtBQUNBLFNBRkEsTUFFQTtBQUNBO0FBQ0E7QUFDQSxPQVJBO0FBVUE7QUFBQTtBQUFBOztBQUVBO0FBQ0EsZ1NBQ0EsU0FEQTtBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBLDhRQUNBLFNBREE7QUFFQTs7QUFFQTtBQUNBLHVSQUNBLFNBREE7QUFFQTs7QUFFQTs7QUFFQSxpREFDQSwwQ0FEQSxHQUNBO0FBQ0E7QUFBQTtBQUFBO0FBREEsT0FEQTs7QUFNQSxrSkFDQSxTQURBLENBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBQ0E7QUFDQSxPQU5BLEVBTUE7QUFDQTtBQUNBO0FBREEsV0FFQSxTQUZBOztBQUlBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BaEJBO0FBaUJBLEtBMVFBO0FBMlFBLGlCQTNRQSx5QkEyUUEsS0EzUUEsRUEyUUE7QUFDQTtBQUNBO0FBQ0EsS0E5UUE7QUErUUEsc0JBL1FBLDhCQStRQSxLQS9RQSxFQStRQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0EsS0FsUkE7QUFvUkEscUJBcFJBLDZCQW9SQSxLQXBSQSxFQW9SQTtBQUFBOztBQUNBO0FBQ0E7QUFDQSw4Q0FEQTtBQUVBLDBCQUZBO0FBR0E7QUFIQTtBQUtBLE9BTkE7QUFRQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLE9BTkE7QUFPQTtBQXBTQTtBQWxIQSIsImZpbGUiOiIuL25vZGVfbW9kdWxlcy9iYWJlbC1sb2FkZXIvbGliL2luZGV4LmpzPyEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9pbmRleC5qcz8hLi9yZXNvdXJjZXMvdHMvcGFnZXMvZGFzaGJvYXJkL3Byb2N1cmVtZW50cy9ucy1wcm9jdXJlbWVudC52dWU/dnVlJnR5cGU9c2NyaXB0Jmxhbmc9anMmLmpzIiwic291cmNlc0NvbnRlbnQiOlsiPHNjcmlwdD5cclxuaW1wb3J0IEZvcm1WYWxpZGF0aW9uIGZyb20gJ0AvbGlicmFyaWVzL2Zvcm0tdmFsaWRhdGlvbic7XHJcbmltcG9ydCB7IFN1YmplY3QsIEJlaGF2aW9yU3ViamVjdCwgZm9ya0pvaW4gfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQgeyBtYXAgfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcclxuaW1wb3J0IHsgbnNTbmFja0JhciwgbnNIdHRwQ2xpZW50IH0gZnJvbSAnQC9ib290c3RyYXAnO1xyXG5pbXBvcnQgTnNNYW5hZ2VQcm9kdWN0cyBmcm9tICcuL21hbmFnZS1wcm9kdWN0cyc7XHJcbmltcG9ydCB7IFRheCB9IGZyb20gXCJAL2xpYnJhcmllcy90YXhcIjtcclxuaW1wb3J0IG5zUHJvY3VyZW1lbnRQcm9kdWN0T3B0aW9uc1Z1ZSBmcm9tICdAL3BvcHVwcy9ucy1wcm9jdXJlbWVudC1wcm9kdWN0LW9wdGlvbnMudnVlJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIG5hbWU6ICducy1wcm9jdXJlbWVudCcsXHJcbiAgICBtb3VudGVkKCkge1xyXG4gICAgICAgIHRoaXMucmVsb2FkRW50aXRpZXMoKTtcclxuICAgIH0sXHJcbiAgICBjb21wdXRlZDoge1xyXG4gICAgICAgIGFjdGl2ZVRhYigpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRUYWJzLmZpbHRlciggdGFiID0+IHRhYi5hY3RpdmUgKS5sZW5ndGggPiAwID8gdGhpcy52YWxpZFRhYnMuZmlsdGVyKCB0YWIgPT4gdGFiLmFjdGl2ZSApWzBdIDogZmFsc2U7XHJcbiAgICAgICAgfSxcclxuICAgIH0sXHJcbiAgICBkYXRhKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBJcyB0aGUgdG90YWwgdGF4ZXNcclxuICAgICAgICAgICAgICogY29tcHV0ZWQgb24gYWxsIHRoZSBzdXBwbGllZCBwcm9kdWN0c1xyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgdG90YWxUYXhWYWx1ZXM6IDAsXHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogaXMgdGhlIHRvdGFsIHB1cmNoYXNlIHByaWNlIG9mXHJcbiAgICAgICAgICAgICAqIGFsbCB0aGUgcHJvZHVjdHNcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIHRvdGFsUHVyY2hhc2VQcmljZTogMCxcclxuXHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogQ3JlYXRpbmcgYW4gaW5zdGFuY2Ugb2YgdGhlIGZvcm0gdmFsaWRhdGlvblxyXG4gICAgICAgICAgICAgKiB0byBwcm9jZWVkIHdpdGggYmFzaWMgZm9ybSB2YWxpZGF0aW9uXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBmb3JtVmFsaWRhdGlvbjogbmV3IEZvcm1WYWxpZGF0aW9uLFxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFJlZmVyZW5jZSB0byB0aGUgZm9ybS4gQ29udGFpbnNcclxuICAgICAgICAgICAgICogYWxsIHRoZSB2YWx1ZXMgYW5kIHRoYXQncyB3aGF0IGlzIHN1Ym1pdHRlZFxyXG4gICAgICAgICAgICAgKiB0byB0aGUgc2VydmVyXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBmb3JtOiB7fSxcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBSZWZlcmVuY2UgdG8gdGhlIG5zU25hY2tCYXIgb2JqZWN0XHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBuc1NuYWNrQmFyLFxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIElzIHRoZSBhcnJheSB0aGF0IGNvbnRhaW5zIHRoZSB2YXJpb3VzIFxyXG4gICAgICAgICAgICAgKiBwcm9jdXJlbWVudCBpbmZvcm1hdGlvbnNcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGZpZWxkczogW10sXHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogSXMgdGhlIGFycmF5IHRoYXQgY29udGFpbnMgdGhlIHJlc3VsdFxyXG4gICAgICAgICAgICAgKiBmcm9tIHRoZSBzZWFyY2guXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBzZWFyY2hSZXN1bHQ6IFtdLFxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFNlYXJjaCB2YWx1ZS5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIHNlYXJjaFZhbHVlOiAnJyxcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBEZWJvdW5jZSByZWZlcmVuY2UsdXNlZCBmb3Igc2VhcmNoaW5nXHJcbiAgICAgICAgICAgICAqIHByb2R1Y3QgdXNpbmcgdGhlIHNlYXJjaCBiYXJcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGRlYm91bmNlU2VhcmNoOiBudWxsLFxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEEgcmVmZXJlbmNlIHRvIHRoZSBuc0h0dHBDbGllbnQgb2JqZWN0XHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBuc0h0dHBDbGllbnQsXHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogTXVzdCBjb250YWluIHRoZSBcclxuICAgICAgICAgICAgICogYXZhaWxhYmxlIHRheGVzIGdyb3VwXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICB0YXhlczogW10sXHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogRGVmaW5lIHRoZSBhdmFpbGFibGUgdGFicyBvblxyXG4gICAgICAgICAgICAgKiB0aGUgYWN0dWFsIHVJXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICB2YWxpZFRhYnM6IFtcclxuICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJ0RldGFpbHMnLFxyXG4gICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXI6ICdkZXRhaWxzJyxcclxuICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB9LCB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICdQcm9kdWN0cycsXHJcbiAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllcjogJ3Byb2R1Y3RzJyxcclxuICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgfSwgXHJcbiAgICAgICAgICAgIF0sXHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogY29udHJvbCB0aGUgc3RhdGUgb2YgdGhlIHJlbG9hZGluZ1xyXG4gICAgICAgICAgICAgKiBzcGlubmVyXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICByZWxvYWRpbmc6IGZhbHNlXHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIHdhdGNoOiB7XHJcbiAgICAgICAgc2VhcmNoVmFsdWUoIHZhbHVlICkge1xyXG4gICAgICAgICAgICBpZiAoIHZhbHVlICkge1xyXG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KCB0aGlzLmRlYm91bmNlU2VhcmNoICk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRlYm91bmNlU2VhcmNoICAgICA9ICAgc2V0VGltZW91dCggKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZG9TZWFyY2goIHZhbHVlICk7XHJcbiAgICAgICAgICAgICAgICB9LCA1MDAgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH0sXHJcbiAgICBjb21wb25lbnRzOiB7XHJcbiAgICAgICAgTnNNYW5hZ2VQcm9kdWN0c1xyXG4gICAgfSxcclxuICAgIHByb3BzOiBbICdzdWJtaXQtbWV0aG9kJywgJ3N1Ym1pdC11cmwnLCAncmV0dXJuLXVybCcsICdzcmMnLCAncnVsZXMnIF0sXHJcbiAgICBtZXRob2RzOiB7XHJcbiAgICAgICAgY29tcHV0ZVRvdGFsKCkge1xyXG5cclxuICAgICAgICAgICAgdGhpcy50b3RhbFRheFZhbHVlcyA9IDA7XHJcblxyXG4gICAgICAgICAgICBpZiAoIHRoaXMuZm9ybS5wcm9kdWN0cy5sZW5ndGggPiAwICkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy50b3RhbFRheFZhbHVlcyA9IHRoaXMuZm9ybS5wcm9kdWN0cy5tYXAoIHAgPT4gcC5wcm9jdXJlbWVudC50YXhfdmFsdWUgKVxyXG4gICAgICAgICAgICAgICAgICAgIC5yZWR1Y2UoICggYiwgYSApID0+IGIgKyBhICk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMudG90YWxQdXJjaGFzZVByaWNlICAgICA9ICAgMDtcclxuXHJcbiAgICAgICAgICAgIGlmICggdGhpcy5mb3JtLnByb2R1Y3RzLmxlbmd0aCA+IDAgKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnRvdGFsUHVyY2hhc2VQcmljZSAgICAgPSAgIHRoaXMuZm9ybS5wcm9kdWN0cy5tYXAoIHAgPT4gcGFyc2VGbG9hdCggcC5wcm9jdXJlbWVudC50b3RhbF9wdXJjaGFzZV9wcmljZSApIClcclxuICAgICAgICAgICAgICAgICAgICAucmVkdWNlKCAoIGIsIGEgKSA9PiBiICsgYSApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRW5zdXJlIGEgbGluZSBpcyBiZWluZyB1cGRhdGVkIGFmdGVyXHJcbiAgICAgICAgICogc29tZSBmaWVsZCBoYXMgYmVlbiBjaGFuZ2VkLlxyXG4gICAgICAgICAqIEBwYXJhbSB7aW50ZWdlcn0gcHJvZHVjdCBpbmRleFxyXG4gICAgICAgICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXBkYXRlTGluZSggaW5kZXggKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHByb2R1Y3QgICA9ICAgdGhpcy5mb3JtLnByb2R1Y3RzWyBpbmRleCBdO1xyXG4gICAgICAgICAgICBjb25zdCB0YXhHcm91cCAgPSAgIHRoaXMudGF4ZXMuZmlsdGVyKCB0YXhHcm91cCA9PiB0YXhHcm91cC5pZCA9PT0gcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfZ3JvdXBfaWQgKTtcclxuXHJcbiAgICAgICAgICAgIGlmICggcGFyc2VGbG9hdCggcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZV9lZGl0ICkgPiAwICYmIHBhcnNlRmxvYXQoIHByb2R1Y3QucHJvY3VyZW1lbnQucXVhbnRpdHkgKSA+IDAgKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBpZiBzb21lIHRheCBncm91cCBpcyBwcm92aWRlZFxyXG4gICAgICAgICAgICAgICAgICogdGhlbiBsZXQncyBjb21wdXRlIGFsbCB0aGUgZ3JvdXBlZCB0YXhlc1xyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBpZiAoIHRheEdyb3VwLmxlbmd0aCA+IDAgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdG90YWxUYXhlcyAgICA9ICAgdGF4R3JvdXBbMF0udGF4ZXMubWFwKCB0YXggPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gVGF4LmdldFRheFZhbHVlKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdHlwZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQucHVyY2hhc2VfcHJpY2VfZWRpdCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlRmxvYXQoIHRheC5yYXRlIClcclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdmFsdWUgICAgICAgICAgICAgICA9ICAgKCB0b3RhbFRheGVzLnJlZHVjZSggKCBiLCBhICkgPT4gYiArIGEgKSApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIHByb2R1Y3QucHJvY3VyZW1lbnQudGF4X3R5cGUgPT09ICdpbmNsdXNpdmUnICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50Lm5ldF9wdXJjaGFzZV9wcmljZSAgICAgID0gICBwYXJzZUZsb2F0KCBwcm9kdWN0LnByb2N1cmVtZW50LnB1cmNoYXNlX3ByaWNlX2VkaXQgKSAtIHByb2R1Y3QucHJvY3VyZW1lbnQudGF4X3ZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50Lmdyb3NzX3B1cmNoYXNlX3ByaWNlICAgID0gICBwYXJzZUZsb2F0KCBwcm9kdWN0LnByb2N1cmVtZW50LnB1cmNoYXNlX3ByaWNlX2VkaXQgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZSAgICAgICAgICA9ICAgcGFyc2VGbG9hdCggcHJvZHVjdC5wcm9jdXJlbWVudC5ncm9zc19wdXJjaGFzZV9wcmljZSApO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQuZ3Jvc3NfcHVyY2hhc2VfcHJpY2UgICAgPSAgIHBhcnNlRmxvYXQoIHByb2R1Y3QucHJvY3VyZW1lbnQucHVyY2hhc2VfcHJpY2VfZWRpdCApICsgcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQubmV0X3B1cmNoYXNlX3ByaWNlICAgICAgPSAgIHBhcnNlRmxvYXQoIHByb2R1Y3QucHJvY3VyZW1lbnQucHVyY2hhc2VfcHJpY2VfZWRpdCApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LnB1cmNoYXNlX3ByaWNlICAgICAgICAgID0gICBwYXJzZUZsb2F0KCBwcm9kdWN0LnByb2N1cmVtZW50Lmdyb3NzX3B1cmNoYXNlX3ByaWNlICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5ncm9zc19wdXJjaGFzZV9wcmljZSAgICA9ICAgcGFyc2VGbG9hdCggcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZV9lZGl0ICk7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZSAgICAgICAgICA9ICAgcGFyc2VGbG9hdCggcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZV9lZGl0ICk7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5uZXRfcHVyY2hhc2VfcHJpY2UgICAgICA9ICAgcGFyc2VGbG9hdCggcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZV9lZGl0ICk7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdmFsdWUgICAgICAgICAgICAgICA9ICAgMDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LnRheF92YWx1ZSAgICAgICAgICAgICAgICAgICA9ICAgcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdmFsdWUgKiBwYXJzZUZsb2F0KCBwcm9kdWN0LnByb2N1cmVtZW50LnF1YW50aXR5ICk7XHJcbiAgICAgICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LnRvdGFsX3B1cmNoYXNlX3ByaWNlICAgICAgICA9ICAgcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZSAqIHBhcnNlRmxvYXQoIHByb2R1Y3QucHJvY3VyZW1lbnQucXVhbnRpdHkgKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5jb21wdXRlVG90YWwoKTtcclxuICAgICAgICAgICAgdGhpcy4kZm9yY2VVcGRhdGUoKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTd2l0Y2ggdGhlIHRheCB0eXBlIGFwcGxpZWQgXHJcbiAgICAgICAgICogb24gdGhlIGN1cnJlbnQgcHJvZHVjdC5cclxuICAgICAgICAgKi9cclxuICAgICAgICBzd2l0Y2hUYXhUeXBlKCBwcm9kdWN0LCBpbmRleCApIHtcclxuICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdHlwZSA9ICBwcm9kdWN0LnByb2N1cmVtZW50LnRheF90eXBlID09PSAnaW5jbHVzaXZlJyA/ICdleGNsdXNpdmUnIDogJ2luY2x1c2l2ZSc7XHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlTGluZSggaW5kZXggKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBQZXJmb3JtIGEgc2VhY2ggYW5kIHBvcHVsYXRlXHJcbiAgICAgICAgICogdGhlIHNlYXJjaCByZXN1bHQgYXJyYXlcclxuICAgICAgICAgKiBAcGFyYW0gc3RyaW5nXHJcbiAgICAgICAgICogQHJldHVybiB2b2lkXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZG9TZWFyY2goIHNlYXJjaCApIHtcclxuICAgICAgICAgICAgbnNIdHRwQ2xpZW50LnBvc3QoICcvYXBpL25leG9wb3MvdjQvcHJvZHVjdHMvc2VhcmNoJywgeyBzZWFyY2ggfSlcclxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoIHJlc3VsdCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCByZXN1bHQubGVuZ3RoID09PSAxICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZFByb2R1Y3RMaXN0KCByZXN1bHRbMF0gKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlYXJjaFJlc3VsdCAgID0gICByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBSZWxvYWQgdGhlIHZhbHVlIGZyb20gdGhlIHNlcnZlci5cclxuICAgICAgICAgKiBVc2VmdWwgdG8gcmVsb2FkIGRhdGEgYWZ0ZXIgaGF2aW5nIGNyZWF0ZWQgYSBuZXdcclxuICAgICAgICAgKiBlbnRpdHlcclxuICAgICAgICAgKiBAcmV0dXJuIHZvaWRcclxuICAgICAgICAgKi9cclxuICAgICAgICByZWxvYWRFbnRpdGllcygpIHtcclxuICAgICAgICAgICAgdGhpcy5yZWxvYWRpbmcgICAgICAgICAgPSAgIHRydWU7XHJcbiAgICAgICAgICAgIGZvcmtKb2luKFtcclxuICAgICAgICAgICAgICAgIG5zSHR0cENsaWVudC5nZXQoICcvYXBpL25leG9wb3MvdjQvY2F0ZWdvcmllcycgKSxcclxuICAgICAgICAgICAgICAgIG5zSHR0cENsaWVudC5nZXQoICcvYXBpL25leG9wb3MvdjQvcHJvZHVjdHMnICksXHJcbiAgICAgICAgICAgICAgICBuc0h0dHBDbGllbnQuZ2V0KCB0aGlzLnNyYyApLFxyXG4gICAgICAgICAgICAgICAgbnNIdHRwQ2xpZW50LmdldCggJy9hcGkvbmV4b3Bvcy92NC90YXhlcy9ncm91cHMnICksXHJcbiAgICAgICAgICAgIF0pLnN1YnNjcmliZSggcmVzdWx0ID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVsb2FkaW5nICAgICAgPSAgIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jYXRlZ29yaWVzICAgICA9ICAgcmVzdWx0WzBdO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9kdWN0cyAgICAgICA9ICAgcmVzdWx0WzFdO1xyXG4gICAgICAgICAgICAgICAgdGhpcy50YXhlcyAgICAgICAgICA9ICAgcmVzdWx0WzNdO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICggdGhpcy5mb3JtLmdlbmVyYWwgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0WzJdLnRhYnMuZ2VuZXJhbC5maWVkcy5mb3JFYWNoKCAoZmllbGQsaW5kZXgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQudmFsdWUgICAgID0gICB0aGlzLmZvcm0udGFicy5nZW5lcmFsLmZpZWxkc1sgaW5kZXggXS52YWx1ZSB8fCAnJztcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0gXHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtICAgICAgICAgICA9ICAgT2JqZWN0LmFzc2lnbiggdGhpcy5mb3JtLCByZXN1bHRbMl0gKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZm9ybSAgICAgICAgICAgPSAgIHRoaXMuZm9ybVZhbGlkYXRpb24uY3JlYXRlRm9ybSggdGhpcy5mb3JtICk7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIGlmICggdGhpcy5mb3JtLnByb2R1Y3RzID09PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLnByb2R1Y3RzICA9ICAgW107XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICAgICAqIGlmIHRoZSBwcm9kdWN0IGhhcyBiZWVuIHByb3ZpZGVkIGJ5IHRoZVxyXG4gICAgICAgICAgICAgICAgICAgICAqIHNlcnZlciB3ZSBuZWVkIHRvIGZvcm1hdCBpdC5cclxuICAgICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0ucHJvZHVjdHMgID0gICB0aGlzLmZvcm0ucHJvZHVjdHMubWFwKCBwcm9kdWN0ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2dyb3NzX3B1cmNoYXNlX3ByaWNlJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwdXJjaGFzZV9wcmljZV9lZGl0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0YXhfdmFsdWUnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ25ldF9wdXJjaGFzZV9wcmljZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncHVyY2hhc2VfcHJpY2UnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RvdGFsX3ByaWNlJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0b3RhbF9wdXJjaGFzZV9wcmljZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncXVhbnRpdHknLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RheF9ncm91cF9pZCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF0uZm9yRWFjaCggZmllbGQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBwcm9kdWN0WyBmaWVsZCBdID09PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZHVjdFsgZmllbGQgXSAgICA9ICAgMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9kdWN0LiRpbnZhbGlkICAgICAgICAgICAgICAgID0gICBwcm9kdWN0LiRpbnZhbGlkIHx8IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9kdWN0LnB1cmNoYXNlX3ByaWNlX2VkaXQgICAgID0gICBwcm9kdWN0LnB1cmNoYXNlX3ByaWNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IHByb2R1Y3QubmFtZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1cmNoYXNlX3VuaXRzOiBwcm9kdWN0LnB1cmNoYXNlX3VuaXRzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY3VyZW1lbnQ6IHByb2R1Y3QsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0X3F1YW50aXRpZXM6IHByb2R1Y3QudW5pdF9xdWFudGl0aWVzIHx8IFtdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coIHRoaXMuZm9ybS5wcm9kdWN0cyApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICB0aGlzLiRmb3JjZVVwZGF0ZSgpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgc2V0VGFiQWN0aXZlKCB0YWIgKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsaWRUYWJzLmZvckVhY2goIHRhYiA9PiB0YWIuYWN0aXZlID0gZmFsc2UgKTtcclxuICAgICAgICAgICAgdGhpcy4kZm9yY2VVcGRhdGUoKTtcclxuICAgICAgICAgICAgdGhpcy4kbmV4dFRpY2soKS50aGVuKCAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0YWIuYWN0aXZlICA9ICAgdHJ1ZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBhZGRQcm9kdWN0TGlzdCggcHJvZHVjdCApIHtcclxuXHJcbiAgICAgICAgICAgIGlmICggcHJvZHVjdC51bml0X3F1YW50aXRpZXMgPT09IHVuZGVmaW5lZCApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuc1NuYWNrQmFyLmVycm9yKCAnVW5hYmxlIHRvIGFkZCBwcm9kdWN0IHdoaWNoIGRvZXNuXFwndCB1bml0IHF1YW50aXRpZXMgZGVmaW5lZC4nIClcclxuICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gICBuZXcgT2JqZWN0O1xyXG4gICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50Lmdyb3NzX3B1cmNoYXNlX3ByaWNlICAgICAgICA9ICAgMDtcclxuICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZV9lZGl0ICAgICAgICAgPSAgIDA7XHJcbiAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQudGF4X3ZhbHVlICAgICAgICAgICAgICAgICAgID0gICAwO1xyXG4gICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50Lm5ldF9wdXJjaGFzZV9wcmljZSAgICAgICAgICA9ICAgMDtcclxuICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZSAgICAgICAgICAgICAgPSAgIDA7XHJcbiAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQudG90YWxfcHJpY2UgICAgICAgICAgICAgICAgID0gICAwO1xyXG4gICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LnRvdGFsX3B1cmNoYXNlX3ByaWNlICAgICAgICA9ICAgMDtcclxuICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5xdWFudGl0eSAgICAgICAgICAgICAgICAgICAgPSAgIDE7XHJcbiAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQuZXhwaXJhdGlvbiAgICAgICAgICAgICAgICAgID0gICBudWxsO1xyXG4gICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LnRheF9ncm91cF9pZCAgICAgICAgICAgICAgICA9ICAgMDtcclxuICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdHlwZSAgICAgICAgICAgICAgICAgICAgPSAgICdpbmNsdXNpdmUnO1xyXG4gICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LnVuaXRfaWQgICAgICAgICAgICAgICAgICAgICA9ICAgMDtcclxuICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5wcm9kdWN0X2lkICAgICAgICAgICAgICAgICAgPSAgIHByb2R1Y3QuaWQ7XHJcbiAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQucHJvY3VyZW1lbnRfaWQgICAgICAgICAgICAgID0gICBudWxsO1xyXG4gICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LiRpbnZhbGlkICAgICAgICAgICAgICAgICAgICA9ICAgZmFsc2U7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnNlYXJjaFJlc3VsdCAgICAgICAgICAgPSAgIFtdO1xyXG4gICAgICAgICAgICB0aGlzLnNlYXJjaFZhbHVlICAgICAgICAgICAgPSAgICcnO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5mb3JtLnByb2R1Y3RzLnB1c2goIHByb2R1Y3QgKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIHN1Ym1pdCgpIHtcclxuXHJcbiAgICAgICAgICAgIGlmICggdGhpcy5mb3JtLnByb2R1Y3RzLmxlbmd0aCA9PT0gMCApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuc1NuYWNrQmFyLmVycm9yKCB0aGlzLiRzbG90c1sgJ2Vycm9yLW5vLXByb2R1Y3RzJyBdID8gdGhpcy4kc2xvdHNbICdlcnJvci1uby1wcm9kdWN0cycgXVswXS50ZXh0IDogJ05vIGVycm9yIG1lc3NhZ2UgcHJvdmlkZWQgb24gdGhlIHNsb3QgXCJlcnJvci1uby1wcm9kdWN0c1wiLicsIHRoaXMuJHNsb3RzWyAnb2theScgXSA/IHRoaXMuJHNsb3RzWyAnb2theScgXVswXS50ZXh0IDogJ09LJyApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmZvcm0ucHJvZHVjdHMuZm9yRWFjaCggcHJvZHVjdCA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoICEgcGFyc2VGbG9hdCggcHJvZHVjdC5wcm9jdXJlbWVudC5xdWFudGl0eSApID49IDEgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC4kaW52YWxpZCAgICA9ICAgdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIHByb2R1Y3QudW5pdF9pZCA9PT0gMCApIHtcclxuICAgICAgICAgICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LiRpbnZhbGlkICAgID0gICB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LiRpbnZhbGlkICAgID0gICBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBpbnZhbGlkUHJvZHVjdHMgICA9ICAgdGhpcy5mb3JtLnByb2R1Y3RzLmZpbHRlciggcHJvZHVjdCA9PiBwcm9kdWN0LnByb2N1cmVtZW50LiRpbnZhbGlkICk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIGludmFsaWRQcm9kdWN0cy5sZW5ndGggPiAwICkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5zU25hY2tCYXIuZXJyb3IoIHRoaXMuJHNsb3RzWyAnZXJyb3ItaW52YWxpZC1wcm9kdWN0cycgXSA/IHRoaXMuJHNsb3RzWyAnZXJyb3ItaW52YWxpZC1wcm9kdWN0cycgXVswXS50ZXh0IDogJ05vIGVycm9yIG1lc3NhZ2UgcHJvdmlkZWQgb24gdGhlIHNsb3QgXCJlcnJvci1pbnZhbGlkLXByb2R1Y3RzXCIuJywgdGhpcy4kc2xvdHNbICdva2F5JyBdID8gdGhpcy4kc2xvdHNbICdva2F5JyBdWzBdLnRleHQgOiAnT0snIClcclxuICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICggdGhpcy5mb3JtVmFsaWRhdGlvbi52YWxpZGF0ZUZvcm0oIHRoaXMuZm9ybSApLmxlbmd0aCA+IDAgKSB7XHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIGhhY2sgdG8gZm9yY2UgcmVyZW5kZXJpbmdcclxuICAgICAgICAgICAgICAgICAqIHRoZXJlIG1pZ2h0IGJlIGEgYmV0dGVyIHNvbHV0aW4gaGVyZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRUYWJBY3RpdmUoIHRoaXMuYWN0aXZlVGFiICk7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5zU25hY2tCYXIuZXJyb3IoIHRoaXMuJHNsb3RzWyAnZXJyb3ItaW52YWxpZC1mb3JtJyBdID8gdGhpcy4kc2xvdHNbICdlcnJvci1pbnZhbGlkLWZvcm0nIF1bMF0udGV4dCA6ICdObyBlcnJvciBtZXNzYWdlIHByb3ZpZGVkIGZvciBoYXZpbmcgYW4gaW52YWxpZCBmb3JtLicsIHRoaXMuJHNsb3RzWyAnb2theScgXSA/IHRoaXMuJHNsb3RzWyAnb2theScgXVswXS50ZXh0IDogJ09LJyApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIHRoaXMuc3VibWl0VXJsID09PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnNTbmFja0Jhci5lcnJvciggdGhpcy4kc2xvdHNbICdlcnJvci1uby1zdWJtaXQtdXJsJyBdID8gdGhpcy4kc2xvdHNbICdlcnJvci1uby1zdWJtaXQtdXJsJyBdWzBdLnRleHQgOiAnTm8gZXJyb3IgbWVzc2FnZSBwcm92aWRlZCBmb3Igbm90IGhhdmluZyBhIHZhbGlkIHN1Ym1pdCB1cmwuJywgdGhpcy4kc2xvdHNbICdva2F5JyBdID8gdGhpcy4kc2xvdHNbICdva2F5JyBdWzBdLnRleHQgOiAnT0snIClcclxuICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuZm9ybVZhbGlkYXRpb24uZGlzYWJsZUZvcm0oIHRoaXMuZm9ybSApO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgZGF0YSAgPSAgIHtcclxuICAgICAgICAgICAgICAgIC4uLnRoaXMuZm9ybVZhbGlkYXRpb24uZXh0cmFjdEZvcm0oIHRoaXMuZm9ybSApLCAuLi57XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHM6IHRoaXMuZm9ybS5wcm9kdWN0cy5tYXAoIHByb2R1Y3QgPT4gcHJvZHVjdC5wcm9jdXJlbWVudCApXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIG5zSHR0cENsaWVudFsgdGhpcy5zdWJtaXRNZXRob2QgPyB0aGlzLnN1Ym1pdE1ldGhvZC50b0xvd2VyQ2FzZSgpIDogJ3Bvc3QnIF0oIHRoaXMuc3VibWl0VXJsLCBkYXRhIClcclxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoIGRhdGEgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICggZGF0YS5zdGF0dXMgPT09ICdzdWNjZXNzJyApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50LmxvY2F0aW9uICAgPSAgIHRoaXMucmV0dXJuVXJsO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm1WYWxpZGF0aW9uLmVuYWJsZUZvcm0oIHRoaXMuZm9ybSApO1xyXG4gICAgICAgICAgICAgICAgfSwgKCBlcnJvciApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBuc1NuYWNrQmFyLmVycm9yKCBlcnJvci5tZXNzYWdlLCB1bmRlZmluZWQsIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IDUwMDBcclxuICAgICAgICAgICAgICAgICAgICB9KS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtVmFsaWRhdGlvbi5lbmFibGVGb3JtKCB0aGlzLmZvcm0gKTtcclxuICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIGVycm9yLmVycm9ycyApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtVmFsaWRhdGlvbi50cmlnZ2VyRXJyb3IoIHRoaXMuZm9ybSwgZXJyb3IuZXJyb3JzICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICB9LFxyXG4gICAgICAgIGRlbGV0ZVByb2R1Y3QoIGluZGV4ICkge1xyXG4gICAgICAgICAgICB0aGlzLmZvcm0ucHJvZHVjdHMuc3BsaWNlKCBpbmRleCwgMSApO1xyXG4gICAgICAgICAgICB0aGlzLiRmb3JjZVVwZGF0ZSgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgaGFuZGxlR2xvYmFsQ2hhbmdlKCBldmVudCApIHtcclxuICAgICAgICAgICAgdGhpcy5nbG9iYWxseUNoZWNrZWQgICAgPSAgIGV2ZW50O1xyXG4gICAgICAgICAgICB0aGlzLnJvd3MuZm9yRWFjaCggciA9PiByLiRjaGVja2VkID0gZXZlbnQgKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBzZXRQcm9kdWN0T3B0aW9ucyggaW5kZXggKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgICA9ICAgbmV3IFByb21pc2UoICggcmVzb2x2ZSwgcmVqZWN0ICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgUG9wdXAuc2hvdyggbnNQcm9jdXJlbWVudFByb2R1Y3RPcHRpb25zVnVlLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdDogdGhpcy5mb3JtLnByb2R1Y3RzWyBpbmRleCBdLFxyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUsIFxyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdFxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBwcm9taXNlLnRoZW4oIHZhbHVlID0+IHtcclxuICAgICAgICAgICAgICAgIGZvciggbGV0IGtleSBpbiB2YWx1ZSApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0ucHJvZHVjdHNbIGluZGV4IF0ucHJvY3VyZW1lbnRbIGtleSBdICAgICAgPSAgIHZhbHVlWyBrZXkgXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUxpbmUoIGluZGV4ICk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG48L3NjcmlwdD5cclxuPHRlbXBsYXRlPlxyXG4gICAgPGRpdiBjbGFzcz1cImZvcm0gZmxleC1hdXRvIGZsZXggZmxleC1jb2xcIiBpZD1cImNydWQtZm9ybVwiPlxyXG4gICAgICAgIDx0ZW1wbGF0ZSB2LWlmPVwiZm9ybS5tYWluXCI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBqdXN0aWZ5LWJldHdlZW4gaXRlbXMtY2VudGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGZvcj1cInRpdGxlXCIgY2xhc3M9XCJmb250LWJvbGQgbXktMiB0ZXh0LWdyYXktNzAwXCI+PHNsb3QgbmFtZT1cInRpdGxlXCI+Tm8gdGl0bGUgUHJvdmlkZWQ8L3Nsb3Q+PC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGZvcj1cInRpdGxlXCIgY2xhc3M9XCJ0ZXh0LXNtIG15LTIgdGV4dC1ncmF5LTcwMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8YSB2LWlmPVwicmV0dXJuVXJsXCIgOmhyZWY9XCJyZXR1cm5VcmxcIiBjbGFzcz1cInJvdW5kZWQtZnVsbCBib3JkZXIgYm9yZGVyLWdyYXktNDAwIGhvdmVyOmJnLXJlZC02MDAgaG92ZXI6dGV4dC13aGl0ZSBiZy13aGl0ZSBweC0yIHB5LTFcIj5SZXR1cm48L2E+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDxkaXYgOmNsYXNzPVwiZm9ybS5tYWluLmRpc2FibGVkID8gJ2JvcmRlci1ncmF5LTUwMCcgOiBmb3JtLm1haW4uZXJyb3JzLmxlbmd0aCA+IDAgPyAnYm9yZGVyLXJlZC02MDAnIDogJ2JvcmRlci1ibHVlLTUwMCdcIiBjbGFzcz1cImZsZXggYm9yZGVyLTIgcm91bmRlZCBvdmVyZmxvdy1oaWRkZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdi1tb2RlbD1cImZvcm0ubWFpbi52YWx1ZVwiIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBAYmx1cj1cImZvcm1WYWxpZGF0aW9uLmNoZWNrRmllbGQoIGZvcm0ubWFpbiApXCIgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEBjaGFuZ2U9XCJmb3JtVmFsaWRhdGlvbi5jaGVja0ZpZWxkKCBmb3JtLm1haW4gKVwiIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6ZGlzYWJsZWQ9XCJmb3JtLm1haW4uZGlzYWJsZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6Y2xhc3M9XCJmb3JtLm1haW4uZGlzYWJsZWQgPyAnYmctZ3JheS00MDAnIDogJydcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXgtYXV0byB0ZXh0LWdyYXktNzAwIG91dGxpbmUtbm9uZSBoLTEwIHB4LTJcIj5cclxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIDpkaXNhYmxlZD1cImZvcm0ubWFpbi5kaXNhYmxlZFwiIDpjbGFzcz1cImZvcm0ubWFpbi5kaXNhYmxlZCA/ICdiZy1ncmF5LTUwMCcgOiBmb3JtLm1haW4uZXJyb3JzLmxlbmd0aCA+IDAgPyAnYmctcmVkLTUwMCcgOiAnYmctYmx1ZS01MDAnXCIgQGNsaWNrPVwic3VibWl0KClcIiBjbGFzcz1cIm91dGxpbmUtbm9uZSBweC00IGgtMTAgdGV4dC13aGl0ZSBib3JkZXItbCBib3JkZXItZ3JheS00MDBcIj48c2xvdCBuYW1lPVwic2F2ZVwiPlNhdmU8L3Nsb3Q+PC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBAY2xpY2s9XCJyZWxvYWRFbnRpdGllcygpXCIgY2xhc3M9XCJiZy13aGl0ZSB0ZXh0LWdyYXktNzAwIG91dGxpbmUtbm9uZSBweC00IGgtMTAgYm9yZGVyLWdyYXktNDAwXCI+PGkgOmNsYXNzPVwicmVsb2FkaW5nID8gJ2FuaW1hdGUgYW5pbWF0ZS1zcGluJyA6ICcnXCIgY2xhc3M9XCJsYXMgbGEtc3luY1wiPjwvaT48L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LXhzIHRleHQtZ3JheS02MDAgcHktMVwiIHYtaWY9XCJmb3JtLm1haW4uZGVzY3JpcHRpb24gJiYgZm9ybS5tYWluLmVycm9ycy5sZW5ndGggPT09IDBcIj57eyBmb3JtLm1haW4uZGVzY3JpcHRpb24gfX08L3A+XHJcbiAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQteHMgcHktMSB0ZXh0LXJlZC01MDBcIiB2LWJpbmQ6a2V5PVwiaW5kZXhcIiB2LWZvcj1cIihlcnJvciwgaW5kZXgpIG9mIGZvcm0ubWFpbi5lcnJvcnNcIj5cclxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj48c2xvdCBuYW1lPVwiZXJyb3ItcmVxdWlyZWRcIj57eyBlcnJvci5pZGVudGlmaWVyIH19PC9zbG90Pjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgIDwvcD5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgaWQ9XCJmb3JtLWNvbnRhaW5lclwiIGNsYXNzPVwiLW14LTQgZmxleCBmbGV4LXdyYXAgbXQtNFwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTQgdy1mdWxsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD1cInRhYmJlZC1jYXJkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9XCJjYXJkLWhlYWRlclwiIGNsYXNzPVwiZmxleCBmbGV4LXdyYXBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgQGNsaWNrPVwic2V0VGFiQWN0aXZlKCB0YWIgKVwiIDpjbGFzcz1cInRhYi5hY3RpdmUgPyAnYmctd2hpdGUnIDogJ2JnLWdyYXktMTAwJ1wiIHYtZm9yPVwiKCB0YWIsIGluZGV4ICkgb2YgdmFsaWRUYWJzXCIgdi1iaW5kOmtleT1cImluZGV4XCIgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBweC00IHB5LTIgcm91bmRlZC10bC1sZyByb3VuZGVkLXRyLWxnIHRleHQtZ3JheS03MDBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyB0YWIubGFiZWwgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtYm9keSBiZy13aGl0ZSByb3VuZGVkLWJyLWxnIHJvdW5kZWQtYmwtbGcgc2hhZG93IHAtMlwiIHYtaWY9XCJhY3RpdmVUYWIuaWRlbnRpZmllciA9PT0gJ2RldGFpbHMnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiLW14LTQgZmxleCBmbGV4LXdyYXBcIiB2LWlmPVwiZm9ybS50YWJzXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggcHgtNCB3LWZ1bGwgbWQ6dy0xLzIgbGc6dy0xLzNcIiA6a2V5PVwiaW5kZXhcIiB2LWZvcj1cIihmaWVsZCwgaW5kZXgpIG9mIGZvcm0udGFicy5nZW5lcmFsLmZpZWxkc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bnMtZmllbGQgOmZpZWxkPVwiZmllbGRcIj48L25zLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1ib2R5IGJnLXdoaXRlIHJvdW5kZWQtYnItbGcgcm91bmRlZC1ibC1sZyBzaGFkb3cgcC0yIFwiIHYtaWY9XCJhY3RpdmVUYWIuaWRlbnRpZmllciA9PT0gJ3Byb2R1Y3RzJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm9yZGVyLWJsdWUtNTAwIGZsZXggYm9yZGVyLTIgcm91bmRlZCBvdmVyZmxvdy1oaWRkZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2LW1vZGVsPVwic2VhcmNoVmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDpwbGFjZWhvbGRlcj1cIiRzbG90c1sgJ3NlYXJjaC1wbGFjZWhvbGRlcicgXSA/ICRzbG90c1sgJ3NlYXJjaC1wbGFjZWhvbGRlcicgXVswXS50ZXh0IDogJ1NLVSwgQmFyY29kZSwgTmFtZSdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbGV4LWF1dG8gdGV4dC1ncmF5LTcwMCBvdXRsaW5lLW5vbmUgaC0xMCBweC0yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImgtMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2hhZG93IGJnLXdoaXRlIHJlbGF0aXZlIHotMTBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgQGNsaWNrPVwiYWRkUHJvZHVjdExpc3QoIHByb2R1Y3QgKVwiIHYtZm9yPVwiKHByb2R1Y3QsIGluZGV4KSBvZiBzZWFyY2hSZXN1bHRcIiA6a2V5PVwiaW5kZXhcIiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGJvcmRlciBib3JkZXItYiBib3JkZXItZ3JheS0zMDAgcC0yIHRleHQtZ3JheS03MDBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJsb2NrIGZvbnQtYm9sZCB0ZXh0LWdyYXktNzAwXCI+e3sgcHJvZHVjdC5uYW1lIH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmxvY2sgdGV4dC1zbSB0ZXh0LWdyYXktNjAwXCI+U0tVIDoge3sgcHJvZHVjdC5za3UgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJibG9jayB0ZXh0LXNtIHRleHQtZ3JheS02MDBcIj5CYXJjb2RlIDoge3sgcHJvZHVjdC5iYXJjb2RlIH19PC9zcGFuPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwib3ZlcmZsb3cteC1hdXRvXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwidy1mdWxsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aGVhZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgdi1mb3I9XCIoIGNvbHVtbiwga2V5ICkgb2YgZm9ybS5jb2x1bW5zXCIgd2lkdGg9XCIyMDBcIiA6a2V5PVwia2V5XCIgY2xhc3M9XCJ0ZXh0LWdyYXktNzAwIHAtMiBib3JkZXIgYm9yZGVyLWdyYXktMzAwIGJnLWdyYXktMjAwXCI+e3sgY29sdW1uLmxhYmVsIH19PC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGhlYWQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0Ym9keT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ciB2LWZvcj1cIiggcHJvZHVjdCwgaW5kZXggKSBvZiBmb3JtLnByb2R1Y3RzXCIgOmtleT1cImluZGV4XCIgOmNsYXNzPVwicHJvZHVjdC5wcm9jdXJlbWVudC4kaW52YWxpZCA/ICdiZy1yZWQtMjAwIGJvcmRlci0yIGJvcmRlci1yZWQtNTAwJyA6ICdiZy1ncmF5LTEwMCdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGVtcGxhdGUgdi1mb3I9XCIoIGNvbHVtbiwga2V5ICkgb2YgZm9ybS5jb2x1bW5zXCIgPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgOmtleT1cImtleVwiIHYtaWY9XCJjb2x1bW4udHlwZSA9PT0gJ25hbWUnXCIgY2xhc3M9XCJwLTIgdGV4dC1ncmF5LTYwMCBib3JkZXIgYm9yZGVyLWdyYXktMzAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZvbnQtc2VtaWJvbGRcIj57eyBwcm9kdWN0Lm5hbWUgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBqdXN0aWZ5LWJldHdlZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCAtbXgtMSBmbGV4LWNvbFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXhzIHRleHQtcmVkLTUwMCBjdXJzb3ItcG9pbnRlciB1bmRlcmxpbmUgcHgtMVwiIEBjbGljaz1cImRlbGV0ZVByb2R1Y3QoIGluZGV4IClcIj5EZWxldGU8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IC1teC0xIGZsZXgtY29sXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQteHMgdGV4dC1yZWQtNTAwIGN1cnNvci1wb2ludGVyIHVuZGVybGluZSBweC0xXCIgQGNsaWNrPVwic2V0UHJvZHVjdE9wdGlvbnMoIGluZGV4IClcIj5PcHRpb25zPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgOmtleT1cImtleVwiIHYtaWY9XCJjb2x1bW4udHlwZSA9PT0gJ3RleHQnXCIgY2xhc3M9XCJwLTIgdy0zIHRleHQtZ3JheS02MDAgYm9yZGVyIGJvcmRlci1ncmF5LTMwMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtc3RhcnRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgQGNoYW5nZT1cInVwZGF0ZUxpbmUoIGluZGV4IClcIiB0eXBlPVwidGV4dFwiIHYtbW9kZWw9XCJwcm9kdWN0LnByb2N1cmVtZW50WyBrZXkgXVwiIGNsYXNzPVwidy0yNCBib3JkZXItMiBwLTIgYm9yZGVyLWJsdWUtNDAwIHJvdW5kZWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgOmtleT1cImtleVwiIHYtaWY9XCJjb2x1bW4udHlwZSA9PT0gJ3RheF9ncm91cF9pZCdcIiBjbGFzcz1cInAtMiB0ZXh0LWdyYXktNjAwIGJvcmRlciBib3JkZXItZ3JheS0zMDBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLXN0YXJ0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBAY2hhbmdlPVwidXBkYXRlTGluZSggaW5kZXggKVwiIHYtbW9kZWw9XCJwcm9kdWN0LnByb2N1cmVtZW50LnRheF9ncm91cF9pZFwiIGNsYXNzPVwicm91bmRlZCBib3JkZXItYmx1ZS01MDAgYm9yZGVyLTIgcC0yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdi1mb3I9XCJvcHRpb24gb2YgdGF4ZXNcIiA6a2V5PVwib3B0aW9uLmlkXCIgOnZhbHVlPVwib3B0aW9uLmlkXCI+e3sgb3B0aW9uLm5hbWUgfX08L29wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgOmtleT1cImtleVwiIHYtaWY9XCJjb2x1bW4udHlwZSA9PT0gJ2N1c3RvbV9zZWxlY3QnXCIgY2xhc3M9XCJwLTIgdGV4dC1ncmF5LTYwMCBib3JkZXIgYm9yZGVyLWdyYXktMzAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgQGNoYW5nZT1cInVwZGF0ZUxpbmUoIGluZGV4IClcIiB2LW1vZGVsPVwicHJvZHVjdC5wcm9jdXJlbWVudFsga2V5IF1cIiBjbGFzcz1cInJvdW5kZWQgYm9yZGVyLWJsdWUtNTAwIGJvcmRlci0yIHAtMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHYtZm9yPVwib3B0aW9uIG9mIGNvbHVtbi5vcHRpb25zXCIgOmtleT1cIm9wdGlvbi52YWx1ZVwiIDp2YWx1ZT1cIm9wdGlvbi52YWx1ZVwiPnt7IG9wdGlvbi5sYWJlbCB9fTwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCA6a2V5PVwia2V5XCIgdi1pZj1cImNvbHVtbi50eXBlID09PSAnY3VycmVuY3knXCIgY2xhc3M9XCJwLTIgdGV4dC1ncmF5LTYwMCBib3JkZXIgYm9yZGVyLWdyYXktMzAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydCBmbGV4LWNvbCBqdXN0aWZ5LWVuZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zbSB0ZXh0LWdyYXktNjAwXCI+e3sgcHJvZHVjdC5wcm9jdXJlbWVudFsga2V5IF0gfCBjdXJyZW5jeSB9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgOmtleT1cImtleVwiIHYtaWY9XCJjb2x1bW4udHlwZSA9PT0gJ3VuaXRfcXVhbnRpdGllcydcIiBjbGFzcz1cInAtMiB0ZXh0LWdyYXktNjAwIGJvcmRlciBib3JkZXItZ3JheS0zMDBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLXN0YXJ0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCB2LW1vZGVsPVwicHJvZHVjdC5wcm9jdXJlbWVudC51bml0X2lkXCIgY2xhc3M9XCJyb3VuZGVkIGJvcmRlci1ibHVlLTUwMCBib3JkZXItMiBwLTIgdy0zMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHYtZm9yPVwib3B0aW9uIG9mIHByb2R1Y3QudW5pdF9xdWFudGl0aWVzXCIgOmtleT1cIm9wdGlvbi5pZFwiIDp2YWx1ZT1cIm9wdGlvbi51bml0LmlkXCI+e3sgb3B0aW9uLnVuaXQubmFtZSB9fTwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHIgY2xhc3M9XCJiZy1ncmF5LTEwMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInAtMiB0ZXh0LWdyYXktNjAwIGJvcmRlciBib3JkZXItZ3JheS0zMDBcIiA6Y29sc3Bhbj1cIk9iamVjdC5rZXlzKCBmb3JtLmNvbHVtbnMgKS5pbmRleE9mKCAndGF4X3ZhbHVlJyApXCI+PC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJwLTIgdGV4dC1ncmF5LTYwMCBib3JkZXIgYm9yZGVyLWdyYXktMzAwXCI+e3sgdG90YWxUYXhWYWx1ZXMgfCBjdXJyZW5jeSB9fTwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwicC0yIHRleHQtZ3JheS02MDAgYm9yZGVyIGJvcmRlci1ncmF5LTMwMFwiIDpjb2xzcGFuPVwiT2JqZWN0LmtleXMoIGZvcm0uY29sdW1ucyApLmluZGV4T2YoICd0b3RhbF9wdXJjaGFzZV9wcmljZScgKSAtICggT2JqZWN0LmtleXMoIGZvcm0uY29sdW1ucyApLmluZGV4T2YoICd0YXhfdmFsdWUnICkgKyAxIClcIj48L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInAtMiB0ZXh0LWdyYXktNjAwIGJvcmRlciBib3JkZXItZ3JheS0zMDBcIj57eyB0b3RhbFB1cmNoYXNlUHJpY2UgfCBjdXJyZW5jeSB9fTwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGFibGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC90ZW1wbGF0ZT5cclxuICAgIDwvZGl2PlxyXG48L3RlbXBsYXRlPiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/ts/pages/dashboard/procurements/ns-procurement.vue?vue&type=script&lang=js&\n"); -======= eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _libraries_form_validation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/libraries/form-validation */ \"./resources/ts/libraries/form-validation.ts\");\n/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs */ \"./node_modules/rxjs/_esm5/index.js\");\n/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs/operators */ \"./node_modules/rxjs/_esm5/operators/index.js\");\n/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/bootstrap */ \"./resources/ts/bootstrap.ts\");\n/* harmony import */ var _manage_products__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./manage-products */ \"./resources/ts/pages/dashboard/procurements/manage-products.vue\");\n/* harmony import */ var _libraries_tax__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @/libraries/tax */ \"./resources/ts/libraries/tax.ts\");\n/* harmony import */ var _popups_ns_procurement_product_options_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @/popups/ns-procurement-product-options.vue */ \"./resources/ts/popups/ns-procurement-product-options.vue\");\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _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; }\n\n\n\n\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n name: 'ns-procurement',\n mounted: function mounted() {\n this.reloadEntities();\n },\n computed: {\n activeTab: function activeTab() {\n return this.validTabs.filter(function (tab) {\n return tab.active;\n }).length > 0 ? this.validTabs.filter(function (tab) {\n return tab.active;\n })[0] : false;\n }\n },\n data: function data() {\n return {\n /**\r\n * Is the total taxes\r\n * computed on all the supplied products\r\n */\n totalTaxValues: 0,\n\n /**\r\n * is the total purchase price of\r\n * all the products\r\n */\n totalPurchasePrice: 0,\n\n /**\r\n * Creating an instance of the form validation\r\n * to proceed with basic form validation\r\n */\n formValidation: new _libraries_form_validation__WEBPACK_IMPORTED_MODULE_0__[\"default\"](),\n\n /**\r\n * Reference to the form. Contains\r\n * all the values and that's what is submitted\r\n * to the server\r\n */\n form: {},\n\n /**\r\n * Reference to the nsSnackBar object\r\n */\n nsSnackBar: _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsSnackBar\"],\n\n /**\r\n * Is the array that contains the various \r\n * procurement informations\r\n */\n fields: [],\n\n /**\r\n * Is the array that contains the result\r\n * from the search.\r\n */\n searchResult: [],\n\n /**\r\n * Search value.\r\n */\n searchValue: '',\n\n /**\r\n * Debounce reference,used for searching\r\n * product using the search bar\r\n */\n debounceSearch: null,\n\n /**\r\n * A reference to the nsHttpClient object\r\n */\n nsHttpClient: _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsHttpClient\"],\n\n /**\r\n * Must contain the \r\n * available taxes group\r\n */\n taxes: [],\n\n /**\r\n * Define the available tabs on\r\n * the actual uI\r\n */\n validTabs: [{\n label: 'Details',\n identifier: 'details',\n active: true\n }, {\n label: 'Products',\n identifier: 'products',\n active: false\n }],\n\n /**\r\n * control the state of the reloading\r\n * spinner\r\n */\n reloading: false\n };\n },\n watch: {\n searchValue: function searchValue(value) {\n var _this = this;\n\n if (value) {\n clearTimeout(this.debounceSearch);\n this.debounceSearch = setTimeout(function () {\n _this.doSearch(value);\n }, 500);\n }\n }\n },\n components: {\n NsManageProducts: _manage_products__WEBPACK_IMPORTED_MODULE_4__[\"default\"]\n },\n props: ['submit-method', 'submit-url', 'return-url', 'src', 'rules'],\n methods: {\n computeTotal: function computeTotal() {\n this.totalTaxValues = 0;\n\n if (this.form.products.length > 0) {\n this.totalTaxValues = this.form.products.map(function (p) {\n return p.procurement.tax_value;\n }).reduce(function (b, a) {\n return b + a;\n });\n }\n\n this.totalPurchasePrice = 0;\n\n if (this.form.products.length > 0) {\n this.totalPurchasePrice = this.form.products.map(function (p) {\n return parseFloat(p.procurement.total_purchase_price);\n }).reduce(function (b, a) {\n return b + a;\n });\n }\n },\n\n /**\r\n * Ensure a line is being updated after\r\n * some field has been changed.\r\n * @param {integer} product index\r\n * @return {void}\r\n */\n updateLine: function updateLine(index) {\n var product = this.form.products[index];\n var taxGroup = this.taxes.filter(function (taxGroup) {\n return taxGroup.id === product.procurement.tax_group_id;\n });\n\n if (parseFloat(product.procurement.purchase_price_edit) > 0 && parseFloat(product.procurement.quantity) > 0) {\n /**\r\n * if some tax group is provided\r\n * then let's compute all the grouped taxes\r\n */\n if (taxGroup.length > 0) {\n var totalTaxes = taxGroup[0].taxes.map(function (tax) {\n return _libraries_tax__WEBPACK_IMPORTED_MODULE_5__[\"Tax\"].getTaxValue(product.procurement.tax_type, product.procurement.purchase_price_edit, parseFloat(tax.rate));\n });\n product.procurement.tax_value = totalTaxes.reduce(function (b, a) {\n return b + a;\n });\n\n if (product.procurement.tax_type === 'inclusive') {\n product.procurement.net_purchase_price = parseFloat(product.procurement.purchase_price_edit) - product.procurement.tax_value;\n product.procurement.gross_purchase_price = parseFloat(product.procurement.purchase_price_edit);\n product.procurement.purchase_price = parseFloat(product.procurement.gross_purchase_price);\n } else {\n product.procurement.gross_purchase_price = parseFloat(product.procurement.purchase_price_edit) + product.procurement.tax_value;\n product.procurement.net_purchase_price = parseFloat(product.procurement.purchase_price_edit);\n product.procurement.purchase_price = parseFloat(product.procurement.gross_purchase_price);\n }\n } else {\n product.procurement.gross_purchase_price = parseFloat(product.procurement.purchase_price_edit);\n product.procurement.purchase_price = parseFloat(product.procurement.purchase_price_edit);\n product.procurement.net_purchase_price = parseFloat(product.procurement.purchase_price_edit);\n product.procurement.tax_value = 0;\n }\n\n product.procurement.tax_value = product.procurement.tax_value * parseFloat(product.procurement.quantity);\n product.procurement.total_purchase_price = product.procurement.purchase_price * parseFloat(product.procurement.quantity);\n }\n\n this.computeTotal();\n this.$forceUpdate();\n },\n\n /**\r\n * Switch the tax type applied \r\n * on the current product.\r\n */\n switchTaxType: function switchTaxType(product, index) {\n product.procurement.tax_type = product.procurement.tax_type === 'inclusive' ? 'exclusive' : 'inclusive';\n this.updateLine(index);\n },\n\n /**\r\n * Perform a seach and populate\r\n * the search result array\r\n * @param string\r\n * @return void\r\n */\n doSearch: function doSearch(search) {\n var _this2 = this;\n\n _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsHttpClient\"].post('/api/nexopos/v4/products/search', {\n search: search\n }).subscribe(function (result) {\n if (result.length === 1) {\n _this2.addProductList(result[0]);\n } else {\n _this2.searchResult = result;\n }\n });\n },\n\n /**\r\n * Reload the value from the server.\r\n * Useful to reload data after having created a new\r\n * entity\r\n * @return void\r\n */\n reloadEntities: function reloadEntities() {\n var _this3 = this;\n\n this.reloading = true;\n Object(rxjs__WEBPACK_IMPORTED_MODULE_1__[\"forkJoin\"])([_bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsHttpClient\"].get('/api/nexopos/v4/categories'), _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsHttpClient\"].get('/api/nexopos/v4/products'), _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsHttpClient\"].get(this.src), _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsHttpClient\"].get('/api/nexopos/v4/taxes/groups')]).subscribe(function (result) {\n _this3.reloading = false;\n _this3.categories = result[0];\n _this3.products = result[1];\n _this3.taxes = result[3];\n\n if (_this3.form.general) {\n result[2].tabs.general.fieds.forEach(function (field, index) {\n field.value = _this3.form.tabs.general.fields[index].value || '';\n });\n }\n\n _this3.form = Object.assign(_this3.form, result[2]);\n _this3.form = _this3.formValidation.createForm(_this3.form);\n\n if (_this3.form.products === undefined) {\n _this3.form.products = [];\n } else {\n /**\r\n * if the product has been provided by the\r\n * server we need to format it.\r\n */\n _this3.form.products = _this3.form.products.map(function (product) {\n ['gross_purchase_price', 'purchase_price_edit', 'tax_value', 'net_purchase_price', 'purchase_price', 'total_price', 'total_purchase_price', 'quantity', 'tax_group_id'].forEach(function (field) {\n if (product[field] === undefined) {\n product[field] = 0;\n }\n });\n product.$invalid = product.$invalid || false;\n product.purchase_price_edit = product.purchase_price;\n return {\n name: product.name,\n purchase_units: product.purchase_units,\n procurement: product,\n unit_quantities: product.unit_quantities || []\n };\n });\n console.log(_this3.form.products);\n }\n\n _this3.$forceUpdate();\n });\n },\n setTabActive: function setTabActive(tab) {\n this.validTabs.forEach(function (tab) {\n return tab.active = false;\n });\n this.$forceUpdate();\n this.$nextTick().then(function () {\n tab.active = true;\n });\n },\n addProductList: function addProductList(product) {\n if (product.unit_quantities === undefined) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsSnackBar\"].error('Unable to add product which doesn\\'t unit quantities defined.').subscribe();\n }\n\n product.procurement = new Object();\n product.procurement.gross_purchase_price = 0;\n product.procurement.purchase_price_edit = 0;\n product.procurement.tax_value = 0;\n product.procurement.net_purchase_price = 0;\n product.procurement.purchase_price = 0;\n product.procurement.total_price = 0;\n product.procurement.total_purchase_price = 0;\n product.procurement.quantity = 1;\n product.procurement.expiration_date = null;\n product.procurement.tax_group_id = 0;\n product.procurement.tax_type = 'inclusive';\n product.procurement.unit_id = 0;\n product.procurement.product_id = product.id;\n product.procurement.procurement_id = null;\n product.procurement.$invalid = false;\n this.searchResult = [];\n this.searchValue = '';\n this.form.products.push(product);\n },\n submit: function submit() {\n var _this4 = this;\n\n if (this.form.products.length === 0) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsSnackBar\"].error(this.$slots['error-no-products'] ? this.$slots['error-no-products'][0].text : 'No error message provided on the slot \"error-no-products\".', this.$slots['okay'] ? this.$slots['okay'][0].text : 'OK').subscribe();\n }\n\n this.form.products.forEach(function (product) {\n if (!parseFloat(product.procurement.quantity) >= 1) {\n product.procurement.$invalid = true;\n } else if (product.unit_id === 0) {\n product.procurement.$invalid = true;\n } else {\n product.procurement.$invalid = false;\n }\n });\n var invalidProducts = this.form.products.filter(function (product) {\n return product.procurement.$invalid;\n });\n\n if (invalidProducts.length > 0) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsSnackBar\"].error(this.$slots['error-invalid-products'] ? this.$slots['error-invalid-products'][0].text : 'No error message provided on the slot \"error-invalid-products\".', this.$slots['okay'] ? this.$slots['okay'][0].text : 'OK').subscribe();\n }\n\n if (this.formValidation.validateForm(this.form).length > 0) {\n /**\r\n * hack to force rerendering\r\n * there might be a better solutin here.\r\n */\n this.setTabActive(this.activeTab);\n return _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsSnackBar\"].error(this.$slots['error-invalid-form'] ? this.$slots['error-invalid-form'][0].text : 'No error message provided for having an invalid form.', this.$slots['okay'] ? this.$slots['okay'][0].text : 'OK').subscribe();\n }\n\n if (this.submitUrl === undefined) {\n return _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsSnackBar\"].error(this.$slots['error-no-submit-url'] ? this.$slots['error-no-submit-url'][0].text : 'No error message provided for not having a valid submit url.', this.$slots['okay'] ? this.$slots['okay'][0].text : 'OK').subscribe();\n }\n\n this.formValidation.disableForm(this.form);\n\n var data = _objectSpread(_objectSpread({}, this.formValidation.extractForm(this.form)), {\n products: this.form.products.map(function (product) {\n return product.procurement;\n })\n });\n\n _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsHttpClient\"][this.submitMethod ? this.submitMethod.toLowerCase() : 'post'](this.submitUrl, data).subscribe(function (data) {\n if (data.status === 'success') {\n return document.location = _this4.returnUrl;\n }\n\n _this4.formValidation.enableForm(_this4.form);\n }, function (error) {\n _bootstrap__WEBPACK_IMPORTED_MODULE_3__[\"nsSnackBar\"].error(error.message, undefined, {\n duration: 5000\n }).subscribe();\n\n _this4.formValidation.enableForm(_this4.form);\n\n if (error.errors) {\n _this4.formValidation.triggerError(_this4.form, error.errors);\n }\n });\n },\n deleteProduct: function deleteProduct(index) {\n this.form.products.splice(index, 1);\n this.$forceUpdate();\n },\n handleGlobalChange: function handleGlobalChange(event) {\n this.globallyChecked = event;\n this.rows.forEach(function (r) {\n return r.$checked = event;\n });\n },\n setProductOptions: function setProductOptions(index) {\n var _this5 = this;\n\n var promise = new Promise(function (resolve, reject) {\n Popup.show(_popups_ns_procurement_product_options_vue__WEBPACK_IMPORTED_MODULE_6__[\"default\"], {\n product: _this5.form.products[index],\n resolve: resolve,\n reject: reject\n });\n });\n promise.then(function (value) {\n for (var key in value) {\n _this5.form.products[index].procurement[key] = value[key];\n }\n\n _this5.updateLine(index);\n });\n }\n }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcmVzb3VyY2VzL3RzL3BhZ2VzL2Rhc2hib2FyZC9wcm9jdXJlbWVudHMvbnMtcHJvY3VyZW1lbnQudnVlP2E4MzciXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0Esd0JBREE7QUFFQSxTQUZBLHFCQUVBO0FBQ0E7QUFDQSxHQUpBO0FBS0E7QUFDQSxhQURBLHVCQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBSEEsR0FMQTtBQVVBLE1BVkEsa0JBVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBTEE7O0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFYQTs7QUFjQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhGQWxCQTs7QUFvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBekJBOztBQTJCQTtBQUNBO0FBQ0E7QUFDQSx1RUE5QkE7O0FBZ0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBcENBOztBQXNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQTFDQTs7QUE0Q0E7QUFDQTtBQUNBO0FBQ0EscUJBL0NBOztBQWlEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQXJEQTs7QUF1REE7QUFDQTtBQUNBO0FBQ0EsMkVBMURBOztBQTREQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBaEVBOztBQWtFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUNBO0FBQ0Esd0JBREE7QUFFQSw2QkFGQTtBQUdBO0FBSEEsT0FEQSxFQUtBO0FBQ0EseUJBREE7QUFFQSw4QkFGQTtBQUdBO0FBSEEsT0FMQSxDQXRFQTs7QUFrRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQXRGQTtBQXdGQSxHQW5HQTtBQW9HQTtBQUNBLGVBREEsdUJBQ0EsS0FEQSxFQUNBO0FBQUE7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUZBLEVBRUEsR0FG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REEsT0FEQTs7QUFNQSxrSkFDQSxTQURBLENBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBQ0E7QUFDQSxPQU5BLEVBTUE7QUFDQTtBQUNBO0FBREEsV0FFQSxTQUZBOztBQUlBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BaEJBO0FBaUJBLEtBMVFBO0FBMlFBLGlCQTNRQSx5QkEyUUEsS0EzUUEsRUEyUUE7QUFDQTtBQUNBO0FBQ0EsS0E5UUE7QUErUUEsc0JBL1FBLDhCQStRQSxLQS9RQSxFQStRQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0EsS0FsUkE7QUFvUkEscUJBcFJBLDZCQW9SQSxLQXBSQSxFQW9SQTtBQUFBOztBQUNBO0FBQ0E7QUFDQSw4Q0FEQTtBQUVBLDBCQUZBO0FBR0E7QUFIQTtBQUtBLE9BTkE7QUFRQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLE9BTkE7QUFPQTtBQXBTQTtBQWxIQSIsImZpbGUiOiIuL25vZGVfbW9kdWxlcy9iYWJlbC1sb2FkZXIvbGliL2luZGV4LmpzPyEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9pbmRleC5qcz8hLi9yZXNvdXJjZXMvdHMvcGFnZXMvZGFzaGJvYXJkL3Byb2N1cmVtZW50cy9ucy1wcm9jdXJlbWVudC52dWU/dnVlJnR5cGU9c2NyaXB0Jmxhbmc9anMmLmpzIiwic291cmNlc0NvbnRlbnQiOlsiPHNjcmlwdD5cclxuaW1wb3J0IEZvcm1WYWxpZGF0aW9uIGZyb20gJ0AvbGlicmFyaWVzL2Zvcm0tdmFsaWRhdGlvbic7XHJcbmltcG9ydCB7IFN1YmplY3QsIEJlaGF2aW9yU3ViamVjdCwgZm9ya0pvaW4gfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQgeyBtYXAgfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcclxuaW1wb3J0IHsgbnNTbmFja0JhciwgbnNIdHRwQ2xpZW50IH0gZnJvbSAnQC9ib290c3RyYXAnO1xyXG5pbXBvcnQgTnNNYW5hZ2VQcm9kdWN0cyBmcm9tICcuL21hbmFnZS1wcm9kdWN0cyc7XHJcbmltcG9ydCB7IFRheCB9IGZyb20gXCJAL2xpYnJhcmllcy90YXhcIjtcclxuaW1wb3J0IG5zUHJvY3VyZW1lbnRQcm9kdWN0T3B0aW9uc1Z1ZSBmcm9tICdAL3BvcHVwcy9ucy1wcm9jdXJlbWVudC1wcm9kdWN0LW9wdGlvbnMudnVlJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIG5hbWU6ICducy1wcm9jdXJlbWVudCcsXHJcbiAgICBtb3VudGVkKCkge1xyXG4gICAgICAgIHRoaXMucmVsb2FkRW50aXRpZXMoKTtcclxuICAgIH0sXHJcbiAgICBjb21wdXRlZDoge1xyXG4gICAgICAgIGFjdGl2ZVRhYigpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRUYWJzLmZpbHRlciggdGFiID0+IHRhYi5hY3RpdmUgKS5sZW5ndGggPiAwID8gdGhpcy52YWxpZFRhYnMuZmlsdGVyKCB0YWIgPT4gdGFiLmFjdGl2ZSApWzBdIDogZmFsc2U7XHJcbiAgICAgICAgfSxcclxuICAgIH0sXHJcbiAgICBkYXRhKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBJcyB0aGUgdG90YWwgdGF4ZXNcclxuICAgICAgICAgICAgICogY29tcHV0ZWQgb24gYWxsIHRoZSBzdXBwbGllZCBwcm9kdWN0c1xyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgdG90YWxUYXhWYWx1ZXM6IDAsXHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogaXMgdGhlIHRvdGFsIHB1cmNoYXNlIHByaWNlIG9mXHJcbiAgICAgICAgICAgICAqIGFsbCB0aGUgcHJvZHVjdHNcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIHRvdGFsUHVyY2hhc2VQcmljZTogMCxcclxuXHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogQ3JlYXRpbmcgYW4gaW5zdGFuY2Ugb2YgdGhlIGZvcm0gdmFsaWRhdGlvblxyXG4gICAgICAgICAgICAgKiB0byBwcm9jZWVkIHdpdGggYmFzaWMgZm9ybSB2YWxpZGF0aW9uXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBmb3JtVmFsaWRhdGlvbjogbmV3IEZvcm1WYWxpZGF0aW9uLFxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFJlZmVyZW5jZSB0byB0aGUgZm9ybS4gQ29udGFpbnNcclxuICAgICAgICAgICAgICogYWxsIHRoZSB2YWx1ZXMgYW5kIHRoYXQncyB3aGF0IGlzIHN1Ym1pdHRlZFxyXG4gICAgICAgICAgICAgKiB0byB0aGUgc2VydmVyXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBmb3JtOiB7fSxcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBSZWZlcmVuY2UgdG8gdGhlIG5zU25hY2tCYXIgb2JqZWN0XHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBuc1NuYWNrQmFyLFxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIElzIHRoZSBhcnJheSB0aGF0IGNvbnRhaW5zIHRoZSB2YXJpb3VzIFxyXG4gICAgICAgICAgICAgKiBwcm9jdXJlbWVudCBpbmZvcm1hdGlvbnNcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGZpZWxkczogW10sXHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogSXMgdGhlIGFycmF5IHRoYXQgY29udGFpbnMgdGhlIHJlc3VsdFxyXG4gICAgICAgICAgICAgKiBmcm9tIHRoZSBzZWFyY2guXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBzZWFyY2hSZXN1bHQ6IFtdLFxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFNlYXJjaCB2YWx1ZS5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIHNlYXJjaFZhbHVlOiAnJyxcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBEZWJvdW5jZSByZWZlcmVuY2UsdXNlZCBmb3Igc2VhcmNoaW5nXHJcbiAgICAgICAgICAgICAqIHByb2R1Y3QgdXNpbmcgdGhlIHNlYXJjaCBiYXJcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGRlYm91bmNlU2VhcmNoOiBudWxsLFxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEEgcmVmZXJlbmNlIHRvIHRoZSBuc0h0dHBDbGllbnQgb2JqZWN0XHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBuc0h0dHBDbGllbnQsXHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogTXVzdCBjb250YWluIHRoZSBcclxuICAgICAgICAgICAgICogYXZhaWxhYmxlIHRheGVzIGdyb3VwXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICB0YXhlczogW10sXHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogRGVmaW5lIHRoZSBhdmFpbGFibGUgdGFicyBvblxyXG4gICAgICAgICAgICAgKiB0aGUgYWN0dWFsIHVJXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICB2YWxpZFRhYnM6IFtcclxuICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJ0RldGFpbHMnLFxyXG4gICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZXI6ICdkZXRhaWxzJyxcclxuICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB9LCB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICdQcm9kdWN0cycsXHJcbiAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmllcjogJ3Byb2R1Y3RzJyxcclxuICAgICAgICAgICAgICAgICAgICBhY3RpdmU6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgfSwgXHJcbiAgICAgICAgICAgIF0sXHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogY29udHJvbCB0aGUgc3RhdGUgb2YgdGhlIHJlbG9hZGluZ1xyXG4gICAgICAgICAgICAgKiBzcGlubmVyXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICByZWxvYWRpbmc6IGZhbHNlXHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIHdhdGNoOiB7XHJcbiAgICAgICAgc2VhcmNoVmFsdWUoIHZhbHVlICkge1xyXG4gICAgICAgICAgICBpZiAoIHZhbHVlICkge1xyXG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KCB0aGlzLmRlYm91bmNlU2VhcmNoICk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRlYm91bmNlU2VhcmNoICAgICA9ICAgc2V0VGltZW91dCggKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZG9TZWFyY2goIHZhbHVlICk7XHJcbiAgICAgICAgICAgICAgICB9LCA1MDAgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH0sXHJcbiAgICBjb21wb25lbnRzOiB7XHJcbiAgICAgICAgTnNNYW5hZ2VQcm9kdWN0c1xyXG4gICAgfSxcclxuICAgIHByb3BzOiBbICdzdWJtaXQtbWV0aG9kJywgJ3N1Ym1pdC11cmwnLCAncmV0dXJuLXVybCcsICdzcmMnLCAncnVsZXMnIF0sXHJcbiAgICBtZXRob2RzOiB7XHJcbiAgICAgICAgY29tcHV0ZVRvdGFsKCkge1xyXG5cclxuICAgICAgICAgICAgdGhpcy50b3RhbFRheFZhbHVlcyA9IDA7XHJcblxyXG4gICAgICAgICAgICBpZiAoIHRoaXMuZm9ybS5wcm9kdWN0cy5sZW5ndGggPiAwICkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy50b3RhbFRheFZhbHVlcyA9IHRoaXMuZm9ybS5wcm9kdWN0cy5tYXAoIHAgPT4gcC5wcm9jdXJlbWVudC50YXhfdmFsdWUgKVxyXG4gICAgICAgICAgICAgICAgICAgIC5yZWR1Y2UoICggYiwgYSApID0+IGIgKyBhICk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMudG90YWxQdXJjaGFzZVByaWNlICAgICA9ICAgMDtcclxuXHJcbiAgICAgICAgICAgIGlmICggdGhpcy5mb3JtLnByb2R1Y3RzLmxlbmd0aCA+IDAgKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnRvdGFsUHVyY2hhc2VQcmljZSAgICAgPSAgIHRoaXMuZm9ybS5wcm9kdWN0cy5tYXAoIHAgPT4gcGFyc2VGbG9hdCggcC5wcm9jdXJlbWVudC50b3RhbF9wdXJjaGFzZV9wcmljZSApIClcclxuICAgICAgICAgICAgICAgICAgICAucmVkdWNlKCAoIGIsIGEgKSA9PiBiICsgYSApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRW5zdXJlIGEgbGluZSBpcyBiZWluZyB1cGRhdGVkIGFmdGVyXHJcbiAgICAgICAgICogc29tZSBmaWVsZCBoYXMgYmVlbiBjaGFuZ2VkLlxyXG4gICAgICAgICAqIEBwYXJhbSB7aW50ZWdlcn0gcHJvZHVjdCBpbmRleFxyXG4gICAgICAgICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXBkYXRlTGluZSggaW5kZXggKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHByb2R1Y3QgICA9ICAgdGhpcy5mb3JtLnByb2R1Y3RzWyBpbmRleCBdO1xyXG4gICAgICAgICAgICBjb25zdCB0YXhHcm91cCAgPSAgIHRoaXMudGF4ZXMuZmlsdGVyKCB0YXhHcm91cCA9PiB0YXhHcm91cC5pZCA9PT0gcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfZ3JvdXBfaWQgKTtcclxuXHJcbiAgICAgICAgICAgIGlmICggcGFyc2VGbG9hdCggcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZV9lZGl0ICkgPiAwICYmIHBhcnNlRmxvYXQoIHByb2R1Y3QucHJvY3VyZW1lbnQucXVhbnRpdHkgKSA+IDAgKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBpZiBzb21lIHRheCBncm91cCBpcyBwcm92aWRlZFxyXG4gICAgICAgICAgICAgICAgICogdGhlbiBsZXQncyBjb21wdXRlIGFsbCB0aGUgZ3JvdXBlZCB0YXhlc1xyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBpZiAoIHRheEdyb3VwLmxlbmd0aCA+IDAgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdG90YWxUYXhlcyAgICA9ICAgdGF4R3JvdXBbMF0udGF4ZXMubWFwKCB0YXggPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gVGF4LmdldFRheFZhbHVlKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdHlwZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQucHVyY2hhc2VfcHJpY2VfZWRpdCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlRmxvYXQoIHRheC5yYXRlIClcclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdmFsdWUgICAgICAgICAgICAgICA9ICAgKCB0b3RhbFRheGVzLnJlZHVjZSggKCBiLCBhICkgPT4gYiArIGEgKSApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIHByb2R1Y3QucHJvY3VyZW1lbnQudGF4X3R5cGUgPT09ICdpbmNsdXNpdmUnICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50Lm5ldF9wdXJjaGFzZV9wcmljZSAgICAgID0gICBwYXJzZUZsb2F0KCBwcm9kdWN0LnByb2N1cmVtZW50LnB1cmNoYXNlX3ByaWNlX2VkaXQgKSAtIHByb2R1Y3QucHJvY3VyZW1lbnQudGF4X3ZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50Lmdyb3NzX3B1cmNoYXNlX3ByaWNlICAgID0gICBwYXJzZUZsb2F0KCBwcm9kdWN0LnByb2N1cmVtZW50LnB1cmNoYXNlX3ByaWNlX2VkaXQgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZSAgICAgICAgICA9ICAgcGFyc2VGbG9hdCggcHJvZHVjdC5wcm9jdXJlbWVudC5ncm9zc19wdXJjaGFzZV9wcmljZSApO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQuZ3Jvc3NfcHVyY2hhc2VfcHJpY2UgICAgPSAgIHBhcnNlRmxvYXQoIHByb2R1Y3QucHJvY3VyZW1lbnQucHVyY2hhc2VfcHJpY2VfZWRpdCApICsgcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQubmV0X3B1cmNoYXNlX3ByaWNlICAgICAgPSAgIHBhcnNlRmxvYXQoIHByb2R1Y3QucHJvY3VyZW1lbnQucHVyY2hhc2VfcHJpY2VfZWRpdCApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LnB1cmNoYXNlX3ByaWNlICAgICAgICAgID0gICBwYXJzZUZsb2F0KCBwcm9kdWN0LnByb2N1cmVtZW50Lmdyb3NzX3B1cmNoYXNlX3ByaWNlICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5ncm9zc19wdXJjaGFzZV9wcmljZSAgICA9ICAgcGFyc2VGbG9hdCggcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZV9lZGl0ICk7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZSAgICAgICAgICA9ICAgcGFyc2VGbG9hdCggcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZV9lZGl0ICk7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5uZXRfcHVyY2hhc2VfcHJpY2UgICAgICA9ICAgcGFyc2VGbG9hdCggcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZV9lZGl0ICk7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdmFsdWUgICAgICAgICAgICAgICA9ICAgMDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LnRheF92YWx1ZSAgICAgICAgICAgICAgICAgICA9ICAgcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdmFsdWUgKiBwYXJzZUZsb2F0KCBwcm9kdWN0LnByb2N1cmVtZW50LnF1YW50aXR5ICk7XHJcbiAgICAgICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LnRvdGFsX3B1cmNoYXNlX3ByaWNlICAgICAgICA9ICAgcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZSAqIHBhcnNlRmxvYXQoIHByb2R1Y3QucHJvY3VyZW1lbnQucXVhbnRpdHkgKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5jb21wdXRlVG90YWwoKTtcclxuICAgICAgICAgICAgdGhpcy4kZm9yY2VVcGRhdGUoKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTd2l0Y2ggdGhlIHRheCB0eXBlIGFwcGxpZWQgXHJcbiAgICAgICAgICogb24gdGhlIGN1cnJlbnQgcHJvZHVjdC5cclxuICAgICAgICAgKi9cclxuICAgICAgICBzd2l0Y2hUYXhUeXBlKCBwcm9kdWN0LCBpbmRleCApIHtcclxuICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdHlwZSA9ICBwcm9kdWN0LnByb2N1cmVtZW50LnRheF90eXBlID09PSAnaW5jbHVzaXZlJyA/ICdleGNsdXNpdmUnIDogJ2luY2x1c2l2ZSc7XHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlTGluZSggaW5kZXggKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBQZXJmb3JtIGEgc2VhY2ggYW5kIHBvcHVsYXRlXHJcbiAgICAgICAgICogdGhlIHNlYXJjaCByZXN1bHQgYXJyYXlcclxuICAgICAgICAgKiBAcGFyYW0gc3RyaW5nXHJcbiAgICAgICAgICogQHJldHVybiB2b2lkXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZG9TZWFyY2goIHNlYXJjaCApIHtcclxuICAgICAgICAgICAgbnNIdHRwQ2xpZW50LnBvc3QoICcvYXBpL25leG9wb3MvdjQvcHJvZHVjdHMvc2VhcmNoJywgeyBzZWFyY2ggfSlcclxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoIHJlc3VsdCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCByZXN1bHQubGVuZ3RoID09PSAxICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZFByb2R1Y3RMaXN0KCByZXN1bHRbMF0gKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlYXJjaFJlc3VsdCAgID0gICByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBSZWxvYWQgdGhlIHZhbHVlIGZyb20gdGhlIHNlcnZlci5cclxuICAgICAgICAgKiBVc2VmdWwgdG8gcmVsb2FkIGRhdGEgYWZ0ZXIgaGF2aW5nIGNyZWF0ZWQgYSBuZXdcclxuICAgICAgICAgKiBlbnRpdHlcclxuICAgICAgICAgKiBAcmV0dXJuIHZvaWRcclxuICAgICAgICAgKi9cclxuICAgICAgICByZWxvYWRFbnRpdGllcygpIHtcclxuICAgICAgICAgICAgdGhpcy5yZWxvYWRpbmcgICAgICAgICAgPSAgIHRydWU7XHJcbiAgICAgICAgICAgIGZvcmtKb2luKFtcclxuICAgICAgICAgICAgICAgIG5zSHR0cENsaWVudC5nZXQoICcvYXBpL25leG9wb3MvdjQvY2F0ZWdvcmllcycgKSxcclxuICAgICAgICAgICAgICAgIG5zSHR0cENsaWVudC5nZXQoICcvYXBpL25leG9wb3MvdjQvcHJvZHVjdHMnICksXHJcbiAgICAgICAgICAgICAgICBuc0h0dHBDbGllbnQuZ2V0KCB0aGlzLnNyYyApLFxyXG4gICAgICAgICAgICAgICAgbnNIdHRwQ2xpZW50LmdldCggJy9hcGkvbmV4b3Bvcy92NC90YXhlcy9ncm91cHMnICksXHJcbiAgICAgICAgICAgIF0pLnN1YnNjcmliZSggcmVzdWx0ID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVsb2FkaW5nICAgICAgPSAgIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jYXRlZ29yaWVzICAgICA9ICAgcmVzdWx0WzBdO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9kdWN0cyAgICAgICA9ICAgcmVzdWx0WzFdO1xyXG4gICAgICAgICAgICAgICAgdGhpcy50YXhlcyAgICAgICAgICA9ICAgcmVzdWx0WzNdO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICggdGhpcy5mb3JtLmdlbmVyYWwgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0WzJdLnRhYnMuZ2VuZXJhbC5maWVkcy5mb3JFYWNoKCAoZmllbGQsaW5kZXgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQudmFsdWUgICAgID0gICB0aGlzLmZvcm0udGFicy5nZW5lcmFsLmZpZWxkc1sgaW5kZXggXS52YWx1ZSB8fCAnJztcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0gXHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtICAgICAgICAgICA9ICAgT2JqZWN0LmFzc2lnbiggdGhpcy5mb3JtLCByZXN1bHRbMl0gKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZm9ybSAgICAgICAgICAgPSAgIHRoaXMuZm9ybVZhbGlkYXRpb24uY3JlYXRlRm9ybSggdGhpcy5mb3JtICk7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIGlmICggdGhpcy5mb3JtLnByb2R1Y3RzID09PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLnByb2R1Y3RzICA9ICAgW107XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICAgICAqIGlmIHRoZSBwcm9kdWN0IGhhcyBiZWVuIHByb3ZpZGVkIGJ5IHRoZVxyXG4gICAgICAgICAgICAgICAgICAgICAqIHNlcnZlciB3ZSBuZWVkIHRvIGZvcm1hdCBpdC5cclxuICAgICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0ucHJvZHVjdHMgID0gICB0aGlzLmZvcm0ucHJvZHVjdHMubWFwKCBwcm9kdWN0ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2dyb3NzX3B1cmNoYXNlX3ByaWNlJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwdXJjaGFzZV9wcmljZV9lZGl0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0YXhfdmFsdWUnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ25ldF9wdXJjaGFzZV9wcmljZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncHVyY2hhc2VfcHJpY2UnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RvdGFsX3ByaWNlJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0b3RhbF9wdXJjaGFzZV9wcmljZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAncXVhbnRpdHknLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RheF9ncm91cF9pZCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF0uZm9yRWFjaCggZmllbGQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBwcm9kdWN0WyBmaWVsZCBdID09PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZHVjdFsgZmllbGQgXSAgICA9ICAgMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9kdWN0LiRpbnZhbGlkICAgICAgICAgICAgICAgID0gICBwcm9kdWN0LiRpbnZhbGlkIHx8IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9kdWN0LnB1cmNoYXNlX3ByaWNlX2VkaXQgICAgID0gICBwcm9kdWN0LnB1cmNoYXNlX3ByaWNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IHByb2R1Y3QubmFtZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1cmNoYXNlX3VuaXRzOiBwcm9kdWN0LnB1cmNoYXNlX3VuaXRzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY3VyZW1lbnQ6IHByb2R1Y3QsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0X3F1YW50aXRpZXM6IHByb2R1Y3QudW5pdF9xdWFudGl0aWVzIHx8IFtdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coIHRoaXMuZm9ybS5wcm9kdWN0cyApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICB0aGlzLiRmb3JjZVVwZGF0ZSgpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgc2V0VGFiQWN0aXZlKCB0YWIgKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsaWRUYWJzLmZvckVhY2goIHRhYiA9PiB0YWIuYWN0aXZlID0gZmFsc2UgKTtcclxuICAgICAgICAgICAgdGhpcy4kZm9yY2VVcGRhdGUoKTtcclxuICAgICAgICAgICAgdGhpcy4kbmV4dFRpY2soKS50aGVuKCAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0YWIuYWN0aXZlICA9ICAgdHJ1ZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBhZGRQcm9kdWN0TGlzdCggcHJvZHVjdCApIHtcclxuXHJcbiAgICAgICAgICAgIGlmICggcHJvZHVjdC51bml0X3F1YW50aXRpZXMgPT09IHVuZGVmaW5lZCApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuc1NuYWNrQmFyLmVycm9yKCAnVW5hYmxlIHRvIGFkZCBwcm9kdWN0IHdoaWNoIGRvZXNuXFwndCB1bml0IHF1YW50aXRpZXMgZGVmaW5lZC4nIClcclxuICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gICBuZXcgT2JqZWN0O1xyXG4gICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50Lmdyb3NzX3B1cmNoYXNlX3ByaWNlICAgICAgICA9ICAgMDtcclxuICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZV9lZGl0ICAgICAgICAgPSAgIDA7XHJcbiAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQudGF4X3ZhbHVlICAgICAgICAgICAgICAgICAgID0gICAwO1xyXG4gICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50Lm5ldF9wdXJjaGFzZV9wcmljZSAgICAgICAgICA9ICAgMDtcclxuICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5wdXJjaGFzZV9wcmljZSAgICAgICAgICAgICAgPSAgIDA7XHJcbiAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQudG90YWxfcHJpY2UgICAgICAgICAgICAgICAgID0gICAwO1xyXG4gICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LnRvdGFsX3B1cmNoYXNlX3ByaWNlICAgICAgICA9ICAgMDtcclxuICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5xdWFudGl0eSAgICAgICAgICAgICAgICAgICAgPSAgIDE7XHJcbiAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQuZXhwaXJhdGlvbl9kYXRlICAgICAgICAgICAgID0gICBudWxsO1xyXG4gICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LnRheF9ncm91cF9pZCAgICAgICAgICAgICAgICA9ICAgMDtcclxuICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdHlwZSAgICAgICAgICAgICAgICAgICAgPSAgICdpbmNsdXNpdmUnO1xyXG4gICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LnVuaXRfaWQgICAgICAgICAgICAgICAgICAgICA9ICAgMDtcclxuICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC5wcm9kdWN0X2lkICAgICAgICAgICAgICAgICAgPSAgIHByb2R1Y3QuaWQ7XHJcbiAgICAgICAgICAgIHByb2R1Y3QucHJvY3VyZW1lbnQucHJvY3VyZW1lbnRfaWQgICAgICAgICAgICAgID0gICBudWxsO1xyXG4gICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LiRpbnZhbGlkICAgICAgICAgICAgICAgICAgICA9ICAgZmFsc2U7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnNlYXJjaFJlc3VsdCAgICAgICAgICAgPSAgIFtdO1xyXG4gICAgICAgICAgICB0aGlzLnNlYXJjaFZhbHVlICAgICAgICAgICAgPSAgICcnO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5mb3JtLnByb2R1Y3RzLnB1c2goIHByb2R1Y3QgKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIHN1Ym1pdCgpIHtcclxuXHJcbiAgICAgICAgICAgIGlmICggdGhpcy5mb3JtLnByb2R1Y3RzLmxlbmd0aCA9PT0gMCApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuc1NuYWNrQmFyLmVycm9yKCB0aGlzLiRzbG90c1sgJ2Vycm9yLW5vLXByb2R1Y3RzJyBdID8gdGhpcy4kc2xvdHNbICdlcnJvci1uby1wcm9kdWN0cycgXVswXS50ZXh0IDogJ05vIGVycm9yIG1lc3NhZ2UgcHJvdmlkZWQgb24gdGhlIHNsb3QgXCJlcnJvci1uby1wcm9kdWN0c1wiLicsIHRoaXMuJHNsb3RzWyAnb2theScgXSA/IHRoaXMuJHNsb3RzWyAnb2theScgXVswXS50ZXh0IDogJ09LJyApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmZvcm0ucHJvZHVjdHMuZm9yRWFjaCggcHJvZHVjdCA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoICEgcGFyc2VGbG9hdCggcHJvZHVjdC5wcm9jdXJlbWVudC5xdWFudGl0eSApID49IDEgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdC5wcm9jdXJlbWVudC4kaW52YWxpZCAgICA9ICAgdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIHByb2R1Y3QudW5pdF9pZCA9PT0gMCApIHtcclxuICAgICAgICAgICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LiRpbnZhbGlkICAgID0gICB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBwcm9kdWN0LnByb2N1cmVtZW50LiRpbnZhbGlkICAgID0gICBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBpbnZhbGlkUHJvZHVjdHMgICA9ICAgdGhpcy5mb3JtLnByb2R1Y3RzLmZpbHRlciggcHJvZHVjdCA9PiBwcm9kdWN0LnByb2N1cmVtZW50LiRpbnZhbGlkICk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIGludmFsaWRQcm9kdWN0cy5sZW5ndGggPiAwICkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5zU25hY2tCYXIuZXJyb3IoIHRoaXMuJHNsb3RzWyAnZXJyb3ItaW52YWxpZC1wcm9kdWN0cycgXSA/IHRoaXMuJHNsb3RzWyAnZXJyb3ItaW52YWxpZC1wcm9kdWN0cycgXVswXS50ZXh0IDogJ05vIGVycm9yIG1lc3NhZ2UgcHJvdmlkZWQgb24gdGhlIHNsb3QgXCJlcnJvci1pbnZhbGlkLXByb2R1Y3RzXCIuJywgdGhpcy4kc2xvdHNbICdva2F5JyBdID8gdGhpcy4kc2xvdHNbICdva2F5JyBdWzBdLnRleHQgOiAnT0snIClcclxuICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICggdGhpcy5mb3JtVmFsaWRhdGlvbi52YWxpZGF0ZUZvcm0oIHRoaXMuZm9ybSApLmxlbmd0aCA+IDAgKSB7XHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIGhhY2sgdG8gZm9yY2UgcmVyZW5kZXJpbmdcclxuICAgICAgICAgICAgICAgICAqIHRoZXJlIG1pZ2h0IGJlIGEgYmV0dGVyIHNvbHV0aW4gaGVyZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRUYWJBY3RpdmUoIHRoaXMuYWN0aXZlVGFiICk7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5zU25hY2tCYXIuZXJyb3IoIHRoaXMuJHNsb3RzWyAnZXJyb3ItaW52YWxpZC1mb3JtJyBdID8gdGhpcy4kc2xvdHNbICdlcnJvci1pbnZhbGlkLWZvcm0nIF1bMF0udGV4dCA6ICdObyBlcnJvciBtZXNzYWdlIHByb3ZpZGVkIGZvciBoYXZpbmcgYW4gaW52YWxpZCBmb3JtLicsIHRoaXMuJHNsb3RzWyAnb2theScgXSA/IHRoaXMuJHNsb3RzWyAnb2theScgXVswXS50ZXh0IDogJ09LJyApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIHRoaXMuc3VibWl0VXJsID09PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnNTbmFja0Jhci5lcnJvciggdGhpcy4kc2xvdHNbICdlcnJvci1uby1zdWJtaXQtdXJsJyBdID8gdGhpcy4kc2xvdHNbICdlcnJvci1uby1zdWJtaXQtdXJsJyBdWzBdLnRleHQgOiAnTm8gZXJyb3IgbWVzc2FnZSBwcm92aWRlZCBmb3Igbm90IGhhdmluZyBhIHZhbGlkIHN1Ym1pdCB1cmwuJywgdGhpcy4kc2xvdHNbICdva2F5JyBdID8gdGhpcy4kc2xvdHNbICdva2F5JyBdWzBdLnRleHQgOiAnT0snIClcclxuICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuZm9ybVZhbGlkYXRpb24uZGlzYWJsZUZvcm0oIHRoaXMuZm9ybSApO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgZGF0YSAgPSAgIHtcclxuICAgICAgICAgICAgICAgIC4uLnRoaXMuZm9ybVZhbGlkYXRpb24uZXh0cmFjdEZvcm0oIHRoaXMuZm9ybSApLCAuLi57XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHM6IHRoaXMuZm9ybS5wcm9kdWN0cy5tYXAoIHByb2R1Y3QgPT4gcHJvZHVjdC5wcm9jdXJlbWVudCApXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIG5zSHR0cENsaWVudFsgdGhpcy5zdWJtaXRNZXRob2QgPyB0aGlzLnN1Ym1pdE1ldGhvZC50b0xvd2VyQ2FzZSgpIDogJ3Bvc3QnIF0oIHRoaXMuc3VibWl0VXJsLCBkYXRhIClcclxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoIGRhdGEgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICggZGF0YS5zdGF0dXMgPT09ICdzdWNjZXNzJyApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50LmxvY2F0aW9uICAgPSAgIHRoaXMucmV0dXJuVXJsO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm1WYWxpZGF0aW9uLmVuYWJsZUZvcm0oIHRoaXMuZm9ybSApO1xyXG4gICAgICAgICAgICAgICAgfSwgKCBlcnJvciApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBuc1NuYWNrQmFyLmVycm9yKCBlcnJvci5tZXNzYWdlLCB1bmRlZmluZWQsIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IDUwMDBcclxuICAgICAgICAgICAgICAgICAgICB9KS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtVmFsaWRhdGlvbi5lbmFibGVGb3JtKCB0aGlzLmZvcm0gKTtcclxuICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIGVycm9yLmVycm9ycyApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtVmFsaWRhdGlvbi50cmlnZ2VyRXJyb3IoIHRoaXMuZm9ybSwgZXJyb3IuZXJyb3JzICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICB9LFxyXG4gICAgICAgIGRlbGV0ZVByb2R1Y3QoIGluZGV4ICkge1xyXG4gICAgICAgICAgICB0aGlzLmZvcm0ucHJvZHVjdHMuc3BsaWNlKCBpbmRleCwgMSApO1xyXG4gICAgICAgICAgICB0aGlzLiRmb3JjZVVwZGF0ZSgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgaGFuZGxlR2xvYmFsQ2hhbmdlKCBldmVudCApIHtcclxuICAgICAgICAgICAgdGhpcy5nbG9iYWxseUNoZWNrZWQgICAgPSAgIGV2ZW50O1xyXG4gICAgICAgICAgICB0aGlzLnJvd3MuZm9yRWFjaCggciA9PiByLiRjaGVja2VkID0gZXZlbnQgKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBzZXRQcm9kdWN0T3B0aW9ucyggaW5kZXggKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgICA9ICAgbmV3IFByb21pc2UoICggcmVzb2x2ZSwgcmVqZWN0ICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgUG9wdXAuc2hvdyggbnNQcm9jdXJlbWVudFByb2R1Y3RPcHRpb25zVnVlLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvZHVjdDogdGhpcy5mb3JtLnByb2R1Y3RzWyBpbmRleCBdLFxyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUsIFxyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdFxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBwcm9taXNlLnRoZW4oIHZhbHVlID0+IHtcclxuICAgICAgICAgICAgICAgIGZvciggbGV0IGtleSBpbiB2YWx1ZSApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0ucHJvZHVjdHNbIGluZGV4IF0ucHJvY3VyZW1lbnRbIGtleSBdICAgICAgPSAgIHZhbHVlWyBrZXkgXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUxpbmUoIGluZGV4ICk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG48L3NjcmlwdD5cclxuPHRlbXBsYXRlPlxyXG4gICAgPGRpdiBjbGFzcz1cImZvcm0gZmxleC1hdXRvIGZsZXggZmxleC1jb2xcIiBpZD1cImNydWQtZm9ybVwiPlxyXG4gICAgICAgIDx0ZW1wbGF0ZSB2LWlmPVwiZm9ybS5tYWluXCI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBqdXN0aWZ5LWJldHdlZW4gaXRlbXMtY2VudGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGZvcj1cInRpdGxlXCIgY2xhc3M9XCJmb250LWJvbGQgbXktMiB0ZXh0LWdyYXktNzAwXCI+PHNsb3QgbmFtZT1cInRpdGxlXCI+Tm8gdGl0bGUgUHJvdmlkZWQ8L3Nsb3Q+PC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGZvcj1cInRpdGxlXCIgY2xhc3M9XCJ0ZXh0LXNtIG15LTIgdGV4dC1ncmF5LTcwMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8YSB2LWlmPVwicmV0dXJuVXJsXCIgOmhyZWY9XCJyZXR1cm5VcmxcIiBjbGFzcz1cInJvdW5kZWQtZnVsbCBib3JkZXIgYm9yZGVyLWdyYXktNDAwIGhvdmVyOmJnLXJlZC02MDAgaG92ZXI6dGV4dC13aGl0ZSBiZy13aGl0ZSBweC0yIHB5LTFcIj5SZXR1cm48L2E+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDxkaXYgOmNsYXNzPVwiZm9ybS5tYWluLmRpc2FibGVkID8gJ2JvcmRlci1ncmF5LTUwMCcgOiBmb3JtLm1haW4uZXJyb3JzLmxlbmd0aCA+IDAgPyAnYm9yZGVyLXJlZC02MDAnIDogJ2JvcmRlci1ibHVlLTUwMCdcIiBjbGFzcz1cImZsZXggYm9yZGVyLTIgcm91bmRlZCBvdmVyZmxvdy1oaWRkZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdi1tb2RlbD1cImZvcm0ubWFpbi52YWx1ZVwiIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBAYmx1cj1cImZvcm1WYWxpZGF0aW9uLmNoZWNrRmllbGQoIGZvcm0ubWFpbiApXCIgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEBjaGFuZ2U9XCJmb3JtVmFsaWRhdGlvbi5jaGVja0ZpZWxkKCBmb3JtLm1haW4gKVwiIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6ZGlzYWJsZWQ9XCJmb3JtLm1haW4uZGlzYWJsZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6Y2xhc3M9XCJmb3JtLm1haW4uZGlzYWJsZWQgPyAnYmctZ3JheS00MDAnIDogJydcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXgtYXV0byB0ZXh0LWdyYXktNzAwIG91dGxpbmUtbm9uZSBoLTEwIHB4LTJcIj5cclxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIDpkaXNhYmxlZD1cImZvcm0ubWFpbi5kaXNhYmxlZFwiIDpjbGFzcz1cImZvcm0ubWFpbi5kaXNhYmxlZCA/ICdiZy1ncmF5LTUwMCcgOiBmb3JtLm1haW4uZXJyb3JzLmxlbmd0aCA+IDAgPyAnYmctcmVkLTUwMCcgOiAnYmctYmx1ZS01MDAnXCIgQGNsaWNrPVwic3VibWl0KClcIiBjbGFzcz1cIm91dGxpbmUtbm9uZSBweC00IGgtMTAgdGV4dC13aGl0ZSBib3JkZXItbCBib3JkZXItZ3JheS00MDBcIj48c2xvdCBuYW1lPVwic2F2ZVwiPlNhdmU8L3Nsb3Q+PC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBAY2xpY2s9XCJyZWxvYWRFbnRpdGllcygpXCIgY2xhc3M9XCJiZy13aGl0ZSB0ZXh0LWdyYXktNzAwIG91dGxpbmUtbm9uZSBweC00IGgtMTAgYm9yZGVyLWdyYXktNDAwXCI+PGkgOmNsYXNzPVwicmVsb2FkaW5nID8gJ2FuaW1hdGUgYW5pbWF0ZS1zcGluJyA6ICcnXCIgY2xhc3M9XCJsYXMgbGEtc3luY1wiPjwvaT48L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LXhzIHRleHQtZ3JheS02MDAgcHktMVwiIHYtaWY9XCJmb3JtLm1haW4uZGVzY3JpcHRpb24gJiYgZm9ybS5tYWluLmVycm9ycy5sZW5ndGggPT09IDBcIj57eyBmb3JtLm1haW4uZGVzY3JpcHRpb24gfX08L3A+XHJcbiAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQteHMgcHktMSB0ZXh0LXJlZC01MDBcIiB2LWJpbmQ6a2V5PVwiaW5kZXhcIiB2LWZvcj1cIihlcnJvciwgaW5kZXgpIG9mIGZvcm0ubWFpbi5lcnJvcnNcIj5cclxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj48c2xvdCBuYW1lPVwiZXJyb3ItcmVxdWlyZWRcIj57eyBlcnJvci5pZGVudGlmaWVyIH19PC9zbG90Pjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgIDwvcD5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgaWQ9XCJmb3JtLWNvbnRhaW5lclwiIGNsYXNzPVwiLW14LTQgZmxleCBmbGV4LXdyYXAgbXQtNFwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB4LTQgdy1mdWxsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD1cInRhYmJlZC1jYXJkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9XCJjYXJkLWhlYWRlclwiIGNsYXNzPVwiZmxleCBmbGV4LXdyYXBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgQGNsaWNrPVwic2V0VGFiQWN0aXZlKCB0YWIgKVwiIDpjbGFzcz1cInRhYi5hY3RpdmUgPyAnYmctd2hpdGUnIDogJ2JnLWdyYXktMTAwJ1wiIHYtZm9yPVwiKCB0YWIsIGluZGV4ICkgb2YgdmFsaWRUYWJzXCIgdi1iaW5kOmtleT1cImluZGV4XCIgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBweC00IHB5LTIgcm91bmRlZC10bC1sZyByb3VuZGVkLXRyLWxnIHRleHQtZ3JheS03MDBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyB0YWIubGFiZWwgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtYm9keSBiZy13aGl0ZSByb3VuZGVkLWJyLWxnIHJvdW5kZWQtYmwtbGcgc2hhZG93IHAtMlwiIHYtaWY9XCJhY3RpdmVUYWIuaWRlbnRpZmllciA9PT0gJ2RldGFpbHMnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiLW14LTQgZmxleCBmbGV4LXdyYXBcIiB2LWlmPVwiZm9ybS50YWJzXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggcHgtNCB3LWZ1bGwgbWQ6dy0xLzIgbGc6dy0xLzNcIiA6a2V5PVwiaW5kZXhcIiB2LWZvcj1cIihmaWVsZCwgaW5kZXgpIG9mIGZvcm0udGFicy5nZW5lcmFsLmZpZWxkc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bnMtZmllbGQgOmZpZWxkPVwiZmllbGRcIj48L25zLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1ib2R5IGJnLXdoaXRlIHJvdW5kZWQtYnItbGcgcm91bmRlZC1ibC1sZyBzaGFkb3cgcC0yIFwiIHYtaWY9XCJhY3RpdmVUYWIuaWRlbnRpZmllciA9PT0gJ3Byb2R1Y3RzJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm9yZGVyLWJsdWUtNTAwIGZsZXggYm9yZGVyLTIgcm91bmRlZCBvdmVyZmxvdy1oaWRkZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2LW1vZGVsPVwic2VhcmNoVmFsdWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDpwbGFjZWhvbGRlcj1cIiRzbG90c1sgJ3NlYXJjaC1wbGFjZWhvbGRlcicgXSA/ICRzbG90c1sgJ3NlYXJjaC1wbGFjZWhvbGRlcicgXVswXS50ZXh0IDogJ1NLVSwgQmFyY29kZSwgTmFtZSdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbGV4LWF1dG8gdGV4dC1ncmF5LTcwMCBvdXRsaW5lLW5vbmUgaC0xMCBweC0yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImgtMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2hhZG93IGJnLXdoaXRlIHJlbGF0aXZlIHotMTBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgQGNsaWNrPVwiYWRkUHJvZHVjdExpc3QoIHByb2R1Y3QgKVwiIHYtZm9yPVwiKHByb2R1Y3QsIGluZGV4KSBvZiBzZWFyY2hSZXN1bHRcIiA6a2V5PVwiaW5kZXhcIiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGJvcmRlciBib3JkZXItYiBib3JkZXItZ3JheS0zMDAgcC0yIHRleHQtZ3JheS03MDBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJsb2NrIGZvbnQtYm9sZCB0ZXh0LWdyYXktNzAwXCI+e3sgcHJvZHVjdC5uYW1lIH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmxvY2sgdGV4dC1zbSB0ZXh0LWdyYXktNjAwXCI+U0tVIDoge3sgcHJvZHVjdC5za3UgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJibG9jayB0ZXh0LXNtIHRleHQtZ3JheS02MDBcIj5CYXJjb2RlIDoge3sgcHJvZHVjdC5iYXJjb2RlIH19PC9zcGFuPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwib3ZlcmZsb3cteC1hdXRvXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwidy1mdWxsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aGVhZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgdi1mb3I9XCIoIGNvbHVtbiwga2V5ICkgb2YgZm9ybS5jb2x1bW5zXCIgd2lkdGg9XCIyMDBcIiA6a2V5PVwia2V5XCIgY2xhc3M9XCJ0ZXh0LWdyYXktNzAwIHAtMiBib3JkZXIgYm9yZGVyLWdyYXktMzAwIGJnLWdyYXktMjAwXCI+e3sgY29sdW1uLmxhYmVsIH19PC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGhlYWQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0Ym9keT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ciB2LWZvcj1cIiggcHJvZHVjdCwgaW5kZXggKSBvZiBmb3JtLnByb2R1Y3RzXCIgOmtleT1cImluZGV4XCIgOmNsYXNzPVwicHJvZHVjdC5wcm9jdXJlbWVudC4kaW52YWxpZCA/ICdiZy1yZWQtMjAwIGJvcmRlci0yIGJvcmRlci1yZWQtNTAwJyA6ICdiZy1ncmF5LTEwMCdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGVtcGxhdGUgdi1mb3I9XCIoIGNvbHVtbiwga2V5ICkgb2YgZm9ybS5jb2x1bW5zXCIgPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgOmtleT1cImtleVwiIHYtaWY9XCJjb2x1bW4udHlwZSA9PT0gJ25hbWUnXCIgY2xhc3M9XCJwLTIgdGV4dC1ncmF5LTYwMCBib3JkZXIgYm9yZGVyLWdyYXktMzAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZvbnQtc2VtaWJvbGRcIj57eyBwcm9kdWN0Lm5hbWUgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBqdXN0aWZ5LWJldHdlZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCAtbXgtMSBmbGV4LWNvbFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHgtMVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXhzIHRleHQtcmVkLTUwMCBjdXJzb3ItcG9pbnRlciB1bmRlcmxpbmUgcHgtMVwiIEBjbGljaz1cImRlbGV0ZVByb2R1Y3QoIGluZGV4IClcIj5EZWxldGU8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IC1teC0xIGZsZXgtY29sXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweC0xXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQteHMgdGV4dC1yZWQtNTAwIGN1cnNvci1wb2ludGVyIHVuZGVybGluZSBweC0xXCIgQGNsaWNrPVwic2V0UHJvZHVjdE9wdGlvbnMoIGluZGV4IClcIj5PcHRpb25zPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgOmtleT1cImtleVwiIHYtaWY9XCJjb2x1bW4udHlwZSA9PT0gJ3RleHQnXCIgY2xhc3M9XCJwLTIgdy0zIHRleHQtZ3JheS02MDAgYm9yZGVyIGJvcmRlci1ncmF5LTMwMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtc3RhcnRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgQGNoYW5nZT1cInVwZGF0ZUxpbmUoIGluZGV4IClcIiB0eXBlPVwidGV4dFwiIHYtbW9kZWw9XCJwcm9kdWN0LnByb2N1cmVtZW50WyBrZXkgXVwiIGNsYXNzPVwidy0yNCBib3JkZXItMiBwLTIgYm9yZGVyLWJsdWUtNDAwIHJvdW5kZWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgOmtleT1cImtleVwiIHYtaWY9XCJjb2x1bW4udHlwZSA9PT0gJ3RheF9ncm91cF9pZCdcIiBjbGFzcz1cInAtMiB0ZXh0LWdyYXktNjAwIGJvcmRlciBib3JkZXItZ3JheS0zMDBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLXN0YXJ0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBAY2hhbmdlPVwidXBkYXRlTGluZSggaW5kZXggKVwiIHYtbW9kZWw9XCJwcm9kdWN0LnByb2N1cmVtZW50LnRheF9ncm91cF9pZFwiIGNsYXNzPVwicm91bmRlZCBib3JkZXItYmx1ZS01MDAgYm9yZGVyLTIgcC0yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdi1mb3I9XCJvcHRpb24gb2YgdGF4ZXNcIiA6a2V5PVwib3B0aW9uLmlkXCIgOnZhbHVlPVwib3B0aW9uLmlkXCI+e3sgb3B0aW9uLm5hbWUgfX08L29wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgOmtleT1cImtleVwiIHYtaWY9XCJjb2x1bW4udHlwZSA9PT0gJ2N1c3RvbV9zZWxlY3QnXCIgY2xhc3M9XCJwLTIgdGV4dC1ncmF5LTYwMCBib3JkZXIgYm9yZGVyLWdyYXktMzAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgQGNoYW5nZT1cInVwZGF0ZUxpbmUoIGluZGV4IClcIiB2LW1vZGVsPVwicHJvZHVjdC5wcm9jdXJlbWVudFsga2V5IF1cIiBjbGFzcz1cInJvdW5kZWQgYm9yZGVyLWJsdWUtNTAwIGJvcmRlci0yIHAtMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHYtZm9yPVwib3B0aW9uIG9mIGNvbHVtbi5vcHRpb25zXCIgOmtleT1cIm9wdGlvbi52YWx1ZVwiIDp2YWx1ZT1cIm9wdGlvbi52YWx1ZVwiPnt7IG9wdGlvbi5sYWJlbCB9fTwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCA6a2V5PVwia2V5XCIgdi1pZj1cImNvbHVtbi50eXBlID09PSAnY3VycmVuY3knXCIgY2xhc3M9XCJwLTIgdGV4dC1ncmF5LTYwMCBib3JkZXIgYm9yZGVyLWdyYXktMzAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1zdGFydCBmbGV4LWNvbCBqdXN0aWZ5LWVuZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1zbSB0ZXh0LWdyYXktNjAwXCI+e3sgcHJvZHVjdC5wcm9jdXJlbWVudFsga2V5IF0gfCBjdXJyZW5jeSB9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgOmtleT1cImtleVwiIHYtaWY9XCJjb2x1bW4udHlwZSA9PT0gJ3VuaXRfcXVhbnRpdGllcydcIiBjbGFzcz1cInAtMiB0ZXh0LWdyYXktNjAwIGJvcmRlciBib3JkZXItZ3JheS0zMDBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLXN0YXJ0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCB2LW1vZGVsPVwicHJvZHVjdC5wcm9jdXJlbWVudC51bml0X2lkXCIgY2xhc3M9XCJyb3VuZGVkIGJvcmRlci1ibHVlLTUwMCBib3JkZXItMiBwLTIgdy0zMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHYtZm9yPVwib3B0aW9uIG9mIHByb2R1Y3QudW5pdF9xdWFudGl0aWVzXCIgOmtleT1cIm9wdGlvbi5pZFwiIDp2YWx1ZT1cIm9wdGlvbi51bml0LmlkXCI+e3sgb3B0aW9uLnVuaXQubmFtZSB9fTwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHIgY2xhc3M9XCJiZy1ncmF5LTEwMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInAtMiB0ZXh0LWdyYXktNjAwIGJvcmRlciBib3JkZXItZ3JheS0zMDBcIiA6Y29sc3Bhbj1cIk9iamVjdC5rZXlzKCBmb3JtLmNvbHVtbnMgKS5pbmRleE9mKCAndGF4X3ZhbHVlJyApXCI+PC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJwLTIgdGV4dC1ncmF5LTYwMCBib3JkZXIgYm9yZGVyLWdyYXktMzAwXCI+e3sgdG90YWxUYXhWYWx1ZXMgfCBjdXJyZW5jeSB9fTwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwicC0yIHRleHQtZ3JheS02MDAgYm9yZGVyIGJvcmRlci1ncmF5LTMwMFwiIDpjb2xzcGFuPVwiT2JqZWN0LmtleXMoIGZvcm0uY29sdW1ucyApLmluZGV4T2YoICd0b3RhbF9wdXJjaGFzZV9wcmljZScgKSAtICggT2JqZWN0LmtleXMoIGZvcm0uY29sdW1ucyApLmluZGV4T2YoICd0YXhfdmFsdWUnICkgKyAxIClcIj48L3RkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInAtMiB0ZXh0LWdyYXktNjAwIGJvcmRlciBib3JkZXItZ3JheS0zMDBcIj57eyB0b3RhbFB1cmNoYXNlUHJpY2UgfCBjdXJyZW5jeSB9fTwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGFibGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC90ZW1wbGF0ZT5cclxuICAgIDwvZGl2PlxyXG48L3RlbXBsYXRlPiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/ts/pages/dashboard/procurements/ns-procurement.vue?vue&type=script&lang=js&\n"); ->>>>>>> 3313f0bf34ae3b3550ee3b8ff27748899eebc41e /***/ }), @@ -280,11 +272,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _boo /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -<<<<<<< HEAD -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _libraries_form_validation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/libraries/form-validation */ \"./resources/ts/libraries/form-validation.ts\");\n/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/bootstrap */ \"./resources/ts/bootstrap.ts\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n name: 'ns-procurement-product-options',\n data: function data() {\n return {\n validation: new _libraries_form_validation__WEBPACK_IMPORTED_MODULE_0__[\"default\"](),\n fields: [],\n rawFields: [{\n label: 'Expiration Date',\n name: 'expiration',\n description: 'Define when that specific product should expire.',\n type: 'date'\n }, {\n label: 'Tax Type',\n name: 'tax_type',\n description: 'Adjust how tax is calculated on the item.',\n type: 'select',\n options: [{\n label: 'Inclusive',\n value: 'inclusive'\n }, {\n label: 'Exclusive',\n value: 'exclusive'\n }]\n }]\n };\n },\n methods: {\n applyChanges: function applyChanges() {\n var validation = this.validation.validateFields(this.fields);\n\n if (validation) {\n var fields = this.validation.extractFields(this.fields);\n this.$popupParams.resolve(fields);\n return this.$popup.close();\n }\n\n return _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error('Unable to proceed. The form is not valid.').subscribe();\n }\n },\n mounted: function mounted() {\n var _this = this;\n\n this.$popup.event.subscribe(function (action) {\n if (action.event === 'click-overlay') {\n _this.$popup.close();\n }\n });\n var fields = this.rawFields.map(function (field) {\n if (field.name === 'expiration') {\n field.value = _this.$popupParams.product.procurement.expiration;\n }\n\n if (field.name === 'tax_type') {\n field.value = _this.$popupParams.product.procurement.tax_type;\n }\n\n return field;\n });\n this.fields = this.validation.createFields(fields);\n }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcmVzb3VyY2VzL3RzL3BvcHVwcy9ucy1wcm9jdXJlbWVudC1wcm9kdWN0LW9wdGlvbnMudnVlPzI3MGUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQWNBO0FBQ0E7QUFDQTtBQUNBLHdDQURBO0FBRUEsTUFGQSxrQkFFQTtBQUNBO0FBQ0EsMEZBREE7QUFFQSxnQkFGQTtBQUdBLGtCQUNBO0FBQ0EsZ0NBREE7QUFFQSwwQkFGQTtBQUdBLHVFQUhBO0FBSUE7QUFKQSxPQURBLEVBTUE7QUFDQSx5QkFEQTtBQUVBLHdCQUZBO0FBR0EsZ0VBSEE7QUFJQSxzQkFKQTtBQUtBLGtCQUNBO0FBQ0EsNEJBREE7QUFFQTtBQUZBLFNBREEsRUFJQTtBQUNBLDRCQURBO0FBRUE7QUFGQSxTQUpBO0FBTEEsT0FOQTtBQUhBO0FBMEJBLEdBN0JBO0FBOEJBO0FBQ0EsZ0JBREEsMEJBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBRUE7QUFDQTtBQUNBOztBQUVBLHNIQUNBLFNBREE7QUFFQTtBQWJBLEdBOUJBO0FBNkNBLFNBN0NBLHFCQTZDQTtBQUFBOztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FKQTtBQU1BO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBVkE7QUFXQTtBQUNBO0FBaEVBIiwiZmlsZSI6Ii4vbm9kZV9tb2R1bGVzL2JhYmVsLWxvYWRlci9saWIvaW5kZXguanM/IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL2luZGV4LmpzPyEuL3Jlc291cmNlcy90cy9wb3B1cHMvbnMtcHJvY3VyZW1lbnQtcHJvZHVjdC1vcHRpb25zLnZ1ZT92dWUmdHlwZT1zY3JpcHQmbGFuZz1qcyYuanMiLCJzb3VyY2VzQ29udGVudCI6WyI8dGVtcGxhdGU+XHJcbiAgICA8ZGl2IGNsYXNzPVwiYmctd2hpdGUgc2hhZG93LWxnIHctNi83LXNjcmVlbiBtZDp3LTUvNy1zY3JlZW4gbGc6dy0zLzctc2NyZWVuXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInAtMiBib3JkZXItYiBib3JkZXItZ3JheS0yMDBcIj5cclxuICAgICAgICAgICAgPGg1IGNsYXNzPVwiZm9udC1zZW1pYm9sZFwiPk9wdGlvbnM8L2g1PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJwLTIgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwXCI+XHJcbiAgICAgICAgICAgIDxucy1maWVsZCBjbGFzcz1cInctZnVsbFwiIDpmaWVsZD1cImZpZWxkXCIgdi1mb3I9XCIoZmllbGQsaW5kZXgpIG9mIGZpZWxkc1wiIDprZXk9XCJpbmRleFwiPjwvbnMtZmllbGQ+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInAtMiBmbGV4IGp1c3RpZnktZW5kXCI+XHJcbiAgICAgICAgICAgIDxucy1idXR0b24gQGNsaWNrPVwiYXBwbHlDaGFuZ2VzKClcIiB0eXBlPVwiaW5mb1wiPlNhdmU8L25zLWJ1dHRvbj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG48L3RlbXBsYXRlPlxyXG48c2NyaXB0PlxyXG5pbXBvcnQgRm9ybVZhbGlkYXRpb24gZnJvbSAnQC9saWJyYXJpZXMvZm9ybS12YWxpZGF0aW9uJztcclxuaW1wb3J0IHsgbnNTbmFja0JhciB9IGZyb20gJ0AvYm9vdHN0cmFwJztcclxuZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgbmFtZTogJ25zLXByb2N1cmVtZW50LXByb2R1Y3Qtb3B0aW9ucycsXHJcbiAgICBkYXRhKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZhbGlkYXRpb246IG5ldyBGb3JtVmFsaWRhdGlvbixcclxuICAgICAgICAgICAgZmllbGRzOiBbXSxcclxuICAgICAgICAgICAgcmF3RmllbGRzOiBbXHJcbiAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICdFeHBpcmF0aW9uIERhdGUnLFxyXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdleHBpcmF0aW9uJyxcclxuICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ0RlZmluZSB3aGVuIHRoYXQgc3BlY2lmaWMgcHJvZHVjdCBzaG91bGQgZXhwaXJlLicsXHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2RhdGUnLFxyXG4gICAgICAgICAgICAgICAgfSwge1xyXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiAnVGF4IFR5cGUnLFxyXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICd0YXhfdHlwZScsXHJcbiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdBZGp1c3QgaG93IHRheCBpcyBjYWxjdWxhdGVkIG9uIHRoZSBpdGVtLicsXHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3NlbGVjdCcsXHJcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9uczogW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogJ0luY2x1c2l2ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogJ2luY2x1c2l2ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiAnRXhjbHVzaXZlJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiAnZXhjbHVzaXZlJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIF0sXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF1cclxuICAgICAgICB9XHJcbiAgICB9LCAgXHJcbiAgICBtZXRob2RzOiB7XHJcbiAgICAgICAgYXBwbHlDaGFuZ2VzKCkge1xyXG4gICAgICAgICAgICBjb25zdCB2YWxpZGF0aW9uICAgID0gICB0aGlzLnZhbGlkYXRpb24udmFsaWRhdGVGaWVsZHMoIHRoaXMuZmllbGRzICk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBpZiAoIHZhbGlkYXRpb24gKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBmaWVsZHMgICAgPSAgIHRoaXMudmFsaWRhdGlvbi5leHRyYWN0RmllbGRzKCB0aGlzLmZpZWxkcyApO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuJHBvcHVwUGFyYW1zLnJlc29sdmUoIGZpZWxkcyApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuJHBvcHVwLmNsb3NlKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBuc1NuYWNrQmFyLmVycm9yKCAnVW5hYmxlIHRvIHByb2NlZWQuIFRoZSBmb3JtIGlzIG5vdCB2YWxpZC4nIClcclxuICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKTtcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG4gICAgbW91bnRlZCgpIHtcclxuICAgICAgICB0aGlzLiRwb3B1cC5ldmVudC5zdWJzY3JpYmUoIGFjdGlvbiA9PiB7XHJcbiAgICAgICAgICAgIGlmICggYWN0aW9uLmV2ZW50ID09PSAnY2xpY2stb3ZlcmxheScgKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLiRwb3B1cC5jbG9zZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGNvbnN0IGZpZWxkcyAgICA9ICAgdGhpcy5yYXdGaWVsZHMubWFwKCBmaWVsZCA9PiB7XHJcbiAgICAgICAgICAgIGlmICggZmllbGQubmFtZSA9PT0gJ2V4cGlyYXRpb24nICkge1xyXG4gICAgICAgICAgICAgICAgZmllbGQudmFsdWUgICAgPSAgIHRoaXMuJHBvcHVwUGFyYW1zLnByb2R1Y3QucHJvY3VyZW1lbnQuZXhwaXJhdGlvblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIGZpZWxkLm5hbWUgPT09ICd0YXhfdHlwZScgKSB7XHJcbiAgICAgICAgICAgICAgICBmaWVsZC52YWx1ZSAgICA9ICAgdGhpcy4kcG9wdXBQYXJhbXMucHJvZHVjdC5wcm9jdXJlbWVudC50YXhfdHlwZVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gZmllbGQ7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5maWVsZHMgICAgID0gICB0aGlzLnZhbGlkYXRpb24uY3JlYXRlRmllbGRzKCBmaWVsZHMgKTtcclxuICAgIH1cclxufVxyXG48L3NjcmlwdD4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/ts/popups/ns-procurement-product-options.vue?vue&type=script&lang=js&\n"); -======= eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _libraries_form_validation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/libraries/form-validation */ \"./resources/ts/libraries/form-validation.ts\");\n/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/bootstrap */ \"./resources/ts/bootstrap.ts\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n name: 'ns-procurement-product-options',\n data: function data() {\n return {\n validation: new _libraries_form_validation__WEBPACK_IMPORTED_MODULE_0__[\"default\"](),\n fields: [],\n rawFields: [{\n label: 'Expiration Date',\n name: 'expiration_date',\n description: 'Define when that specific product should expire.',\n type: 'datetimepicker'\n }, {\n label: 'Barcode',\n name: 'barcode',\n description: 'Renders the automatically generated barcode.',\n type: 'text',\n disabled: true\n }, {\n label: 'Tax Type',\n name: 'tax_type',\n description: 'Adjust how tax is calculated on the item.',\n type: 'select',\n options: [{\n label: 'Inclusive',\n value: 'inclusive'\n }, {\n label: 'Exclusive',\n value: 'exclusive'\n }]\n }]\n };\n },\n methods: {\n applyChanges: function applyChanges() {\n var validation = this.validation.validateFields(this.fields);\n\n if (validation) {\n var fields = this.validation.extractFields(this.fields);\n this.$popupParams.resolve(fields);\n return this.$popup.close();\n }\n\n return _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error('Unable to proceed. The form is not valid.').subscribe();\n }\n },\n mounted: function mounted() {\n var _this = this;\n\n this.$popup.event.subscribe(function (action) {\n if (action.event === 'click-overlay') {\n _this.$popup.close();\n }\n });\n var fields = this.rawFields.map(function (field) {\n if (field.name === 'expiration_date') {\n field.value = _this.$popupParams.product.procurement.expiration_date;\n }\n\n if (field.name === 'tax_type') {\n field.value = _this.$popupParams.product.procurement.tax_type;\n }\n\n if (field.name === 'barcode') {\n field.value = _this.$popupParams.product.procurement.barcode;\n }\n\n return field;\n });\n this.fields = this.validation.createFields(fields);\n }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcmVzb3VyY2VzL3RzL3BvcHVwcy9ucy1wcm9jdXJlbWVudC1wcm9kdWN0LW9wdGlvbnMudnVlPzI3MGUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQWNBO0FBQ0E7QUFDQTtBQUNBLHdDQURBO0FBRUEsTUFGQSxrQkFFQTtBQUNBO0FBQ0EsMEZBREE7QUFFQSxnQkFGQTtBQUdBLGtCQUNBO0FBQ0EsZ0NBREE7QUFFQSwrQkFGQTtBQUdBLHVFQUhBO0FBSUE7QUFKQSxPQURBLEVBTUE7QUFDQSx3QkFEQTtBQUVBLHVCQUZBO0FBR0EsbUVBSEE7QUFJQSxvQkFKQTtBQUtBO0FBTEEsT0FOQSxFQVlBO0FBQ0EseUJBREE7QUFFQSx3QkFGQTtBQUdBLGdFQUhBO0FBSUEsc0JBSkE7QUFLQSxrQkFDQTtBQUNBLDRCQURBO0FBRUE7QUFGQSxTQURBLEVBSUE7QUFDQSw0QkFEQTtBQUVBO0FBRkEsU0FKQTtBQUxBLE9BWkE7QUFIQTtBQWdDQSxHQW5DQTtBQW9DQTtBQUNBLGdCQURBLDBCQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUVBO0FBQ0E7QUFDQTs7QUFFQSxzSEFDQSxTQURBO0FBRUE7QUFiQSxHQXBDQTtBQW1EQSxTQW5EQSxxQkFtREE7QUFBQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBSkE7QUFNQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FkQTtBQWdCQTtBQUNBO0FBM0VBIiwiZmlsZSI6Ii4vbm9kZV9tb2R1bGVzL2JhYmVsLWxvYWRlci9saWIvaW5kZXguanM/IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL2luZGV4LmpzPyEuL3Jlc291cmNlcy90cy9wb3B1cHMvbnMtcHJvY3VyZW1lbnQtcHJvZHVjdC1vcHRpb25zLnZ1ZT92dWUmdHlwZT1zY3JpcHQmbGFuZz1qcyYuanMiLCJzb3VyY2VzQ29udGVudCI6WyI8dGVtcGxhdGU+XHJcbiAgICA8ZGl2IGNsYXNzPVwiYmctd2hpdGUgc2hhZG93LWxnIHctNi83LXNjcmVlbiBtZDp3LTUvNy1zY3JlZW4gbGc6dy0zLzctc2NyZWVuXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInAtMiBib3JkZXItYiBib3JkZXItZ3JheS0yMDBcIj5cclxuICAgICAgICAgICAgPGg1IGNsYXNzPVwiZm9udC1zZW1pYm9sZFwiPk9wdGlvbnM8L2g1PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJwLTIgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwXCI+XHJcbiAgICAgICAgICAgIDxucy1maWVsZCBjbGFzcz1cInctZnVsbFwiIDpmaWVsZD1cImZpZWxkXCIgdi1mb3I9XCIoZmllbGQsaW5kZXgpIG9mIGZpZWxkc1wiIDprZXk9XCJpbmRleFwiPjwvbnMtZmllbGQ+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInAtMiBmbGV4IGp1c3RpZnktZW5kXCI+XHJcbiAgICAgICAgICAgIDxucy1idXR0b24gQGNsaWNrPVwiYXBwbHlDaGFuZ2VzKClcIiB0eXBlPVwiaW5mb1wiPlNhdmU8L25zLWJ1dHRvbj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG48L3RlbXBsYXRlPlxyXG48c2NyaXB0PlxyXG5pbXBvcnQgRm9ybVZhbGlkYXRpb24gZnJvbSAnQC9saWJyYXJpZXMvZm9ybS12YWxpZGF0aW9uJztcclxuaW1wb3J0IHsgbnNTbmFja0JhciB9IGZyb20gJ0AvYm9vdHN0cmFwJztcclxuZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgbmFtZTogJ25zLXByb2N1cmVtZW50LXByb2R1Y3Qtb3B0aW9ucycsXHJcbiAgICBkYXRhKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHZhbGlkYXRpb246IG5ldyBGb3JtVmFsaWRhdGlvbixcclxuICAgICAgICAgICAgZmllbGRzOiBbXSxcclxuICAgICAgICAgICAgcmF3RmllbGRzOiBbXHJcbiAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICdFeHBpcmF0aW9uIERhdGUnLFxyXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdleHBpcmF0aW9uX2RhdGUnLFxyXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnRGVmaW5lIHdoZW4gdGhhdCBzcGVjaWZpYyBwcm9kdWN0IHNob3VsZCBleHBpcmUuJyxcclxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnZGF0ZXRpbWVwaWNrZXInLFxyXG4gICAgICAgICAgICAgICAgfSwge1xyXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiAnQmFyY29kZScsXHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2JhcmNvZGUnLFxyXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUmVuZGVycyB0aGUgYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYmFyY29kZS4nLFxyXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcclxuICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIH0sIHtcclxuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJ1RheCBUeXBlJyxcclxuICAgICAgICAgICAgICAgICAgICBuYW1lOiAndGF4X3R5cGUnLFxyXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQWRqdXN0IGhvdyB0YXggaXMgY2FsY3VsYXRlZCBvbiB0aGUgaXRlbS4nLFxyXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdzZWxlY3QnLFxyXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICdJbmNsdXNpdmUnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6ICdpbmNsdXNpdmUnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogJ0V4Y2x1c2l2ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogJ2V4Y2x1c2l2ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBdLFxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBdXHJcbiAgICAgICAgfVxyXG4gICAgfSwgIFxyXG4gICAgbWV0aG9kczoge1xyXG4gICAgICAgIGFwcGx5Q2hhbmdlcygpIHtcclxuICAgICAgICAgICAgY29uc3QgdmFsaWRhdGlvbiAgICA9ICAgdGhpcy52YWxpZGF0aW9uLnZhbGlkYXRlRmllbGRzKCB0aGlzLmZpZWxkcyApO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgaWYgKCB2YWxpZGF0aW9uICkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZmllbGRzICAgID0gICB0aGlzLnZhbGlkYXRpb24uZXh0cmFjdEZpZWxkcyggdGhpcy5maWVsZHMgKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLiRwb3B1cFBhcmFtcy5yZXNvbHZlKCBmaWVsZHMgKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLiRwb3B1cC5jbG9zZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gbnNTbmFja0Jhci5lcnJvciggJ1VuYWJsZSB0byBwcm9jZWVkLiBUaGUgZm9ybSBpcyBub3QgdmFsaWQuJyApXHJcbiAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIG1vdW50ZWQoKSB7XHJcbiAgICAgICAgdGhpcy4kcG9wdXAuZXZlbnQuc3Vic2NyaWJlKCBhY3Rpb24gPT4ge1xyXG4gICAgICAgICAgICBpZiAoIGFjdGlvbi5ldmVudCA9PT0gJ2NsaWNrLW92ZXJsYXknICkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy4kcG9wdXAuY2xvc2UoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBjb25zdCBmaWVsZHMgICAgPSAgIHRoaXMucmF3RmllbGRzLm1hcCggZmllbGQgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIGZpZWxkLm5hbWUgPT09ICdleHBpcmF0aW9uX2RhdGUnICkge1xyXG4gICAgICAgICAgICAgICAgZmllbGQudmFsdWUgICAgPSAgIHRoaXMuJHBvcHVwUGFyYW1zLnByb2R1Y3QucHJvY3VyZW1lbnQuZXhwaXJhdGlvbl9kYXRlXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICggZmllbGQubmFtZSA9PT0gJ3RheF90eXBlJyApIHtcclxuICAgICAgICAgICAgICAgIGZpZWxkLnZhbHVlICAgID0gICB0aGlzLiRwb3B1cFBhcmFtcy5wcm9kdWN0LnByb2N1cmVtZW50LnRheF90eXBlXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICggZmllbGQubmFtZSA9PT0gJ2JhcmNvZGUnICkge1xyXG4gICAgICAgICAgICAgICAgZmllbGQudmFsdWUgICAgPSAgIHRoaXMuJHBvcHVwUGFyYW1zLnByb2R1Y3QucHJvY3VyZW1lbnQuYmFyY29kZVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gZmllbGQ7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMuZmllbGRzICAgICA9ICAgdGhpcy52YWxpZGF0aW9uLmNyZWF0ZUZpZWxkcyggZmllbGRzICk7XHJcbiAgICB9XHJcbn1cclxuPC9zY3JpcHQ+Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/ts/popups/ns-procurement-product-options.vue?vue&type=script&lang=js&\n"); ->>>>>>> 3313f0bf34ae3b3550ee3b8ff27748899eebc41e /***/ }), diff --git a/public/js/pos-init.js b/public/js/pos-init.js index 9e05751ca..4cb5b0e18 100755 --- a/public/js/pos-init.js +++ b/public/js/pos-init.js @@ -176,11 +176,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _boo /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -<<<<<<< HEAD -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/bootstrap */ \"./resources/ts/bootstrap.ts\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n data: function data() {\n return {\n unitsQuantities: []\n };\n },\n mounted: function mounted() {\n var _this = this;\n\n this.$popup.event.subscribe(function (action) {\n if (action.event === 'click-overlay') {\n /**\r\n * as this runs under a Promise\r\n * we need to make sure that\r\n * it resolve false using the \"resolve\" function\r\n * provided as $popupParams.\r\n * Here we resolve \"false\" as the user has broken the Promise\r\n */\n _this.$popupParams.reject(false);\n /**\r\n * we can safely close the popup.\r\n */\n\n\n _this.$popup.close();\n }\n });\n this.loadUnits();\n },\n methods: {\n loadUnits: function loadUnits() {\n var _this2 = this;\n\n _bootstrap__WEBPACK_IMPORTED_MODULE_0__[\"nsHttpClient\"].get(\"/api/nexopos/v4/products/\".concat(this.$popupParams.product.$original().id, \"/units/quantities\")).subscribe(function (result) {\n if (result.length === 0) {\n _this2.$popup.close();\n\n return _bootstrap__WEBPACK_IMPORTED_MODULE_0__[\"nsSnackBar\"].error('This product doesn\\'t has any unit defined for selling.').subscribe();\n }\n\n _this2.unitsQuantities = result;\n /**\r\n * This will automatically\r\n * select a unit if there is only one unit available.\r\n */\n\n if (_this2.unitsQuantities.length === 1) {\n _this2.selectUnit(_this2.unitsQuantities[0]);\n }\n });\n },\n\n /**\r\n * we'll resolve a value that\r\n * will be added to the object\r\n * built at the end\r\n * @param Unit\r\n */\n selectUnit: function selectUnit(unitQuantity) {\n this.$popupParams.resolve({\n unit_quantity_id: unitQuantity.id,\n unit_name: unitQuantity.unit.name,\n $quantities: function $quantities() {\n return unitQuantity;\n }\n });\n this.$popup.close(); // this.types.forEach( type => type.selected = false );\n // type.selected = true;\n // POS.order.types.next( this.types );\n }\n }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcmVzb3VyY2VzL3RzL3BvcHVwcy9ucy1wb3MtdW5pdHMudnVlPzNmNWIiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTJCQTtBQUNBO0FBQ0EsTUFEQSxrQkFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBLEdBTEE7QUFNQSxTQU5BLHFCQU1BO0FBQUE7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7OztBQUNBO0FBQ0E7QUFDQSxLQWhCQTtBQWtCQTtBQUNBLEdBMUJBO0FBMkJBO0FBQ0EsYUFEQSx1QkFDQTtBQUFBOztBQUNBLHFLQUNBLFNBREEsQ0FDQTtBQUVBO0FBQ0E7O0FBQ0E7QUFDQTs7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BakJBO0FBa0JBLEtBcEJBOztBQXFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQTNCQSxzQkEyQkEsWUEzQkEsRUEyQkE7QUFDQTtBQUNBLHlDQURBO0FBRUEseUNBRkE7QUFHQTtBQUFBO0FBQUE7QUFIQTtBQUtBLDBCQU5BLENBT0E7QUFDQTtBQUNBO0FBQ0E7QUFyQ0E7QUEzQkEiLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYmFiZWwtbG9hZGVyL2xpYi9pbmRleC5qcz8hLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvaW5kZXguanM/IS4vcmVzb3VyY2VzL3RzL3BvcHVwcy9ucy1wb3MtdW5pdHMudnVlP3Z1ZSZ0eXBlPXNjcmlwdCZsYW5nPWpzJi5qcyIsInNvdXJjZXNDb250ZW50IjpbIjx0ZW1wbGF0ZT5cclxuICAgIDxkaXYgY2xhc3M9XCJiZy13aGl0ZSB3LTIvMy1zY3JlZW4gbGc6dy0xLzMtc2NyZWVuIG92ZXJmbG93LWhpZGRlbiBmbGV4IGZsZXgtY29sXCI+XHJcbiAgICAgICAgPGRpdiBpZD1cImhlYWRlclwiIGNsYXNzPVwiaC0xNiBmbGV4IGp1c3RpZnktY2VudGVyIGl0ZW1zLWNlbnRlciBmbGV4LXNocmluay0wXCI+XHJcbiAgICAgICAgICAgIDxoMyBjbGFzcz1cImZvbnQtYm9sZCB0ZXh0LWdyYXktNzAwXCI+Q2hvb3NlIFNlbGxpbmcgVW5pdDwvaDM+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGRpdiB2LWlmPVwidW5pdHNRdWFudGl0aWVzLmxlbmd0aCA+IDBcIiBjbGFzcz1cImdyaWQgZ3JpZC1mbG93LXJvdyBncmlkLWNvbHMtMiBvdmVyZmxvdy15LWF1dG9cIj5cclxuICAgICAgICAgICAgPGRpdiBAY2xpY2s9XCJzZWxlY3RVbml0KCB1bml0UXVhbnRpdHkgKVwiIDprZXk9XCJ1bml0UXVhbnRpdHkuaWRcIiB2LWZvcj1cInVuaXRRdWFudGl0eSBvZiB1bml0c1F1YW50aXRpZXNcIiBjbGFzcz1cImhvdmVyOmJnLWdyYXktMjAwIGN1cnNvci1wb2ludGVyIGJvcmRlciBmbGV4LXNocmluay0wIGJvcmRlci1ncmF5LTIwMCBmbGV4IGZsZXgtY29sIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImgtNDAgdy1mdWxsIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIG92ZXJmbG93LWhpZGRlblwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxpbWcgdi1pZj1cInVuaXRRdWFudGl0eS5wcmV2aWV3X3VybFwiIDpzcmM9XCJ1bml0UXVhbnRpdHkucHJldmlld191cmxcIiBjbGFzcz1cIm9iamVjdC1jb3ZlciBoLWZ1bGxcIiA6YWx0PVwidW5pdFF1YW50aXR5LnVuaXQubmFtZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoLTQwIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCIgdi1pZj1cIiEgdW5pdFF1YW50aXR5LnByZXZpZXdfdXJsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGFzIGxhLWltYWdlIHRleHQtZ3JheS02MDAgdGV4dC02eGxcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoLTAgdy1mdWxsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlbGF0aXZlIHctZnVsbCBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciAtdG9wLTEwIGgtMjAgcHktMiBmbGV4LWNvbFwiIHN0eWxlPVwiYmFja2dyb3VuZDpyZ2IoMjU1IDI1NSAyNTUgLyA3MyUpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cImZvbnQtYm9sZCB0ZXh0LWdyYXktNzAwIHB5LTIgdGV4dC1jZW50ZXJcIj57eyB1bml0UXVhbnRpdHkudW5pdC5uYW1lIH19ICh7eyB1bml0UXVhbnRpdHkgLnF1YW50aXR5IH19KTwvaDM+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNjAwXCI+e3sgdW5pdFF1YW50aXR5LnNhbGVfcHJpY2UgfCBjdXJyZW5jeSB9fTwvcD5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiaC01NiBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlclwiIHYtaWY9XCJ1bml0c1F1YW50aXRpZXMubGVuZ3RoID09PSAwXCI+XHJcbiAgICAgICAgICAgIDxucy1zcGlubmVyPjwvbnMtc3Bpbm5lcj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG48L3RlbXBsYXRlPlxyXG48c2NyaXB0PlxyXG5pbXBvcnQgeyBuc0h0dHBDbGllbnQsIG5zU25hY2tCYXIgfSBmcm9tICdAL2Jvb3RzdHJhcCc7XHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIGRhdGEoKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdW5pdHNRdWFudGl0aWVzOiBbXVxyXG4gICAgICAgIH1cclxuICAgIH0sXHJcbiAgICBtb3VudGVkKCkge1xyXG4gICAgICAgIHRoaXMuJHBvcHVwLmV2ZW50LnN1YnNjcmliZSggYWN0aW9uID0+IHtcclxuICAgICAgICAgICAgaWYgKCBhY3Rpb24uZXZlbnQgPT09ICdjbGljay1vdmVybGF5JyApIHtcclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogYXMgdGhpcyBydW5zIHVuZGVyIGEgUHJvbWlzZVxyXG4gICAgICAgICAgICAgICAgICogd2UgbmVlZCB0byBtYWtlIHN1cmUgdGhhdFxyXG4gICAgICAgICAgICAgICAgICogaXQgcmVzb2x2ZSBmYWxzZSB1c2luZyB0aGUgXCJyZXNvbHZlXCIgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAqIHByb3ZpZGVkIGFzICRwb3B1cFBhcmFtcy5cclxuICAgICAgICAgICAgICAgICAqIEhlcmUgd2UgcmVzb2x2ZSBcImZhbHNlXCIgYXMgdGhlIHVzZXIgaGFzIGJyb2tlbiB0aGUgUHJvbWlzZVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICB0aGlzLiRwb3B1cFBhcmFtcy5yZWplY3QoIGZhbHNlICk7XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiB3ZSBjYW4gc2FmZWx5IGNsb3NlIHRoZSBwb3B1cC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgdGhpcy4kcG9wdXAuY2xvc2UoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLmxvYWRVbml0cygpO1xyXG4gICAgfSxcclxuICAgIG1ldGhvZHM6IHtcclxuICAgICAgICBsb2FkVW5pdHMoKSB7XHJcbiAgICAgICAgICAgIG5zSHR0cENsaWVudC5nZXQoIGAvYXBpL25leG9wb3MvdjQvcHJvZHVjdHMvJHt0aGlzLiRwb3B1cFBhcmFtcy5wcm9kdWN0LiRvcmlnaW5hbCgpLmlkfS91bml0cy9xdWFudGl0aWVzYCApXHJcbiAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCByZXN1bHQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIGlmICggcmVzdWx0Lmxlbmd0aCA9PT0gMCApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kcG9wdXAuY2xvc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5zU25hY2tCYXIuZXJyb3IoICdUaGlzIHByb2R1Y3QgZG9lc25cXCd0IGhhcyBhbnkgdW5pdCBkZWZpbmVkIGZvciBzZWxsaW5nLicgKS5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudW5pdHNRdWFudGl0aWVzICA9ICAgcmVzdWx0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAgICAgKiBUaGlzIHdpbGwgYXV0b21hdGljYWxseVxyXG4gICAgICAgICAgICAgICAgICAgICAqIHNlbGVjdCBhIHVuaXQgaWYgdGhlcmUgaXMgb25seSBvbmUgdW5pdCBhdmFpbGFibGUuXHJcbiAgICAgICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCB0aGlzLnVuaXRzUXVhbnRpdGllcy5sZW5ndGggPT09IDEgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0VW5pdCggdGhpcy51bml0c1F1YW50aXRpZXNbMF0gKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogd2UnbGwgcmVzb2x2ZSBhIHZhbHVlIHRoYXRcclxuICAgICAgICAgKiB3aWxsIGJlIGFkZGVkIHRvIHRoZSBvYmplY3RcclxuICAgICAgICAgKiBidWlsdCBhdCB0aGUgZW5kXHJcbiAgICAgICAgICogQHBhcmFtIFVuaXRcclxuICAgICAgICAgKi9cclxuICAgICAgICBzZWxlY3RVbml0KCB1bml0UXVhbnRpdHkgKSB7XHJcbiAgICAgICAgICAgIHRoaXMuJHBvcHVwUGFyYW1zLnJlc29sdmUoe1xyXG4gICAgICAgICAgICAgICAgdW5pdF9xdWFudGl0eV9pZCAgICA6ICAgdW5pdFF1YW50aXR5LmlkLFxyXG4gICAgICAgICAgICAgICAgdW5pdF9uYW1lICAgICAgICAgICA6ICAgdW5pdFF1YW50aXR5LnVuaXQubmFtZSxcclxuICAgICAgICAgICAgICAgICRxdWFudGl0aWVzICAgICAgICAgOiAgICgpID0+IHVuaXRRdWFudGl0eVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy4kcG9wdXAuY2xvc2UoKTtcclxuICAgICAgICAgICAgLy8gdGhpcy50eXBlcy5mb3JFYWNoKCB0eXBlID0+IHR5cGUuc2VsZWN0ZWQgPSBmYWxzZSApO1xyXG4gICAgICAgICAgICAvLyB0eXBlLnNlbGVjdGVkICAgPSAgIHRydWU7XHJcbiAgICAgICAgICAgIC8vIFBPUy5vcmRlci50eXBlcy5uZXh0KCB0aGlzLnR5cGVzICk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbjwvc2NyaXB0PiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/ts/popups/ns-pos-units.vue?vue&type=script&lang=js&\n"); -======= eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/bootstrap */ \"./resources/ts/bootstrap.ts\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n data: function data() {\n return {\n unitsQuantities: [],\n loadsUnits: false\n };\n },\n mounted: function mounted() {\n var _this = this;\n\n this.$popup.event.subscribe(function (action) {\n if (action.event === 'click-overlay') {\n /**\r\n * as this runs under a Promise\r\n * we need to make sure that\r\n * it resolve false using the \"resolve\" function\r\n * provided as $popupParams.\r\n * Here we resolve \"false\" as the user has broken the Promise\r\n */\n _this.$popupParams.reject(false);\n /**\r\n * we can safely close the popup.\r\n */\n\n\n _this.$popup.close();\n }\n });\n /**\r\n * If there is a default selected unit quantity\r\n * provided, we assume the product was added using the unit\r\n * quantity barcode.\r\n */\n\n if (this.$popupParams.product.$original().selectedUnitQuantity !== undefined) {\n this.selectUnit(this.$popupParams.product.$original().selectedUnitQuantity);\n } else {\n this.loadsUnits = true;\n this.loadUnits();\n }\n },\n methods: {\n loadUnits: function loadUnits() {\n var _this2 = this;\n\n _bootstrap__WEBPACK_IMPORTED_MODULE_0__[\"nsHttpClient\"].get(\"/api/nexopos/v4/products/\".concat(this.$popupParams.product.$original().id, \"/units/quantities\")).subscribe(function (result) {\n if (result.length === 0) {\n _this2.$popup.close();\n\n return _bootstrap__WEBPACK_IMPORTED_MODULE_0__[\"nsSnackBar\"].error('This product doesn\\'t has any unit defined for selling.').subscribe();\n }\n\n _this2.unitsQuantities = result;\n /**\r\n * This will automatically\r\n * select a unit if there is only one unit available.\r\n */\n\n if (_this2.unitsQuantities.length === 1) {\n _this2.selectUnit(_this2.unitsQuantities[0]);\n }\n });\n },\n\n /**\r\n * we'll resolve a value that\r\n * will be added to the object\r\n * built at the end\r\n * @param Unit\r\n */\n selectUnit: function selectUnit(unitQuantity) {\n this.$popupParams.resolve({\n unit_quantity_id: unitQuantity.id,\n unit_name: unitQuantity.unit.name,\n $quantities: function $quantities() {\n return unitQuantity;\n }\n });\n this.$popup.close(); // this.types.forEach( type => type.selected = false );\n // type.selected = true;\n // POS.order.types.next( this.types );\n }\n }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcmVzb3VyY2VzL3RzL3BvcHVwcy9ucy1wb3MtdW5pdHMudnVlPzNmNWIiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTJCQTtBQUNBO0FBQ0EsTUFEQSxrQkFDQTtBQUNBO0FBQ0EseUJBREE7QUFFQTtBQUZBO0FBSUEsR0FOQTtBQU9BLFNBUEEscUJBT0E7QUFBQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTs7O0FBQ0E7QUFDQTtBQUNBLEtBaEJBO0FBa0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBQ0E7QUFDQTtBQUNBLEtBRkEsTUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBckNBO0FBc0NBO0FBQ0EsYUFEQSx1QkFDQTtBQUFBOztBQUNBLHFLQUNBLFNBREEsQ0FDQTtBQUVBO0FBQ0E7O0FBQ0E7QUFDQTs7QUFFQTtBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BakJBO0FBa0JBLEtBcEJBOztBQXFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQTNCQSxzQkEyQkEsWUEzQkEsRUEyQkE7QUFDQTtBQUNBLHlDQURBO0FBRUEseUNBRkE7QUFHQTtBQUFBO0FBQUE7QUFIQTtBQUtBLDBCQU5BLENBT0E7QUFDQTtBQUNBO0FBQ0E7QUFyQ0E7QUF0Q0EiLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYmFiZWwtbG9hZGVyL2xpYi9pbmRleC5qcz8hLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvaW5kZXguanM/IS4vcmVzb3VyY2VzL3RzL3BvcHVwcy9ucy1wb3MtdW5pdHMudnVlP3Z1ZSZ0eXBlPXNjcmlwdCZsYW5nPWpzJi5qcyIsInNvdXJjZXNDb250ZW50IjpbIjx0ZW1wbGF0ZT5cclxuICAgIDxkaXYgY2xhc3M9XCJiZy13aGl0ZSB3LTIvMy1zY3JlZW4gbGc6dy0xLzMtc2NyZWVuIG92ZXJmbG93LWhpZGRlbiBmbGV4IGZsZXgtY29sXCIgdi1pZj1cImxvYWRzVW5pdHNcIj5cclxuICAgICAgICA8ZGl2IGlkPVwiaGVhZGVyXCIgY2xhc3M9XCJoLTE2IGZsZXgganVzdGlmeS1jZW50ZXIgaXRlbXMtY2VudGVyIGZsZXgtc2hyaW5rLTBcIj5cclxuICAgICAgICAgICAgPGgzIGNsYXNzPVwiZm9udC1ib2xkIHRleHQtZ3JheS03MDBcIj5DaG9vc2UgU2VsbGluZyBVbml0PC9oMz5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IHYtaWY9XCJ1bml0c1F1YW50aXRpZXMubGVuZ3RoID4gMFwiIGNsYXNzPVwiZ3JpZCBncmlkLWZsb3ctcm93IGdyaWQtY29scy0yIG92ZXJmbG93LXktYXV0b1wiPlxyXG4gICAgICAgICAgICA8ZGl2IEBjbGljaz1cInNlbGVjdFVuaXQoIHVuaXRRdWFudGl0eSApXCIgOmtleT1cInVuaXRRdWFudGl0eS5pZFwiIHYtZm9yPVwidW5pdFF1YW50aXR5IG9mIHVuaXRzUXVhbnRpdGllc1wiIGNsYXNzPVwiaG92ZXI6YmctZ3JheS0yMDAgY3Vyc29yLXBvaW50ZXIgYm9yZGVyIGZsZXgtc2hyaW5rLTAgYm9yZGVyLWdyYXktMjAwIGZsZXggZmxleC1jb2wgaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaC00MCB3LWZ1bGwgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgb3ZlcmZsb3ctaGlkZGVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGltZyB2LWlmPVwidW5pdFF1YW50aXR5LnByZXZpZXdfdXJsXCIgOnNyYz1cInVuaXRRdWFudGl0eS5wcmV2aWV3X3VybFwiIGNsYXNzPVwib2JqZWN0LWNvdmVyIGgtZnVsbFwiIDphbHQ9XCJ1bml0UXVhbnRpdHkudW5pdC5uYW1lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImgtNDAgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIiB2LWlmPVwiISB1bml0UXVhbnRpdHkucHJldmlld191cmxcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJsYXMgbGEtaW1hZ2UgdGV4dC1ncmF5LTYwMCB0ZXh0LTZ4bFwiPjwvaT5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImgtMCB3LWZ1bGxcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVsYXRpdmUgdy1mdWxsIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIC10b3AtMTAgaC0yMCBweS0yIGZsZXgtY29sXCIgc3R5bGU9XCJiYWNrZ3JvdW5kOnJnYigyNTUgMjU1IDI1NSAvIDczJSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwiZm9udC1ib2xkIHRleHQtZ3JheS03MDAgcHktMiB0ZXh0LWNlbnRlclwiPnt7IHVuaXRRdWFudGl0eS51bml0Lm5hbWUgfX0gKHt7IHVuaXRRdWFudGl0eSAucXVhbnRpdHkgfX0pPC9oMz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtZ3JheS02MDBcIj57eyB1bml0UXVhbnRpdHkuc2FsZV9wcmljZSB8IGN1cnJlbmN5IH19PC9wPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJoLTU2IGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCIgdi1pZj1cInVuaXRzUXVhbnRpdGllcy5sZW5ndGggPT09IDBcIj5cclxuICAgICAgICAgICAgPG5zLXNwaW5uZXI+PC9ucy1zcGlubmVyPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbjwvdGVtcGxhdGU+XHJcbjxzY3JpcHQ+XHJcbmltcG9ydCB7IG5zSHR0cENsaWVudCwgbnNTbmFja0JhciB9IGZyb20gJ0AvYm9vdHN0cmFwJztcclxuZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgZGF0YSgpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB1bml0c1F1YW50aXRpZXM6IFtdLFxyXG4gICAgICAgICAgICBsb2Fkc1VuaXRzOiBmYWxzZSxcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG4gICAgbW91bnRlZCgpIHtcclxuICAgICAgICB0aGlzLiRwb3B1cC5ldmVudC5zdWJzY3JpYmUoIGFjdGlvbiA9PiB7XHJcbiAgICAgICAgICAgIGlmICggYWN0aW9uLmV2ZW50ID09PSAnY2xpY2stb3ZlcmxheScgKSB7XHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIGFzIHRoaXMgcnVucyB1bmRlciBhIFByb21pc2VcclxuICAgICAgICAgICAgICAgICAqIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXRcclxuICAgICAgICAgICAgICAgICAqIGl0IHJlc29sdmUgZmFsc2UgdXNpbmcgdGhlIFwicmVzb2x2ZVwiIGZ1bmN0aW9uXHJcbiAgICAgICAgICAgICAgICAgKiBwcm92aWRlZCBhcyAkcG9wdXBQYXJhbXMuXHJcbiAgICAgICAgICAgICAgICAgKiBIZXJlIHdlIHJlc29sdmUgXCJmYWxzZVwiIGFzIHRoZSB1c2VyIGhhcyBicm9rZW4gdGhlIFByb21pc2VcclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgdGhpcy4kcG9wdXBQYXJhbXMucmVqZWN0KCBmYWxzZSApO1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogd2UgY2FuIHNhZmVseSBjbG9zZSB0aGUgcG9wdXAuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIHRoaXMuJHBvcHVwLmNsb3NlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogSWYgdGhlcmUgaXMgYSBkZWZhdWx0IHNlbGVjdGVkIHVuaXQgcXVhbnRpdHlcclxuICAgICAgICAgKiBwcm92aWRlZCwgd2UgYXNzdW1lIHRoZSBwcm9kdWN0IHdhcyBhZGRlZCB1c2luZyB0aGUgdW5pdFxyXG4gICAgICAgICAqIHF1YW50aXR5IGJhcmNvZGUuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgaWYgKCB0aGlzLiRwb3B1cFBhcmFtcy5wcm9kdWN0LiRvcmlnaW5hbCgpLnNlbGVjdGVkVW5pdFF1YW50aXR5ICE9PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0VW5pdCggdGhpcy4kcG9wdXBQYXJhbXMucHJvZHVjdC4kb3JpZ2luYWwoKS5zZWxlY3RlZFVuaXRRdWFudGl0eSApO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMubG9hZHNVbml0cyAgICAgPSAgIHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMubG9hZFVuaXRzKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIG1ldGhvZHM6IHtcclxuICAgICAgICBsb2FkVW5pdHMoKSB7XHJcbiAgICAgICAgICAgIG5zSHR0cENsaWVudC5nZXQoIGAvYXBpL25leG9wb3MvdjQvcHJvZHVjdHMvJHt0aGlzLiRwb3B1cFBhcmFtcy5wcm9kdWN0LiRvcmlnaW5hbCgpLmlkfS91bml0cy9xdWFudGl0aWVzYCApXHJcbiAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCByZXN1bHQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIGlmICggcmVzdWx0Lmxlbmd0aCA9PT0gMCApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kcG9wdXAuY2xvc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5zU25hY2tCYXIuZXJyb3IoICdUaGlzIHByb2R1Y3QgZG9lc25cXCd0IGhhcyBhbnkgdW5pdCBkZWZpbmVkIGZvciBzZWxsaW5nLicgKS5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudW5pdHNRdWFudGl0aWVzICA9ICAgcmVzdWx0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAgICAgKiBUaGlzIHdpbGwgYXV0b21hdGljYWxseVxyXG4gICAgICAgICAgICAgICAgICAgICAqIHNlbGVjdCBhIHVuaXQgaWYgdGhlcmUgaXMgb25seSBvbmUgdW5pdCBhdmFpbGFibGUuXHJcbiAgICAgICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCB0aGlzLnVuaXRzUXVhbnRpdGllcy5sZW5ndGggPT09IDEgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0VW5pdCggdGhpcy51bml0c1F1YW50aXRpZXNbMF0gKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogd2UnbGwgcmVzb2x2ZSBhIHZhbHVlIHRoYXRcclxuICAgICAgICAgKiB3aWxsIGJlIGFkZGVkIHRvIHRoZSBvYmplY3RcclxuICAgICAgICAgKiBidWlsdCBhdCB0aGUgZW5kXHJcbiAgICAgICAgICogQHBhcmFtIFVuaXRcclxuICAgICAgICAgKi9cclxuICAgICAgICBzZWxlY3RVbml0KCB1bml0UXVhbnRpdHkgKSB7XHJcbiAgICAgICAgICAgIHRoaXMuJHBvcHVwUGFyYW1zLnJlc29sdmUoe1xyXG4gICAgICAgICAgICAgICAgdW5pdF9xdWFudGl0eV9pZCAgICA6ICAgdW5pdFF1YW50aXR5LmlkLFxyXG4gICAgICAgICAgICAgICAgdW5pdF9uYW1lICAgICAgICAgICA6ICAgdW5pdFF1YW50aXR5LnVuaXQubmFtZSxcclxuICAgICAgICAgICAgICAgICRxdWFudGl0aWVzICAgICAgICAgOiAgICgpID0+IHVuaXRRdWFudGl0eVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy4kcG9wdXAuY2xvc2UoKTtcclxuICAgICAgICAgICAgLy8gdGhpcy50eXBlcy5mb3JFYWNoKCB0eXBlID0+IHR5cGUuc2VsZWN0ZWQgPSBmYWxzZSApO1xyXG4gICAgICAgICAgICAvLyB0eXBlLnNlbGVjdGVkICAgPSAgIHRydWU7XHJcbiAgICAgICAgICAgIC8vIFBPUy5vcmRlci50eXBlcy5uZXh0KCB0aGlzLnR5cGVzICk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbjwvc2NyaXB0PiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/ts/popups/ns-pos-units.vue?vue&type=script&lang=js&\n"); ->>>>>>> 3313f0bf34ae3b3550ee3b8ff27748899eebc41e /***/ }), @@ -936,12 +932,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _nod /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -<<<<<<< HEAD eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"POS\", function() { return POS; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"POSInit\", function() { return POSInit; });\n/* harmony import */ var _pages_dashboard_pos_queues_products_product_quantity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pages/dashboard/pos/queues/products/product-quantity */ \"./resources/ts/pages/dashboard/pos/queues/products/product-quantity.ts\");\n/* harmony import */ var _pages_dashboard_pos_queues_products_product_unit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./pages/dashboard/pos/queues/products/product-unit */ \"./resources/ts/pages/dashboard/pos/queues/products/product-unit.ts\");\n/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ \"./node_modules/rxjs/_esm5/index.js\");\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.common.js\");\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(vue__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./bootstrap */ \"./resources/ts/bootstrap.ts\");\n/* harmony import */ var _libraries_responsive__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./libraries/responsive */ \"./resources/ts/libraries/responsive.ts\");\n/* harmony import */ var _libraries_popup__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./libraries/popup */ \"./resources/ts/libraries/popup.ts\");\n/* harmony import */ var _libraries_lang__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./libraries/lang */ \"./resources/ts/libraries/lang.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n};\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * these are dynamic component\r\n * that are loaded conditionally\r\n */\r\nconst NsPosDashboardButton = window.NsPosDashboardButton = __webpack_require__(/*! ./pages/dashboard/pos/header-buttons/ns-pos-dashboard-button */ \"./resources/ts/pages/dashboard/pos/header-buttons/ns-pos-dashboard-button.vue\").default;\r\nconst NsPosPendingOrderButton = window.NsPosPendingOrderButton = __webpack_require__(/*! ./pages/dashboard/pos/header-buttons/ns-pos-pending-orders-button */ \"./resources/ts/pages/dashboard/pos/header-buttons/ns-pos-pending-orders-button.vue\").default;\r\nconst NsPosOrderTypeButton = window.NsPosOrderTypeButton = __webpack_require__(/*! ./pages/dashboard/pos/header-buttons/ns-pos-order-type-button */ \"./resources/ts/pages/dashboard/pos/header-buttons/ns-pos-order-type-button.vue\").default;\r\nconst NsPosCustomersButton = window.NsPosCustomersButton = __webpack_require__(/*! ./pages/dashboard/pos/header-buttons/ns-pos-customers-button */ \"./resources/ts/pages/dashboard/pos/header-buttons/ns-pos-customers-button.vue\").default;\r\nconst NsPosResetButton = window.NsPosResetButton = __webpack_require__(/*! ./pages/dashboard/pos/header-buttons/ns-pos-reset-button */ \"./resources/ts/pages/dashboard/pos/header-buttons/ns-pos-reset-button.vue\").default;\r\nconst NsPosCashRegister = window.NsPosCashRegister = __webpack_require__(/*! ./pages/dashboard/pos/header-buttons/ns-pos-registers-button */ \"./resources/ts/pages/dashboard/pos/header-buttons/ns-pos-registers-button.vue\").default;\r\nconst NsAlertPopup = window.NsAlertPopup = __webpack_require__(/*! ./popups/ns-alert-popup */ \"./resources/ts/popups/ns-alert-popup.vue\").default;\r\nconst NsConfirmPopup = window.NsConfirmPopup = __webpack_require__(/*! ./popups/ns-pos-confirm-popup */ \"./resources/ts/popups/ns-pos-confirm-popup.vue\").default;\r\nconst NsPromptPopup = window.NsPromptPopup = __webpack_require__(/*! ./popups/ns-prompt-popup */ \"./resources/ts/popups/ns-prompt-popup.vue\").default;\r\nconst NsLayawayPopup = window.NsLayawayPopup = __webpack_require__(/*! ./popups/ns-pos-layaway-popup */ \"./resources/ts/popups/ns-pos-layaway-popup.vue\").default;\r\nconst NSPosShippingPopup = window.NsLayawayPopup = __webpack_require__(/*! ./popups/ns-pos-shipping-popup */ \"./resources/ts/popups/ns-pos-shipping-popup.vue\").default;\r\nclass POS {\r\n constructor() {\r\n this._orderTypeProcessQueue = [];\r\n this._initialQueue = [];\r\n this._responsive = new _libraries_responsive__WEBPACK_IMPORTED_MODULE_5__[\"Responsive\"];\r\n this._isSubmitting = false;\r\n this._processingAddQueue = false;\r\n this.defaultOrder = () => {\r\n const order = {\r\n discount_type: null,\r\n title: '',\r\n discount: 0,\r\n register_id: this.get('register') ? this.get('register').id : undefined,\r\n discount_percentage: 0,\r\n subtotal: 0,\r\n total: 0,\r\n coupons: [],\r\n total_coupons: 0,\r\n tendered: 0,\r\n note: '',\r\n note_visibility: 'hidden',\r\n tax_group_id: undefined,\r\n tax_type: undefined,\r\n taxes: [],\r\n tax_groups: [],\r\n payment_status: undefined,\r\n customer_id: undefined,\r\n change: 0,\r\n total_products: 0,\r\n shipping: 0,\r\n tax_value: 0,\r\n shipping_rate: 0,\r\n shipping_type: undefined,\r\n customer: undefined,\r\n type: undefined,\r\n products: [],\r\n instalments: [],\r\n payments: [],\r\n addresses: {\r\n shipping: undefined,\r\n billing: undefined\r\n }\r\n };\r\n return order;\r\n };\r\n /**\r\n * this is resolved when a product is being added to the\r\n * cart. That will help to mutate the product before\r\n * it's added the cart.\r\n */\r\n this.addToCartQueue = [\r\n _pages_dashboard_pos_queues_products_product_unit__WEBPACK_IMPORTED_MODULE_1__[\"ProductUnitPromise\"],\r\n _pages_dashboard_pos_queues_products_product_quantity__WEBPACK_IMPORTED_MODULE_0__[\"ProductQuantityPromise\"]\r\n ];\r\n this.initialize();\r\n }\r\n get screen() {\r\n return this._screen;\r\n }\r\n get visibleSection() {\r\n return this._visibleSection;\r\n }\r\n get paymentsType() {\r\n return this._paymentsType;\r\n }\r\n get order() {\r\n return this._order;\r\n }\r\n get types() {\r\n return this._types;\r\n }\r\n get products() {\r\n return this._products;\r\n }\r\n get customers() {\r\n return this._customers;\r\n }\r\n get options() {\r\n return this._options;\r\n }\r\n get orderTypeQueue() {\r\n return this._orderTypeProcessQueue;\r\n }\r\n get settings() {\r\n return this._settings;\r\n }\r\n get breadcrumbs() {\r\n return this._breadcrumbs;\r\n }\r\n get initialQueue() {\r\n return this._initialQueue;\r\n }\r\n get processingAddQueue() {\r\n return this._processingAddQueue;\r\n }\r\n reset() {\r\n this._isSubmitting = false;\r\n /**\r\n * to reset order details\r\n */\r\n this.order.next(this.defaultOrder());\r\n this._products.next([]);\r\n this._customers.next([]);\r\n this._breadcrumbs.next([]);\r\n this.defineCurrentScreen();\r\n this.processInitialQueue();\r\n this.refreshCart();\r\n }\r\n initialize() {\r\n this._products = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]([]);\r\n this._customers = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]([]);\r\n this._types = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]([]);\r\n this._breadcrumbs = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]([]);\r\n this._screen = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]('');\r\n this._paymentsType = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]([]);\r\n this._visibleSection = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]('both');\r\n this._options = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]({});\r\n this._settings = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]({});\r\n this._order = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"](this.defaultOrder());\r\n this._orderTypeProcessQueue = [\r\n {\r\n identifier: 'handle.delivery-order',\r\n promise: (selectedType) => new Promise((resolve, reject) => {\r\n if (selectedType.identifier === 'delivery') {\r\n return _libraries_popup__WEBPACK_IMPORTED_MODULE_6__[\"Popup\"].show(NSPosShippingPopup, { resolve, reject });\r\n }\r\n reject(false);\r\n })\r\n }\r\n ];\r\n /**\r\n * This initial process will try to detect\r\n * if there is a tax group assigned on the settings\r\n * and set it as default tax group.\r\n */\r\n this.initialQueue.push(() => new Promise((resolve, reject) => {\r\n const options = this.options.getValue();\r\n const order = this.order.getValue();\r\n if (options.ns_pos_tax_group !== false) {\r\n order.tax_group_id = options.ns_pos_tax_group;\r\n order.tax_type = options.ns_pos_tax_type;\r\n this.order.next(order);\r\n }\r\n return resolve({\r\n status: 'success',\r\n message: 'tax group assignated'\r\n });\r\n }));\r\n /**\r\n * this initial process will select the default\r\n * customer and assign him to the POS\r\n */\r\n this.initialQueue.push(() => new Promise((resolve, reject) => {\r\n const options = this.options.getValue();\r\n const order = this.order.getValue();\r\n if (options.ns_customers_default !== false) {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"].get(`/api/nexopos/v4/customers/${options.ns_customers_default}`)\r\n .subscribe(customer => {\r\n this.selectCustomer(customer);\r\n resolve({\r\n status: 'success',\r\n message: Object(_libraries_lang__WEBPACK_IMPORTED_MODULE_7__[\"__\"])('The customer has been loaded')\r\n });\r\n }, (error) => {\r\n reject(error);\r\n });\r\n }\r\n return resolve({\r\n status: 'success',\r\n message: 'tax group assignated'\r\n });\r\n }));\r\n /**\r\n * Whenever there is a change\r\n * on the products, we'll update\r\n * the cart.\r\n */\r\n this.products.subscribe(_ => {\r\n this.refreshCart();\r\n });\r\n /**\r\n * listen to type for updating\r\n * the order accordingly\r\n */\r\n this.types.subscribe(types => {\r\n const selected = types.filter(type => type.selected);\r\n if (selected.length > 0) {\r\n const order = this.order.getValue();\r\n order.type = selected[0];\r\n this.order.next(order);\r\n }\r\n });\r\n /**\r\n * We're handling here the responsive aspect\r\n * of the POS.\r\n */\r\n window.addEventListener('resize', () => {\r\n this._responsive.detect();\r\n this.defineCurrentScreen();\r\n });\r\n this.defineCurrentScreen();\r\n }\r\n /**\r\n * This is the first initial queue\r\n * that runs when the POS is loaded.\r\n * It also run when the pos is reset.\r\n * @return void\r\n */\r\n processInitialQueue() {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n for (let index in this._initialQueue) {\r\n try {\r\n const response = yield this._initialQueue[index]();\r\n }\r\n catch (exception) {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error(exception.message).subscribe();\r\n }\r\n }\r\n });\r\n }\r\n /**\r\n * This methods run as part of the verification\r\n * of the cart refreshing. Cannot refresh the cart.\r\n * @param coupon coupon\r\n */\r\n removeCoupon(coupon) {\r\n const order = this.order.getValue();\r\n const coupons = order.coupons;\r\n const index = coupons.indexOf(coupon);\r\n coupons.splice(index, 1);\r\n order.coupons = coupons;\r\n this.order.next(order);\r\n }\r\n pushCoupon(coupon) {\r\n const order = this.order.getValue();\r\n order.coupons.forEach(_coupon => {\r\n if (_coupon.code === coupon.code) {\r\n const message = Object(_libraries_lang__WEBPACK_IMPORTED_MODULE_7__[\"__\"])('This coupon is already added to the cart');\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error(message)\r\n .subscribe();\r\n throw message;\r\n }\r\n });\r\n order.coupons.push(coupon);\r\n this.order.next(order);\r\n this.refreshCart();\r\n }\r\n get header() {\r\n /**\r\n * As POS object is defined on the\r\n * header, we can use that to reference the buttons (component)\r\n * that needs to be rendered dynamically\r\n */\r\n const data = {\r\n buttons: {\r\n NsPosDashboardButton,\r\n NsPosPendingOrderButton,\r\n NsPosOrderTypeButton,\r\n NsPosCustomersButton,\r\n NsPosResetButton,\r\n }\r\n };\r\n /**\r\n * if the cash register is enabled\r\n * we'll add that button to the list\r\n * of button available.\r\n */\r\n if (this.options.getValue().ns_pos_registers_enabled === 'yes') {\r\n data.buttons['NsPosCashRegister'] = NsPosCashRegister;\r\n }\r\n /**\r\n * expose the pos header data, for allowing\r\n * custom button injection.\r\n */\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHooks\"].doAction('ns-pos-header', data);\r\n return data;\r\n }\r\n defineOptions(options) {\r\n this._options.next(options);\r\n }\r\n defineCurrentScreen() {\r\n this._visibleSection.next(['xs', 'sm'].includes(this._responsive.is()) ? 'grid' : 'both');\r\n this._screen.next(this._responsive.is());\r\n }\r\n changeVisibleSection(section) {\r\n if (['both', 'cart', 'grid'].includes(section)) {\r\n if (['cart', 'both'].includes(section)) {\r\n this.refreshCart();\r\n }\r\n this._visibleSection.next(section);\r\n }\r\n }\r\n addPayment(payment) {\r\n if (payment.value > 0) {\r\n const order = this._order.getValue();\r\n order.payments.push(payment);\r\n this._order.next(order);\r\n return this.computePaid();\r\n }\r\n return _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error('Invalid amount.').subscribe();\r\n }\r\n removePayment(payment) {\r\n if (payment.id !== undefined) {\r\n return _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error('Unable to delete a payment attached to the order').subscribe();\r\n }\r\n const order = this._order.getValue();\r\n const index = order.payments.indexOf(payment);\r\n order.payments.splice(index, 1);\r\n this._order.next(order);\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsEvent\"].emit({\r\n identifier: 'ns.pos.remove-payment',\r\n value: payment\r\n });\r\n this.updateCustomerAccount(payment);\r\n this.computePaid();\r\n }\r\n updateCustomerAccount(payment) {\r\n if (payment.identifier === 'account-payment') {\r\n const customer = this.order.getValue().customer;\r\n customer.account_amount += payment.value;\r\n this.selectCustomer(customer);\r\n }\r\n }\r\n getNetPrice(value, rate, type) {\r\n if (type === 'inclusive') {\r\n return (value / (rate + 100)) * 100;\r\n }\r\n else if (type === 'exclusive') {\r\n return ((value / 100) * (rate + 100));\r\n }\r\n }\r\n getVatValue(value, rate, type) {\r\n if (type === 'inclusive') {\r\n return value - this.getNetPrice(value, rate, type);\r\n }\r\n else if (type === 'exclusive') {\r\n return this.getNetPrice(value, rate, type) - value;\r\n }\r\n }\r\n computeTaxes() {\r\n return new Promise((resolve, reject) => {\r\n const order = this.order.getValue();\r\n if (order.tax_group_id === undefined || order.tax_group_id === null) {\r\n return reject(false);\r\n }\r\n const groups = order.tax_groups;\r\n /**\r\n * if the tax group is already cached\r\n * we'll pull that rather than doing a new request.\r\n */\r\n if (groups && groups[order.tax_group_id] !== undefined) {\r\n order.taxes = order.taxes.map(tax => {\r\n tax.tax_value = this.getVatValue(order.subtotal, tax.rate, order.tax_type);\r\n return tax;\r\n });\r\n return resolve({\r\n status: 'success',\r\n data: { tax: groups[order.tax_group_id], order }\r\n });\r\n }\r\n if (order.tax_group_id !== null) {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"].get(`/api/nexopos/v4/taxes/groups/${order.tax_group_id}`)\r\n .subscribe((tax) => {\r\n order.tax_groups = order.tax_groups || [];\r\n order.taxes = tax.taxes.map(tax => {\r\n return {\r\n tax_id: tax.id,\r\n tax_name: tax.name,\r\n rate: parseFloat(tax.rate),\r\n tax_value: this.getVatValue(order.subtotal, tax.rate, order.tax_type)\r\n };\r\n });\r\n /**\r\n * this is set to cache the\r\n * tax group to avoid subsequent request\r\n * to the server.\r\n */\r\n order.tax_groups[tax.id] = tax;\r\n return resolve({\r\n status: 'success',\r\n data: { tax, order }\r\n });\r\n }, (error) => {\r\n return reject(error);\r\n });\r\n }\r\n else {\r\n return reject({\r\n status: 'failed',\r\n message: Object(_libraries_lang__WEBPACK_IMPORTED_MODULE_7__[\"__\"])('No tax group assigned to the order')\r\n });\r\n }\r\n });\r\n }\r\n /**\r\n * This will check if the order can be saved as layway.\r\n * might request additionnal information through a popup.\r\n * @param order Order\r\n */\r\n canProceedAsLaidAway(_order) {\r\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\r\n const minimalPaymentPercent = _order.customer.group.minimal_credit_payment;\r\n const expected = (_order.total * minimalPaymentPercent) / 100;\r\n /**\r\n * checking order details\r\n * installments & payment date\r\n */\r\n try {\r\n const order = yield new Promise((resolve, reject) => {\r\n _libraries_popup__WEBPACK_IMPORTED_MODULE_6__[\"Popup\"].show(NsLayawayPopup, { order: _order, reject, resolve });\r\n });\r\n if (order.tendered < expected) {\r\n const message = `Before saving the order as laid away, a minimum payment of ${vue__WEBPACK_IMPORTED_MODULE_3___default.a.filter('currency')(expected)} is required`;\r\n _libraries_popup__WEBPACK_IMPORTED_MODULE_6__[\"Popup\"].show(NsAlertPopup, { title: 'Unable to proceed', message });\r\n return reject({ status: 'failed', message });\r\n }\r\n return resolve({ status: 'success', message: Object(_libraries_lang__WEBPACK_IMPORTED_MODULE_7__[\"__\"])('Layaway defined'), data: { order } });\r\n }\r\n catch (exception) {\r\n return reject(exception);\r\n }\r\n }));\r\n }\r\n /**\r\n * Fields might be provided to overwrite the default information\r\n * set on the order.\r\n * @param orderFields Object\r\n */\r\n submitOrder(orderFields = {}) {\r\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\r\n var order = Object.assign(Object.assign({}, this.order.getValue()), orderFields);\r\n const minimalPayment = order.customer.group.minimal_credit_payment;\r\n /**\r\n * this verification applies only if the\r\n * order is not \"hold\".\r\n */\r\n if (order.payment_status !== 'hold') {\r\n if (order.payments.length === 0 || order.total > order.tendered) {\r\n if (this.options.getValue().ns_orders_allow_partial === 'no') {\r\n const message = 'Partially paid orders are disabled.';\r\n return reject({ status: 'failed', message });\r\n }\r\n else if (minimalPayment >= 0) {\r\n try {\r\n const result = yield this.canProceedAsLaidAway(order);\r\n /**\r\n * the order might have been updated\r\n * by the layaway popup.\r\n */\r\n order = result.data.order;\r\n }\r\n catch (exception) {\r\n return reject(exception);\r\n }\r\n }\r\n }\r\n }\r\n if (!this._isSubmitting) {\r\n /**\r\n * @todo do we need to set a new value here\r\n * probably the passed value should be send to the server.\r\n */\r\n const method = order.id !== undefined ? 'put' : 'post';\r\n this._isSubmitting = true;\r\n return _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"][method](`/api/nexopos/v4/orders${order.id !== undefined ? '/' + order.id : ''}`, order)\r\n .subscribe(result => {\r\n resolve(result);\r\n this.reset();\r\n /**\r\n * will trigger an acction when\r\n * the order has been successfully submitted\r\n */\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHooks\"].doAction('ns-order-submit-successful', result);\r\n this._isSubmitting = false;\r\n }, (error) => {\r\n this._isSubmitting = false;\r\n reject(error);\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHooks\"].doAction('ns-order-submit-failed', error);\r\n });\r\n }\r\n return reject({ status: 'failed', message: 'An order is currently being processed.' });\r\n }));\r\n }\r\n loadOrder(order_id) {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"].get(`/api/nexopos/v4/orders/${order_id}/pos`)\r\n .subscribe((order) => {\r\n order = Object.assign(Object.assign({}, this.defaultOrder()), order);\r\n /**\r\n * We'll rebuilt the product\r\n */\r\n const products = order.products.map((orderProduct) => {\r\n orderProduct.$original = () => orderProduct.product;\r\n orderProduct.$quantities = () => orderProduct\r\n .product\r\n .unit_quantities\r\n .filter(unitQuantity => unitQuantity.id === orderProduct.unit_quantity_id)[0];\r\n return orderProduct;\r\n });\r\n /**\r\n * we'll redefine the order type\r\n */\r\n order.type = this.types.getValue().filter(type => type.identifier === order.type)[0];\r\n /**\r\n * the address is provided differently\r\n * then we need to rebuild it the way it's saved and used\r\n */\r\n order.addresses = {\r\n shipping: order.shipping_address,\r\n billing: order.billing_address\r\n };\r\n delete order.shipping_address;\r\n delete order.billing_address;\r\n /**\r\n * let's all set, let's load the order\r\n * from now. No further change is required\r\n */\r\n this.buildOrder(order);\r\n this.buildProducts(products);\r\n this.selectCustomer(order.customer);\r\n });\r\n }\r\n buildOrder(order) {\r\n this.order.next(order);\r\n }\r\n buildProducts(products) {\r\n this.refreshProducts(products);\r\n this.products.next(products);\r\n }\r\n printOrder(order_id) {\r\n const options = this.options.getValue();\r\n if (options.ns_pos_printing_enabled_for === 'disabled') {\r\n return false;\r\n }\r\n const printSection = document.createElement('iframe');\r\n printSection.id = 'printing-section';\r\n printSection.className = 'hidden';\r\n printSection.src = this.settings.getValue()['urls']['printing_url'].replace('{id}', order_id);\r\n document.body.appendChild(printSection);\r\n }\r\n computePaid() {\r\n const order = this._order.getValue();\r\n order.tendered = 0;\r\n if (order.payments.length > 0) {\r\n order.tendered = order.payments.map(p => p.value).reduce((b, a) => a + b);\r\n }\r\n if (order.tendered >= order.total) {\r\n order.payment_status = 'paid';\r\n }\r\n else if (order.tendered > 0 && order.tendered < order.total) {\r\n order.payment_status = 'partially_paid';\r\n }\r\n order.change = order.tendered - order.total;\r\n this._order.next(order);\r\n }\r\n setPaymentActive(payment) {\r\n const payments = this._paymentsType.getValue();\r\n const index = payments.indexOf(payment);\r\n payments.forEach(p => p.selected = false);\r\n payments[index].selected = true;\r\n this._paymentsType.next(payments);\r\n }\r\n definedPaymentsType(payments) {\r\n this._paymentsType.next(payments);\r\n }\r\n selectCustomer(customer) {\r\n return new Promise((resolve, reject) => {\r\n const order = this.order.getValue();\r\n order.customer = customer;\r\n order.customer_id = customer.id;\r\n this.order.next(order);\r\n /**\r\n * asynchronously we can load\r\n * customer meta data\r\n */\r\n if (customer.group === undefined || customer.group === null) {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"].get(`/api/nexopos/v4/customers/${customer.id}/group`)\r\n .subscribe(group => {\r\n order.customer.group = group;\r\n this.order.next(order);\r\n resolve(order);\r\n }, (error) => {\r\n reject(error);\r\n });\r\n }\r\n });\r\n }\r\n updateCart(current, update) {\r\n for (let key in update) {\r\n if (update[key] !== undefined) {\r\n vue__WEBPACK_IMPORTED_MODULE_3___default.a.set(current, key, update[key]);\r\n }\r\n }\r\n this.order.next(current);\r\n /**\r\n * explicitely here we do manually refresh the cart\r\n * as if we listen to cart update by subscribing,\r\n * that will create a loop (huge performance issue).\r\n */\r\n this.refreshCart();\r\n }\r\n /**\r\n * everytime the cart\r\n * refreshed, we might need\r\n * to perform some verification\r\n */\r\n checkCart() {\r\n const order = this.order.getValue();\r\n const unmatchedConditions = [];\r\n order.coupons.forEach(coupon => {\r\n /**\r\n * by default we'll bypass\r\n * the product if it's not available\r\n */\r\n let isProductValid = true;\r\n /**\r\n * if the coupon includes products\r\n * we make sure the products are included on the cart\r\n */\r\n if (coupon.products.length > 0) {\r\n isProductValid = order.products.filter(product => {\r\n return coupon.products.map(p => p.product_id).includes(product.product_id);\r\n }).length > 0;\r\n if (!isProductValid && unmatchedConditions.indexOf(coupon) === -1) {\r\n unmatchedConditions.push(coupon);\r\n }\r\n }\r\n /**\r\n * by default we'll bypass\r\n * the product if it's not available\r\n */\r\n let isCategoryValid = true;\r\n /**\r\n * if the coupon includes products\r\n * we make sure the products are included on the cart\r\n */\r\n if (coupon.categories.length > 0) {\r\n isCategoryValid = order.products.filter(product => {\r\n return coupon.categories.map(p => p.category_id).includes(product.$original().category_id);\r\n }).length > 0;\r\n if (!isCategoryValid && unmatchedConditions.indexOf(coupon) === -1) {\r\n unmatchedConditions.push(coupon);\r\n }\r\n }\r\n });\r\n unmatchedConditions.forEach(coupon => {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error(Object(_libraries_lang__WEBPACK_IMPORTED_MODULE_7__[\"__\"])('The coupons \"%s\" has been removed from the cart, as it\\'s required conditions are no more meet.')\r\n .replace('%s', coupon.name), Object(_libraries_lang__WEBPACK_IMPORTED_MODULE_7__[\"__\"])('Okay'), {\r\n duration: 6000\r\n }).subscribe();\r\n this.removeCoupon(coupon);\r\n });\r\n }\r\n refreshCart() {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n /**\r\n * check if according to the product\r\n * available on the cart the coupons must\r\n * remains the same.\r\n */\r\n this.checkCart();\r\n const products = this.products.getValue();\r\n let order = this.order.getValue();\r\n const productTotal = products\r\n .map(product => product.total_price);\r\n if (productTotal.length > 0) {\r\n order.subtotal = productTotal.reduce((b, a) => b + a);\r\n }\r\n else {\r\n order.subtotal = 0;\r\n }\r\n /**\r\n * we'll compute here the value\r\n * of the coupons\r\n */\r\n const totalValue = order.coupons.map(customerCoupon => {\r\n if (customerCoupon.type === 'percentage_discount') {\r\n customerCoupon.value = (order.subtotal * customerCoupon.discount_value) / 100;\r\n return customerCoupon.value;\r\n }\r\n customerCoupon.value = customerCoupon.discount_value;\r\n return customerCoupon.value;\r\n });\r\n order.total_coupons = 0;\r\n if (totalValue.length > 0) {\r\n order.total_coupons = totalValue.reduce((before, after) => before + after);\r\n }\r\n if (order.discount_type === 'percentage') {\r\n order.discount = (order.discount_percentage * order.subtotal) / 100;\r\n }\r\n /**\r\n * if the discount amount is greather\r\n * than the subtotal, the discount amount\r\n * will be set to the order.subtotal\r\n */\r\n if (order.discount > order.subtotal && order.total_coupons === 0) {\r\n order.discount = order.subtotal;\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].info('The discount has been set to the cart subtotal')\r\n .subscribe();\r\n }\r\n /**\r\n * save actual change to ensure\r\n * all listener are up to date.\r\n */\r\n this.order.next(order);\r\n /**\r\n * will compute the taxes based on\r\n * the actual state of the order\r\n */\r\n try {\r\n const response = yield this.computeTaxes();\r\n order = response['data'].order;\r\n }\r\n catch (exception) {\r\n if (exception !== false && exception.message !== undefined) {\r\n throw exception.message;\r\n }\r\n }\r\n /**\r\n * retreive all products taxes\r\n * and sum the total.\r\n */\r\n const totalTaxes = products.map((product) => product.tax_value);\r\n /**\r\n * tax might be computed above the tax that currently\r\n * applie to the items.\r\n */\r\n order.tax_value = 0;\r\n const vatType = this.options.getValue().ns_pos_vat;\r\n if (['products_vat', 'products_flat_vat', 'products_variable_vat'].includes(vatType) && totalTaxes.length > 0) {\r\n order.tax_value += totalTaxes.reduce((b, a) => b + a);\r\n }\r\n if (['flat_vat', 'variable_vat', 'products_variable_vat'].includes(vatType) && order.taxes && order.taxes.length > 0) {\r\n order.tax_value += order.taxes\r\n .map(tax => tax.tax_value)\r\n .reduce((before, after) => before + after);\r\n }\r\n order.total = (order.subtotal + order.shipping + order.tax_value) - order.discount - order.total_coupons;\r\n order.products = products;\r\n order.total_products = products.length;\r\n this.order.next(order);\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHooks\"].doAction('ns-cart-after-refreshed', order);\r\n });\r\n }\r\n /**\r\n * Get actual stock used by the product\r\n * using the defined unit\r\n * @param product_id\r\n * @param unit_id\r\n */\r\n getStockUsage(product_id, unit_quantity_id) {\r\n const stocks = this._products.getValue().filter((product) => {\r\n return product.product_id === product_id && product.unit_quantity_id === unit_quantity_id;\r\n }).map(product => product.quantity);\r\n if (stocks.length > 0) {\r\n return stocks.reduce((b, a) => b + a);\r\n }\r\n return 0;\r\n }\r\n /**\r\n * Process the item to add it to the cart\r\n * @param product\r\n */\r\n addToCart(product) {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n /**\r\n * This is where all the mutation made by the\r\n * queue promises are stored.\r\n */\r\n let productData = new Object;\r\n /**\r\n * Let's combien the built product\r\n * with the data resolved by the promises\r\n */\r\n let cartProduct = {\r\n product_id: product.id,\r\n name: product.name,\r\n discount_type: 'percentage',\r\n discount: 0,\r\n discount_percentage: 0,\r\n quantity: 0,\r\n tax_group_id: product.tax_group_id,\r\n tax_value: 0,\r\n unit_price: 0,\r\n total_price: 0,\r\n mode: 'normal',\r\n $original: () => product\r\n };\r\n /**\r\n * will determin if the\r\n * script is processing the add queue\r\n */\r\n this._processingAddQueue = true;\r\n for (let index in this.addToCartQueue) {\r\n /**\r\n * the popup promise receives the product that\r\n * is above to be added. Hopefully as it's passed by reference\r\n * updating the product should mutate that once the queue is handled.\r\n */\r\n try {\r\n const promiseInstance = new this.addToCartQueue[index](cartProduct);\r\n const result = (yield promiseInstance.run(productData));\r\n /**\r\n * We just mix both to make sure\r\n * the mutated value overwrite previously defined values.\r\n */\r\n productData = Object.assign(Object.assign({}, productData), result);\r\n }\r\n catch (brokenPromise) {\r\n /**\r\n * if a popup resolve \"false\",\r\n * that means for some reason the Promise has\r\n * been broken, therefore we need to stop the queue.\r\n */\r\n if (brokenPromise === false) {\r\n this._processingAddQueue = false;\r\n return false;\r\n }\r\n }\r\n }\r\n /**\r\n * end proceesing add queue\r\n */\r\n this._processingAddQueue = false;\r\n /**\r\n * Let's combien the built product\r\n * with the data resolved by the promises\r\n */\r\n cartProduct = Object.assign(Object.assign({}, cartProduct), productData);\r\n /**\r\n * retreive product that\r\n * are currently stored\r\n */\r\n const products = this._products.getValue();\r\n /**\r\n * push the new product\r\n * at the front of the cart\r\n */\r\n products.unshift(cartProduct);\r\n /**\r\n * Once the product has been added to the cart\r\n * it's being computed\r\n */\r\n this.refreshProducts(products);\r\n /**\r\n * dispatch event that the\r\n * product has been added.\r\n */\r\n this._products.next(products);\r\n });\r\n }\r\n defineTypes(types) {\r\n this._types.next(types);\r\n }\r\n removeProduct(product) {\r\n const products = this._products.getValue();\r\n const index = products.indexOf(product);\r\n products.splice(index, 1);\r\n this._products.next(products);\r\n }\r\n updateProduct(product, data, index = null) {\r\n const products = this._products.getValue();\r\n index = index === null ? products.indexOf(product) : index;\r\n /**\r\n * to ensure Vue updates accordingly.\r\n */\r\n vue__WEBPACK_IMPORTED_MODULE_3___default.a.set(products, index, Object.assign(Object.assign({}, product), data));\r\n this.refreshProducts(products);\r\n this._products.next(products);\r\n }\r\n refreshProducts(products) {\r\n products.forEach(product => {\r\n this.computeProduct(product);\r\n });\r\n }\r\n computeProduct(product) {\r\n /**\r\n * determining what is the\r\n * real sale price\r\n */\r\n if (product.mode === 'normal') {\r\n product.unit_price = product.$quantities().sale_price;\r\n product.tax_value = product.$quantities().sale_price_tax * product.quantity;\r\n }\r\n else {\r\n product.unit_price = product.$quantities().wholesale_price;\r\n product.tax_value = product.$quantities().wholesale_price_tax * product.quantity;\r\n }\r\n /**\r\n * computing the discount when it's\r\n * based on a percentage\r\n */\r\n if (['flat', 'percentage'].includes(product.discount_type)) {\r\n if (product.discount_type === 'percentage') {\r\n product.discount = ((product.unit_price * product.discount_percentage) / 100) * product.quantity;\r\n }\r\n }\r\n product.total_price = (product.unit_price * product.quantity) - product.discount;\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHooks\"].doAction('ns-after-product-computed', product);\r\n }\r\n loadCustomer(id) {\r\n return _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"].get(`/api/nexopos/v4/customers/${id}`);\r\n }\r\n defineSettings(settings) {\r\n this._settings.next(settings);\r\n }\r\n voidOrder(order) {\r\n if (order.id !== undefined) {\r\n if (['hold'].includes(order.payment_status)) {\r\n _libraries_popup__WEBPACK_IMPORTED_MODULE_6__[\"Popup\"].show(NsConfirmPopup, {\r\n title: 'Order Deletion',\r\n message: 'The current order will be deleted as no payment has been made so far.',\r\n onAction: (action) => {\r\n if (action) {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"].delete(`/api/nexopos/v4/orders/${order.id}`)\r\n .subscribe((result) => {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].success(result.message).subscribe();\r\n this.reset();\r\n }, (error) => {\r\n return _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error(error.message).subscribe();\r\n });\r\n }\r\n }\r\n });\r\n }\r\n else {\r\n _libraries_popup__WEBPACK_IMPORTED_MODULE_6__[\"Popup\"].show(NsPromptPopup, {\r\n title: 'Void The Order',\r\n message: 'The current order will be void. This will cancel the transaction, but the order won\\'t be deleted. Further details about the operation will be tracked on the report. Consider providing the reason of this operation.',\r\n onAction: (reason) => {\r\n if (reason !== false) {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"].post(`/api/nexopos/v4/orders/${order.id}/void`, { reason })\r\n .subscribe((result) => {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].success(result.message).subscribe();\r\n this.reset();\r\n }, (error) => {\r\n return _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error(error.message).subscribe();\r\n });\r\n }\r\n }\r\n });\r\n }\r\n }\r\n else {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error('Unable to void an unpaid order.').subscribe();\r\n }\r\n }\r\n triggerOrderTypeSelection(selectedType) {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n for (let i = 0; i < this.orderTypeQueue.length; i++) {\r\n try {\r\n const result = yield this.orderTypeQueue[i].promise(selectedType);\r\n console.log(result);\r\n }\r\n catch (exception) {\r\n console.log(exception);\r\n }\r\n }\r\n });\r\n }\r\n set(key, value) {\r\n const settings = this.settings.getValue();\r\n settings[key] = value;\r\n this.settings.next(settings);\r\n }\r\n get(key) {\r\n const settings = this.settings.getValue();\r\n return settings[key];\r\n }\r\n destroy() {\r\n this._products.unsubscribe();\r\n this._customers.unsubscribe();\r\n this._types.unsubscribe();\r\n this._breadcrumbs.unsubscribe();\r\n this._paymentsType.unsubscribe();\r\n this._screen.unsubscribe();\r\n this._order.unsubscribe();\r\n this._settings.unsubscribe();\r\n }\r\n}\r\nwindow.POS = new POS;\r\nconst POSInit = window.POS;\r\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvdHMvcG9zLWluaXQudHM/ODVhNiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBZ0c7QUFDUjtBQUM5QjtBQUtwQztBQUVtRDtBQUdyQjtBQUNWO0FBR0o7QUFFdEM7OztHQUdHO0FBQ0gsTUFBTSxvQkFBb0IsR0FBZ0IsTUFBTyxDQUFDLG9CQUFvQixHQUFjLG1CQUFPLENBQUUsbUpBQThELENBQUUsQ0FBQyxPQUFPLENBQUM7QUFDdEssTUFBTSx1QkFBdUIsR0FBYSxNQUFPLENBQUMsdUJBQXVCLEdBQVcsbUJBQU8sQ0FBRSw2SkFBNkUsQ0FBRSxDQUFDLE9BQU8sQ0FBQztBQUNyTCxNQUFNLG9CQUFvQixHQUFnQixNQUFPLENBQUMsb0JBQW9CLEdBQWMsbUJBQU8sQ0FBRSxxSkFBeUUsQ0FBRSxDQUFDLE9BQU8sQ0FBQztBQUNqTCxNQUFNLG9CQUFvQixHQUFnQixNQUFPLENBQUMsb0JBQW9CLEdBQWMsbUJBQU8sQ0FBRSxtSkFBd0UsQ0FBRSxDQUFDLE9BQU8sQ0FBQztBQUNoTCxNQUFNLGdCQUFnQixHQUFvQixNQUFPLENBQUMsZ0JBQWdCLEdBQWtCLG1CQUFPLENBQUUsMklBQW9FLENBQUUsQ0FBQyxPQUFPLENBQUM7QUFDNUssTUFBTSxpQkFBaUIsR0FBbUIsTUFBTyxDQUFDLGlCQUFpQixHQUFpQixtQkFBTyxDQUFFLG1KQUF3RSxDQUFFLENBQUMsT0FBTyxDQUFDO0FBQ2hMLE1BQU0sWUFBWSxHQUF3QixNQUFPLENBQUMsWUFBWSxHQUFzQixtQkFBTyxDQUFFLHlFQUFtQyxDQUFFLENBQUMsT0FBTyxDQUFDO0FBQzNJLE1BQU0sY0FBYyxHQUFzQixNQUFPLENBQUMsY0FBYyxHQUFvQixtQkFBTyxDQUFFLHFGQUF5QyxDQUFFLENBQUMsT0FBTyxDQUFDO0FBQ2pKLE1BQU0sYUFBYSxHQUF1QixNQUFPLENBQUMsYUFBYSxHQUFxQixtQkFBTyxDQUFFLDJFQUFvQyxD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Q0FBQztDQUNKO0FBRUMsTUFBZSxDQUFDLEdBQUcsR0FBVyxJQUFJLEdBQUcsQ0FBQztBQUVqQyxNQUFNLE9BQU8sR0FBZSxNQUFlLENBQUMsR0FBRyxDQUFDIiwiZmlsZSI6Ii4vcmVzb3VyY2VzL3RzL3Bvcy1pbml0LnRzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUHJvZHVjdFF1YW50aXR5UHJvbWlzZSB9IGZyb20gXCIuL3BhZ2VzL2Rhc2hib2FyZC9wb3MvcXVldWVzL3Byb2R1Y3RzL3Byb2R1Y3QtcXVhbnRpdHlcIjtcclxuaW1wb3J0IHsgUHJvZHVjdFVuaXRQcm9taXNlIH0gZnJvbSBcIi4vcGFnZXMvZGFzaGJvYXJkL3Bvcy9xdWV1ZXMvcHJvZHVjdHMvcHJvZHVjdC11bml0XCI7XHJcbmltcG9ydCB7IFN1YmplY3QsIEJlaGF2aW9yU3ViamVjdCwgZm9ya0pvaW4gfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQgeyBQcm9kdWN0IH0gZnJvbSBcIi4vaW50ZXJmYWNlcy9wcm9kdWN0XCI7XHJcbmltcG9ydCB7IEN1c3RvbWVyIH0gZnJvbSBcIi4vaW50ZXJmYWNlcy9jdXN0b21lclwiO1xyXG5pbXBvcnQgeyBPcmRlclR5cGUgfSBmcm9tIFwiLi9pbnRlcmZhY2VzL29yZGVyLXR5cGVcIjtcclxuaW1wb3J0IHsgUE9TVmlydHVhbFN0b2NrIH0gZnJvbSBcIi4vaW50ZXJmYWNlcy9wb3MtdmlydWFsLXN0b2NrXCI7XHJcbmltcG9ydCBWdWUgZnJvbSAndnVlJztcclxuaW1wb3J0IHsgT3JkZXIgfSBmcm9tIFwiLi9pbnRlcmZhY2VzL29yZGVyXCI7XHJcbmltcG9ydCB7IG5zRXZlbnQsIG5zSG9va3MsIG5zSHR0cENsaWVudCwgbnNTbmFja0JhciB9IGZyb20gXCIuL2Jvb3RzdHJhcFwiO1xyXG5pbXBvcnQgeyBQYXltZW50VHlwZSB9IGZyb20gXCIuL2ludGVyZmFjZXMvcGF5bWVudC10eXBlXCI7XHJcbmltcG9ydCB7IFBheW1lbnQgfSBmcm9tIFwiLi9pbnRlcmZhY2VzL3BheW1lbnRcIjtcclxuaW1wb3J0IHsgUmVzcG9uc2l2ZSB9IGZyb20gXCIuL2xpYnJhcmllcy9yZXNwb25zaXZlXCI7XHJcbmltcG9ydCB7IFBvcHVwIH0gZnJvbSBcIi4vbGlicmFyaWVzL3BvcHVwXCI7XHJcbmltcG9ydCB7IE9yZGVyUHJvZHVjdCB9IGZyb20gXCIuL2ludGVyZmFjZXMvb3JkZXItcHJvZHVjdFwiO1xyXG5pbXBvcnQgeyBTdGF0dXNSZXNwb25zZSB9IGZyb20gXCIuL3N0YXR1cy1yZXNwb25zZVwiO1xyXG5pbXBvcnQgeyBfXyB9IGZyb20gXCIuL2xpYnJhcmllcy9sYW5nXCI7XHJcblxyXG4vKipcclxuICogdGhlc2UgYXJlIGR5bmFtaWMgY29tcG9uZW50XHJcbiAqIHRoYXQgYXJlIGxvYWRlZCBjb25kaXRpb25hbGx5XHJcbiAqL1xyXG5jb25zdCBOc1Bvc0Rhc2hib2FyZEJ1dHRvbiAgICAgID0gICAoPGFueT53aW5kb3cpLk5zUG9zRGFzaGJvYXJkQnV0dG9uICAgICAgICAgID0gICByZXF1aXJlKCAnLi9wYWdlcy9kYXNoYm9hcmQvcG9zL2hlYWRlci1idXR0b25zL25zLXBvcy1kYXNoYm9hcmQtYnV0dG9uJyApLmRlZmF1bHQ7XHJcbmNvbnN0IE5zUG9zUGVuZGluZ09yZGVyQnV0dG9uICAgPSAgICg8YW55PndpbmRvdykuTnNQb3NQZW5kaW5nT3JkZXJCdXR0b24gICAgICAgPSAgIHJlcXVpcmUoICcuL3BhZ2VzL2Rhc2hib2FyZC9wb3MvaGVhZGVyLWJ1dHRvbnMvbnMtcG9zLScgKyAncGVuZGluZy1vcmRlcnMnICsgJy1idXR0b24nICkuZGVmYXVsdDtcclxuY29uc3QgTnNQb3NPcmRlclR5cGVCdXR0b24gICAgICA9ICAgKDxhbnk+d2luZG93KS5Oc1Bvc09yZGVyVHlwZUJ1dHRvbiAgICAgICAgICA9ICAgcmVxdWlyZSggJy4vcGFnZXMvZGFzaGJvYXJkL3Bvcy9oZWFkZXItYnV0dG9ucy9ucy1wb3MtJyArICdvcmRlci10eXBlJyArICctYnV0dG9uJyApLmRlZmF1bHQ7XHJcbmNvbnN0IE5zUG9zQ3VzdG9tZXJzQnV0dG9uICAgICAgPSAgICg8YW55PndpbmRvdykuTnNQb3NDdXN0b21lcnNCdXR0b24gICAgICAgICAgPSAgIHJlcXVpcmUoICcuL3BhZ2VzL2Rhc2hib2FyZC9wb3MvaGVhZGVyLWJ1dHRvbnMvbnMtcG9zLScgKyAnY3VzdG9tZXJzJyArICctYnV0dG9uJyApLmRlZmF1bHQ7XHJcbmNvbnN0IE5zUG9zUmVzZXRCdXR0b24gICAgICAgICAgPSAgICg8YW55PndpbmRvdykuTnNQb3NSZXNldEJ1dHRvbiAgICAgICAgICAgICAgPSAgIHJlcXVpcmUoICcuL3BhZ2VzL2Rhc2hib2FyZC9wb3MvaGVhZGVyLWJ1dHRvbnMvbnMtcG9zLScgKyAncmVzZXQnICsgJy1idXR0b24nICkuZGVmYXVsdDtcclxuY29uc3QgTnNQb3NDYXNoUmVnaXN0ZXIgICAgICAgICA9ICAgKDxhbnk+d2luZG93KS5Oc1Bvc0Nhc2hSZWdpc3RlciAgICAgICAgICAgICA9ICAgcmVxdWlyZSggJy4vcGFnZXMvZGFzaGJvYXJkL3Bvcy9oZWFkZXItYnV0dG9ucy9ucy1wb3MtJyArICdyZWdpc3RlcnMnICsgJy1idXR0b24nICkuZGVmYXVsdDtcclxuY29uc3QgTnNBbGVydFBvcHVwICAgICAgICAgICAgICA9ICAgKDxhbnk+d2luZG93KS5Oc0FsZXJ0UG9wdXAgICAgICAgICAgICAgICAgICA9ICAgcmVxdWlyZSggJy4vcG9wdXBzL25zLScgKyAnYWxlcnQnICsgJy1wb3B1cCcgKS5kZWZhdWx0O1xyXG5jb25zdCBOc0NvbmZpcm1Qb3B1cCAgICAgICAgICAgID0gICAoPGFueT53aW5kb3cpLk5zQ29uZmlybVBvcHVwICAgICAgICAgICAgICAgID0gICByZXF1aXJlKCAnLi9wb3B1cHMvbnMtcG9zLScgKyAnY29uZmlybScgKyAnLXBvcHVwJyApLmRlZmF1bHQ7XHJcbmNvbnN0IE5zUHJvbXB0UG9wdXAgICAgICAgICAgICAgPSAgICg8YW55PndpbmRvdykuTnNQcm9tcHRQb3B1cCAgICAgICAgICAgICAgICAgPSAgIHJlcXVpcmUoICcuL3BvcHVwcy9ucy0nICsgJ3Byb21wdCcgKyAnLXBvcHVwJyApLmRlZmF1bHQ7XHJcbmNvbnN0IE5zTGF5YXdheVBvcHVwICAgICAgICAgICAgPSAgICg8YW55PndpbmRvdykuTnNMYXlhd2F5UG9wdXAgICAgICAgICAgICAgICAgPSAgIHJlcXVpcmUoICcuL3BvcHVwcy9ucy1wb3MtJyArICdsYXlhd2F5JyArICctcG9wdXAnICkuZGVmYXVsdDtcclxuY29uc3QgTlNQb3NTaGlwcGluZ1BvcHVwICAgICAgICA9ICAgKDxhbnk+d2luZG93KS5Oc0xheWF3YXlQb3B1cCAgICAgICAgICAgICAgICA9ICAgcmVxdWlyZSggJy4vcG9wdXBzL25zLXBvcy0nICsgJ3NoaXBwaW5nJyArICctcG9wdXAnICkuZGVmYXVsdDtcclxuXHJcbmV4cG9ydCBjbGFzcyBQT1Mge1xyXG4gICAgcHJpdmF0ZSBfcHJvZHVjdHM6IEJlaGF2aW9yU3ViamVjdDxPcmRlclByb2R1Y3RbXT47XHJcbiAgICBwcml2YXRlIF9icmVhZGNydW1iczogQmVoYXZpb3JTdWJqZWN0PGFueVtdPjtcclxuICAgIHByaXZhdGUgX2N1c3RvbWVyczogQmVoYXZpb3JTdWJqZWN0PEN1c3RvbWVyW10+O1xyXG4gICAgcHJpdmF0ZSBfc2V0dGluZ3M6IEJlaGF2aW9yU3ViamVjdDx7IFsga2V5OiBzdHJpbmddIDogYW55fT47XHJcbiAgICBwcml2YXRlIF90eXBlczogQmVoYXZpb3JTdWJqZWN0PE9yZGVyVHlwZVtdPjtcclxuICAgIHByaXZhdGUgX29yZGVyVHlwZVByb2Nlc3NRdWV1ZTogeyBpZGVudGlmaWVyOiBzdHJpbmcsIHByb21pc2U6ICggc2VsZWN0ZWRUeXBlOiBPcmRlclR5cGUgKSA9PiBQcm9taXNlPFN0YXR1c1Jlc3BvbnNlPiB9W10gICAgID0gICBbXTtcclxuICAgIHByaXZhdGUgX3BheW1lbnRzVHlwZTogQmVoYXZpb3JTdWJqZWN0PFBheW1lbnRUeXBlW10+O1xyXG4gICAgcHJpdmF0ZSBfb3JkZXI6IEJlaGF2aW9yU3ViamVjdDxPcmRlcj47XHJcbiAgICBwcml2YXRlIF9zY3JlZW46IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+O1xyXG4gICAgcHJpdmF0ZSBfaW5pdGlhbFF1ZXVlOiAoKCkgPT4gUHJvbWlzZTxTdGF0dXNSZXNwb25zZT4pW10gICAgID0gICBbXTtcclxuICAgIHByaXZhdGUgX29wdGlvbnM6IEJlaGF2aW9yU3ViamVjdDx7IFtrZXk6c3RyaW5nXSA6IGFueX0+O1xyXG4gICAgcHJpdmF0ZSBfcmVzcG9uc2l2ZSAgICAgICAgID0gICBuZXcgUmVzcG9uc2l2ZTtcclxuICAgIHByaXZhdGUgX3Zpc2libGVTZWN0aW9uOiBCZWhhdmlvclN1YmplY3Q8J2NhcnQnIHwgJ2dyaWQnIHwgJ2JvdGgnPjtcclxuICAgIHByaXZhdGUgX2lzU3VibWl0dGluZyAgICAgICAgICAgPSAgIGZhbHNlO1xyXG4gICAgcHJpdmF0ZSBfcHJvY2Vzc2luZ0FkZFF1ZXVlICAgICA9ICAgZmFsc2U7XHJcbiAgICBwcml2YXRlIGRlZmF1bHRPcmRlciAgICAgICAgICAgID0gICAoKTogT3JkZXIgPT4ge1xyXG4gICAgICAgIGNvbnN0IG9yZGVyOiBPcmRlciAgICAgPSAgIHtcclxuICAgICAgICAgICAgZGlzY291bnRfdHlwZTogbnVsbCxcclxuICAgICAgICAgICAgdGl0bGU6ICcnLFxyXG4gICAgICAgICAgICBkaXNjb3VudDogMCxcclxuICAgICAgICAgICAgcmVnaXN0ZXJfaWQ6IHRoaXMuZ2V0KCAncmVnaXN0ZXInICkgPyB0aGlzLmdldCggJ3JlZ2lzdGVyJyApLmlkIDogdW5kZWZpbmVkLCAvLyBldmVyeXRpbWUgaXQgcmVzZXQsIHRoaXMgdmFsdWUgd2lsbCBiZSBwdWxsZWQuXHJcbiAgICAgICAgICAgIGRpc2NvdW50X3BlcmNlbnRhZ2U6IDAsXHJcbiAgICAgICAgICAgIHN1YnRvdGFsOiAwLFxyXG4gICAgICAgICAgICB0b3RhbDogMCxcclxuICAgICAgICAgICAgY291cG9uczogW10sXHJcbiAgICAgICAgICAgIHRvdGFsX2NvdXBvbnMgOiAwLFxyXG4gICAgICAgICAgICB0ZW5kZXJlZDogMCxcclxuICAgICAgICAgICAgbm90ZTogJycsXHJcbiAgICAgICAgICAgIG5vdGVfdmlzaWJpbGl0eTogJ2hpZGRlbicsXHJcbiAgICAgICAgICAgIHRheF9ncm91cF9pZDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICB0YXhfdHlwZTogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICB0YXhlczogW10sIFxyXG4gICAgICAgICAgICB0YXhfZ3JvdXBzOiBbXSxcclxuICAgICAgICAgICAgcGF5bWVudF9zdGF0dXM6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgY3VzdG9tZXJfaWQ6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgY2hhbmdlOiAwLFxyXG4gICAgICAgICAgICB0b3RhbF9wcm9kdWN0czogMCxcclxuICAgICAgICAgICAgc2hpcHBpbmc6IDAsXHJcbiAgICAgICAgICAgIHRheF92YWx1ZTogMCxcclxuICAgICAgICAgICAgc2hpcHBpbmdfcmF0ZTogMCxcclxuICAgICAgICAgICAgc2hpcHBpbmdfdHlwZTogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBjdXN0b21lcjogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICB0eXBlOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgIHByb2R1Y3RzOiBbXSxcclxuICAgICAgICAgICAgaW5zdGFsbWVudHM6IFtdLFxyXG4gICAgICAgICAgICBwYXltZW50czogW10sXHJcbiAgICAgICAgICAgIGFkZHJlc3Nlczoge1xyXG4gICAgICAgICAgICAgICAgc2hpcHBpbmc6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgICAgIGJpbGxpbmc6IHVuZGVmaW5lZFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gb3JkZXI7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgdGhpcy5pbml0aWFsaXplKCk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHNjcmVlbigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2NyZWVuO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCB2aXNpYmxlU2VjdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdmlzaWJsZVNlY3Rpb247XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHBheW1lbnRzVHlwZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcGF5bWVudHNUeXBlO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBvcmRlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fb3JkZXI7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHR5cGVzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlcztcclxuICAgIH1cclxuXHJcbiAgICBnZXQgcHJvZHVjdHMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Byb2R1Y3RzO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBjdXN0b21lcnMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2N1c3RvbWVycztcclxuICAgIH1cclxuXHJcbiAgICBnZXQgb3B0aW9ucygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fb3B0aW9ucztcclxuICAgIH1cclxuXHJcbiAgICBnZXQgb3JkZXJUeXBlUXVldWUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX29yZGVyVHlwZVByb2Nlc3NRdWV1ZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgc2V0dGluZ3MoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBicmVhZGNydW1icygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fYnJlYWRjcnVtYnM7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGluaXRpYWxRdWV1ZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5faW5pdGlhbFF1ZXVlO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBwcm9jZXNzaW5nQWRkUXVldWUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Byb2Nlc3NpbmdBZGRRdWV1ZTtcclxuICAgIH1cclxuXHJcbiAgICByZXNldCgpIHtcclxuICAgICAgICB0aGlzLl9pc1N1Ym1pdHRpbmcgID0gICBmYWxzZTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogdG8gcmVzZXQgb3JkZXIgZGV0YWlsc1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMub3JkZXIubmV4dCggdGhpcy5kZWZhdWx0T3JkZXIoKSApO1xyXG4gICAgICAgIHRoaXMuX3Byb2R1Y3RzLm5leHQoW10pO1xyXG4gICAgICAgIHRoaXMuX2N1c3RvbWVycy5uZXh0KFtdKTtcclxuICAgICAgICB0aGlzLl9icmVhZGNydW1icy5uZXh0KFtdKTtcclxuICAgICAgICB0aGlzLmRlZmluZUN1cnJlbnRTY3JlZW4oKTtcclxuXHJcbiAgICAgICAgdGhpcy5wcm9jZXNzSW5pdGlhbFF1ZXVlKCk7XHJcbiAgICAgICAgdGhpcy5yZWZyZXNoQ2FydCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBpbml0aWFsaXplKClcclxuICAgIHtcclxuICAgICAgICB0aGlzLl9wcm9kdWN0cyAgICAgICAgICA9ICAgbmV3IEJlaGF2aW9yU3ViamVjdDxPcmRlclByb2R1Y3RbXT4oW10pO1xyXG4gICAgICAgIHRoaXMuX2N1c3RvbWVycyAgICAgICAgID0gICBuZXcgQmVoYXZpb3JTdWJqZWN0PEN1c3RvbWVyW10+KFtdKTtcclxuICAgICAgICB0aGlzLl90eXBlcyAgICAgICAgICAgICA9ICAgbmV3IEJlaGF2aW9yU3ViamVjdDxPcmRlclR5cGVbXT4oW10pO1xyXG4gICAgICAgIHRoaXMuX2JyZWFkY3J1bWJzICAgICAgID0gICBuZXcgQmVoYXZpb3JTdWJqZWN0PGFueVtdPihbXSk7XHJcbiAgICAgICAgdGhpcy5fc2NyZWVuICAgICAgICAgICAgPSAgIG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPignJyk7XHJcbiAgICAgICAgdGhpcy5fcGF5bWVudHNUeXBlICAgICAgPSAgIG5ldyBCZWhhdmlvclN1YmplY3Q8UGF5bWVudFR5cGVbXT4oW10pOyAgIFxyXG4gICAgICAgIHRoaXMuX3Zpc2libGVTZWN0aW9uICAgID0gICBuZXcgQmVoYXZpb3JTdWJqZWN0KCAnYm90aCcgKTsgICAgIFxyXG4gICAgICAgIHRoaXMuX29wdGlvbnMgICAgICAgICAgID0gICBuZXcgQmVoYXZpb3JTdWJqZWN0KHt9KTtcclxuICAgICAgICB0aGlzLl9zZXR0aW5ncyAgICAgICAgICA9ICAgbmV3IEJlaGF2aW9yU3ViamVjdDx7IFsga2V5OiBzdHJpbmcgXSA6IGFueSB9Pih7fSk7XHJcbiAgICAgICAgdGhpcy5fb3JkZXIgICAgICAgICAgICAgPSAgIG5ldyBCZWhhdmlvclN1YmplY3Q8T3JkZXI+KCB0aGlzLmRlZmF1bHRPcmRlcigpICk7XHJcbiAgICAgICAgdGhpcy5fb3JkZXJUeXBlUHJvY2Vzc1F1ZXVlID0gICBbXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIGlkZW50aWZpZXIgOiAnaGFuZGxlLmRlbGl2ZXJ5LW9yZGVyJyxcclxuICAgICAgICAgICAgICAgIHByb21pc2UgICAgIDogKCBzZWxlY3RlZFR5cGU6IE9yZGVyVHlwZSApID0+IG5ldyBQcm9taXNlPFN0YXR1c1Jlc3BvbnNlPiggKCByZXNvbHZlLCByZWplY3QgKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCBzZWxlY3RlZFR5cGUuaWRlbnRpZmllciA9PT0gJ2RlbGl2ZXJ5JyApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFBvcHVwLnNob3coIE5TUG9zU2hpcHBpbmdQb3B1cCwgeyByZXNvbHZlLCByZWplY3QgfSApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KCBmYWxzZSApO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIF1cclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVGhpcyBpbml0aWFsIHByb2Nlc3Mgd2lsbCB0cnkgdG8gZGV0ZWN0XHJcbiAgICAgICAgICogaWYgdGhlcmUgaXMgYSB0YXggZ3JvdXAgYXNzaWduZWQgb24gdGhlIHNldHRpbmdzXHJcbiAgICAgICAgICogYW5kIHNldCBpdCBhcyBkZWZhdWx0IHRheCBncm91cC5cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmluaXRpYWxRdWV1ZS5wdXNoKCAoKSA9PiBuZXcgUHJvbWlzZSggKCByZXNvbHZlLCByZWplY3QgKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgICA9ICAgdGhpcy5vcHRpb25zLmdldFZhbHVlKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IG9yZGVyICAgICA9ICAgdGhpcy5vcmRlci5nZXRWYWx1ZSgpO1xyXG5cclxuICAgICAgICAgICAgaWYgKCBvcHRpb25zLm5zX3Bvc190YXhfZ3JvdXAgIT09IGZhbHNlICkge1xyXG4gICAgICAgICAgICAgICAgb3JkZXIudGF4X2dyb3VwX2lkICA9ICAgb3B0aW9ucy5uc19wb3NfdGF4X2dyb3VwO1xyXG4gICAgICAgICAgICAgICAgb3JkZXIudGF4X3R5cGUgICAgICA9ICAgb3B0aW9ucy5uc19wb3NfdGF4X3R5cGU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9yZGVyLm5leHQoIG9yZGVyICk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHtcclxuICAgICAgICAgICAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnLFxyXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ3RheCBncm91cCBhc3NpZ25hdGVkJ1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9ICkgKTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogdGhpcyBpbml0aWFsIHByb2Nlc3Mgd2lsbCBzZWxlY3QgdGhlIGRlZmF1bHRcclxuICAgICAgICAgKiBjdXN0b21lciBhbmQgYXNzaWduIGhpbSB0byB0aGUgUE9TXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5pbml0aWFsUXVldWUucHVzaCggKCkgPT4gbmV3IFByb21pc2UoICggcmVzb2x2ZSwgcmVqZWN0ICkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBvcHRpb25zICAgPSAgIHRoaXMub3B0aW9ucy5nZXRWYWx1ZSgpO1xyXG4gICAgICAgICAgICBjb25zdCBvcmRlciAgICAgPSAgIHRoaXMub3JkZXIuZ2V0VmFsdWUoKTtcclxuXHJcbiAgICAgICAgICAgIGlmICggb3B0aW9ucy5uc19jdXN0b21lcnNfZGVmYXVsdCAhPT0gZmFsc2UgKSB7XHJcbiAgICAgICAgICAgICAgICBuc0h0dHBDbGllbnQuZ2V0KCBgL2FwaS9uZXhvcG9zL3Y0L2N1c3RvbWVycy8ke29wdGlvbnMubnNfY3VzdG9tZXJzX2RlZmF1bHR9YCApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZSggY3VzdG9tZXIgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdEN1c3RvbWVyKCBjdXN0b21lciApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHsgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXM6ICdzdWNjZXNzJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IF9fKCAnVGhlIGN1c3RvbWVyIGhhcyBiZWVuIGxvYWRlZCcgKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9LCAoIGVycm9yICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoIGVycm9yICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHtcclxuICAgICAgICAgICAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnLFxyXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ3RheCBncm91cCBhc3NpZ25hdGVkJ1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9ICkgKTtcclxuICAgICAgICBcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBXaGVuZXZlciB0aGVyZSBpcyBhIGNoYW5nZVxyXG4gICAgICAgICAqIG9uIHRoZSBwcm9kdWN0cywgd2UnbGwgdXBkYXRlXHJcbiAgICAgICAgICogdGhlIGNhcnQuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5wcm9kdWN0cy5zdWJzY3JpYmUoIF8gPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hDYXJ0KCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIGxpc3RlbiB0byB0eXBlIGZvciB1cGRhdGluZ1xyXG4gICAgICAgICAqIHRoZSBvcmRlciBhY2NvcmRpbmdseVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMudHlwZXMuc3Vic2NyaWJlKCB0eXBlcyA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkICA9ICAgdHlwZXMuZmlsdGVyKCB0eXBlID0+IHR5cGUuc2VsZWN0ZWQgKTtcclxuXHJcbiAgICAgICAgICAgIGlmICggc2VsZWN0ZWQubGVuZ3RoID4gMCApIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG9yZGVyICAgICA9ICAgdGhpcy5vcmRlci5nZXRWYWx1ZSgpO1xyXG4gICAgICAgICAgICAgICAgb3JkZXIudHlwZSAgICAgID0gICBzZWxlY3RlZFswXTtcclxuICAgICAgICAgICAgICAgIHRoaXMub3JkZXIubmV4dCggb3JkZXIgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBXZSdyZSBoYW5kbGluZyBoZXJlIHRoZSByZXNwb25zaXZlIGFzcGVjdFxyXG4gICAgICAgICAqIG9mIHRoZSBQT1MuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoICdyZXNpemUnLCAoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX3Jlc3BvbnNpdmUuZGV0ZWN0KCk7XHJcbiAgICAgICAgICAgIHRoaXMuZGVmaW5lQ3VycmVudFNjcmVlbigpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLmRlZmluZUN1cnJlbnRTY3JlZW4oKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoaXMgaXMgdGhlIGZpcnN0IGluaXRpYWwgcXVldWVcclxuICAgICAqIHRoYXQgcnVucyB3aGVuIHRoZSBQT1MgaXMgbG9hZGVkLiBcclxuICAgICAqIEl0IGFsc28gcnVuIHdoZW4gdGhlIHBvcyBpcyByZXNldC5cclxuICAgICAqIEByZXR1cm4gdm9pZFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXN5bmMgcHJvY2Vzc0luaXRpYWxRdWV1ZSgpIHtcclxuICAgICAgICBmb3IoIGxldCBpbmRleCBpbiB0aGlzLl9pbml0aWFsUXVldWUgKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZXNwb25zZSAgPSAgIGF3YWl0IHRoaXMuX2luaXRpYWxRdWV1ZVsgaW5kZXggXSgpO1xyXG4gICAgICAgICAgICB9IGNhdGNoKCBleGNlcHRpb24gKSB7XHJcbiAgICAgICAgICAgICAgICBuc1NuYWNrQmFyLmVycm9yKCBleGNlcHRpb24ubWVzc2FnZSApLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhpcyBtZXRob2RzIHJ1biBhcyBwYXJ0IG9mIHRoZSB2ZXJpZmljYXRpb25cclxuICAgICAqIG9mIHRoZSBjYXJ0IHJlZnJlc2hpbmcuIENhbm5vdCByZWZyZXNoIHRoZSBjYXJ0LlxyXG4gICAgICogQHBhcmFtIGNvdXBvbiBjb3Vwb25cclxuICAgICAqL1xyXG4gICAgcmVtb3ZlQ291cG9uKCBjb3Vwb24gKSB7XHJcbiAgICAgICAgY29uc3Qgb3JkZXIgICAgID0gICB0aGlzLm9yZGVyLmdldFZhbHVlKCk7XHJcbiAgICAgICAgY29uc3QgY291cG9ucyAgID0gICBvcmRlci5jb3Vwb25zO1xyXG4gICAgICAgIGNvbnN0IGluZGV4ICAgICA9ICAgY291cG9ucy5pbmRleE9mKCBjb3Vwb24gKTtcclxuICAgICAgICBjb3Vwb25zLnNwbGljZSggaW5kZXgsIDEgKTtcclxuICAgICAgICBvcmRlci5jb3Vwb25zICAgPSAgIGNvdXBvbnM7XHJcbiAgICAgICAgdGhpcy5vcmRlci5uZXh0KCBvcmRlciApO1xyXG4gICAgfVxyXG5cclxuICAgIHB1c2hDb3Vwb24oIGNvdXBvbiApIHtcclxuICAgICAgICBjb25zdCBvcmRlciAgICAgPSAgIHRoaXMub3JkZXIuZ2V0VmFsdWUoKTtcclxuXHJcbiAgICAgICAgb3JkZXIuY291cG9ucy5mb3JFYWNoKCBfY291cG9uID0+IHtcclxuICAgICAgICAgICAgaWYgKCBfY291cG9uLmNvZGUgPT09IGNvdXBvbi5jb2RlICkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbWVzc2FnZSAgID0gICBfXyggJ1RoaXMgY291cG9uIGlzIGFscmVhZHkgYWRkZWQgdG8gdGhlIGNhcnQnICk7XHJcbiAgICAgICAgICAgICAgICBuc1NuYWNrQmFyLmVycm9yKCBtZXNzYWdlIClcclxuICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBtZXNzYWdlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuXHJcbiAgICAgICAgb3JkZXIuY291cG9ucy5wdXNoKCBjb3Vwb24gKTtcclxuICAgICAgICB0aGlzLm9yZGVyLm5leHQoIG9yZGVyICk7XHJcbiAgICAgICAgdGhpcy5yZWZyZXNoQ2FydCgpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBnZXQgaGVhZGVyKCkge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEFzIFBPUyBvYmplY3QgaXMgZGVmaW5lZCBvbiB0aGVcclxuICAgICAgICAgKiBoZWFkZXIsIHdlIGNhbiB1c2UgdGhhdCB0byByZWZlcmVuY2UgdGhlIGJ1dHRvbnMgKGNvbXBvbmVudClcclxuICAgICAgICAgKiB0aGF0IG5lZWRzIHRvIGJlIHJlbmRlcmVkIGR5bmFtaWNhbGx5XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgY29uc3QgZGF0YSAgPSAgIHtcclxuICAgICAgICAgICAgYnV0dG9uczoge1xyXG4gICAgICAgICAgICAgICAgTnNQb3NEYXNoYm9hcmRCdXR0b24sXHJcbiAgICAgICAgICAgICAgICBOc1Bvc1BlbmRpbmdPcmRlckJ1dHRvbixcclxuICAgICAgICAgICAgICAgIE5zUG9zT3JkZXJUeXBlQnV0dG9uLFxyXG4gICAgICAgICAgICAgICAgTnNQb3NDdXN0b21lcnNCdXR0b24sXHJcbiAgICAgICAgICAgICAgICBOc1Bvc1Jlc2V0QnV0dG9uLFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogaWYgdGhlIGNhc2ggcmVnaXN0ZXIgaXMgZW5hYmxlZFxyXG4gICAgICAgICAqIHdlJ2xsIGFkZCB0aGF0IGJ1dHRvbiB0byB0aGUgbGlzdFxyXG4gICAgICAgICAqIG9mIGJ1dHRvbiBhdmFpbGFibGUuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgaWYgKCB0aGlzLm9wdGlvbnMuZ2V0VmFsdWUoKS5uc19wb3NfcmVnaXN0ZXJzX2VuYWJsZWQgPT09ICd5ZXMnICkge1xyXG4gICAgICAgICAgICBkYXRhLmJ1dHRvbnNbICdOc1Bvc0Nhc2hSZWdpc3RlcicgXSAgPSAgIE5zUG9zQ2FzaFJlZ2lzdGVyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogZXhwb3NlIHRoZSBwb3MgaGVhZGVyIGRhdGEsIGZvciBhbGxvd2luZ1xyXG4gICAgICAgICAqIGN1c3RvbSBidXR0b24gaW5qZWN0aW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIG5zSG9va3MuZG9BY3Rpb24oICducy1wb3MtaGVhZGVyJywgZGF0YSApO1xyXG5cclxuICAgICAgICByZXR1cm4gZGF0YTtcclxuICAgIH1cclxuXHJcbiAgICBkZWZpbmVPcHRpb25zKCBvcHRpb25zICkge1xyXG4gICAgICAgIHRoaXMuX29wdGlvbnMubmV4dCggb3B0aW9ucyApO1xyXG4gICAgfVxyXG5cclxuICAgIGRlZmluZUN1cnJlbnRTY3JlZW4oKSB7XHJcbiAgICAgICAgdGhpcy5fdmlzaWJsZVNlY3Rpb24ubmV4dCggWyAneHMnLCAnc20nIF0uaW5jbHVkZXMoIDxzdHJpbmc+dGhpcy5fcmVzcG9uc2l2ZS5pcygpICkgPyAnZ3JpZCcgOiAnYm90aCcgKTtcclxuICAgICAgICB0aGlzLl9zY3JlZW4ubmV4dCggPHN0cmluZz50aGlzLl9yZXNwb25zaXZlLmlzKCkgKTtcclxuICAgIH1cclxuXHJcbiAgICBjaGFuZ2VWaXNpYmxlU2VjdGlvbiggc2VjdGlvbiApIHtcclxuICAgICAgICBpZiAoWyAnYm90aCcsICdjYXJ0JywgJ2dyaWQnIF0uaW5jbHVkZXMoIHNlY3Rpb24gKSApIHtcclxuXHJcbiAgICAgICAgICAgIGlmIChbICdjYXJ0JywgJ2JvdGgnIF0uaW5jbHVkZXMoIHNlY3Rpb24gKSApIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVmcmVzaENhcnQoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5fdmlzaWJsZVNlY3Rpb24ubmV4dCggc2VjdGlvbiApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhZGRQYXltZW50KCBwYXltZW50OiBQYXltZW50ICkge1xyXG4gICAgICAgIGlmICggcGF5bWVudC52YWx1ZSA+IDAgKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG9yZGVyICA9ICAgdGhpcy5fb3JkZXIuZ2V0VmFsdWUoKTtcclxuICAgICAgICAgICAgb3JkZXIucGF5bWVudHMucHVzaCggcGF5bWVudCApO1xyXG4gICAgICAgICAgICB0aGlzLl9vcmRlci5uZXh0KCBvcmRlciApO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcHV0ZVBhaWQoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBuc1NuYWNrQmFyLmVycm9yKCAnSW52YWxpZCBhbW91bnQuJyApLnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbW92ZVBheW1lbnQoIHBheW1lbnQ6IFBheW1lbnQgKSB7XHJcblxyXG4gICAgICAgIGlmICggcGF5bWVudC5pZCAhPT0gdW5kZWZpbmVkICkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnNTbmFja0Jhci5lcnJvciggJ1VuYWJsZSB0byBkZWxldGUgYSBwYXltZW50IGF0dGFjaGVkIHRvIHRoZSBvcmRlcicgKS5zdWJzY3JpYmUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IG9yZGVyICAgICA9ICAgdGhpcy5fb3JkZXIuZ2V0VmFsdWUoKTtcclxuICAgICAgICBjb25zdCBpbmRleCAgICAgPSAgIG9yZGVyLnBheW1lbnRzLmluZGV4T2YoIHBheW1lbnQgKTtcclxuICAgICAgICBvcmRlci5wYXltZW50cy5zcGxpY2UoIGluZGV4LCAxICk7XHJcbiAgICAgICAgdGhpcy5fb3JkZXIubmV4dCggb3JkZXIgKTtcclxuXHJcbiAgICAgICAgbnNFdmVudC5lbWl0KHsgXHJcbiAgICAgICAgICAgIGlkZW50aWZpZXI6ICducy5wb3MucmVtb3ZlLXBheW1lbnQnLFxyXG4gICAgICAgICAgICB2YWx1ZTogcGF5bWVudFxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLnVwZGF0ZUN1c3RvbWVyQWNjb3VudCggcGF5bWVudCApO1xyXG4gICAgICAgIHRoaXMuY29tcHV0ZVBhaWQoKTtcclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGVDdXN0b21lckFjY291bnQoIHBheW1lbnQ6IFBheW1lbnQgKSB7XHJcbiAgICAgICAgaWYgKCBwYXltZW50LmlkZW50aWZpZXIgPT09ICdhY2NvdW50LXBheW1lbnQnICkge1xyXG4gICAgICAgICAgICBjb25zdCBjdXN0b21lciAgICAgICAgICAgICAgPSAgIHRoaXMub3JkZXIuZ2V0VmFsdWUoKS5jdXN0b21lcjtcclxuICAgICAgICAgICAgY3VzdG9tZXIuYWNjb3VudF9hbW91bnQgICAgICs9ICBwYXltZW50LnZhbHVlO1xyXG4gICAgICAgICAgICB0aGlzLnNlbGVjdEN1c3RvbWVyKCBjdXN0b21lciApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXROZXRQcmljZSggdmFsdWUsIHJhdGUsIHR5cGUgKSB7XHJcbiAgICAgICAgaWYgKCB0eXBlID09PSAnaW5jbHVzaXZlJyApIHtcclxuICAgICAgICAgICAgcmV0dXJuICggdmFsdWUgLyAoIHJhdGUgKyAxMDAgKSApICogMTAwO1xyXG4gICAgICAgIH0gZWxzZSBpZiggdHlwZSA9PT0gJ2V4Y2x1c2l2ZScgKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAoICggdmFsdWUgLyAxMDAgKSAqICggcmF0ZSArIDEwMCApICk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldFZhdFZhbHVlKCB2YWx1ZSwgcmF0ZSwgdHlwZSApIHtcclxuICAgICAgICBpZiAoIHR5cGUgPT09ICdpbmNsdXNpdmUnICkge1xyXG4gICAgICAgICAgICByZXR1cm4gdmFsdWUgLSB0aGlzLmdldE5ldFByaWNlKCB2YWx1ZSwgcmF0ZSwgdHlwZSApO1xyXG4gICAgICAgIH0gZWxzZSBpZiggdHlwZSA9PT0gJ2V4Y2x1c2l2ZScgKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE5ldFByaWNlKCB2YWx1ZSwgcmF0ZSwgdHlwZSApIC0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNvbXB1dGVUYXhlcygpIHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoICggcmVzb2x2ZSwgcmVqZWN0ICkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBvcmRlciAgICAgPSAgIHRoaXMub3JkZXIuZ2V0VmFsdWUoKTtcclxuXHJcbiAgICAgICAgICAgIGlmICggb3JkZXIudGF4X2dyb3VwX2lkID09PSB1bmRlZmluZWQgfHwgb3JkZXIudGF4X2dyb3VwX2lkID09PSBudWxsICkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCggZmFsc2UgKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgZ3JvdXBzICAgID0gICBvcmRlci50YXhfZ3JvdXBzO1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIGlmIHRoZSB0YXggZ3JvdXAgaXMgYWxyZWFkeSBjYWNoZWRcclxuICAgICAgICAgICAgICogd2UnbGwgcHVsbCB0aGF0IHJhdGhlciB0aGFuIGRvaW5nIGEgbmV3IHJlcXVlc3QuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBpZiAoIGdyb3VwcyAmJiBncm91cHNbIG9yZGVyLnRheF9ncm91cF9pZCBdICE9PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgICAgICBvcmRlci50YXhlcyAgICAgICAgID0gICBvcmRlci50YXhlcy5tYXAoIHRheCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGF4LnRheF92YWx1ZSAgID0gICB0aGlzLmdldFZhdFZhbHVlKCBvcmRlci5zdWJ0b3RhbCwgdGF4LnJhdGUsIG9yZGVyLnRheF90eXBlICk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRheDtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiAnc3VjY2VzcycsXHJcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogeyB0YXggOiBncm91cHNbIG9yZGVyLnRheF9ncm91cF9pZCBdLCBvcmRlciB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYoIG9yZGVyLnRheF9ncm91cF9pZCAhPT0gbnVsbCApIHtcclxuICAgICAgICAgICAgICAgIG5zSHR0cENsaWVudC5nZXQoIGAvYXBpL25leG9wb3MvdjQvdGF4ZXMvZ3JvdXBzLyR7b3JkZXIudGF4X2dyb3VwX2lkfWAgKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoICh0YXg6YW55KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyLnRheF9ncm91cHMgICAgPSAgIG9yZGVyLnRheF9ncm91cHMgfHwgW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyLnRheGVzICAgICAgICAgPSAgIHRheC50YXhlcy5tYXAoIHRheCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRheF9pZCAgICAgIDogICB0YXguaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGF4X25hbWUgICAgOiAgIHRheC5uYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhdGUgICAgICAgIDogICBwYXJzZUZsb2F0KCB0YXgucmF0ZSApLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRheF92YWx1ZSAgIDogICB0aGlzLmdldFZhdFZhbHVlKCBvcmRlci5zdWJ0b3RhbCwgdGF4LnJhdGUsIG9yZGVyLnRheF90eXBlIClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgKiB0aGlzIGlzIHNldCB0byBjYWNoZSB0aGUgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAqIHRheCBncm91cCB0byBhdm9pZCBzdWJzZXF1ZW50IHJlcXVlc3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgICogdG8gdGhlIHNlcnZlci5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyLnRheF9ncm91cHNbIHRheC5pZCBdICAgID0gICB0YXg7IFxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHsgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXM6ICdzdWNjZXNzJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgOiB7IHRheCwgb3JkZXIgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgIH0sICggZXJyb3IgKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoIGVycm9yICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3Qoe1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogJ2ZhaWxlZCcsXHJcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogX18oICdObyB0YXggZ3JvdXAgYXNzaWduZWQgdG8gdGhlIG9yZGVyJyApXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoaXMgd2lsbCBjaGVjayBpZiB0aGUgb3JkZXIgY2FuIGJlIHNhdmVkIGFzIGxheXdheS5cclxuICAgICAqIG1pZ2h0IHJlcXVlc3QgYWRkaXRpb25uYWwgaW5mb3JtYXRpb24gdGhyb3VnaCBhIHBvcHVwLlxyXG4gICAgICogQHBhcmFtIG9yZGVyIE9yZGVyXHJcbiAgICAgKi9cclxuICAgIGNhblByb2NlZWRBc0xhaWRBd2F5KCBfb3JkZXI6IE9yZGVyICk6IHsgc3RhdHVzOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZywgZGF0YTogeyBvcmRlcjogT3JkZXIgfSB9IHwgYW55IHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoIGFzeW5jICggcmVzb2x2ZSwgcmVqZWN0ICkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBtaW5pbWFsUGF5bWVudFBlcmNlbnQgICAgID0gICBfb3JkZXIuY3VzdG9tZXIuZ3JvdXAubWluaW1hbF9jcmVkaXRfcGF5bWVudDtcclxuICAgICAgICAgICAgY29uc3QgZXhwZWN0ZWQgICAgICAgICAgICAgICAgICA9ICAgKCBfb3JkZXIudG90YWwgKiBtaW5pbWFsUGF5bWVudFBlcmNlbnQgKSAvIDEwMDtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBjaGVja2luZyBvcmRlciBkZXRhaWxzXHJcbiAgICAgICAgICAgICAqIGluc3RhbGxtZW50cyAmIHBheW1lbnQgZGF0ZVxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG9yZGVyICAgID0gICBhd2FpdCBuZXcgUHJvbWlzZTxPcmRlcj4oICggcmVzb2x2ZSwgcmVqZWN0ICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIFBvcHVwLnNob3coIE5zTGF5YXdheVBvcHVwLCB7IG9yZGVyOiBfb3JkZXIsIHJlamVjdCwgcmVzb2x2ZSB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICggb3JkZXIudGVuZGVyZWQgPCBleHBlY3RlZCApIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXNzYWdlICAgPSAgICBgQmVmb3JlIHNhdmluZyB0aGUgb3JkZXIgYXMgbGFpZCBhd2F5LCBhIG1pbmltdW0gcGF5bWVudCBvZiAkeyBWdWUuZmlsdGVyKCAnY3VycmVuY3knICkoIGV4cGVjdGVkICkgfSBpcyByZXF1aXJlZGA7XHJcbiAgICAgICAgICAgICAgICAgICAgUG9wdXAuc2hvdyggTnNBbGVydFBvcHVwLCB7IHRpdGxlOiAnVW5hYmxlIHRvIHByb2NlZWQnLCBtZXNzYWdlIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoeyBzdGF0dXM6ICdmYWlsZWQnLCBtZXNzYWdlIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHsgc3RhdHVzOiAnc3VjY2VzcycsIG1lc3NhZ2U6IF9fKCAnTGF5YXdheSBkZWZpbmVkJyApLCBkYXRhOiB7IG9yZGVyIH0gfSk7XHJcblxyXG4gICAgICAgICAgICB9IGNhdGNoKCBleGNlcHRpb24gKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KCBleGNlcHRpb24gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmllbGRzIG1pZ2h0IGJlIHByb3ZpZGVkIHRvIG92ZXJ3cml0ZSB0aGUgZGVmYXVsdCBpbmZvcm1hdGlvbiBcclxuICAgICAqIHNldCBvbiB0aGUgb3JkZXIuIFxyXG4gICAgICogQHBhcmFtIG9yZGVyRmllbGRzIE9iamVjdFxyXG4gICAgICovXHJcbiAgICBzdWJtaXRPcmRlciggb3JkZXJGaWVsZHMgPSB7fSApIHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoIGFzeW5jICggcmVzb2x2ZSwgcmVqZWN0ICkgPT4ge1xyXG4gICAgICAgICAgICB2YXIgb3JkZXIgICAgICAgICAgICAgPSAgIHsgXHJcbiAgICAgICAgICAgICAgICAuLi48T3JkZXI+dGhpcy5vcmRlciEuZ2V0VmFsdWUoKSxcclxuICAgICAgICAgICAgICAgIC4uLm9yZGVyRmllbGRzXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBjb25zdCBtaW5pbWFsUGF5bWVudCAgICA9ICAgb3JkZXIuY3VzdG9tZXIuZ3JvdXAubWluaW1hbF9jcmVkaXRfcGF5bWVudDtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiB0aGlzIHZlcmlmaWNhdGlvbiBhcHBsaWVzIG9ubHkgaWYgdGhlIFxyXG4gICAgICAgICAgICAgKiBvcmRlciBpcyBub3QgXCJob2xkXCIuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBpZiAoIG9yZGVyLnBheW1lbnRfc3RhdHVzICE9PSAnaG9sZCcgKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIG9yZGVyLnBheW1lbnRzLmxlbmd0aCAgPT09IDAgfHwgb3JkZXIudG90YWwgPiBvcmRlci50ZW5kZXJlZCApIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIHRoaXMub3B0aW9ucy5nZXRWYWx1ZSgpLm5zX29yZGVyc19hbGxvd19wYXJ0aWFsID09PSAnbm8nICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXNzYWdlICAgPSAgICdQYXJ0aWFsbHkgcGFpZCBvcmRlcnMgYXJlIGRpc2FibGVkLic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoeyBzdGF0dXM6ICdmYWlsZWQnLCBtZXNzYWdlIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIG1pbmltYWxQYXltZW50ID49IDAgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgICAgPSAgIGF3YWl0IHRoaXMuY2FuUHJvY2VlZEFzTGFpZEF3YXkoIG9yZGVyICk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiB0aGUgb3JkZXIgbWlnaHQgaGF2ZSBiZWVuIHVwZGF0ZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGJ5IHRoZSBsYXlhd2F5IHBvcHVwLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlciAgICAgICAgICAgPSAgIHJlc3VsdC5kYXRhLm9yZGVyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoKCBleGNlcHRpb24gKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KCBleGNlcHRpb24gKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCAhIHRoaXMuX2lzU3VibWl0dGluZyApIHtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBAdG9kbyBkbyB3ZSBuZWVkIHRvIHNldCBhIG5ldyB2YWx1ZSBoZXJlXHJcbiAgICAgICAgICAgICAgICAgKiBwcm9iYWJseSB0aGUgcGFzc2VkIHZhbHVlIHNob3VsZCBiZSBzZW5kIHRvIHRoZSBzZXJ2ZXIuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGNvbnN0IG1ldGhvZCAgICA9ICAgb3JkZXIuaWQgIT09IHVuZGVmaW5lZCA/ICdwdXQnIDogJ3Bvc3QnO1xyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9pc1N1Ym1pdHRpbmcgID0gICB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBuc0h0dHBDbGllbnRbIG1ldGhvZCBdKCBgL2FwaS9uZXhvcG9zL3Y0L29yZGVycyR7IG9yZGVyLmlkICE9PSB1bmRlZmluZWQgPyAnLycgKyBvcmRlci5pZCA6ICcnIH1gLCBvcmRlciApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZSggcmVzdWx0ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSggcmVzdWx0ICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgKiB3aWxsIHRyaWdnZXIgYW4gYWNjdGlvbiB3aGVuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAqIHRoZSBvcmRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgc3VibWl0dGVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuc0hvb2tzLmRvQWN0aW9uKCAnbnMtb3JkZXItc3VibWl0LXN1Y2Nlc3NmdWwnLCByZXN1bHQgKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2lzU3VibWl0dGluZyAgPSAgIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sICggZXJyb3I6IGFueSApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faXNTdWJtaXR0aW5nICA9ICAgZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCggZXJyb3IgKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5zSG9va3MuZG9BY3Rpb24oICducy1vcmRlci1zdWJtaXQtZmFpbGVkJywgZXJyb3IgKTtcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KHsgc3RhdHVzOiAnZmFpbGVkJywgbWVzc2FnZTogJ0FuIG9yZGVyIGlzIGN1cnJlbnRseSBiZWluZyBwcm9jZXNzZWQuJyB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBsb2FkT3JkZXIoIG9yZGVyX2lkICkge1xyXG4gICAgICAgIG5zSHR0cENsaWVudC5nZXQoIGAvYXBpL25leG9wb3MvdjQvb3JkZXJzLyR7b3JkZXJfaWR9L3Bvc2AgKVxyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCAoIG9yZGVyOiBhbnkgKSA9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgb3JkZXIgICAgICAgPSAgIHsgLi4udGhpcy5kZWZhdWx0T3JkZXIoKSwgLi4ub3JkZXIgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFdlJ2xsIHJlYnVpbHQgdGhlIHByb2R1Y3RcclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcHJvZHVjdHMgID0gICBvcmRlci5wcm9kdWN0cy5tYXAoIChvcmRlclByb2R1Y3Q6IE9yZGVyUHJvZHVjdCApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBvcmRlclByb2R1Y3QuJG9yaWdpbmFsICAgICAgID0gICAoKSA9PiBvcmRlclByb2R1Y3QucHJvZHVjdDtcclxuICAgICAgICAgICAgICAgICAgICBvcmRlclByb2R1Y3QuJHF1YW50aXRpZXMgICAgID0gICAoKSA9PiBvcmRlclByb2R1Y3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgLnByb2R1Y3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgLnVuaXRfcXVhbnRpdGllc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKCB1bml0UXVhbnRpdHkgPT4gdW5pdFF1YW50aXR5LmlkID09PSBvcmRlclByb2R1Y3QudW5pdF9xdWFudGl0eV9pZCApWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvcmRlclByb2R1Y3Q7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIHdlJ2xsIHJlZGVmaW5lIHRoZSBvcmRlciB0eXBlXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIG9yZGVyLnR5cGUgICAgICAgICAgPSAgIHRoaXMudHlwZXMuZ2V0VmFsdWUoKS5maWx0ZXIoIHR5cGUgPT4gdHlwZS5pZGVudGlmaWVyID09PSBvcmRlci50eXBlIClbMF07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiB0aGUgYWRkcmVzcyBpcyBwcm92aWRlZCBkaWZmZXJlbnRseVxyXG4gICAgICAgICAgICAgICAgICogdGhlbiB3ZSBuZWVkIHRvIHJlYnVpbGQgaXQgdGhlIHdheSBpdCdzIHNhdmVkIGFuZCB1c2VkXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIG9yZGVyLmFkZHJlc3NlcyAgICAgPSAgIHtcclxuICAgICAgICAgICAgICAgICAgICBzaGlwcGluZyAgICA6ICAgb3JkZXIuc2hpcHBpbmdfYWRkcmVzcyxcclxuICAgICAgICAgICAgICAgICAgICBiaWxsaW5nICAgICA6ICAgb3JkZXIuYmlsbGluZ19hZGRyZXNzXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgZGVsZXRlIG9yZGVyLnNoaXBwaW5nX2FkZHJlc3M7XHJcbiAgICAgICAgICAgICAgICBkZWxldGUgb3JkZXIuYmlsbGluZ19hZGRyZXNzO1xyXG5cclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBsZXQncyBhbGwgc2V0LCBsZXQncyBsb2FkIHRoZSBvcmRlclxyXG4gICAgICAgICAgICAgICAgICogZnJvbSBub3cuIE5vIGZ1cnRoZXIgY2hhbmdlIGlzIHJlcXVpcmVkXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgdGhpcy5idWlsZE9yZGVyKCBvcmRlciApO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5idWlsZFByb2R1Y3RzKCBwcm9kdWN0cyApO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RDdXN0b21lciggb3JkZXIuY3VzdG9tZXIgKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgYnVpbGRPcmRlciggb3JkZXIgKSB7XHJcbiAgICAgICAgdGhpcy5vcmRlci5uZXh0KCBvcmRlciApO1xyXG4gICAgfVxyXG5cclxuICAgIGJ1aWxkUHJvZHVjdHMoIHByb2R1Y3RzICkge1xyXG4gICAgICAgIHRoaXMucmVmcmVzaFByb2R1Y3RzKCBwcm9kdWN0cyApO1xyXG4gICAgICAgIHRoaXMucHJvZHVjdHMubmV4dCggcHJvZHVjdHMgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcmludE9yZGVyKCBvcmRlcl9pZCApIHtcclxuICAgICAgICBjb25zdCBvcHRpb25zICAgICAgICAgICA9ICAgdGhpcy5vcHRpb25zLmdldFZhbHVlKCk7XHJcblxyXG4gICAgICAgIGlmICggb3B0aW9ucy5uc19wb3NfcHJpbnRpbmdfZW5hYmxlZF9mb3IgPT09ICdkaXNhYmxlZCcgKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByaW50U2VjdGlvbiAgICAgID0gICBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnaWZyYW1lJyApO1xyXG4gICAgICAgIHByaW50U2VjdGlvbi5pZCAgICAgICAgID0gICAncHJpbnRpbmctc2VjdGlvbic7XHJcbiAgICAgICAgcHJpbnRTZWN0aW9uLmNsYXNzTmFtZSAgPSAgICdoaWRkZW4nO1xyXG4gICAgICAgIHByaW50U2VjdGlvbi5zcmMgICAgICAgID0gICB0aGlzLnNldHRpbmdzLmdldFZhbHVlKClbICd1cmxzJyBdWyAncHJpbnRpbmdfdXJsJyBdLnJlcGxhY2UoICd7aWR9Jywgb3JkZXJfaWQgKTtcclxuXHJcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCggcHJpbnRTZWN0aW9uICk7XHJcbiAgICB9XHJcblxyXG4gICAgY29tcHV0ZVBhaWQoKSB7XHJcbiAgICAgICAgY29uc3Qgb3JkZXIgICAgID0gICB0aGlzLl9vcmRlci5nZXRWYWx1ZSgpOyAgIFxyXG4gICAgICAgIG9yZGVyLnRlbmRlcmVkICAgICAgPSAgIDA7XHJcblxyXG4gICAgICAgIGlmICggb3JkZXIucGF5bWVudHMubGVuZ3RoID4gMCApIHtcclxuICAgICAgICAgICAgb3JkZXIudGVuZGVyZWQgICAgICA9ICAgb3JkZXIucGF5bWVudHMubWFwKCBwID0+IHAudmFsdWUgKS5yZWR1Y2UoICggYiwgYSApID0+IGEgKyBiICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIG9yZGVyLnRlbmRlcmVkID49IG9yZGVyLnRvdGFsICkge1xyXG4gICAgICAgICAgICBvcmRlci5wYXltZW50X3N0YXR1cyAgICA9ICAgJ3BhaWQnO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoIG9yZGVyLnRlbmRlcmVkID4gMCAmJiBvcmRlci50ZW5kZXJlZCA8IG9yZGVyLnRvdGFsICkge1xyXG4gICAgICAgICAgICBvcmRlci5wYXltZW50X3N0YXR1cyAgICA9ICAgJ3BhcnRpYWxseV9wYWlkJztcclxuICAgICAgICB9IFxyXG4gICAgICAgIFxyXG4gICAgICAgIG9yZGVyLmNoYW5nZSAgICA9ICAgb3JkZXIudGVuZGVyZWQgLSBvcmRlci50b3RhbDtcclxuXHJcbiAgICAgICAgdGhpcy5fb3JkZXIubmV4dCggb3JkZXIgKTtcclxuICAgIH1cclxuXHJcbiAgICBzZXRQYXltZW50QWN0aXZlKCBwYXltZW50ICkge1xyXG4gICAgICAgIGNvbnN0IHBheW1lbnRzICA9ICAgdGhpcy5fcGF5bWVudHNUeXBlLmdldFZhbHVlKCk7XHJcbiAgICAgICAgY29uc3QgaW5kZXggICAgID0gICBwYXltZW50cy5pbmRleE9mKCBwYXltZW50ICk7XHJcbiAgICAgICAgcGF5bWVudHMuZm9yRWFjaCggcCA9PiBwLnNlbGVjdGVkID0gZmFsc2UgKTtcclxuICAgICAgICBwYXltZW50c1sgaW5kZXggXS5zZWxlY3RlZCAgPSAgIHRydWU7XHJcbiAgICAgICAgdGhpcy5fcGF5bWVudHNUeXBlLm5leHQoIHBheW1lbnRzICk7XHJcbiAgICB9XHJcblxyXG4gICAgZGVmaW5lZFBheW1lbnRzVHlwZSggcGF5bWVudHMgKSB7XHJcbiAgICAgICAgdGhpcy5fcGF5bWVudHNUeXBlLm5leHQoIHBheW1lbnRzICk7XHJcbiAgICB9XHJcblxyXG4gICAgc2VsZWN0Q3VzdG9tZXIoIGN1c3RvbWVyICkge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSggKCByZXNvbHZlLCByZWplY3QgKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IG9yZGVyICAgICAgICAgPSAgIHRoaXMub3JkZXIuZ2V0VmFsdWUoKTtcclxuICAgICAgICAgICAgb3JkZXIuY3VzdG9tZXIgICAgICA9ICAgY3VzdG9tZXI7XHJcbiAgICAgICAgICAgIG9yZGVyLmN1c3RvbWVyX2lkICAgPSAgIGN1c3RvbWVyLmlkXHJcbiAgICAgICAgICAgIHRoaXMub3JkZXIubmV4dCggb3JkZXIgKTtcclxuICAgIFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogYXN5bmNocm9ub3VzbHkgd2UgY2FuIGxvYWRcclxuICAgICAgICAgICAgICogY3VzdG9tZXIgbWV0YSBkYXRhXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBpZiAoIGN1c3RvbWVyLmdyb3VwID09PSB1bmRlZmluZWQgfHwgY3VzdG9tZXIuZ3JvdXAgPT09IG51bGwgKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICBuc0h0dHBDbGllbnQuZ2V0KCBgL2FwaS9uZXhvcG9zL3Y0L2N1c3RvbWVycy8ke2N1c3RvbWVyLmlkfS9ncm91cGAgKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoIGdyb3VwID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIuY3VzdG9tZXIuZ3JvdXAgICAgICAgID0gICBncm91cDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcmRlci5uZXh0KCBvcmRlciApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCBvcmRlciApO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sICggZXJyb3IgKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCggZXJyb3IgKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZUNhcnQoIGN1cnJlbnQsIHVwZGF0ZSApIHtcclxuICAgICAgICBmb3IoIGxldCBrZXkgaW4gdXBkYXRlICkge1xyXG4gICAgICAgICAgICBpZiAoIHVwZGF0ZVsga2V5IF0gIT09IHVuZGVmaW5lZCApIHtcclxuICAgICAgICAgICAgICAgIFZ1ZS5zZXQoIGN1cnJlbnQsIGtleSwgdXBkYXRlWyBrZXkgXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMub3JkZXIubmV4dCggY3VycmVudCApO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIGV4cGxpY2l0ZWx5IGhlcmUgd2UgZG8gbWFudWFsbHkgcmVmcmVzaCB0aGUgY2FydFxyXG4gICAgICAgICAqIGFzIGlmIHdlIGxpc3RlbiB0byBjYXJ0IHVwZGF0ZSBieSBzdWJzY3JpYmluZyxcclxuICAgICAgICAgKiB0aGF0IHdpbGwgY3JlYXRlIGEgbG9vcCAoaHVnZSBwZXJmb3JtYW5jZSBpc3N1ZSkuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5yZWZyZXNoQ2FydCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogZXZlcnl0aW1lIHRoZSBjYXJ0XHJcbiAgICAgKiByZWZyZXNoZWQsIHdlIG1pZ2h0IG5lZWRcclxuICAgICAqIHRvIHBlcmZvcm0gc29tZSB2ZXJpZmljYXRpb25cclxuICAgICAqL1xyXG4gICAgY2hlY2tDYXJ0KCkge1xyXG4gICAgICAgIGNvbnN0IG9yZGVyICAgICAgICAgICAgICAgICA9ICAgdGhpcy5vcmRlci5nZXRWYWx1ZSgpO1xyXG4gICAgICAgIGNvbnN0IHVubWF0Y2hlZENvbmRpdGlvbnMgICA9ICAgW107XHJcblxyXG4gICAgICAgIG9yZGVyLmNvdXBvbnMuZm9yRWFjaCggY291cG9uID0+IHtcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIGJ5IGRlZmF1bHQgd2UnbGwgYnlwYXNzXHJcbiAgICAgICAgICAgICAqIHRoZSBwcm9kdWN0IGlmIGl0J3Mgbm90IGF2YWlsYWJsZVxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgbGV0IGlzUHJvZHVjdFZhbGlkICA9ICAgdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBpZiB0aGUgY291cG9uIGluY2x1ZGVzIHByb2R1Y3RzXHJcbiAgICAgICAgICAgICAqIHdlIG1ha2Ugc3VyZSB0aGUgcHJvZHVjdHMgYXJlIGluY2x1ZGVkIG9uIHRoZSBjYXJ0XHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBpZiAoIGNvdXBvbi5wcm9kdWN0cy5sZW5ndGggPiAwICkge1xyXG4gICAgICAgICAgICAgICAgaXNQcm9kdWN0VmFsaWQgID0gICBvcmRlci5wcm9kdWN0cy5maWx0ZXIoIHByb2R1Y3QgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb3Vwb24ucHJvZHVjdHMubWFwKCBwID0+IHAucHJvZHVjdF9pZCApLmluY2x1ZGVzKCBwcm9kdWN0LnByb2R1Y3RfaWQgKTtcclxuICAgICAgICAgICAgICAgIH0pLmxlbmd0aCA+IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCAhIGlzUHJvZHVjdFZhbGlkICYmIHVubWF0Y2hlZENvbmRpdGlvbnMuaW5kZXhPZiggY291cG9uICkgPT09IC0xICkge1xyXG4gICAgICAgICAgICAgICAgICAgIHVubWF0Y2hlZENvbmRpdGlvbnMucHVzaCggY291cG9uICk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBieSBkZWZhdWx0IHdlJ2xsIGJ5cGFzc1xyXG4gICAgICAgICAgICAgKiB0aGUgcHJvZHVjdCBpZiBpdCdzIG5vdCBhdmFpbGFibGVcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGxldCBpc0NhdGVnb3J5VmFsaWQgID0gICB0cnVlO1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIGlmIHRoZSBjb3Vwb24gaW5jbHVkZXMgcHJvZHVjdHNcclxuICAgICAgICAgICAgICogd2UgbWFrZSBzdXJlIHRoZSBwcm9kdWN0cyBhcmUgaW5jbHVkZWQgb24gdGhlIGNhcnRcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGlmICggY291cG9uLmNhdGVnb3JpZXMubGVuZ3RoID4gMCApIHtcclxuICAgICAgICAgICAgICAgIGlzQ2F0ZWdvcnlWYWxpZCAgPSAgIG9yZGVyLnByb2R1Y3RzLmZpbHRlciggcHJvZHVjdCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvdXBvbi5jYXRlZ29yaWVzLm1hcCggcCA9PiBwLmNhdGVnb3J5X2lkICkuaW5jbHVkZXMoIHByb2R1Y3QuJG9yaWdpbmFsKCkuY2F0ZWdvcnlfaWQgKTtcclxuICAgICAgICAgICAgICAgIH0pLmxlbmd0aCA+IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCAhIGlzQ2F0ZWdvcnlWYWxpZCAmJiB1bm1hdGNoZWRDb25kaXRpb25zLmluZGV4T2YoIGNvdXBvbiApID09PSAtMSApIHtcclxuICAgICAgICAgICAgICAgICAgICB1bm1hdGNoZWRDb25kaXRpb25zLnB1c2goIGNvdXBvbiApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHVubWF0Y2hlZENvbmRpdGlvbnMuZm9yRWFjaCggY291cG9uID0+IHtcclxuICAgICAgICAgICAgbnNTbmFja0Jhci5lcnJvciggXHJcbiAgICAgICAgICAgICAgICBfXyggJ1RoZSBjb3Vwb25zIFwiJXNcIiBoYXMgYmVlbiByZW1vdmVkIGZyb20gdGhlIGNhcnQsIGFzIGl0XFwncyByZXF1aXJlZCBjb25kaXRpb25zIGFyZSBubyBtb3JlIG1lZXQuJyApXHJcbiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoICclcycsIGNvdXBvbi5uYW1lICksIFxyXG4gICAgICAgICAgICAgICAgX18oICdPa2F5JyApLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IDYwMDBcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlQ291cG9uKCBjb3Vwb24gKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyByZWZyZXNoQ2FydCgpIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBjaGVjayBpZiBhY2NvcmRpbmcgdG8gdGhlIHByb2R1Y3RcclxuICAgICAgICAgKiBhdmFpbGFibGUgb24gdGhlIGNhcnQgdGhlIGNvdXBvbnMgbXVzdCBcclxuICAgICAgICAgKiByZW1haW5zIHRoZSBzYW1lLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMuY2hlY2tDYXJ0KCk7XHJcblxyXG4gICAgICAgIGNvbnN0IHByb2R1Y3RzICAgICAgPSAgIHRoaXMucHJvZHVjdHMuZ2V0VmFsdWUoKTtcclxuICAgICAgICBsZXQgb3JkZXIgICAgICAgICAgID0gICB0aGlzLm9yZGVyLmdldFZhbHVlKCk7XHJcbiAgICAgICAgY29uc3QgcHJvZHVjdFRvdGFsICA9ICAgcHJvZHVjdHNcclxuICAgICAgICAgICAgLm1hcCggcHJvZHVjdCA9PiBwcm9kdWN0LnRvdGFsX3ByaWNlICk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKCBwcm9kdWN0VG90YWwubGVuZ3RoID4gMCApIHtcclxuICAgICAgICAgICAgb3JkZXIuc3VidG90YWwgID0gICBwcm9kdWN0VG90YWwucmVkdWNlKCAoIGIsIGEgKSA9PiBiICsgYSApO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIG9yZGVyLnN1YnRvdGFsICA9ICAgMDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIHdlJ2xsIGNvbXB1dGUgaGVyZSB0aGUgdmFsdWVcclxuICAgICAgICAgKiBvZiB0aGUgY291cG9uc1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNvbnN0IHRvdGFsVmFsdWUgICAgPSAgIG9yZGVyLmNvdXBvbnMubWFwKCBjdXN0b21lckNvdXBvbiA9PiB7XHJcbiAgICAgICAgICAgIGlmICggY3VzdG9tZXJDb3Vwb24udHlwZSA9PT0gJ3BlcmNlbnRhZ2VfZGlzY291bnQnICkge1xyXG4gICAgICAgICAgICAgICAgY3VzdG9tZXJDb3Vwb24udmFsdWUgICAgPSAgICggb3JkZXIuc3VidG90YWwgKiBjdXN0b21lckNvdXBvbi5kaXNjb3VudF92YWx1ZSApIC8gMTAwO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGN1c3RvbWVyQ291cG9uLnZhbHVlO1xyXG4gICAgICAgICAgICB9IFxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgY3VzdG9tZXJDb3Vwb24udmFsdWUgICAgPSAgIGN1c3RvbWVyQ291cG9uLmRpc2NvdW50X3ZhbHVlO1xyXG4gICAgICAgICAgICByZXR1cm4gY3VzdG9tZXJDb3Vwb24udmFsdWU7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIG9yZGVyLnRvdGFsX2NvdXBvbnMgICAgICAgICA9ICAgMDtcclxuICAgICAgICBpZiAoIHRvdGFsVmFsdWUubGVuZ3RoID4gMCApIHtcclxuICAgICAgICAgICAgb3JkZXIudG90YWxfY291cG9ucyAgICAgPSAgIHRvdGFsVmFsdWUucmVkdWNlKCAoIGJlZm9yZSwgYWZ0ZXIgKSA9PiBiZWZvcmUgKyBhZnRlciApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCBvcmRlci5kaXNjb3VudF90eXBlID09PSAncGVyY2VudGFnZScgKSB7XHJcbiAgICAgICAgICAgIG9yZGVyLmRpc2NvdW50ICAgPSAgICggb3JkZXIuZGlzY291bnRfcGVyY2VudGFnZSAqIG9yZGVyLnN1YnRvdGFsICkgLyAxMDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBpZiB0aGUgZGlzY291bnQgYW1vdW50IGlzIGdyZWF0aGVyXHJcbiAgICAgICAgICogdGhhbiB0aGUgc3VidG90YWwsIHRoZSBkaXNjb3VudCBhbW91bnRcclxuICAgICAgICAgKiB3aWxsIGJlIHNldCB0byB0aGUgb3JkZXIuc3VidG90YWxcclxuICAgICAgICAgKi9cclxuICAgICAgICBpZiAoIG9yZGVyLmRpc2NvdW50ID4gb3JkZXIuc3VidG90YWwgJiYgb3JkZXIudG90YWxfY291cG9ucyA9PT0gMCApIHtcclxuICAgICAgICAgICAgb3JkZXIuZGlzY291bnQgPSBvcmRlci5zdWJ0b3RhbDtcclxuICAgICAgICAgICAgbnNTbmFja0Jhci5pbmZvKCAnVGhlIGRpc2NvdW50IGhhcyBiZWVuIHNldCB0byB0aGUgY2FydCBzdWJ0b3RhbCcgKVxyXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogc2F2ZSBhY3R1YWwgY2hhbmdlIHRvIGVuc3VyZVxyXG4gICAgICAgICAqIGFsbCBsaXN0ZW5lciBhcmUgdXAgdG8gZGF0ZS5cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLm9yZGVyLm5leHQoIG9yZGVyICk7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIHdpbGwgY29tcHV0ZSB0aGUgdGF4ZXMgYmFzZWQgb24gXHJcbiAgICAgICAgICogdGhlIGFjdHVhbCBzdGF0ZSBvZiB0aGUgb3JkZXJcclxuICAgICAgICAgKi9cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSAgPSAgIGF3YWl0IHRoaXMuY29tcHV0ZVRheGVzKCk7XHJcbiAgICAgICAgICAgIG9yZGVyICAgICAgICAgICA9ICAgcmVzcG9uc2VbICdkYXRhJyBdLm9yZGVyO1xyXG4gICAgICAgIH0gY2F0Y2goIGV4Y2VwdGlvbiApIHtcclxuICAgICAgICAgICAgaWYgKCBleGNlcHRpb24gIT09IGZhbHNlICYmIGV4Y2VwdGlvbi5tZXNzYWdlICE9PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBleGNlcHRpb24ubWVzc2FnZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogcmV0cmVpdmUgYWxsIHByb2R1Y3RzIHRheGVzXHJcbiAgICAgICAgICogYW5kIHN1bSB0aGUgdG90YWwuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgY29uc3QgdG90YWxUYXhlcyAgICAgICAgPSAgIHByb2R1Y3RzLm1hcCggKCBwcm9kdWN0OiBPcmRlclByb2R1Y3QgKSA9PiBwcm9kdWN0LnRheF92YWx1ZSApO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiB0YXggbWlnaHQgYmUgY29tcHV0ZWQgYWJvdmUgdGhlIHRheCB0aGF0IGN1cnJlbnRseVxyXG4gICAgICAgICAqIGFwcGxpZSB0byB0aGUgaXRlbXMuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgb3JkZXIudGF4X3ZhbHVlICAgICAgICAgPSAgIDA7XHJcbiAgICAgICAgY29uc3QgdmF0VHlwZSAgICAgICAgICAgPSAgIHRoaXMub3B0aW9ucy5nZXRWYWx1ZSgpLm5zX3Bvc192YXQ7XHJcblxyXG4gICAgICAgIGlmKCBbICdwcm9kdWN0c192YXQnLCAncHJvZHVjdHNfZmxhdF92YXQnLCAncHJvZHVjdHNfdmFyaWFibGVfdmF0JyBdLmluY2x1ZGVzKCB2YXRUeXBlICkgJiYgdG90YWxUYXhlcy5sZW5ndGggPiAwICkge1xyXG4gICAgICAgICAgICBvcmRlci50YXhfdmFsdWUgICAgKz0gICB0b3RhbFRheGVzLnJlZHVjZSggKCBiLCBhICkgPT4gYiArIGEgKTtcclxuICAgICAgICB9IFxyXG4gICAgICAgIFxyXG4gICAgICAgIGlmICggWyAnZmxhdF92YXQnLCAndmFyaWFibGVfdmF0JywgJ3Byb2R1Y3RzX3ZhcmlhYmxlX3ZhdCcgXS5pbmNsdWRlcyggdmF0VHlwZSApICYmIG9yZGVyLnRheGVzICYmIG9yZGVyLnRheGVzLmxlbmd0aCA+IDAgKSB7XHJcbiAgICAgICAgICAgIG9yZGVyLnRheF92YWx1ZSAgICAgKz0gICBvcmRlci50YXhlc1xyXG4gICAgICAgICAgICAgICAgLm1hcCggdGF4ID0+IHRheC50YXhfdmFsdWUgKVxyXG4gICAgICAgICAgICAgICAgLnJlZHVjZSggKCBiZWZvcmUsIGFmdGVyICkgPT4gYmVmb3JlICsgYWZ0ZXIgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIG9yZGVyLnRvdGFsICAgICAgICAgICAgID0gICAoIG9yZGVyLnN1YnRvdGFsICsgb3JkZXIuc2hpcHBpbmcgKyBvcmRlci50YXhfdmFsdWUgKSAtIG9yZGVyLmRpc2NvdW50IC0gb3JkZXIudG90YWxfY291cG9ucztcclxuICAgICAgICBvcmRlci5wcm9kdWN0cyAgICAgICAgICA9ICAgcHJvZHVjdHM7XHJcbiAgICAgICAgb3JkZXIudG90YWxfcHJvZHVjdHMgICAgPSAgIHByb2R1Y3RzLmxlbmd0aFxyXG5cclxuICAgICAgICB0aGlzLm9yZGVyLm5leHQoIG9yZGVyICk7XHJcblxyXG4gICAgICAgIG5zSG9va3MuZG9BY3Rpb24oICducy1jYXJ0LWFmdGVyLXJlZnJlc2hlZCcsIG9yZGVyICk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgYWN0dWFsIHN0b2NrIHVzZWQgYnkgdGhlIHByb2R1Y3RcclxuICAgICAqIHVzaW5nIHRoZSBkZWZpbmVkIHVuaXRcclxuICAgICAqIEBwYXJhbSBwcm9kdWN0X2lkIFxyXG4gICAgICogQHBhcmFtIHVuaXRfaWQgXHJcbiAgICAgKi9cclxuICAgIGdldFN0b2NrVXNhZ2UoIHByb2R1Y3RfaWQ6IG51bWJlciwgdW5pdF9xdWFudGl0eV9pZDogbnVtYmVyICkge1xyXG4gICAgICAgIGNvbnN0IHN0b2NrcyAgICA9ICAgdGhpcy5fcHJvZHVjdHMuZ2V0VmFsdWUoKS5maWx0ZXIoIChwcm9kdWN0OiBPcmRlclByb2R1Y3QgKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBwcm9kdWN0LnByb2R1Y3RfaWQgPT09IHByb2R1Y3RfaWQgJiYgcHJvZHVjdC51bml0X3F1YW50aXR5X2lkID09PSB1bml0X3F1YW50aXR5X2lkO1xyXG4gICAgICAgIH0pLm1hcCggcHJvZHVjdCA9PiBwcm9kdWN0LnF1YW50aXR5ICk7XHJcblxyXG4gICAgICAgIGlmICggc3RvY2tzLmxlbmd0aCA+IDAgKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBzdG9ja3MucmVkdWNlKCAoIGIsIGEgKSA9PiBiICsgYSApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiB0aGlzIGlzIHJlc29sdmVkIHdoZW4gYSBwcm9kdWN0IGlzIGJlaW5nIGFkZGVkIHRvIHRoZVxyXG4gICAgICogY2FydC4gVGhhdCB3aWxsIGhlbHAgdG8gbXV0YXRlIHRoZSBwcm9kdWN0IGJlZm9yZSBcclxuICAgICAqIGl0J3MgYWRkZWQgdGhlIGNhcnQuXHJcbiAgICAgKi9cclxuICAgIGFkZFRvQ2FydFF1ZXVlICA9ICAgW1xyXG4gICAgICAgIFByb2R1Y3RVbml0UHJvbWlzZSxcclxuICAgICAgICBQcm9kdWN0UXVhbnRpdHlQcm9taXNlXHJcbiAgICBdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUHJvY2VzcyB0aGUgaXRlbSB0byBhZGQgaXQgdG8gdGhlIGNhcnRcclxuICAgICAqIEBwYXJhbSBwcm9kdWN0IFxyXG4gICAgICovXHJcbiAgICBhc3luYyBhZGRUb0NhcnQoIHByb2R1Y3QgKSB7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFRoaXMgaXMgd2hlcmUgYWxsIHRoZSBtdXRhdGlvbiBtYWRlIGJ5IHRoZSAgXHJcbiAgICAgICAgICogcXVldWUgcHJvbWlzZXMgYXJlIHN0b3JlZC5cclxuICAgICAgICAgKi9cclxuICAgICAgICBsZXQgcHJvZHVjdERhdGEgICA9ICAgbmV3IE9iamVjdDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogTGV0J3MgY29tYmllbiB0aGUgYnVpbHQgcHJvZHVjdFxyXG4gICAgICAgICAqIHdpdGggdGhlIGRhdGEgcmVzb2x2ZWQgYnkgdGhlIHByb21pc2VzXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgbGV0IGNhcnRQcm9kdWN0OiBPcmRlclByb2R1Y3QgICA9ICB7XHJcbiAgICAgICAgICAgIHByb2R1Y3RfaWQgICAgICAgICAgOiBwcm9kdWN0LmlkLFxyXG4gICAgICAgICAgICBuYW1lICAgICAgICAgICAgICAgIDogcHJvZHVjdC5uYW1lLFxyXG4gICAgICAgICAgICBkaXNjb3VudF90eXBlICAgICAgIDogJ3BlcmNlbnRhZ2UnLFxyXG4gICAgICAgICAgICBkaXNjb3VudCAgICAgICAgICAgIDogMCxcclxuICAgICAgICAgICAgZGlzY291bnRfcGVyY2VudGFnZSA6IDAsXHJcbiAgICAgICAgICAgIHF1YW50aXR5ICAgICAgICAgICAgOiAwLFxyXG4gICAgICAgICAgICB0YXhfZ3JvdXBfaWQgICAgICAgIDogcHJvZHVjdC50YXhfZ3JvdXBfaWQsXHJcbiAgICAgICAgICAgIHRheF92YWx1ZSAgICAgICAgICAgOiAwLCAvLyBpcyBjb21wdXRlZCBhdXRvbWF0aWNhbGx5IHVzaW5nICRvcmlnaW5hbCgpXHJcbiAgICAgICAgICAgIHVuaXRfcHJpY2UgICAgICAgICAgOiAwLFxyXG4gICAgICAgICAgICB0b3RhbF9wcmljZSAgICAgICAgIDogMCxcclxuICAgICAgICAgICAgbW9kZSAgICAgICAgICAgICAgICA6ICdub3JtYWwnLFxyXG4gICAgICAgICAgICAkb3JpZ2luYWwgICAgICAgICAgIDogKCkgPT4gcHJvZHVjdFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIHdpbGwgZGV0ZXJtaW4gaWYgdGhlIFxyXG4gICAgICAgICAqIHNjcmlwdCBpcyBwcm9jZXNzaW5nIHRoZSBhZGQgcXVldWVcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLl9wcm9jZXNzaW5nQWRkUXVldWUgICAgPSAgIHRydWU7XHJcblxyXG4gICAgICAgIGZvciggbGV0IGluZGV4IGluIHRoaXMuYWRkVG9DYXJ0UXVldWUgKSB7XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogdGhlIHBvcHVwIHByb21pc2UgcmVjZWl2ZXMgdGhlIHByb2R1Y3QgdGhhdFxyXG4gICAgICAgICAgICAgKiBpcyBhYm92ZSB0byBiZSBhZGRlZC4gSG9wZWZ1bGx5IGFzIGl0J3MgcGFzc2VkIGJ5IHJlZmVyZW5jZVxyXG4gICAgICAgICAgICAgKiB1cGRhdGluZyB0aGUgcHJvZHVjdCBzaG91bGQgbXV0YXRlIHRoYXQgb25jZSB0aGUgcXVldWUgaXMgaGFuZGxlZC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlSW5zdGFuY2UgICA9ICAgbmV3IHRoaXMuYWRkVG9DYXJ0UXVldWVbIGluZGV4IF0oIGNhcnRQcm9kdWN0ICk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgICAgICAgICAgICA9ICAgPE9iamVjdD4oYXdhaXQgcHJvbWlzZUluc3RhbmNlLnJ1biggcHJvZHVjdERhdGEgKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBXZSBqdXN0IG1peCBib3RoIHRvIG1ha2Ugc3VyZVxyXG4gICAgICAgICAgICAgICAgICogdGhlIG11dGF0ZWQgdmFsdWUgb3ZlcndyaXRlIHByZXZpb3VzbHkgZGVmaW5lZCB2YWx1ZXMuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIHByb2R1Y3REYXRhICAgICAgICAgICAgID0gICB7IC4uLnByb2R1Y3REYXRhLCAuLi5yZXN1bHQgfTtcclxuXHJcbiAgICAgICAgICAgIH0gY2F0Y2goIGJyb2tlblByb21pc2UgKSB7XHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIGlmIGEgcG9wdXAgcmVzb2x2ZSBcImZhbHNlXCIsXHJcbiAgICAgICAgICAgICAgICAgKiB0aGF0IG1lYW5zIGZvciBzb21lIHJlYXNvbiB0aGUgUHJvbWlzZSBoYXNcclxuICAgICAgICAgICAgICAgICAqIGJlZW4gYnJva2VuLCB0aGVyZWZvcmUgd2UgbmVlZCB0byBzdG9wIHRoZSBxdWV1ZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgaWYgKCBicm9rZW5Qcm9taXNlID09PSBmYWxzZSApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wcm9jZXNzaW5nQWRkUXVldWUgICAgPSAgIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBlbmQgcHJvY2Vlc2luZyBhZGQgcXVldWVcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLl9wcm9jZXNzaW5nQWRkUXVldWUgICAgPSAgIGZhbHNlO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBMZXQncyBjb21iaWVuIHRoZSBidWlsdCBwcm9kdWN0XHJcbiAgICAgICAgICogd2l0aCB0aGUgZGF0YSByZXNvbHZlZCBieSB0aGUgcHJvbWlzZXNcclxuICAgICAgICAgKi9cclxuICAgICAgICBjYXJ0UHJvZHVjdCAgID0gICB7IC4uLmNhcnRQcm9kdWN0LCAuLi5wcm9kdWN0RGF0YSB9O1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIHJldHJlaXZlIHByb2R1Y3QgdGhhdCBcclxuICAgICAgICAgKiBhcmUgY3VycmVudGx5IHN0b3JlZFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNvbnN0IHByb2R1Y3RzICAgICAgPSAgIHRoaXMuX3Byb2R1Y3RzLmdldFZhbHVlKCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogcHVzaCB0aGUgbmV3IHByb2R1Y3RcclxuICAgICAgICAgKiBhdCB0aGUgZnJvbnQgb2YgdGhlIGNhcnRcclxuICAgICAgICAgKi9cclxuICAgICAgICBwcm9kdWN0cy51bnNoaWZ0KCBjYXJ0UHJvZHVjdCApO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBPbmNlIHRoZSBwcm9kdWN0IGhhcyBiZWVuIGFkZGVkIHRvIHRoZSBjYXJ0XHJcbiAgICAgICAgICogaXQncyBiZWluZyBjb21wdXRlZFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMucmVmcmVzaFByb2R1Y3RzKCBwcm9kdWN0cyApO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBkaXNwYXRjaCBldmVudCB0aGF0IHRoZSBcclxuICAgICAgICAgKiBwcm9kdWN0IGhhcyBiZWVuIGFkZGVkLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMuX3Byb2R1Y3RzLm5leHQoIHByb2R1Y3RzICk7XHJcbiAgICB9XHJcblxyXG4gICAgZGVmaW5lVHlwZXMoIHR5cGVzICkge1xyXG4gICAgICAgIHRoaXMuX3R5cGVzLm5leHQoIHR5cGVzICk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVtb3ZlUHJvZHVjdCggcHJvZHVjdCApIHtcclxuICAgICAgICBjb25zdCBwcm9kdWN0cyAgPSAgIHRoaXMuX3Byb2R1Y3RzLmdldFZhbHVlKCk7XHJcbiAgICAgICAgY29uc3QgaW5kZXggICAgID0gICBwcm9kdWN0cy5pbmRleE9mKCBwcm9kdWN0ICk7XHJcbiAgICAgICAgcHJvZHVjdHMuc3BsaWNlKCBpbmRleCwgMSApO1xyXG4gICAgICAgIHRoaXMuX3Byb2R1Y3RzLm5leHQoIHByb2R1Y3RzICk7XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlUHJvZHVjdCggcHJvZHVjdCwgZGF0YSwgaW5kZXggPSBudWxsICkge1xyXG4gICAgICAgIGNvbnN0IHByb2R1Y3RzICAgICAgPSAgIHRoaXMuX3Byb2R1Y3RzLmdldFZhbHVlKCk7XHJcbiAgICAgICAgaW5kZXggICAgICAgICAgICAgICA9ICAgaW5kZXggPT09IG51bGwgPyBwcm9kdWN0cy5pbmRleE9mKCBwcm9kdWN0ICkgOiBpbmRleDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogdG8gZW5zdXJlIFZ1ZSB1cGRhdGVzIGFjY29yZGluZ2x5LlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFZ1ZS5zZXQoIHByb2R1Y3RzLCBpbmRleCwgeyAuLi5wcm9kdWN0LCAuLi5kYXRhIH0pO1xyXG5cclxuICAgICAgICB0aGlzLnJlZnJlc2hQcm9kdWN0cyggcHJvZHVjdHMgKTtcclxuICAgICAgICB0aGlzLl9wcm9kdWN0cy5uZXh0KCBwcm9kdWN0cyApO1xyXG4gICAgfVxyXG5cclxuICAgIHJlZnJlc2hQcm9kdWN0cyggcHJvZHVjdHMgKSB7XHJcbiAgICAgICAgcHJvZHVjdHMuZm9yRWFjaCggcHJvZHVjdCA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuY29tcHV0ZVByb2R1Y3QoIHByb2R1Y3QgKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBjb21wdXRlUHJvZHVjdCggcHJvZHVjdDogT3JkZXJQcm9kdWN0ICkge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIGRldGVybWluaW5nIHdoYXQgaXMgdGhlIFxyXG4gICAgICAgICAqIHJlYWwgc2FsZSBwcmljZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGlmICggcHJvZHVjdC5tb2RlID09PSAnbm9ybWFsJyApIHtcclxuICAgICAgICAgICAgcHJvZHVjdC51bml0X3ByaWNlICAgICAgICAgID0gICAgICAgcHJvZHVjdC4kcXVhbnRpdGllcygpLnNhbGVfcHJpY2U7XHJcbiAgICAgICAgICAgIHByb2R1Y3QudGF4X3ZhbHVlICAgICAgICAgICA9ICAgICAgIHByb2R1Y3QuJHF1YW50aXRpZXMoKS5zYWxlX3ByaWNlX3RheCAqIHByb2R1Y3QucXVhbnRpdHk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcHJvZHVjdC51bml0X3ByaWNlICAgICAgICAgID0gICAgICAgcHJvZHVjdC4kcXVhbnRpdGllcygpLndob2xlc2FsZV9wcmljZTtcclxuICAgICAgICAgICAgcHJvZHVjdC50YXhfdmFsdWUgICAgICAgICAgID0gICAgICAgcHJvZHVjdC4kcXVhbnRpdGllcygpLndob2xlc2FsZV9wcmljZV90YXggKiBwcm9kdWN0LnF1YW50aXR5O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogY29tcHV0aW5nIHRoZSBkaXNjb3VudCB3aGVuIGl0J3MgXHJcbiAgICAgICAgICogYmFzZWQgb24gYSBwZXJjZW50YWdlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgaWYgKFsgJ2ZsYXQnLCAncGVyY2VudGFnZScgXS5pbmNsdWRlcyggcHJvZHVjdC5kaXNjb3VudF90eXBlICkgKSB7XHJcbiAgICAgICAgICAgIGlmICggcHJvZHVjdC5kaXNjb3VudF90eXBlID09PSAncGVyY2VudGFnZScgKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9kdWN0LmRpc2NvdW50ICA9ICAgKCAoIHByb2R1Y3QudW5pdF9wcmljZSAqIHByb2R1Y3QuZGlzY291bnRfcGVyY2VudGFnZSApIC8gMTAwICkgKiBwcm9kdWN0LnF1YW50aXR5O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBwcm9kdWN0LnRvdGFsX3ByaWNlICAgICAgICAgPSAgICggcHJvZHVjdC51bml0X3ByaWNlICogcHJvZHVjdC5xdWFudGl0eSApIC0gcHJvZHVjdC5kaXNjb3VudDtcclxuXHJcbiAgICAgICAgbnNIb29rcy5kb0FjdGlvbiggJ25zLWFmdGVyLXByb2R1Y3QtY29tcHV0ZWQnLCBwcm9kdWN0ICk7XHJcbiAgICB9XHJcblxyXG4gICAgbG9hZEN1c3RvbWVyKCBpZCApIHtcclxuICAgICAgICByZXR1cm4gbnNIdHRwQ2xpZW50LmdldCggYC9hcGkvbmV4b3Bvcy92NC9jdXN0b21lcnMvJHtpZH1gICk7XHJcbiAgICB9XHJcblxyXG4gICAgZGVmaW5lU2V0dGluZ3MoIHNldHRpbmdzICkge1xyXG4gICAgICAgIHRoaXMuX3NldHRpbmdzLm5leHQoIHNldHRpbmdzICk7XHJcbiAgICB9XHJcblxyXG4gICAgdm9pZE9yZGVyKCBvcmRlciApIHtcclxuICAgICAgICBpZiAoIG9yZGVyLmlkICE9PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgIGlmICggWyAnaG9sZCcgXS5pbmNsdWRlcyggb3JkZXIucGF5bWVudF9zdGF0dXMgKSApIHtcclxuICAgICAgICAgICAgICAgIFBvcHVwLnNob3coIE5zQ29uZmlybVBvcHVwLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdPcmRlciBEZWxldGlvbicsXHJcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ1RoZSBjdXJyZW50IG9yZGVyIHdpbGwgYmUgZGVsZXRlZCBhcyBubyBwYXltZW50IGhhcyBiZWVuIG1hZGUgc28gZmFyLicsXHJcbiAgICAgICAgICAgICAgICAgICAgb25BY3Rpb246ICggYWN0aW9uICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGFjdGlvbiApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zSHR0cENsaWVudC5kZWxldGUoIGAvYXBpL25leG9wb3MvdjQvb3JkZXJzLyR7b3JkZXIuaWR9YCApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZSggKCByZXN1bHQ6IGFueSApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnNTbmFja0Jhci5zdWNjZXNzKCByZXN1bHQubWVzc2FnZSApLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgKCBlcnJvciApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5zU25hY2tCYXIuZXJyb3IoIGVycm9yLm1lc3NhZ2UgKS5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBQb3B1cC5zaG93KCBOc1Byb21wdFBvcHVwLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdWb2lkIFRoZSBPcmRlcicsXHJcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ1RoZSBjdXJyZW50IG9yZGVyIHdpbGwgYmUgdm9pZC4gVGhpcyB3aWxsIGNhbmNlbCB0aGUgdHJhbnNhY3Rpb24sIGJ1dCB0aGUgb3JkZXIgd29uXFwndCBiZSBkZWxldGVkLiBGdXJ0aGVyIGRldGFpbHMgYWJvdXQgdGhlIG9wZXJhdGlvbiB3aWxsIGJlIHRyYWNrZWQgb24gdGhlIHJlcG9ydC4gQ29uc2lkZXIgcHJvdmlkaW5nIHRoZSByZWFzb24gb2YgdGhpcyBvcGVyYXRpb24uJyxcclxuICAgICAgICAgICAgICAgICAgICBvbkFjdGlvbjogKCByZWFzb24gKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggcmVhc29uICE9PSBmYWxzZSApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zSHR0cENsaWVudC5wb3N0KCBgL2FwaS9uZXhvcG9zL3Y0L29yZGVycy8ke29yZGVyLmlkfS92b2lkYCwgeyByZWFzb24gfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCAoIHJlc3VsdDogYW55ICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuc1NuYWNrQmFyLnN1Y2Nlc3MoIHJlc3VsdC5tZXNzYWdlICkuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCAoIGVycm9yICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnNTbmFja0Jhci5lcnJvciggZXJyb3IubWVzc2FnZSApLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSAgICAgICAgICAgIFxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIG5zU25hY2tCYXIuZXJyb3IoICdVbmFibGUgdG8gdm9pZCBhbiB1bnBhaWQgb3JkZXIuJyApLnN1YnNjcmliZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhc3luYyB0cmlnZ2VyT3JkZXJUeXBlU2VsZWN0aW9uKCBzZWxlY3RlZFR5cGUgKSB7XHJcbiAgICAgICAgZm9yKCBsZXQgaSA9IDA7IGkgPCB0aGlzLm9yZGVyVHlwZVF1ZXVlLmxlbmd0aDsgaSsrICkge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ICAgID0gICBhd2FpdCB0aGlzLm9yZGVyVHlwZVF1ZXVlW2ldLnByb21pc2UoIHNlbGVjdGVkVHlwZSApO1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coIHJlc3VsdCApO1xyXG4gICAgICAgICAgICB9IGNhdGNoKCBleGNlcHRpb24gKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyggZXhjZXB0aW9uICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgc2V0KCBrZXksIHZhbHVlICkge1xyXG4gICAgICAgIGNvbnN0IHNldHRpbmdzICA9ICAgdGhpcy5zZXR0aW5ncy5nZXRWYWx1ZSgpO1xyXG4gICAgICAgIHNldHRpbmdzWyBrZXkgXSAgICAgPSAgIHZhbHVlO1xyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MubmV4dCggc2V0dGluZ3MgKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQoIGtleSApIHtcclxuICAgICAgICBjb25zdCBzZXR0aW5ncyAgPSAgIHRoaXMuc2V0dGluZ3MuZ2V0VmFsdWUoKTtcclxuICAgICAgICByZXR1cm4gc2V0dGluZ3NbIGtleSBdO1xyXG4gICAgfVxyXG5cclxuICAgIGRlc3Ryb3koKSB7XHJcbiAgICAgICAgdGhpcy5fcHJvZHVjdHMudW5zdWJzY3JpYmUoKTtcclxuICAgICAgICB0aGlzLl9jdXN0b21lcnMudW5zdWJzY3JpYmUoKTtcclxuICAgICAgICB0aGlzLl90eXBlcy51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgIHRoaXMuX2JyZWFkY3J1bWJzLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgdGhpcy5fcGF5bWVudHNUeXBlLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgdGhpcy5fc2NyZWVuLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgdGhpcy5fb3JkZXIudW5zdWJzY3JpYmUoKTtcclxuICAgICAgICB0aGlzLl9zZXR0aW5ncy51bnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG59XHJcblxyXG4oIHdpbmRvdyBhcyBhbnkgKS5QT1MgICAgICAgPSAgIG5ldyBQT1M7XHJcblxyXG5leHBvcnQgY29uc3QgUE9TSW5pdCAgICA9ICAgPFBPUz4oIHdpbmRvdyBhcyBhbnkgKS5QT1M7XHJcbiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./resources/ts/pos-init.ts\n"); -======= -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"POS\", function() { return POS; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"POSInit\", function() { return POSInit; });\n/* harmony import */ var _pages_dashboard_pos_queues_products_product_quantity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pages/dashboard/pos/queues/products/product-quantity */ \"./resources/ts/pages/dashboard/pos/queues/products/product-quantity.ts\");\n/* harmony import */ var _pages_dashboard_pos_queues_products_product_unit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./pages/dashboard/pos/queues/products/product-unit */ \"./resources/ts/pages/dashboard/pos/queues/products/product-unit.ts\");\n/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ \"./node_modules/rxjs/_esm5/index.js\");\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.common.js\");\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(vue__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./bootstrap */ \"./resources/ts/bootstrap.ts\");\n/* harmony import */ var _libraries_responsive__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./libraries/responsive */ \"./resources/ts/libraries/responsive.ts\");\n/* harmony import */ var _libraries_popup__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./libraries/popup */ \"./resources/ts/libraries/popup.ts\");\n/* harmony import */ var _libraries_lang__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./libraries/lang */ \"./resources/ts/libraries/lang.ts\");\nvar __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n};\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * these are dynamic component\r\n * that are loaded conditionally\r\n */\r\nconst NsPosDashboardButton = window.NsPosDashboardButton = __webpack_require__(/*! ./pages/dashboard/pos/header-buttons/ns-pos-dashboard-button */ \"./resources/ts/pages/dashboard/pos/header-buttons/ns-pos-dashboard-button.vue\").default;\r\nconst NsPosPendingOrderButton = window.NsPosPendingOrderButton = __webpack_require__(/*! ./pages/dashboard/pos/header-buttons/ns-pos-pending-orders-button */ \"./resources/ts/pages/dashboard/pos/header-buttons/ns-pos-pending-orders-button.vue\").default;\r\nconst NsPosOrderTypeButton = window.NsPosOrderTypeButton = __webpack_require__(/*! ./pages/dashboard/pos/header-buttons/ns-pos-order-type-button */ \"./resources/ts/pages/dashboard/pos/header-buttons/ns-pos-order-type-button.vue\").default;\r\nconst NsPosCustomersButton = window.NsPosCustomersButton = __webpack_require__(/*! ./pages/dashboard/pos/header-buttons/ns-pos-customers-button */ \"./resources/ts/pages/dashboard/pos/header-buttons/ns-pos-customers-button.vue\").default;\r\nconst NsPosResetButton = window.NsPosResetButton = __webpack_require__(/*! ./pages/dashboard/pos/header-buttons/ns-pos-reset-button */ \"./resources/ts/pages/dashboard/pos/header-buttons/ns-pos-reset-button.vue\").default;\r\nconst NsPosCashRegister = window.NsPosCashRegister = __webpack_require__(/*! ./pages/dashboard/pos/header-buttons/ns-pos-registers-button */ \"./resources/ts/pages/dashboard/pos/header-buttons/ns-pos-registers-button.vue\").default;\r\nconst NsAlertPopup = window.NsAlertPopup = __webpack_require__(/*! ./popups/ns-alert-popup */ \"./resources/ts/popups/ns-alert-popup.vue\").default;\r\nconst NsConfirmPopup = window.NsConfirmPopup = __webpack_require__(/*! ./popups/ns-pos-confirm-popup */ \"./resources/ts/popups/ns-pos-confirm-popup.vue\").default;\r\nconst NsPromptPopup = window.NsPromptPopup = __webpack_require__(/*! ./popups/ns-prompt-popup */ \"./resources/ts/popups/ns-prompt-popup.vue\").default;\r\nconst NsLayawayPopup = window.NsLayawayPopup = __webpack_require__(/*! ./popups/ns-pos-layaway-popup */ \"./resources/ts/popups/ns-pos-layaway-popup.vue\").default;\r\nconst NSPosShippingPopup = window.NsLayawayPopup = __webpack_require__(/*! ./popups/ns-pos-shipping-popup */ \"./resources/ts/popups/ns-pos-shipping-popup.vue\").default;\r\nclass POS {\r\n constructor() {\r\n this._orderTypeProcessQueue = [];\r\n this._initialQueue = [];\r\n this._responsive = new _libraries_responsive__WEBPACK_IMPORTED_MODULE_5__[\"Responsive\"];\r\n this._isSubmitting = false;\r\n this._processingAddQueue = false;\r\n this.defaultOrder = () => {\r\n const order = {\r\n discount_type: null,\r\n title: '',\r\n discount: 0,\r\n register_id: this.get('register') ? this.get('register').id : undefined,\r\n discount_percentage: 0,\r\n subtotal: 0,\r\n total: 0,\r\n coupons: [],\r\n total_coupons: 0,\r\n tendered: 0,\r\n note: '',\r\n note_visibility: 'hidden',\r\n tax_group_id: undefined,\r\n tax_type: undefined,\r\n taxes: [],\r\n tax_groups: [],\r\n payment_status: undefined,\r\n customer_id: undefined,\r\n change: 0,\r\n total_products: 0,\r\n shipping: 0,\r\n tax_value: 0,\r\n shipping_rate: 0,\r\n shipping_type: undefined,\r\n customer: undefined,\r\n type: undefined,\r\n products: [],\r\n instalments: [],\r\n payments: [],\r\n addresses: {\r\n shipping: undefined,\r\n billing: undefined\r\n }\r\n };\r\n return order;\r\n };\r\n /**\r\n * this is resolved when a product is being added to the\r\n * cart. That will help to mutate the product before\r\n * it's added the cart.\r\n */\r\n this.addToCartQueue = [\r\n _pages_dashboard_pos_queues_products_product_unit__WEBPACK_IMPORTED_MODULE_1__[\"ProductUnitPromise\"],\r\n _pages_dashboard_pos_queues_products_product_quantity__WEBPACK_IMPORTED_MODULE_0__[\"ProductQuantityPromise\"]\r\n ];\r\n this.initialize();\r\n }\r\n get screen() {\r\n return this._screen;\r\n }\r\n get visibleSection() {\r\n return this._visibleSection;\r\n }\r\n get paymentsType() {\r\n return this._paymentsType;\r\n }\r\n get order() {\r\n return this._order;\r\n }\r\n get types() {\r\n return this._types;\r\n }\r\n get products() {\r\n return this._products;\r\n }\r\n get customers() {\r\n return this._customers;\r\n }\r\n get options() {\r\n return this._options;\r\n }\r\n get orderTypeQueue() {\r\n return this._orderTypeProcessQueue;\r\n }\r\n get settings() {\r\n return this._settings;\r\n }\r\n get breadcrumbs() {\r\n return this._breadcrumbs;\r\n }\r\n get initialQueue() {\r\n return this._initialQueue;\r\n }\r\n get processingAddQueue() {\r\n return this._processingAddQueue;\r\n }\r\n reset() {\r\n this._isSubmitting = false;\r\n /**\r\n * to reset order details\r\n */\r\n this.order.next(this.defaultOrder());\r\n this._products.next([]);\r\n this._customers.next([]);\r\n this._breadcrumbs.next([]);\r\n this.defineCurrentScreen();\r\n this.processInitialQueue();\r\n this.refreshCart();\r\n }\r\n initialize() {\r\n this._products = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]([]);\r\n this._customers = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]([]);\r\n this._types = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]([]);\r\n this._breadcrumbs = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]([]);\r\n this._screen = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]('');\r\n this._paymentsType = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]([]);\r\n this._visibleSection = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]('both');\r\n this._options = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]({});\r\n this._settings = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"]({});\r\n this._order = new rxjs__WEBPACK_IMPORTED_MODULE_2__[\"BehaviorSubject\"](this.defaultOrder());\r\n this._orderTypeProcessQueue = [\r\n {\r\n identifier: 'handle.delivery-order',\r\n promise: (selectedType) => new Promise((resolve, reject) => {\r\n if (selectedType.identifier === 'delivery') {\r\n return _libraries_popup__WEBPACK_IMPORTED_MODULE_6__[\"Popup\"].show(NSPosShippingPopup, { resolve, reject });\r\n }\r\n reject(false);\r\n })\r\n }\r\n ];\r\n /**\r\n * This initial process will try to detect\r\n * if there is a tax group assigned on the settings\r\n * and set it as default tax group.\r\n */\r\n this.initialQueue.push(() => new Promise((resolve, reject) => {\r\n const options = this.options.getValue();\r\n const order = this.order.getValue();\r\n if (options.ns_pos_tax_group !== false) {\r\n order.tax_group_id = options.ns_pos_tax_group;\r\n order.tax_type = options.ns_pos_tax_type;\r\n this.order.next(order);\r\n }\r\n return resolve({\r\n status: 'success',\r\n message: 'tax group assignated'\r\n });\r\n }));\r\n /**\r\n * this initial process will select the default\r\n * customer and assign him to the POS\r\n */\r\n this.initialQueue.push(() => new Promise((resolve, reject) => {\r\n const options = this.options.getValue();\r\n const order = this.order.getValue();\r\n if (options.ns_customers_default !== false) {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"].get(`/api/nexopos/v4/customers/${options.ns_customers_default}`)\r\n .subscribe(customer => {\r\n this.selectCustomer(customer);\r\n resolve({\r\n status: 'success',\r\n message: Object(_libraries_lang__WEBPACK_IMPORTED_MODULE_7__[\"__\"])('The customer has been loaded')\r\n });\r\n }, (error) => {\r\n reject(error);\r\n });\r\n }\r\n return resolve({\r\n status: 'success',\r\n message: 'tax group assignated'\r\n });\r\n }));\r\n /**\r\n * Whenever there is a change\r\n * on the products, we'll update\r\n * the cart.\r\n */\r\n this.products.subscribe(_ => {\r\n this.refreshCart();\r\n });\r\n /**\r\n * listen to type for updating\r\n * the order accordingly\r\n */\r\n this.types.subscribe(types => {\r\n const selected = types.filter(type => type.selected);\r\n if (selected.length > 0) {\r\n const order = this.order.getValue();\r\n order.type = selected[0];\r\n this.order.next(order);\r\n }\r\n });\r\n /**\r\n * We're handling here the responsive aspect\r\n * of the POS.\r\n */\r\n window.addEventListener('resize', () => {\r\n this._responsive.detect();\r\n this.defineCurrentScreen();\r\n });\r\n this.defineCurrentScreen();\r\n }\r\n /**\r\n * This is the first initial queue\r\n * that runs when the POS is loaded.\r\n * It also run when the pos is reset.\r\n * @return void\r\n */\r\n processInitialQueue() {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n for (let index in this._initialQueue) {\r\n try {\r\n const response = yield this._initialQueue[index]();\r\n }\r\n catch (exception) {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error(exception.message).subscribe();\r\n }\r\n }\r\n });\r\n }\r\n /**\r\n * This methods run as part of the verification\r\n * of the cart refreshing. Cannot refresh the cart.\r\n * @param coupon coupon\r\n */\r\n removeCoupon(coupon) {\r\n const order = this.order.getValue();\r\n const coupons = order.coupons;\r\n const index = coupons.indexOf(coupon);\r\n coupons.splice(index, 1);\r\n order.coupons = coupons;\r\n this.order.next(order);\r\n }\r\n pushCoupon(coupon) {\r\n const order = this.order.getValue();\r\n order.coupons.forEach(_coupon => {\r\n if (_coupon.code === coupon.code) {\r\n const message = Object(_libraries_lang__WEBPACK_IMPORTED_MODULE_7__[\"__\"])('This coupon is already added to the cart');\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error(message)\r\n .subscribe();\r\n throw message;\r\n }\r\n });\r\n order.coupons.push(coupon);\r\n this.order.next(order);\r\n this.refreshCart();\r\n }\r\n get header() {\r\n /**\r\n * As POS object is defined on the\r\n * header, we can use that to reference the buttons (component)\r\n * that needs to be rendered dynamically\r\n */\r\n const data = {\r\n buttons: {\r\n NsPosDashboardButton,\r\n NsPosPendingOrderButton,\r\n NsPosOrderTypeButton,\r\n NsPosCustomersButton,\r\n NsPosResetButton,\r\n }\r\n };\r\n /**\r\n * if the cash register is enabled\r\n * we'll add that button to the list\r\n * of button available.\r\n */\r\n if (this.options.getValue().ns_pos_registers_enabled === 'yes') {\r\n data.buttons['NsPosCashRegister'] = NsPosCashRegister;\r\n }\r\n return data;\r\n }\r\n defineOptions(options) {\r\n this._options.next(options);\r\n }\r\n defineCurrentScreen() {\r\n this._visibleSection.next(['xs', 'sm'].includes(this._responsive.is()) ? 'grid' : 'both');\r\n this._screen.next(this._responsive.is());\r\n }\r\n changeVisibleSection(section) {\r\n if (['both', 'cart', 'grid'].includes(section)) {\r\n if (['cart', 'both'].includes(section)) {\r\n this.refreshCart();\r\n }\r\n this._visibleSection.next(section);\r\n }\r\n }\r\n addPayment(payment) {\r\n if (payment.value > 0) {\r\n const order = this._order.getValue();\r\n order.payments.push(payment);\r\n this._order.next(order);\r\n return this.computePaid();\r\n }\r\n return _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error('Invalid amount.').subscribe();\r\n }\r\n removePayment(payment) {\r\n if (payment.id !== undefined) {\r\n return _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error('Unable to delete a payment attached to the order').subscribe();\r\n }\r\n const order = this._order.getValue();\r\n const index = order.payments.indexOf(payment);\r\n order.payments.splice(index, 1);\r\n this._order.next(order);\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsEvent\"].emit({\r\n identifier: 'ns.pos.remove-payment',\r\n value: payment\r\n });\r\n this.updateCustomerAccount(payment);\r\n this.computePaid();\r\n }\r\n updateCustomerAccount(payment) {\r\n if (payment.identifier === 'account-payment') {\r\n const customer = this.order.getValue().customer;\r\n customer.account_amount += payment.value;\r\n this.selectCustomer(customer);\r\n }\r\n }\r\n getNetPrice(value, rate, type) {\r\n if (type === 'inclusive') {\r\n return (value / (rate + 100)) * 100;\r\n }\r\n else if (type === 'exclusive') {\r\n return ((value / 100) * (rate + 100));\r\n }\r\n }\r\n getVatValue(value, rate, type) {\r\n if (type === 'inclusive') {\r\n return value - this.getNetPrice(value, rate, type);\r\n }\r\n else if (type === 'exclusive') {\r\n return this.getNetPrice(value, rate, type) - value;\r\n }\r\n }\r\n computeTaxes() {\r\n return new Promise((resolve, reject) => {\r\n const order = this.order.getValue();\r\n if (order.tax_group_id === undefined || order.tax_group_id === null) {\r\n return reject(false);\r\n }\r\n const groups = order.tax_groups;\r\n /**\r\n * if the tax group is already cached\r\n * we'll pull that rather than doing a new request.\r\n */\r\n if (groups && groups[order.tax_group_id] !== undefined) {\r\n order.taxes = order.taxes.map(tax => {\r\n tax.tax_value = this.getVatValue(order.subtotal, tax.rate, order.tax_type);\r\n return tax;\r\n });\r\n return resolve({\r\n status: 'success',\r\n data: { tax: groups[order.tax_group_id], order }\r\n });\r\n }\r\n if (order.tax_group_id !== null) {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"].get(`/api/nexopos/v4/taxes/groups/${order.tax_group_id}`)\r\n .subscribe((tax) => {\r\n order.tax_groups = order.tax_groups || [];\r\n order.taxes = tax.taxes.map(tax => {\r\n return {\r\n tax_id: tax.id,\r\n tax_name: tax.name,\r\n rate: parseFloat(tax.rate),\r\n tax_value: this.getVatValue(order.subtotal, tax.rate, order.tax_type)\r\n };\r\n });\r\n /**\r\n * this is set to cache the\r\n * tax group to avoid subsequent request\r\n * to the server.\r\n */\r\n order.tax_groups[tax.id] = tax;\r\n return resolve({\r\n status: 'success',\r\n data: { tax, order }\r\n });\r\n }, (error) => {\r\n return reject(error);\r\n });\r\n }\r\n else {\r\n return reject({\r\n status: 'failed',\r\n message: Object(_libraries_lang__WEBPACK_IMPORTED_MODULE_7__[\"__\"])('No tax group assigned to the order')\r\n });\r\n }\r\n });\r\n }\r\n /**\r\n * This will check if the order can be saved as layway.\r\n * might request additionnal information through a popup.\r\n * @param order Order\r\n */\r\n canProceedAsLaidAway(_order) {\r\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\r\n const minimalPaymentPercent = _order.customer.group.minimal_credit_payment;\r\n const expected = (_order.total * minimalPaymentPercent) / 100;\r\n /**\r\n * checking order details\r\n * installments & payment date\r\n */\r\n try {\r\n const order = yield new Promise((resolve, reject) => {\r\n _libraries_popup__WEBPACK_IMPORTED_MODULE_6__[\"Popup\"].show(NsLayawayPopup, { order: _order, reject, resolve });\r\n });\r\n if (order.tendered < expected) {\r\n const message = `Before saving the order as laid away, a minimum payment of ${vue__WEBPACK_IMPORTED_MODULE_3___default.a.filter('currency')(expected)} is required`;\r\n _libraries_popup__WEBPACK_IMPORTED_MODULE_6__[\"Popup\"].show(NsAlertPopup, { title: 'Unable to proceed', message });\r\n return reject({ status: 'failed', message });\r\n }\r\n return resolve({ status: 'success', message: Object(_libraries_lang__WEBPACK_IMPORTED_MODULE_7__[\"__\"])('Layaway defined'), data: { order } });\r\n }\r\n catch (exception) {\r\n return reject(exception);\r\n }\r\n }));\r\n }\r\n /**\r\n * Fields might be provided to overwrite the default information\r\n * set on the order.\r\n * @param orderFields Object\r\n */\r\n submitOrder(orderFields = {}) {\r\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\r\n var order = Object.assign(Object.assign({}, this.order.getValue()), orderFields);\r\n const minimalPayment = order.customer.group.minimal_credit_payment;\r\n /**\r\n * this verification applies only if the\r\n * order is not \"hold\".\r\n */\r\n if (order.payment_status !== 'hold') {\r\n if (order.payments.length === 0 || order.total > order.tendered) {\r\n if (this.options.getValue().ns_orders_allow_partial === 'no') {\r\n const message = 'Partially paid orders are disabled.';\r\n return reject({ status: 'failed', message });\r\n }\r\n else if (minimalPayment >= 0) {\r\n try {\r\n const result = yield this.canProceedAsLaidAway(order);\r\n /**\r\n * the order might have been updated\r\n * by the layaway popup.\r\n */\r\n order = result.data.order;\r\n }\r\n catch (exception) {\r\n return reject(exception);\r\n }\r\n }\r\n }\r\n }\r\n if (!this._isSubmitting) {\r\n /**\r\n * @todo do we need to set a new value here\r\n * probably the passed value should be send to the server.\r\n */\r\n const method = order.id !== undefined ? 'put' : 'post';\r\n this._isSubmitting = true;\r\n return _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"][method](`/api/nexopos/v4/orders${order.id !== undefined ? '/' + order.id : ''}`, order)\r\n .subscribe(result => {\r\n resolve(result);\r\n this.reset();\r\n /**\r\n * will trigger an acction when\r\n * the order has been successfully submitted\r\n */\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHooks\"].doAction('ns-order-submit-successful', result);\r\n this._isSubmitting = false;\r\n }, (error) => {\r\n this._isSubmitting = false;\r\n reject(error);\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHooks\"].doAction('ns-order-submit-failed', error);\r\n });\r\n }\r\n return reject({ status: 'failed', message: 'An order is currently being processed.' });\r\n }));\r\n }\r\n loadOrder(order_id) {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"].get(`/api/nexopos/v4/orders/${order_id}/pos`)\r\n .subscribe((order) => {\r\n order = Object.assign(Object.assign({}, this.defaultOrder()), order);\r\n /**\r\n * We'll rebuilt the product\r\n */\r\n const products = order.products.map((orderProduct) => {\r\n orderProduct.$original = () => orderProduct.product;\r\n orderProduct.$quantities = () => orderProduct\r\n .product\r\n .unit_quantities\r\n .filter(unitQuantity => unitQuantity.id === orderProduct.unit_quantity_id)[0];\r\n return orderProduct;\r\n });\r\n /**\r\n * we'll redefine the order type\r\n */\r\n order.type = this.types.getValue().filter(type => type.identifier === order.type)[0];\r\n /**\r\n * the address is provided differently\r\n * then we need to rebuild it the way it's saved and used\r\n */\r\n order.addresses = {\r\n shipping: order.shipping_address,\r\n billing: order.billing_address\r\n };\r\n delete order.shipping_address;\r\n delete order.billing_address;\r\n /**\r\n * let's all set, let's load the order\r\n * from now. No further change is required\r\n */\r\n this.buildOrder(order);\r\n this.buildProducts(products);\r\n this.selectCustomer(order.customer);\r\n });\r\n }\r\n buildOrder(order) {\r\n this.order.next(order);\r\n }\r\n buildProducts(products) {\r\n this.refreshProducts(products);\r\n this.products.next(products);\r\n }\r\n printOrder(order_id) {\r\n const options = this.options.getValue();\r\n if (options.ns_pos_printing_enabled_for === 'disabled') {\r\n return false;\r\n }\r\n const printSection = document.createElement('iframe');\r\n printSection.id = 'printing-section';\r\n printSection.className = 'hidden';\r\n printSection.src = this.settings.getValue()['urls']['printing_url'].replace('{id}', order_id);\r\n document.body.appendChild(printSection);\r\n }\r\n computePaid() {\r\n const order = this._order.getValue();\r\n order.tendered = 0;\r\n if (order.payments.length > 0) {\r\n order.tendered = order.payments.map(p => p.value).reduce((b, a) => a + b);\r\n }\r\n if (order.tendered >= order.total) {\r\n order.payment_status = 'paid';\r\n }\r\n else if (order.tendered > 0 && order.tendered < order.total) {\r\n order.payment_status = 'partially_paid';\r\n }\r\n order.change = order.tendered - order.total;\r\n this._order.next(order);\r\n }\r\n setPaymentActive(payment) {\r\n const payments = this._paymentsType.getValue();\r\n const index = payments.indexOf(payment);\r\n payments.forEach(p => p.selected = false);\r\n payments[index].selected = true;\r\n this._paymentsType.next(payments);\r\n }\r\n definedPaymentsType(payments) {\r\n this._paymentsType.next(payments);\r\n }\r\n selectCustomer(customer) {\r\n return new Promise((resolve, reject) => {\r\n const order = this.order.getValue();\r\n order.customer = customer;\r\n order.customer_id = customer.id;\r\n this.order.next(order);\r\n /**\r\n * asynchronously we can load\r\n * customer meta data\r\n */\r\n if (customer.group === undefined || customer.group === null) {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"].get(`/api/nexopos/v4/customers/${customer.id}/group`)\r\n .subscribe(group => {\r\n order.customer.group = group;\r\n this.order.next(order);\r\n resolve(order);\r\n }, (error) => {\r\n reject(error);\r\n });\r\n }\r\n });\r\n }\r\n updateCart(current, update) {\r\n for (let key in update) {\r\n if (update[key] !== undefined) {\r\n vue__WEBPACK_IMPORTED_MODULE_3___default.a.set(current, key, update[key]);\r\n }\r\n }\r\n this.order.next(current);\r\n /**\r\n * explicitely here we do manually refresh the cart\r\n * as if we listen to cart update by subscribing,\r\n * that will create a loop (huge performance issue).\r\n */\r\n this.refreshCart();\r\n }\r\n /**\r\n * everytime the cart\r\n * refreshed, we might need\r\n * to perform some verification\r\n */\r\n checkCart() {\r\n const order = this.order.getValue();\r\n const unmatchedConditions = [];\r\n order.coupons.forEach(coupon => {\r\n /**\r\n * by default we'll bypass\r\n * the product if it's not available\r\n */\r\n let isProductValid = true;\r\n /**\r\n * if the coupon includes products\r\n * we make sure the products are included on the cart\r\n */\r\n if (coupon.products.length > 0) {\r\n isProductValid = order.products.filter(product => {\r\n return coupon.products.map(p => p.product_id).includes(product.product_id);\r\n }).length > 0;\r\n if (!isProductValid && unmatchedConditions.indexOf(coupon) === -1) {\r\n unmatchedConditions.push(coupon);\r\n }\r\n }\r\n /**\r\n * by default we'll bypass\r\n * the product if it's not available\r\n */\r\n let isCategoryValid = true;\r\n /**\r\n * if the coupon includes products\r\n * we make sure the products are included on the cart\r\n */\r\n if (coupon.categories.length > 0) {\r\n isCategoryValid = order.products.filter(product => {\r\n return coupon.categories.map(p => p.category_id).includes(product.$original().category_id);\r\n }).length > 0;\r\n if (!isCategoryValid && unmatchedConditions.indexOf(coupon) === -1) {\r\n unmatchedConditions.push(coupon);\r\n }\r\n }\r\n });\r\n unmatchedConditions.forEach(coupon => {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error(Object(_libraries_lang__WEBPACK_IMPORTED_MODULE_7__[\"__\"])('The coupons \"%s\" has been removed from the cart, as it\\'s required conditions are no more meet.')\r\n .replace('%s', coupon.name), Object(_libraries_lang__WEBPACK_IMPORTED_MODULE_7__[\"__\"])('Okay'), {\r\n duration: 6000\r\n }).subscribe();\r\n this.removeCoupon(coupon);\r\n });\r\n }\r\n refreshCart() {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n /**\r\n * check if according to the product\r\n * available on the cart the coupons must\r\n * remains the same.\r\n */\r\n this.checkCart();\r\n const products = this.products.getValue();\r\n let order = this.order.getValue();\r\n const productTotal = products\r\n .map(product => product.total_price);\r\n if (productTotal.length > 0) {\r\n order.subtotal = productTotal.reduce((b, a) => b + a);\r\n }\r\n else {\r\n order.subtotal = 0;\r\n }\r\n /**\r\n * we'll compute here the value\r\n * of the coupons\r\n */\r\n const totalValue = order.coupons.map(customerCoupon => {\r\n if (customerCoupon.type === 'percentage_discount') {\r\n customerCoupon.value = (order.subtotal * customerCoupon.discount_value) / 100;\r\n return customerCoupon.value;\r\n }\r\n customerCoupon.value = customerCoupon.discount_value;\r\n return customerCoupon.value;\r\n });\r\n order.total_coupons = 0;\r\n if (totalValue.length > 0) {\r\n order.total_coupons = totalValue.reduce((before, after) => before + after);\r\n }\r\n if (order.discount_type === 'percentage') {\r\n order.discount = (order.discount_percentage * order.subtotal) / 100;\r\n }\r\n /**\r\n * if the discount amount is greather\r\n * than the subtotal, the discount amount\r\n * will be set to the order.subtotal\r\n */\r\n if (order.discount > order.subtotal && order.total_coupons === 0) {\r\n order.discount = order.subtotal;\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].info('The discount has been set to the cart subtotal')\r\n .subscribe();\r\n }\r\n /**\r\n * save actual change to ensure\r\n * all listener are up to date.\r\n */\r\n this.order.next(order);\r\n /**\r\n * will compute the taxes based on\r\n * the actual state of the order\r\n */\r\n try {\r\n const response = yield this.computeTaxes();\r\n order = response['data'].order;\r\n }\r\n catch (exception) {\r\n if (exception !== false && exception.message !== undefined) {\r\n throw exception.message;\r\n }\r\n }\r\n /**\r\n * retreive all products taxes\r\n * and sum the total.\r\n */\r\n const totalTaxes = products.map((product) => product.tax_value);\r\n /**\r\n * tax might be computed above the tax that currently\r\n * applie to the items.\r\n */\r\n order.tax_value = 0;\r\n const vatType = this.options.getValue().ns_pos_vat;\r\n if (['products_vat', 'products_flat_vat', 'products_variable_vat'].includes(vatType) && totalTaxes.length > 0) {\r\n order.tax_value += totalTaxes.reduce((b, a) => b + a);\r\n }\r\n if (['flat_vat', 'variable_vat', 'products_variable_vat'].includes(vatType) && order.taxes && order.taxes.length > 0) {\r\n order.tax_value += order.taxes\r\n .map(tax => tax.tax_value)\r\n .reduce((before, after) => before + after);\r\n }\r\n order.total = (order.subtotal + order.shipping + order.tax_value) - order.discount - order.total_coupons;\r\n order.products = products;\r\n order.total_products = products.length;\r\n this.order.next(order);\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHooks\"].doAction('ns-cart-after-refreshed', order);\r\n });\r\n }\r\n /**\r\n * Get actual stock used by the product\r\n * using the defined unit\r\n * @param product_id\r\n * @param unit_id\r\n */\r\n getStockUsage(product_id, unit_quantity_id) {\r\n const stocks = this._products.getValue().filter((product) => {\r\n return product.product_id === product_id && product.unit_quantity_id === unit_quantity_id;\r\n }).map(product => product.quantity);\r\n if (stocks.length > 0) {\r\n return stocks.reduce((b, a) => b + a);\r\n }\r\n return 0;\r\n }\r\n /**\r\n * Process the item to add it to the cart\r\n * @param product\r\n */\r\n addToCart(product) {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n /**\r\n * This is where all the mutation made by the\r\n * queue promises are stored.\r\n */\r\n let productData = new Object;\r\n /**\r\n * Let's combien the built product\r\n * with the data resolved by the promises\r\n */\r\n let cartProduct = {\r\n product_id: product.id,\r\n name: product.name,\r\n discount_type: 'percentage',\r\n discount: 0,\r\n discount_percentage: 0,\r\n quantity: 0,\r\n tax_group_id: product.tax_group_id,\r\n tax_value: 0,\r\n unit_price: 0,\r\n total_price: 0,\r\n mode: 'normal',\r\n $original: () => product\r\n };\r\n /**\r\n * will determin if the\r\n * script is processing the add queue\r\n */\r\n this._processingAddQueue = true;\r\n for (let index in this.addToCartQueue) {\r\n /**\r\n * the popup promise receives the product that\r\n * is above to be added. Hopefully as it's passed by reference\r\n * updating the product should mutate that once the queue is handled.\r\n */\r\n try {\r\n const promiseInstance = new this.addToCartQueue[index](cartProduct);\r\n const result = (yield promiseInstance.run(productData));\r\n /**\r\n * We just mix both to make sure\r\n * the mutated value overwrite previously defined values.\r\n */\r\n productData = Object.assign(Object.assign({}, productData), result);\r\n }\r\n catch (brokenPromise) {\r\n /**\r\n * if a popup resolve \"false\",\r\n * that means for some reason the Promise has\r\n * been broken, therefore we need to stop the queue.\r\n */\r\n if (brokenPromise === false) {\r\n this._processingAddQueue = false;\r\n return false;\r\n }\r\n }\r\n }\r\n /**\r\n * end proceesing add queue\r\n */\r\n this._processingAddQueue = false;\r\n /**\r\n * Let's combien the built product\r\n * with the data resolved by the promises\r\n */\r\n cartProduct = Object.assign(Object.assign({}, cartProduct), productData);\r\n /**\r\n * retreive product that\r\n * are currently stored\r\n */\r\n const products = this._products.getValue();\r\n /**\r\n * push the new product\r\n * at the front of the cart\r\n */\r\n products.unshift(cartProduct);\r\n /**\r\n * Once the product has been added to the cart\r\n * it's being computed\r\n */\r\n this.refreshProducts(products);\r\n /**\r\n * dispatch event that the\r\n * product has been added.\r\n */\r\n this._products.next(products);\r\n });\r\n }\r\n defineTypes(types) {\r\n this._types.next(types);\r\n }\r\n removeProduct(product) {\r\n const products = this._products.getValue();\r\n const index = products.indexOf(product);\r\n products.splice(index, 1);\r\n this._products.next(products);\r\n }\r\n updateProduct(product, data, index = null) {\r\n const products = this._products.getValue();\r\n index = index === null ? products.indexOf(product) : index;\r\n /**\r\n * to ensure Vue updates accordingly.\r\n */\r\n vue__WEBPACK_IMPORTED_MODULE_3___default.a.set(products, index, Object.assign(Object.assign({}, product), data));\r\n this.refreshProducts(products);\r\n this._products.next(products);\r\n }\r\n refreshProducts(products) {\r\n products.forEach(product => {\r\n this.computeProduct(product);\r\n });\r\n }\r\n computeProduct(product) {\r\n /**\r\n * determining what is the\r\n * real sale price\r\n */\r\n if (product.mode === 'normal') {\r\n product.unit_price = product.$quantities().sale_price;\r\n product.tax_value = product.$quantities().sale_price_tax * product.quantity;\r\n }\r\n else {\r\n product.unit_price = product.$quantities().wholesale_price;\r\n product.tax_value = product.$quantities().wholesale_price_tax * product.quantity;\r\n }\r\n /**\r\n * computing the discount when it's\r\n * based on a percentage\r\n */\r\n if (['flat', 'percentage'].includes(product.discount_type)) {\r\n if (product.discount_type === 'percentage') {\r\n product.discount = ((product.unit_price * product.discount_percentage) / 100) * product.quantity;\r\n }\r\n }\r\n product.total_price = (product.unit_price * product.quantity) - product.discount;\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHooks\"].doAction('ns-after-product-computed', product);\r\n }\r\n loadCustomer(id) {\r\n return _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"].get(`/api/nexopos/v4/customers/${id}`);\r\n }\r\n defineSettings(settings) {\r\n this._settings.next(settings);\r\n }\r\n voidOrder(order) {\r\n if (order.id !== undefined) {\r\n if (['hold'].includes(order.payment_status)) {\r\n _libraries_popup__WEBPACK_IMPORTED_MODULE_6__[\"Popup\"].show(NsConfirmPopup, {\r\n title: 'Order Deletion',\r\n message: 'The current order will be deleted as no payment has been made so far.',\r\n onAction: (action) => {\r\n if (action) {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"].delete(`/api/nexopos/v4/orders/${order.id}`)\r\n .subscribe((result) => {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].success(result.message).subscribe();\r\n this.reset();\r\n }, (error) => {\r\n return _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error(error.message).subscribe();\r\n });\r\n }\r\n }\r\n });\r\n }\r\n else {\r\n _libraries_popup__WEBPACK_IMPORTED_MODULE_6__[\"Popup\"].show(NsPromptPopup, {\r\n title: 'Void The Order',\r\n message: 'The current order will be void. This will cancel the transaction, but the order won\\'t be deleted. Further details about the operation will be tracked on the report. Consider providing the reason of this operation.',\r\n onAction: (reason) => {\r\n if (reason !== false) {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsHttpClient\"].post(`/api/nexopos/v4/orders/${order.id}/void`, { reason })\r\n .subscribe((result) => {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].success(result.message).subscribe();\r\n this.reset();\r\n }, (error) => {\r\n return _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error(error.message).subscribe();\r\n });\r\n }\r\n }\r\n });\r\n }\r\n }\r\n else {\r\n _bootstrap__WEBPACK_IMPORTED_MODULE_4__[\"nsSnackBar\"].error('Unable to void an unpaid order.').subscribe();\r\n }\r\n }\r\n triggerOrderTypeSelection(selectedType) {\r\n return __awaiter(this, void 0, void 0, function* () {\r\n for (let i = 0; i < this.orderTypeQueue.length; i++) {\r\n try {\r\n const result = yield this.orderTypeQueue[i].promise(selectedType);\r\n console.log(result);\r\n }\r\n catch (exception) {\r\n console.log(exception);\r\n }\r\n }\r\n });\r\n }\r\n set(key, value) {\r\n const settings = this.settings.getValue();\r\n settings[key] = value;\r\n this.settings.next(settings);\r\n }\r\n get(key) {\r\n const settings = this.settings.getValue();\r\n return settings[key];\r\n }\r\n destroy() {\r\n this._products.unsubscribe();\r\n this._customers.unsubscribe();\r\n this._types.unsubscribe();\r\n this._breadcrumbs.unsubscribe();\r\n this._paymentsType.unsubscribe();\r\n this._screen.unsubscribe();\r\n this._order.unsubscribe();\r\n this._settings.unsubscribe();\r\n }\r\n}\r\nwindow.POS = new POS;\r\nconst POSInit = window.POS;\r\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9yZXNvdXJjZXMvdHMvcG9zLWluaXQudHM/ODVhNiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBZ0c7QUFDUjtBQUM5QjtBQUtwQztBQUVtRDtBQUdyQjtBQUNWO0FBR0o7QUFFdEM7OztHQUdHO0FBQ0gsTUFBTSxvQkFBb0IsR0FBZ0IsTUFBTyxDQUFDLG9CQUFvQixHQUFjLG1CQUFPLENBQUUsbUpBQThELENBQUUsQ0FBQyxPQUFPLENBQUM7QUFDdEssTUFBTSx1QkFBdUIsR0FBYSxNQUFPLENBQUMsdUJBQXVCLEdBQVcsbUJBQU8sQ0FBRSw2SkFBNkUsQ0FBRSxDQUFDLE9BQU8sQ0FBQztBQUNyTCxNQUFNLG9CQUFvQixHQUFnQixNQUFPLENBQUMsb0JBQW9CLEdBQWMsbUJBQU8sQ0FBRSxxSkFBeUUsQ0FBRSxDQUFDLE9BQU8sQ0FBQztBQUNqTCxNQUFNLG9CQUFvQixHQUFnQixNQUFPLENBQUMsb0JBQW9CLEdBQWMsbUJBQU8sQ0FBRSxtSkFBd0UsQ0FBRSxDQUFDLE9BQU8sQ0FBQztBQUNoTCxNQUFNLGdCQUFnQixHQUFvQixNQUFPLENBQUMsZ0JBQWdCLEdBQWtCLG1CQUFPLENBQUUsMklBQW9FLENBQUUsQ0FBQyxPQUFPLENBQUM7QUFDNUssTUFBTSxpQkFBaUIsR0FBbUIsTUFBTyxDQUFDLGlCQUFpQixHQUFpQixtQkFBTyxDQUFFLG1KQUF3RSxDQUFFLENBQUMsT0FBTyxDQUFDO0FBQ2hMLE1BQU0sWUFBWSxHQUF3QixNQUFPLENBQUMsWUFBWSxHQUFzQixtQkFBTyxDQUFFLHlFQUFtQyxDQUFFLENBQUMsT0FBTyxDQUFDO0FBQzNJLE1BQU0sY0FBYyxHQUFzQixNQUFPLENBQUMsY0FBYyxHQUFvQixtQkFBTyxDQUFFLHFGQUF5QyxDQUFFLENBQUMsT0FBTyxDQUFDO0FBQ2pKLE1BQU0sYUFBYSxHQUF1QixNQUFPLENBQUMsYUFBYSxHQUFxQixtQkFBTyxDQUFFLDJFQUFvQyxD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TyxHQUFlLE1BQWUsQ0FBQyxHQUFHLENBQUMiLCJmaWxlIjoiLi9yZXNvdXJjZXMvdHMvcG9zLWluaXQudHMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQcm9kdWN0UXVhbnRpdHlQcm9taXNlIH0gZnJvbSBcIi4vcGFnZXMvZGFzaGJvYXJkL3Bvcy9xdWV1ZXMvcHJvZHVjdHMvcHJvZHVjdC1xdWFudGl0eVwiO1xyXG5pbXBvcnQgeyBQcm9kdWN0VW5pdFByb21pc2UgfSBmcm9tIFwiLi9wYWdlcy9kYXNoYm9hcmQvcG9zL3F1ZXVlcy9wcm9kdWN0cy9wcm9kdWN0LXVuaXRcIjtcclxuaW1wb3J0IHsgU3ViamVjdCwgQmVoYXZpb3JTdWJqZWN0LCBmb3JrSm9pbiB9IGZyb20gXCJyeGpzXCI7XHJcbmltcG9ydCB7IFByb2R1Y3QgfSBmcm9tIFwiLi9pbnRlcmZhY2VzL3Byb2R1Y3RcIjtcclxuaW1wb3J0IHsgQ3VzdG9tZXIgfSBmcm9tIFwiLi9pbnRlcmZhY2VzL2N1c3RvbWVyXCI7XHJcbmltcG9ydCB7IE9yZGVyVHlwZSB9IGZyb20gXCIuL2ludGVyZmFjZXMvb3JkZXItdHlwZVwiO1xyXG5pbXBvcnQgeyBQT1NWaXJ0dWFsU3RvY2sgfSBmcm9tIFwiLi9pbnRlcmZhY2VzL3Bvcy12aXJ1YWwtc3RvY2tcIjtcclxuaW1wb3J0IFZ1ZSBmcm9tICd2dWUnO1xyXG5pbXBvcnQgeyBPcmRlciB9IGZyb20gXCIuL2ludGVyZmFjZXMvb3JkZXJcIjtcclxuaW1wb3J0IHsgbnNFdmVudCwgbnNIb29rcywgbnNIdHRwQ2xpZW50LCBuc1NuYWNrQmFyIH0gZnJvbSBcIi4vYm9vdHN0cmFwXCI7XHJcbmltcG9ydCB7IFBheW1lbnRUeXBlIH0gZnJvbSBcIi4vaW50ZXJmYWNlcy9wYXltZW50LXR5cGVcIjtcclxuaW1wb3J0IHsgUGF5bWVudCB9IGZyb20gXCIuL2ludGVyZmFjZXMvcGF5bWVudFwiO1xyXG5pbXBvcnQgeyBSZXNwb25zaXZlIH0gZnJvbSBcIi4vbGlicmFyaWVzL3Jlc3BvbnNpdmVcIjtcclxuaW1wb3J0IHsgUG9wdXAgfSBmcm9tIFwiLi9saWJyYXJpZXMvcG9wdXBcIjtcclxuaW1wb3J0IHsgT3JkZXJQcm9kdWN0IH0gZnJvbSBcIi4vaW50ZXJmYWNlcy9vcmRlci1wcm9kdWN0XCI7XHJcbmltcG9ydCB7IFN0YXR1c1Jlc3BvbnNlIH0gZnJvbSBcIi4vc3RhdHVzLXJlc3BvbnNlXCI7XHJcbmltcG9ydCB7IF9fIH0gZnJvbSBcIi4vbGlicmFyaWVzL2xhbmdcIjtcclxuXHJcbi8qKlxyXG4gKiB0aGVzZSBhcmUgZHluYW1pYyBjb21wb25lbnRcclxuICogdGhhdCBhcmUgbG9hZGVkIGNvbmRpdGlvbmFsbHlcclxuICovXHJcbmNvbnN0IE5zUG9zRGFzaGJvYXJkQnV0dG9uICAgICAgPSAgICg8YW55PndpbmRvdykuTnNQb3NEYXNoYm9hcmRCdXR0b24gICAgICAgICAgPSAgIHJlcXVpcmUoICcuL3BhZ2VzL2Rhc2hib2FyZC9wb3MvaGVhZGVyLWJ1dHRvbnMvbnMtcG9zLWRhc2hib2FyZC1idXR0b24nICkuZGVmYXVsdDtcclxuY29uc3QgTnNQb3NQZW5kaW5nT3JkZXJCdXR0b24gICA9ICAgKDxhbnk+d2luZG93KS5Oc1Bvc1BlbmRpbmdPcmRlckJ1dHRvbiAgICAgICA9ICAgcmVxdWlyZSggJy4vcGFnZXMvZGFzaGJvYXJkL3Bvcy9oZWFkZXItYnV0dG9ucy9ucy1wb3MtJyArICdwZW5kaW5nLW9yZGVycycgKyAnLWJ1dHRvbicgKS5kZWZhdWx0O1xyXG5jb25zdCBOc1Bvc09yZGVyVHlwZUJ1dHRvbiAgICAgID0gICAoPGFueT53aW5kb3cpLk5zUG9zT3JkZXJUeXBlQnV0dG9uICAgICAgICAgID0gICByZXF1aXJlKCAnLi9wYWdlcy9kYXNoYm9hcmQvcG9zL2hlYWRlci1idXR0b25zL25zLXBvcy0nICsgJ29yZGVyLXR5cGUnICsgJy1idXR0b24nICkuZGVmYXVsdDtcclxuY29uc3QgTnNQb3NDdXN0b21lcnNCdXR0b24gICAgICA9ICAgKDxhbnk+d2luZG93KS5Oc1Bvc0N1c3RvbWVyc0J1dHRvbiAgICAgICAgICA9ICAgcmVxdWlyZSggJy4vcGFnZXMvZGFzaGJvYXJkL3Bvcy9oZWFkZXItYnV0dG9ucy9ucy1wb3MtJyArICdjdXN0b21lcnMnICsgJy1idXR0b24nICkuZGVmYXVsdDtcclxuY29uc3QgTnNQb3NSZXNldEJ1dHRvbiAgICAgICAgICA9ICAgKDxhbnk+d2luZG93KS5Oc1Bvc1Jlc2V0QnV0dG9uICAgICAgICAgICAgICA9ICAgcmVxdWlyZSggJy4vcGFnZXMvZGFzaGJvYXJkL3Bvcy9oZWFkZXItYnV0dG9ucy9ucy1wb3MtJyArICdyZXNldCcgKyAnLWJ1dHRvbicgKS5kZWZhdWx0O1xyXG5jb25zdCBOc1Bvc0Nhc2hSZWdpc3RlciAgICAgICAgID0gICAoPGFueT53aW5kb3cpLk5zUG9zQ2FzaFJlZ2lzdGVyICAgICAgICAgICAgID0gICByZXF1aXJlKCAnLi9wYWdlcy9kYXNoYm9hcmQvcG9zL2hlYWRlci1idXR0b25zL25zLXBvcy0nICsgJ3JlZ2lzdGVycycgKyAnLWJ1dHRvbicgKS5kZWZhdWx0O1xyXG5jb25zdCBOc0FsZXJ0UG9wdXAgICAgICAgICAgICAgID0gICAoPGFueT53aW5kb3cpLk5zQWxlcnRQb3B1cCAgICAgICAgICAgICAgICAgID0gICByZXF1aXJlKCAnLi9wb3B1cHMvbnMtJyArICdhbGVydCcgKyAnLXBvcHVwJyApLmRlZmF1bHQ7XHJcbmNvbnN0IE5zQ29uZmlybVBvcHVwICAgICAgICAgICAgPSAgICg8YW55PndpbmRvdykuTnNDb25maXJtUG9wdXAgICAgICAgICAgICAgICAgPSAgIHJlcXVpcmUoICcuL3BvcHVwcy9ucy1wb3MtJyArICdjb25maXJtJyArICctcG9wdXAnICkuZGVmYXVsdDtcclxuY29uc3QgTnNQcm9tcHRQb3B1cCAgICAgICAgICAgICA9ICAgKDxhbnk+d2luZG93KS5Oc1Byb21wdFBvcHVwICAgICAgICAgICAgICAgICA9ICAgcmVxdWlyZSggJy4vcG9wdXBzL25zLScgKyAncHJvbXB0JyArICctcG9wdXAnICkuZGVmYXVsdDtcclxuY29uc3QgTnNMYXlhd2F5UG9wdXAgICAgICAgICAgICA9ICAgKDxhbnk+d2luZG93KS5Oc0xheWF3YXlQb3B1cCAgICAgICAgICAgICAgICA9ICAgcmVxdWlyZSggJy4vcG9wdXBzL25zLXBvcy0nICsgJ2xheWF3YXknICsgJy1wb3B1cCcgKS5kZWZhdWx0O1xyXG5jb25zdCBOU1Bvc1NoaXBwaW5nUG9wdXAgICAgICAgID0gICAoPGFueT53aW5kb3cpLk5zTGF5YXdheVBvcHVwICAgICAgICAgICAgICAgID0gICByZXF1aXJlKCAnLi9wb3B1cHMvbnMtcG9zLScgKyAnc2hpcHBpbmcnICsgJy1wb3B1cCcgKS5kZWZhdWx0O1xyXG5cclxuZXhwb3J0IGNsYXNzIFBPUyB7XHJcbiAgICBwcml2YXRlIF9wcm9kdWN0czogQmVoYXZpb3JTdWJqZWN0PE9yZGVyUHJvZHVjdFtdPjtcclxuICAgIHByaXZhdGUgX2JyZWFkY3J1bWJzOiBCZWhhdmlvclN1YmplY3Q8YW55W10+O1xyXG4gICAgcHJpdmF0ZSBfY3VzdG9tZXJzOiBCZWhhdmlvclN1YmplY3Q8Q3VzdG9tZXJbXT47XHJcbiAgICBwcml2YXRlIF9zZXR0aW5nczogQmVoYXZpb3JTdWJqZWN0PHsgWyBrZXk6IHN0cmluZ10gOiBhbnl9PjtcclxuICAgIHByaXZhdGUgX3R5cGVzOiBCZWhhdmlvclN1YmplY3Q8T3JkZXJUeXBlW10+O1xyXG4gICAgcHJpdmF0ZSBfb3JkZXJUeXBlUHJvY2Vzc1F1ZXVlOiB7IGlkZW50aWZpZXI6IHN0cmluZywgcHJvbWlzZTogKCBzZWxlY3RlZFR5cGU6IE9yZGVyVHlwZSApID0+IFByb21pc2U8U3RhdHVzUmVzcG9uc2U+IH1bXSAgICAgPSAgIFtdO1xyXG4gICAgcHJpdmF0ZSBfcGF5bWVudHNUeXBlOiBCZWhhdmlvclN1YmplY3Q8UGF5bWVudFR5cGVbXT47XHJcbiAgICBwcml2YXRlIF9vcmRlcjogQmVoYXZpb3JTdWJqZWN0PE9yZGVyPjtcclxuICAgIHByaXZhdGUgX3NjcmVlbjogQmVoYXZpb3JTdWJqZWN0PHN0cmluZz47XHJcbiAgICBwcml2YXRlIF9pbml0aWFsUXVldWU6ICgoKSA9PiBQcm9taXNlPFN0YXR1c1Jlc3BvbnNlPilbXSAgICAgPSAgIFtdO1xyXG4gICAgcHJpdmF0ZSBfb3B0aW9uczogQmVoYXZpb3JTdWJqZWN0PHsgW2tleTpzdHJpbmddIDogYW55fT47XHJcbiAgICBwcml2YXRlIF9yZXNwb25zaXZlICAgICAgICAgPSAgIG5ldyBSZXNwb25zaXZlO1xyXG4gICAgcHJpdmF0ZSBfdmlzaWJsZVNlY3Rpb246IEJlaGF2aW9yU3ViamVjdDwnY2FydCcgfCAnZ3JpZCcgfCAnYm90aCc+O1xyXG4gICAgcHJpdmF0ZSBfaXNTdWJtaXR0aW5nICAgICAgICAgICA9ICAgZmFsc2U7XHJcbiAgICBwcml2YXRlIF9wcm9jZXNzaW5nQWRkUXVldWUgICAgID0gICBmYWxzZTtcclxuICAgIHByaXZhdGUgZGVmYXVsdE9yZGVyICAgICAgICAgICAgPSAgICgpOiBPcmRlciA9PiB7XHJcbiAgICAgICAgY29uc3Qgb3JkZXI6IE9yZGVyICAgICA9ICAge1xyXG4gICAgICAgICAgICBkaXNjb3VudF90eXBlOiBudWxsLFxyXG4gICAgICAgICAgICB0aXRsZTogJycsXHJcbiAgICAgICAgICAgIGRpc2NvdW50OiAwLFxyXG4gICAgICAgICAgICByZWdpc3Rlcl9pZDogdGhpcy5nZXQoICdyZWdpc3RlcicgKSA/IHRoaXMuZ2V0KCAncmVnaXN0ZXInICkuaWQgOiB1bmRlZmluZWQsIC8vIGV2ZXJ5dGltZSBpdCByZXNldCwgdGhpcyB2YWx1ZSB3aWxsIGJlIHB1bGxlZC5cclxuICAgICAgICAgICAgZGlzY291bnRfcGVyY2VudGFnZTogMCxcclxuICAgICAgICAgICAgc3VidG90YWw6IDAsXHJcbiAgICAgICAgICAgIHRvdGFsOiAwLFxyXG4gICAgICAgICAgICBjb3Vwb25zOiBbXSxcclxuICAgICAgICAgICAgdG90YWxfY291cG9ucyA6IDAsXHJcbiAgICAgICAgICAgIHRlbmRlcmVkOiAwLFxyXG4gICAgICAgICAgICBub3RlOiAnJyxcclxuICAgICAgICAgICAgbm90ZV92aXNpYmlsaXR5OiAnaGlkZGVuJyxcclxuICAgICAgICAgICAgdGF4X2dyb3VwX2lkOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgIHRheF90eXBlOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgIHRheGVzOiBbXSwgXHJcbiAgICAgICAgICAgIHRheF9ncm91cHM6IFtdLFxyXG4gICAgICAgICAgICBwYXltZW50X3N0YXR1czogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBjdXN0b21lcl9pZDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBjaGFuZ2U6IDAsXHJcbiAgICAgICAgICAgIHRvdGFsX3Byb2R1Y3RzOiAwLFxyXG4gICAgICAgICAgICBzaGlwcGluZzogMCxcclxuICAgICAgICAgICAgdGF4X3ZhbHVlOiAwLFxyXG4gICAgICAgICAgICBzaGlwcGluZ19yYXRlOiAwLFxyXG4gICAgICAgICAgICBzaGlwcGluZ190eXBlOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgIGN1c3RvbWVyOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgIHR5cGU6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgcHJvZHVjdHM6IFtdLFxyXG4gICAgICAgICAgICBpbnN0YWxtZW50czogW10sXHJcbiAgICAgICAgICAgIHBheW1lbnRzOiBbXSxcclxuICAgICAgICAgICAgYWRkcmVzc2VzOiB7XHJcbiAgICAgICAgICAgICAgICBzaGlwcGluZzogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgYmlsbGluZzogdW5kZWZpbmVkXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBvcmRlcjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICB0aGlzLmluaXRpYWxpemUoKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgc2NyZWVuKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zY3JlZW47XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHZpc2libGVTZWN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl92aXNpYmxlU2VjdGlvbjtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgcGF5bWVudHNUeXBlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wYXltZW50c1R5cGU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG9yZGVyKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9vcmRlcjtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgdHlwZXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGVzO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBwcm9kdWN0cygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcHJvZHVjdHM7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGN1c3RvbWVycygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fY3VzdG9tZXJzO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBvcHRpb25zKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9vcHRpb25zO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBvcmRlclR5cGVRdWV1ZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fb3JkZXJUeXBlUHJvY2Vzc1F1ZXVlO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBzZXR0aW5ncygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2V0dGluZ3M7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGJyZWFkY3J1bWJzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9icmVhZGNydW1icztcclxuICAgIH1cclxuXHJcbiAgICBnZXQgaW5pdGlhbFF1ZXVlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9pbml0aWFsUXVldWU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHByb2Nlc3NpbmdBZGRRdWV1ZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcHJvY2Vzc2luZ0FkZFF1ZXVlO1xyXG4gICAgfVxyXG5cclxuICAgIHJlc2V0KCkge1xyXG4gICAgICAgIHRoaXMuX2lzU3VibWl0dGluZyAgPSAgIGZhbHNlO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiB0byByZXNldCBvcmRlciBkZXRhaWxzXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5vcmRlci5uZXh0KCB0aGlzLmRlZmF1bHRPcmRlcigpICk7XHJcbiAgICAgICAgdGhpcy5fcHJvZHVjdHMubmV4dChbXSk7XHJcbiAgICAgICAgdGhpcy5fY3VzdG9tZXJzLm5leHQoW10pO1xyXG4gICAgICAgIHRoaXMuX2JyZWFkY3J1bWJzLm5leHQoW10pO1xyXG4gICAgICAgIHRoaXMuZGVmaW5lQ3VycmVudFNjcmVlbigpO1xyXG5cclxuICAgICAgICB0aGlzLnByb2Nlc3NJbml0aWFsUXVldWUoKTtcclxuICAgICAgICB0aGlzLnJlZnJlc2hDYXJ0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGluaXRpYWxpemUoKVxyXG4gICAge1xyXG4gICAgICAgIHRoaXMuX3Byb2R1Y3RzICAgICAgICAgID0gICBuZXcgQmVoYXZpb3JTdWJqZWN0PE9yZGVyUHJvZHVjdFtdPihbXSk7XHJcbiAgICAgICAgdGhpcy5fY3VzdG9tZXJzICAgICAgICAgPSAgIG5ldyBCZWhhdmlvclN1YmplY3Q8Q3VzdG9tZXJbXT4oW10pO1xyXG4gICAgICAgIHRoaXMuX3R5cGVzICAgICAgICAgICAgID0gICBuZXcgQmVoYXZpb3JTdWJqZWN0PE9yZGVyVHlwZVtdPihbXSk7XHJcbiAgICAgICAgdGhpcy5fYnJlYWRjcnVtYnMgICAgICAgPSAgIG5ldyBCZWhhdmlvclN1YmplY3Q8YW55W10+KFtdKTtcclxuICAgICAgICB0aGlzLl9zY3JlZW4gICAgICAgICAgICA9ICAgbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KCcnKTtcclxuICAgICAgICB0aGlzLl9wYXltZW50c1R5cGUgICAgICA9ICAgbmV3IEJlaGF2aW9yU3ViamVjdDxQYXltZW50VHlwZVtdPihbXSk7ICAgXHJcbiAgICAgICAgdGhpcy5fdmlzaWJsZVNlY3Rpb24gICAgPSAgIG5ldyBCZWhhdmlvclN1YmplY3QoICdib3RoJyApOyAgICAgXHJcbiAgICAgICAgdGhpcy5fb3B0aW9ucyAgICAgICAgICAgPSAgIG5ldyBCZWhhdmlvclN1YmplY3Qoe30pO1xyXG4gICAgICAgIHRoaXMuX3NldHRpbmdzICAgICAgICAgID0gICBuZXcgQmVoYXZpb3JTdWJqZWN0PHsgWyBrZXk6IHN0cmluZyBdIDogYW55IH0+KHt9KTtcclxuICAgICAgICB0aGlzLl9vcmRlciAgICAgICAgICAgICA9ICAgbmV3IEJlaGF2aW9yU3ViamVjdDxPcmRlcj4oIHRoaXMuZGVmYXVsdE9yZGVyKCkgKTtcclxuICAgICAgICB0aGlzLl9vcmRlclR5cGVQcm9jZXNzUXVldWUgPSAgIFtcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgaWRlbnRpZmllciA6ICdoYW5kbGUuZGVsaXZlcnktb3JkZXInLFxyXG4gICAgICAgICAgICAgICAgcHJvbWlzZSAgICAgOiAoIHNlbGVjdGVkVHlwZTogT3JkZXJUeXBlICkgPT4gbmV3IFByb21pc2U8U3RhdHVzUmVzcG9uc2U+KCAoIHJlc29sdmUsIHJlamVjdCApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIHNlbGVjdGVkVHlwZS5pZGVudGlmaWVyID09PSAnZGVsaXZlcnknICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUG9wdXAuc2hvdyggTlNQb3NTaGlwcGluZ1BvcHVwLCB7IHJlc29sdmUsIHJlamVjdCB9ICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoIGZhbHNlICk7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgXVxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBUaGlzIGluaXRpYWwgcHJvY2VzcyB3aWxsIHRyeSB0byBkZXRlY3RcclxuICAgICAgICAgKiBpZiB0aGVyZSBpcyBhIHRheCBncm91cCBhc3NpZ25lZCBvbiB0aGUgc2V0dGluZ3NcclxuICAgICAgICAgKiBhbmQgc2V0IGl0IGFzIGRlZmF1bHQgdGF4IGdyb3VwLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMuaW5pdGlhbFF1ZXVlLnB1c2goICgpID0+IG5ldyBQcm9taXNlKCAoIHJlc29sdmUsIHJlamVjdCApID0+IHtcclxuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyAgID0gICB0aGlzLm9wdGlvbnMuZ2V0VmFsdWUoKTtcclxuICAgICAgICAgICAgY29uc3Qgb3JkZXIgICAgID0gICB0aGlzLm9yZGVyLmdldFZhbHVlKCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIG9wdGlvbnMubnNfcG9zX3RheF9ncm91cCAhPT0gZmFsc2UgKSB7XHJcbiAgICAgICAgICAgICAgICBvcmRlci50YXhfZ3JvdXBfaWQgID0gICBvcHRpb25zLm5zX3Bvc190YXhfZ3JvdXA7XHJcbiAgICAgICAgICAgICAgICBvcmRlci50YXhfdHlwZSAgICAgID0gICBvcHRpb25zLm5zX3Bvc190YXhfdHlwZTtcclxuICAgICAgICAgICAgICAgIHRoaXMub3JkZXIubmV4dCggb3JkZXIgKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoe1xyXG4gICAgICAgICAgICAgICAgc3RhdHVzOiAnc3VjY2VzcycsXHJcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAndGF4IGdyb3VwIGFzc2lnbmF0ZWQnXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0gKSApO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiB0aGlzIGluaXRpYWwgcHJvY2VzcyB3aWxsIHNlbGVjdCB0aGUgZGVmYXVsdFxyXG4gICAgICAgICAqIGN1c3RvbWVyIGFuZCBhc3NpZ24gaGltIHRvIHRoZSBQT1NcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmluaXRpYWxRdWV1ZS5wdXNoKCAoKSA9PiBuZXcgUHJvbWlzZSggKCByZXNvbHZlLCByZWplY3QgKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgICA9ICAgdGhpcy5vcHRpb25zLmdldFZhbHVlKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IG9yZGVyICAgICA9ICAgdGhpcy5vcmRlci5nZXRWYWx1ZSgpO1xyXG5cclxuICAgICAgICAgICAgaWYgKCBvcHRpb25zLm5zX2N1c3RvbWVyc19kZWZhdWx0ICE9PSBmYWxzZSApIHtcclxuICAgICAgICAgICAgICAgIG5zSHR0cENsaWVudC5nZXQoIGAvYXBpL25leG9wb3MvdjQvY3VzdG9tZXJzLyR7b3B0aW9ucy5uc19jdXN0b21lcnNfZGVmYXVsdH1gIClcclxuICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCBjdXN0b21lciA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0Q3VzdG9tZXIoIGN1c3RvbWVyICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoeyBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogX18oICdUaGUgY3VzdG9tZXIgaGFzIGJlZW4gbG9hZGVkJyApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sICggZXJyb3IgKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCggZXJyb3IgKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoe1xyXG4gICAgICAgICAgICAgICAgc3RhdHVzOiAnc3VjY2VzcycsXHJcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAndGF4IGdyb3VwIGFzc2lnbmF0ZWQnXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0gKSApO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdoZW5ldmVyIHRoZXJlIGlzIGEgY2hhbmdlXHJcbiAgICAgICAgICogb24gdGhlIHByb2R1Y3RzLCB3ZSdsbCB1cGRhdGVcclxuICAgICAgICAgKiB0aGUgY2FydC5cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLnByb2R1Y3RzLnN1YnNjcmliZSggXyA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMucmVmcmVzaENhcnQoKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogbGlzdGVuIHRvIHR5cGUgZm9yIHVwZGF0aW5nXHJcbiAgICAgICAgICogdGhlIG9yZGVyIGFjY29yZGluZ2x5XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy50eXBlcy5zdWJzY3JpYmUoIHR5cGVzID0+IHtcclxuICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWQgID0gICB0eXBlcy5maWx0ZXIoIHR5cGUgPT4gdHlwZS5zZWxlY3RlZCApO1xyXG5cclxuICAgICAgICAgICAgaWYgKCBzZWxlY3RlZC5sZW5ndGggPiAwICkge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgb3JkZXIgICAgID0gICB0aGlzLm9yZGVyLmdldFZhbHVlKCk7XHJcbiAgICAgICAgICAgICAgICBvcmRlci50eXBlICAgICAgPSAgIHNlbGVjdGVkWzBdO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vcmRlci5uZXh0KCBvcmRlciApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdlJ3JlIGhhbmRsaW5nIGhlcmUgdGhlIHJlc3BvbnNpdmUgYXNwZWN0XHJcbiAgICAgICAgICogb2YgdGhlIFBPUy5cclxuICAgICAgICAgKi9cclxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lciggJ3Jlc2l6ZScsICgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fcmVzcG9uc2l2ZS5kZXRlY3QoKTtcclxuICAgICAgICAgICAgdGhpcy5kZWZpbmVDdXJyZW50U2NyZWVuKCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMuZGVmaW5lQ3VycmVudFNjcmVlbigpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhpcyBpcyB0aGUgZmlyc3QgaW5pdGlhbCBxdWV1ZVxyXG4gICAgICogdGhhdCBydW5zIHdoZW4gdGhlIFBPUyBpcyBsb2FkZWQuIFxyXG4gICAgICogSXQgYWxzbyBydW4gd2hlbiB0aGUgcG9zIGlzIHJlc2V0LlxyXG4gICAgICogQHJldHVybiB2b2lkXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhc3luYyBwcm9jZXNzSW5pdGlhbFF1ZXVlKCkge1xyXG4gICAgICAgIGZvciggbGV0IGluZGV4IGluIHRoaXMuX2luaXRpYWxRdWV1ZSApIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlICA9ICAgYXdhaXQgdGhpcy5faW5pdGlhbFF1ZXVlWyBpbmRleCBdKCk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2goIGV4Y2VwdGlvbiApIHtcclxuICAgICAgICAgICAgICAgIG5zU25hY2tCYXIuZXJyb3IoIGV4Y2VwdGlvbi5tZXNzYWdlICkuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGlzIG1ldGhvZHMgcnVuIGFzIHBhcnQgb2YgdGhlIHZlcmlmaWNhdGlvblxyXG4gICAgICogb2YgdGhlIGNhcnQgcmVmcmVzaGluZy4gQ2Fubm90IHJlZnJlc2ggdGhlIGNhcnQuXHJcbiAgICAgKiBAcGFyYW0gY291cG9uIGNvdXBvblxyXG4gICAgICovXHJcbiAgICByZW1vdmVDb3Vwb24oIGNvdXBvbiApIHtcclxuICAgICAgICBjb25zdCBvcmRlciAgICAgPSAgIHRoaXMub3JkZXIuZ2V0VmFsdWUoKTtcclxuICAgICAgICBjb25zdCBjb3Vwb25zICAgPSAgIG9yZGVyLmNvdXBvbnM7XHJcbiAgICAgICAgY29uc3QgaW5kZXggICAgID0gICBjb3Vwb25zLmluZGV4T2YoIGNvdXBvbiApO1xyXG4gICAgICAgIGNvdXBvbnMuc3BsaWNlKCBpbmRleCwgMSApO1xyXG4gICAgICAgIG9yZGVyLmNvdXBvbnMgICA9ICAgY291cG9ucztcclxuICAgICAgICB0aGlzLm9yZGVyLm5leHQoIG9yZGVyICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVzaENvdXBvbiggY291cG9uICkge1xyXG4gICAgICAgIGNvbnN0IG9yZGVyICAgICA9ICAgdGhpcy5vcmRlci5nZXRWYWx1ZSgpO1xyXG5cclxuICAgICAgICBvcmRlci5jb3Vwb25zLmZvckVhY2goIF9jb3Vwb24gPT4ge1xyXG4gICAgICAgICAgICBpZiAoIF9jb3Vwb24uY29kZSA9PT0gY291cG9uLmNvZGUgKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtZXNzYWdlICAgPSAgIF9fKCAnVGhpcyBjb3Vwb24gaXMgYWxyZWFkeSBhZGRlZCB0byB0aGUgY2FydCcgKTtcclxuICAgICAgICAgICAgICAgIG5zU25hY2tCYXIuZXJyb3IoIG1lc3NhZ2UgKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgICAgIHRocm93IG1lc3NhZ2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG5cclxuICAgICAgICBvcmRlci5jb3Vwb25zLnB1c2goIGNvdXBvbiApO1xyXG4gICAgICAgIHRoaXMub3JkZXIubmV4dCggb3JkZXIgKTtcclxuICAgICAgICB0aGlzLnJlZnJlc2hDYXJ0KCk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGdldCBoZWFkZXIoKSB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQXMgUE9TIG9iamVjdCBpcyBkZWZpbmVkIG9uIHRoZVxyXG4gICAgICAgICAqIGhlYWRlciwgd2UgY2FuIHVzZSB0aGF0IHRvIHJlZmVyZW5jZSB0aGUgYnV0dG9ucyAoY29tcG9uZW50KVxyXG4gICAgICAgICAqIHRoYXQgbmVlZHMgdG8gYmUgcmVuZGVyZWQgZHluYW1pY2FsbHlcclxuICAgICAgICAgKi9cclxuICAgICAgICBjb25zdCBkYXRhICA9ICAge1xyXG4gICAgICAgICAgICBidXR0b25zOiB7XHJcbiAgICAgICAgICAgICAgICBOc1Bvc0Rhc2hib2FyZEJ1dHRvbixcclxuICAgICAgICAgICAgICAgIE5zUG9zUGVuZGluZ09yZGVyQnV0dG9uLFxyXG4gICAgICAgICAgICAgICAgTnNQb3NPcmRlclR5cGVCdXR0b24sXHJcbiAgICAgICAgICAgICAgICBOc1Bvc0N1c3RvbWVyc0J1dHRvbixcclxuICAgICAgICAgICAgICAgIE5zUG9zUmVzZXRCdXR0b24sXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBpZiB0aGUgY2FzaCByZWdpc3RlciBpcyBlbmFibGVkXHJcbiAgICAgICAgICogd2UnbGwgYWRkIHRoYXQgYnV0dG9uIHRvIHRoZSBsaXN0XHJcbiAgICAgICAgICogb2YgYnV0dG9uIGF2YWlsYWJsZS5cclxuICAgICAgICAgKi9cclxuICAgICAgICBpZiAoIHRoaXMub3B0aW9ucy5nZXRWYWx1ZSgpLm5zX3Bvc19yZWdpc3RlcnNfZW5hYmxlZCA9PT0gJ3llcycgKSB7XHJcbiAgICAgICAgICAgIGRhdGEuYnV0dG9uc1sgJ05zUG9zQ2FzaFJlZ2lzdGVyJyBdICA9ICAgTnNQb3NDYXNoUmVnaXN0ZXI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZGF0YTtcclxuICAgIH1cclxuXHJcbiAgICBkZWZpbmVPcHRpb25zKCBvcHRpb25zICkge1xyXG4gICAgICAgIHRoaXMuX29wdGlvbnMubmV4dCggb3B0aW9ucyApO1xyXG4gICAgfVxyXG5cclxuICAgIGRlZmluZUN1cnJlbnRTY3JlZW4oKSB7XHJcbiAgICAgICAgdGhpcy5fdmlzaWJsZVNlY3Rpb24ubmV4dCggWyAneHMnLCAnc20nIF0uaW5jbHVkZXMoIDxzdHJpbmc+dGhpcy5fcmVzcG9uc2l2ZS5pcygpICkgPyAnZ3JpZCcgOiAnYm90aCcgKTtcclxuICAgICAgICB0aGlzLl9zY3JlZW4ubmV4dCggPHN0cmluZz50aGlzLl9yZXNwb25zaXZlLmlzKCkgKTtcclxuICAgIH1cclxuXHJcbiAgICBjaGFuZ2VWaXNpYmxlU2VjdGlvbiggc2VjdGlvbiApIHtcclxuICAgICAgICBpZiAoWyAnYm90aCcsICdjYXJ0JywgJ2dyaWQnIF0uaW5jbHVkZXMoIHNlY3Rpb24gKSApIHtcclxuXHJcbiAgICAgICAgICAgIGlmIChbICdjYXJ0JywgJ2JvdGgnIF0uaW5jbHVkZXMoIHNlY3Rpb24gKSApIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVmcmVzaENhcnQoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5fdmlzaWJsZVNlY3Rpb24ubmV4dCggc2VjdGlvbiApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhZGRQYXltZW50KCBwYXltZW50OiBQYXltZW50ICkge1xyXG4gICAgICAgIGlmICggcGF5bWVudC52YWx1ZSA+IDAgKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG9yZGVyICA9ICAgdGhpcy5fb3JkZXIuZ2V0VmFsdWUoKTtcclxuICAgICAgICAgICAgb3JkZXIucGF5bWVudHMucHVzaCggcGF5bWVudCApO1xyXG4gICAgICAgICAgICB0aGlzLl9vcmRlci5uZXh0KCBvcmRlciApO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcHV0ZVBhaWQoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBuc1NuYWNrQmFyLmVycm9yKCAnSW52YWxpZCBhbW91bnQuJyApLnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbW92ZVBheW1lbnQoIHBheW1lbnQ6IFBheW1lbnQgKSB7XHJcblxyXG4gICAgICAgIGlmICggcGF5bWVudC5pZCAhPT0gdW5kZWZpbmVkICkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnNTbmFja0Jhci5lcnJvciggJ1VuYWJsZSB0byBkZWxldGUgYSBwYXltZW50IGF0dGFjaGVkIHRvIHRoZSBvcmRlcicgKS5zdWJzY3JpYmUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IG9yZGVyICAgICA9ICAgdGhpcy5fb3JkZXIuZ2V0VmFsdWUoKTtcclxuICAgICAgICBjb25zdCBpbmRleCAgICAgPSAgIG9yZGVyLnBheW1lbnRzLmluZGV4T2YoIHBheW1lbnQgKTtcclxuICAgICAgICBvcmRlci5wYXltZW50cy5zcGxpY2UoIGluZGV4LCAxICk7XHJcbiAgICAgICAgdGhpcy5fb3JkZXIubmV4dCggb3JkZXIgKTtcclxuXHJcbiAgICAgICAgbnNFdmVudC5lbWl0KHsgXHJcbiAgICAgICAgICAgIGlkZW50aWZpZXI6ICducy5wb3MucmVtb3ZlLXBheW1lbnQnLFxyXG4gICAgICAgICAgICB2YWx1ZTogcGF5bWVudFxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLnVwZGF0ZUN1c3RvbWVyQWNjb3VudCggcGF5bWVudCApO1xyXG4gICAgICAgIHRoaXMuY29tcHV0ZVBhaWQoKTtcclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGVDdXN0b21lckFjY291bnQoIHBheW1lbnQ6IFBheW1lbnQgKSB7XHJcbiAgICAgICAgaWYgKCBwYXltZW50LmlkZW50aWZpZXIgPT09ICdhY2NvdW50LXBheW1lbnQnICkge1xyXG4gICAgICAgICAgICBjb25zdCBjdXN0b21lciAgICAgICAgICAgICAgPSAgIHRoaXMub3JkZXIuZ2V0VmFsdWUoKS5jdXN0b21lcjtcclxuICAgICAgICAgICAgY3VzdG9tZXIuYWNjb3VudF9hbW91bnQgICAgICs9ICBwYXltZW50LnZhbHVlO1xyXG4gICAgICAgICAgICB0aGlzLnNlbGVjdEN1c3RvbWVyKCBjdXN0b21lciApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXROZXRQcmljZSggdmFsdWUsIHJhdGUsIHR5cGUgKSB7XHJcbiAgICAgICAgaWYgKCB0eXBlID09PSAnaW5jbHVzaXZlJyApIHtcclxuICAgICAgICAgICAgcmV0dXJuICggdmFsdWUgLyAoIHJhdGUgKyAxMDAgKSApICogMTAwO1xyXG4gICAgICAgIH0gZWxzZSBpZiggdHlwZSA9PT0gJ2V4Y2x1c2l2ZScgKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAoICggdmFsdWUgLyAxMDAgKSAqICggcmF0ZSArIDEwMCApICk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldFZhdFZhbHVlKCB2YWx1ZSwgcmF0ZSwgdHlwZSApIHtcclxuICAgICAgICBpZiAoIHR5cGUgPT09ICdpbmNsdXNpdmUnICkge1xyXG4gICAgICAgICAgICByZXR1cm4gdmFsdWUgLSB0aGlzLmdldE5ldFByaWNlKCB2YWx1ZSwgcmF0ZSwgdHlwZSApO1xyXG4gICAgICAgIH0gZWxzZSBpZiggdHlwZSA9PT0gJ2V4Y2x1c2l2ZScgKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE5ldFByaWNlKCB2YWx1ZSwgcmF0ZSwgdHlwZSApIC0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNvbXB1dGVUYXhlcygpIHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoICggcmVzb2x2ZSwgcmVqZWN0ICkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBvcmRlciAgICAgPSAgIHRoaXMub3JkZXIuZ2V0VmFsdWUoKTtcclxuXHJcbiAgICAgICAgICAgIGlmICggb3JkZXIudGF4X2dyb3VwX2lkID09PSB1bmRlZmluZWQgfHwgb3JkZXIudGF4X2dyb3VwX2lkID09PSBudWxsICkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCggZmFsc2UgKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgZ3JvdXBzICAgID0gICBvcmRlci50YXhfZ3JvdXBzO1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIGlmIHRoZSB0YXggZ3JvdXAgaXMgYWxyZWFkeSBjYWNoZWRcclxuICAgICAgICAgICAgICogd2UnbGwgcHVsbCB0aGF0IHJhdGhlciB0aGFuIGRvaW5nIGEgbmV3IHJlcXVlc3QuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBpZiAoIGdyb3VwcyAmJiBncm91cHNbIG9yZGVyLnRheF9ncm91cF9pZCBdICE9PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgICAgICBvcmRlci50YXhlcyAgICAgICAgID0gICBvcmRlci50YXhlcy5tYXAoIHRheCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGF4LnRheF92YWx1ZSAgID0gICB0aGlzLmdldFZhdFZhbHVlKCBvcmRlci5zdWJ0b3RhbCwgdGF4LnJhdGUsIG9yZGVyLnRheF90eXBlICk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRheDtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiAnc3VjY2VzcycsXHJcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogeyB0YXggOiBncm91cHNbIG9yZGVyLnRheF9ncm91cF9pZCBdLCBvcmRlciB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYoIG9yZGVyLnRheF9ncm91cF9pZCAhPT0gbnVsbCApIHtcclxuICAgICAgICAgICAgICAgIG5zSHR0cENsaWVudC5nZXQoIGAvYXBpL25leG9wb3MvdjQvdGF4ZXMvZ3JvdXBzLyR7b3JkZXIudGF4X2dyb3VwX2lkfWAgKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoICh0YXg6YW55KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyLnRheF9ncm91cHMgICAgPSAgIG9yZGVyLnRheF9ncm91cHMgfHwgW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyLnRheGVzICAgICAgICAgPSAgIHRheC50YXhlcy5tYXAoIHRheCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRheF9pZCAgICAgIDogICB0YXguaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGF4X25hbWUgICAgOiAgIHRheC5uYW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhdGUgICAgICAgIDogICBwYXJzZUZsb2F0KCB0YXgucmF0ZSApLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRheF92YWx1ZSAgIDogICB0aGlzLmdldFZhdFZhbHVlKCBvcmRlci5zdWJ0b3RhbCwgdGF4LnJhdGUsIG9yZGVyLnRheF90eXBlIClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgKiB0aGlzIGlzIHNldCB0byBjYWNoZSB0aGUgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAqIHRheCBncm91cCB0byBhdm9pZCBzdWJzZXF1ZW50IHJlcXVlc3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgICogdG8gdGhlIHNlcnZlci5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyLnRheF9ncm91cHNbIHRheC5pZCBdICAgID0gICB0YXg7IFxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHsgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXM6ICdzdWNjZXNzJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgOiB7IHRheCwgb3JkZXIgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgIH0sICggZXJyb3IgKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoIGVycm9yICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3Qoe1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogJ2ZhaWxlZCcsXHJcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogX18oICdObyB0YXggZ3JvdXAgYXNzaWduZWQgdG8gdGhlIG9yZGVyJyApXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoaXMgd2lsbCBjaGVjayBpZiB0aGUgb3JkZXIgY2FuIGJlIHNhdmVkIGFzIGxheXdheS5cclxuICAgICAqIG1pZ2h0IHJlcXVlc3QgYWRkaXRpb25uYWwgaW5mb3JtYXRpb24gdGhyb3VnaCBhIHBvcHVwLlxyXG4gICAgICogQHBhcmFtIG9yZGVyIE9yZGVyXHJcbiAgICAgKi9cclxuICAgIGNhblByb2NlZWRBc0xhaWRBd2F5KCBfb3JkZXI6IE9yZGVyICk6IHsgc3RhdHVzOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZywgZGF0YTogeyBvcmRlcjogT3JkZXIgfSB9IHwgYW55IHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoIGFzeW5jICggcmVzb2x2ZSwgcmVqZWN0ICkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBtaW5pbWFsUGF5bWVudFBlcmNlbnQgICAgID0gICBfb3JkZXIuY3VzdG9tZXIuZ3JvdXAubWluaW1hbF9jcmVkaXRfcGF5bWVudDtcclxuICAgICAgICAgICAgY29uc3QgZXhwZWN0ZWQgICAgICAgICAgICAgICAgICA9ICAgKCBfb3JkZXIudG90YWwgKiBtaW5pbWFsUGF5bWVudFBlcmNlbnQgKSAvIDEwMDtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBjaGVja2luZyBvcmRlciBkZXRhaWxzXHJcbiAgICAgICAgICAgICAqIGluc3RhbGxtZW50cyAmIHBheW1lbnQgZGF0ZVxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG9yZGVyICAgID0gICBhd2FpdCBuZXcgUHJvbWlzZTxPcmRlcj4oICggcmVzb2x2ZSwgcmVqZWN0ICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIFBvcHVwLnNob3coIE5zTGF5YXdheVBvcHVwLCB7IG9yZGVyOiBfb3JkZXIsIHJlamVjdCwgcmVzb2x2ZSB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICggb3JkZXIudGVuZGVyZWQgPCBleHBlY3RlZCApIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXNzYWdlICAgPSAgICBgQmVmb3JlIHNhdmluZyB0aGUgb3JkZXIgYXMgbGFpZCBhd2F5LCBhIG1pbmltdW0gcGF5bWVudCBvZiAkeyBWdWUuZmlsdGVyKCAnY3VycmVuY3knICkoIGV4cGVjdGVkICkgfSBpcyByZXF1aXJlZGA7XHJcbiAgICAgICAgICAgICAgICAgICAgUG9wdXAuc2hvdyggTnNBbGVydFBvcHVwLCB7IHRpdGxlOiAnVW5hYmxlIHRvIHByb2NlZWQnLCBtZXNzYWdlIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoeyBzdGF0dXM6ICdmYWlsZWQnLCBtZXNzYWdlIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHsgc3RhdHVzOiAnc3VjY2VzcycsIG1lc3NhZ2U6IF9fKCAnTGF5YXdheSBkZWZpbmVkJyApLCBkYXRhOiB7IG9yZGVyIH0gfSk7XHJcblxyXG4gICAgICAgICAgICB9IGNhdGNoKCBleGNlcHRpb24gKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KCBleGNlcHRpb24gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmllbGRzIG1pZ2h0IGJlIHByb3ZpZGVkIHRvIG92ZXJ3cml0ZSB0aGUgZGVmYXVsdCBpbmZvcm1hdGlvbiBcclxuICAgICAqIHNldCBvbiB0aGUgb3JkZXIuIFxyXG4gICAgICogQHBhcmFtIG9yZGVyRmllbGRzIE9iamVjdFxyXG4gICAgICovXHJcbiAgICBzdWJtaXRPcmRlciggb3JkZXJGaWVsZHMgPSB7fSApIHtcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoIGFzeW5jICggcmVzb2x2ZSwgcmVqZWN0ICkgPT4ge1xyXG4gICAgICAgICAgICB2YXIgb3JkZXIgICAgICAgICAgICAgPSAgIHsgXHJcbiAgICAgICAgICAgICAgICAuLi48T3JkZXI+dGhpcy5vcmRlciEuZ2V0VmFsdWUoKSxcclxuICAgICAgICAgICAgICAgIC4uLm9yZGVyRmllbGRzXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBjb25zdCBtaW5pbWFsUGF5bWVudCAgICA9ICAgb3JkZXIuY3VzdG9tZXIuZ3JvdXAubWluaW1hbF9jcmVkaXRfcGF5bWVudDtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiB0aGlzIHZlcmlmaWNhdGlvbiBhcHBsaWVzIG9ubHkgaWYgdGhlIFxyXG4gICAgICAgICAgICAgKiBvcmRlciBpcyBub3QgXCJob2xkXCIuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBpZiAoIG9yZGVyLnBheW1lbnRfc3RhdHVzICE9PSAnaG9sZCcgKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIG9yZGVyLnBheW1lbnRzLmxlbmd0aCAgPT09IDAgfHwgb3JkZXIudG90YWwgPiBvcmRlci50ZW5kZXJlZCApIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIHRoaXMub3B0aW9ucy5nZXRWYWx1ZSgpLm5zX29yZGVyc19hbGxvd19wYXJ0aWFsID09PSAnbm8nICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXNzYWdlICAgPSAgICdQYXJ0aWFsbHkgcGFpZCBvcmRlcnMgYXJlIGRpc2FibGVkLic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoeyBzdGF0dXM6ICdmYWlsZWQnLCBtZXNzYWdlIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIG1pbmltYWxQYXltZW50ID49IDAgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgICAgPSAgIGF3YWl0IHRoaXMuY2FuUHJvY2VlZEFzTGFpZEF3YXkoIG9yZGVyICk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiB0aGUgb3JkZXIgbWlnaHQgaGF2ZSBiZWVuIHVwZGF0ZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGJ5IHRoZSBsYXlhd2F5IHBvcHVwLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlciAgICAgICAgICAgPSAgIHJlc3VsdC5kYXRhLm9yZGVyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoKCBleGNlcHRpb24gKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KCBleGNlcHRpb24gKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCAhIHRoaXMuX2lzU3VibWl0dGluZyApIHtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBAdG9kbyBkbyB3ZSBuZWVkIHRvIHNldCBhIG5ldyB2YWx1ZSBoZXJlXHJcbiAgICAgICAgICAgICAgICAgKiBwcm9iYWJseSB0aGUgcGFzc2VkIHZhbHVlIHNob3VsZCBiZSBzZW5kIHRvIHRoZSBzZXJ2ZXIuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGNvbnN0IG1ldGhvZCAgICA9ICAgb3JkZXIuaWQgIT09IHVuZGVmaW5lZCA/ICdwdXQnIDogJ3Bvc3QnO1xyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9pc1N1Ym1pdHRpbmcgID0gICB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBuc0h0dHBDbGllbnRbIG1ldGhvZCBdKCBgL2FwaS9uZXhvcG9zL3Y0L29yZGVycyR7IG9yZGVyLmlkICE9PSB1bmRlZmluZWQgPyAnLycgKyBvcmRlci5pZCA6ICcnIH1gLCBvcmRlciApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZSggcmVzdWx0ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSggcmVzdWx0ICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgKiB3aWxsIHRyaWdnZXIgYW4gYWNjdGlvbiB3aGVuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAqIHRoZSBvcmRlciBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgc3VibWl0dGVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuc0hvb2tzLmRvQWN0aW9uKCAnbnMtb3JkZXItc3VibWl0LXN1Y2Nlc3NmdWwnLCByZXN1bHQgKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2lzU3VibWl0dGluZyAgPSAgIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sICggZXJyb3I6IGFueSApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faXNTdWJtaXR0aW5nICA9ICAgZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCggZXJyb3IgKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5zSG9va3MuZG9BY3Rpb24oICducy1vcmRlci1zdWJtaXQtZmFpbGVkJywgZXJyb3IgKTtcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KHsgc3RhdHVzOiAnZmFpbGVkJywgbWVzc2FnZTogJ0FuIG9yZGVyIGlzIGN1cnJlbnRseSBiZWluZyBwcm9jZXNzZWQuJyB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBsb2FkT3JkZXIoIG9yZGVyX2lkICkge1xyXG4gICAgICAgIG5zSHR0cENsaWVudC5nZXQoIGAvYXBpL25leG9wb3MvdjQvb3JkZXJzLyR7b3JkZXJfaWR9L3Bvc2AgKVxyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCAoIG9yZGVyOiBhbnkgKSA9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgb3JkZXIgICAgICAgPSAgIHsgLi4udGhpcy5kZWZhdWx0T3JkZXIoKSwgLi4ub3JkZXIgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFdlJ2xsIHJlYnVpbHQgdGhlIHByb2R1Y3RcclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcHJvZHVjdHMgID0gICBvcmRlci5wcm9kdWN0cy5tYXAoIChvcmRlclByb2R1Y3Q6IE9yZGVyUHJvZHVjdCApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBvcmRlclByb2R1Y3QuJG9yaWdpbmFsICAgICAgID0gICAoKSA9PiBvcmRlclByb2R1Y3QucHJvZHVjdDtcclxuICAgICAgICAgICAgICAgICAgICBvcmRlclByb2R1Y3QuJHF1YW50aXRpZXMgICAgID0gICAoKSA9PiBvcmRlclByb2R1Y3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgLnByb2R1Y3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgLnVuaXRfcXVhbnRpdGllc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKCB1bml0UXVhbnRpdHkgPT4gdW5pdFF1YW50aXR5LmlkID09PSBvcmRlclByb2R1Y3QudW5pdF9xdWFudGl0eV9pZCApWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvcmRlclByb2R1Y3Q7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIHdlJ2xsIHJlZGVmaW5lIHRoZSBvcmRlciB0eXBlXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIG9yZGVyLnR5cGUgICAgICAgICAgPSAgIHRoaXMudHlwZXMuZ2V0VmFsdWUoKS5maWx0ZXIoIHR5cGUgPT4gdHlwZS5pZGVudGlmaWVyID09PSBvcmRlci50eXBlIClbMF07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiB0aGUgYWRkcmVzcyBpcyBwcm92aWRlZCBkaWZmZXJlbnRseVxyXG4gICAgICAgICAgICAgICAgICogdGhlbiB3ZSBuZWVkIHRvIHJlYnVpbGQgaXQgdGhlIHdheSBpdCdzIHNhdmVkIGFuZCB1c2VkXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIG9yZGVyLmFkZHJlc3NlcyAgICAgPSAgIHtcclxuICAgICAgICAgICAgICAgICAgICBzaGlwcGluZyAgICA6ICAgb3JkZXIuc2hpcHBpbmdfYWRkcmVzcyxcclxuICAgICAgICAgICAgICAgICAgICBiaWxsaW5nICAgICA6ICAgb3JkZXIuYmlsbGluZ19hZGRyZXNzXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgZGVsZXRlIG9yZGVyLnNoaXBwaW5nX2FkZHJlc3M7XHJcbiAgICAgICAgICAgICAgICBkZWxldGUgb3JkZXIuYmlsbGluZ19hZGRyZXNzO1xyXG5cclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBsZXQncyBhbGwgc2V0LCBsZXQncyBsb2FkIHRoZSBvcmRlclxyXG4gICAgICAgICAgICAgICAgICogZnJvbSBub3cuIE5vIGZ1cnRoZXIgY2hhbmdlIGlzIHJlcXVpcmVkXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgdGhpcy5idWlsZE9yZGVyKCBvcmRlciApO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5idWlsZFByb2R1Y3RzKCBwcm9kdWN0cyApO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RDdXN0b21lciggb3JkZXIuY3VzdG9tZXIgKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgYnVpbGRPcmRlciggb3JkZXIgKSB7XHJcbiAgICAgICAgdGhpcy5vcmRlci5uZXh0KCBvcmRlciApO1xyXG4gICAgfVxyXG5cclxuICAgIGJ1aWxkUHJvZHVjdHMoIHByb2R1Y3RzICkge1xyXG4gICAgICAgIHRoaXMucmVmcmVzaFByb2R1Y3RzKCBwcm9kdWN0cyApO1xyXG4gICAgICAgIHRoaXMucHJvZHVjdHMubmV4dCggcHJvZHVjdHMgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcmludE9yZGVyKCBvcmRlcl9pZCApIHtcclxuICAgICAgICBjb25zdCBvcHRpb25zICAgICAgICAgICA9ICAgdGhpcy5vcHRpb25zLmdldFZhbHVlKCk7XHJcblxyXG4gICAgICAgIGlmICggb3B0aW9ucy5uc19wb3NfcHJpbnRpbmdfZW5hYmxlZF9mb3IgPT09ICdkaXNhYmxlZCcgKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHByaW50U2VjdGlvbiAgICAgID0gICBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnaWZyYW1lJyApO1xyXG4gICAgICAgIHByaW50U2VjdGlvbi5pZCAgICAgICAgID0gICAncHJpbnRpbmctc2VjdGlvbic7XHJcbiAgICAgICAgcHJpbnRTZWN0aW9uLmNsYXNzTmFtZSAgPSAgICdoaWRkZW4nO1xyXG4gICAgICAgIHByaW50U2VjdGlvbi5zcmMgICAgICAgID0gICB0aGlzLnNldHRpbmdzLmdldFZhbHVlKClbICd1cmxzJyBdWyAncHJpbnRpbmdfdXJsJyBdLnJlcGxhY2UoICd7aWR9Jywgb3JkZXJfaWQgKTtcclxuXHJcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCggcHJpbnRTZWN0aW9uICk7XHJcbiAgICB9XHJcblxyXG4gICAgY29tcHV0ZVBhaWQoKSB7XHJcbiAgICAgICAgY29uc3Qgb3JkZXIgICAgID0gICB0aGlzLl9vcmRlci5nZXRWYWx1ZSgpOyAgIFxyXG4gICAgICAgIG9yZGVyLnRlbmRlcmVkICAgICAgPSAgIDA7XHJcblxyXG4gICAgICAgIGlmICggb3JkZXIucGF5bWVudHMubGVuZ3RoID4gMCApIHtcclxuICAgICAgICAgICAgb3JkZXIudGVuZGVyZWQgICAgICA9ICAgb3JkZXIucGF5bWVudHMubWFwKCBwID0+IHAudmFsdWUgKS5yZWR1Y2UoICggYiwgYSApID0+IGEgKyBiICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIG9yZGVyLnRlbmRlcmVkID49IG9yZGVyLnRvdGFsICkge1xyXG4gICAgICAgICAgICBvcmRlci5wYXltZW50X3N0YXR1cyAgICA9ICAgJ3BhaWQnO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoIG9yZGVyLnRlbmRlcmVkID4gMCAmJiBvcmRlci50ZW5kZXJlZCA8IG9yZGVyLnRvdGFsICkge1xyXG4gICAgICAgICAgICBvcmRlci5wYXltZW50X3N0YXR1cyAgICA9ICAgJ3BhcnRpYWxseV9wYWlkJztcclxuICAgICAgICB9IFxyXG4gICAgICAgIFxyXG4gICAgICAgIG9yZGVyLmNoYW5nZSAgICA9ICAgb3JkZXIudGVuZGVyZWQgLSBvcmRlci50b3RhbDtcclxuXHJcbiAgICAgICAgdGhpcy5fb3JkZXIubmV4dCggb3JkZXIgKTtcclxuICAgIH1cclxuXHJcbiAgICBzZXRQYXltZW50QWN0aXZlKCBwYXltZW50ICkge1xyXG4gICAgICAgIGNvbnN0IHBheW1lbnRzICA9ICAgdGhpcy5fcGF5bWVudHNUeXBlLmdldFZhbHVlKCk7XHJcbiAgICAgICAgY29uc3QgaW5kZXggICAgID0gICBwYXltZW50cy5pbmRleE9mKCBwYXltZW50ICk7XHJcbiAgICAgICAgcGF5bWVudHMuZm9yRWFjaCggcCA9PiBwLnNlbGVjdGVkID0gZmFsc2UgKTtcclxuICAgICAgICBwYXltZW50c1sgaW5kZXggXS5zZWxlY3RlZCAgPSAgIHRydWU7XHJcbiAgICAgICAgdGhpcy5fcGF5bWVudHNUeXBlLm5leHQoIHBheW1lbnRzICk7XHJcbiAgICB9XHJcblxyXG4gICAgZGVmaW5lZFBheW1lbnRzVHlwZSggcGF5bWVudHMgKSB7XHJcbiAgICAgICAgdGhpcy5fcGF5bWVudHNUeXBlLm5leHQoIHBheW1lbnRzICk7XHJcbiAgICB9XHJcblxyXG4gICAgc2VsZWN0Q3VzdG9tZXIoIGN1c3RvbWVyICkge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSggKCByZXNvbHZlLCByZWplY3QgKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IG9yZGVyICAgICAgICAgPSAgIHRoaXMub3JkZXIuZ2V0VmFsdWUoKTtcclxuICAgICAgICAgICAgb3JkZXIuY3VzdG9tZXIgICAgICA9ICAgY3VzdG9tZXI7XHJcbiAgICAgICAgICAgIG9yZGVyLmN1c3RvbWVyX2lkICAgPSAgIGN1c3RvbWVyLmlkXHJcbiAgICAgICAgICAgIHRoaXMub3JkZXIubmV4dCggb3JkZXIgKTtcclxuICAgIFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogYXN5bmNocm9ub3VzbHkgd2UgY2FuIGxvYWRcclxuICAgICAgICAgICAgICogY3VzdG9tZXIgbWV0YSBkYXRhXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBpZiAoIGN1c3RvbWVyLmdyb3VwID09PSB1bmRlZmluZWQgfHwgY3VzdG9tZXIuZ3JvdXAgPT09IG51bGwgKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICBuc0h0dHBDbGllbnQuZ2V0KCBgL2FwaS9uZXhvcG9zL3Y0L2N1c3RvbWVycy8ke2N1c3RvbWVyLmlkfS9ncm91cGAgKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoIGdyb3VwID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIuY3VzdG9tZXIuZ3JvdXAgICAgICAgID0gICBncm91cDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcmRlci5uZXh0KCBvcmRlciApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCBvcmRlciApO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sICggZXJyb3IgKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCggZXJyb3IgKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZUNhcnQoIGN1cnJlbnQsIHVwZGF0ZSApIHtcclxuICAgICAgICBmb3IoIGxldCBrZXkgaW4gdXBkYXRlICkge1xyXG4gICAgICAgICAgICBpZiAoIHVwZGF0ZVsga2V5IF0gIT09IHVuZGVmaW5lZCApIHtcclxuICAgICAgICAgICAgICAgIFZ1ZS5zZXQoIGN1cnJlbnQsIGtleSwgdXBkYXRlWyBrZXkgXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMub3JkZXIubmV4dCggY3VycmVudCApO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIGV4cGxpY2l0ZWx5IGhlcmUgd2UgZG8gbWFudWFsbHkgcmVmcmVzaCB0aGUgY2FydFxyXG4gICAgICAgICAqIGFzIGlmIHdlIGxpc3RlbiB0byBjYXJ0IHVwZGF0ZSBieSBzdWJzY3JpYmluZyxcclxuICAgICAgICAgKiB0aGF0IHdpbGwgY3JlYXRlIGEgbG9vcCAoaHVnZSBwZXJmb3JtYW5jZSBpc3N1ZSkuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5yZWZyZXNoQ2FydCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogZXZlcnl0aW1lIHRoZSBjYXJ0XHJcbiAgICAgKiByZWZyZXNoZWQsIHdlIG1pZ2h0IG5lZWRcclxuICAgICAqIHRvIHBlcmZvcm0gc29tZSB2ZXJpZmljYXRpb25cclxuICAgICAqL1xyXG4gICAgY2hlY2tDYXJ0KCkge1xyXG4gICAgICAgIGNvbnN0IG9yZGVyICAgICAgICAgICAgICAgICA9ICAgdGhpcy5vcmRlci5nZXRWYWx1ZSgpO1xyXG4gICAgICAgIGNvbnN0IHVubWF0Y2hlZENvbmRpdGlvbnMgICA9ICAgW107XHJcblxyXG4gICAgICAgIG9yZGVyLmNvdXBvbnMuZm9yRWFjaCggY291cG9uID0+IHtcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIGJ5IGRlZmF1bHQgd2UnbGwgYnlwYXNzXHJcbiAgICAgICAgICAgICAqIHRoZSBwcm9kdWN0IGlmIGl0J3Mgbm90IGF2YWlsYWJsZVxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgbGV0IGlzUHJvZHVjdFZhbGlkICA9ICAgdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBpZiB0aGUgY291cG9uIGluY2x1ZGVzIHByb2R1Y3RzXHJcbiAgICAgICAgICAgICAqIHdlIG1ha2Ugc3VyZSB0aGUgcHJvZHVjdHMgYXJlIGluY2x1ZGVkIG9uIHRoZSBjYXJ0XHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBpZiAoIGNvdXBvbi5wcm9kdWN0cy5sZW5ndGggPiAwICkge1xyXG4gICAgICAgICAgICAgICAgaXNQcm9kdWN0VmFsaWQgID0gICBvcmRlci5wcm9kdWN0cy5maWx0ZXIoIHByb2R1Y3QgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb3Vwb24ucHJvZHVjdHMubWFwKCBwID0+IHAucHJvZHVjdF9pZCApLmluY2x1ZGVzKCBwcm9kdWN0LnByb2R1Y3RfaWQgKTtcclxuICAgICAgICAgICAgICAgIH0pLmxlbmd0aCA+IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCAhIGlzUHJvZHVjdFZhbGlkICYmIHVubWF0Y2hlZENvbmRpdGlvbnMuaW5kZXhPZiggY291cG9uICkgPT09IC0xICkge1xyXG4gICAgICAgICAgICAgICAgICAgIHVubWF0Y2hlZENvbmRpdGlvbnMucHVzaCggY291cG9uICk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBieSBkZWZhdWx0IHdlJ2xsIGJ5cGFzc1xyXG4gICAgICAgICAgICAgKiB0aGUgcHJvZHVjdCBpZiBpdCdzIG5vdCBhdmFpbGFibGVcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGxldCBpc0NhdGVnb3J5VmFsaWQgID0gICB0cnVlO1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIGlmIHRoZSBjb3Vwb24gaW5jbHVkZXMgcHJvZHVjdHNcclxuICAgICAgICAgICAgICogd2UgbWFrZSBzdXJlIHRoZSBwcm9kdWN0cyBhcmUgaW5jbHVkZWQgb24gdGhlIGNhcnRcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGlmICggY291cG9uLmNhdGVnb3JpZXMubGVuZ3RoID4gMCApIHtcclxuICAgICAgICAgICAgICAgIGlzQ2F0ZWdvcnlWYWxpZCAgPSAgIG9yZGVyLnByb2R1Y3RzLmZpbHRlciggcHJvZHVjdCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvdXBvbi5jYXRlZ29yaWVzLm1hcCggcCA9PiBwLmNhdGVnb3J5X2lkICkuaW5jbHVkZXMoIHByb2R1Y3QuJG9yaWdpbmFsKCkuY2F0ZWdvcnlfaWQgKTtcclxuICAgICAgICAgICAgICAgIH0pLmxlbmd0aCA+IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCAhIGlzQ2F0ZWdvcnlWYWxpZCAmJiB1bm1hdGNoZWRDb25kaXRpb25zLmluZGV4T2YoIGNvdXBvbiApID09PSAtMSApIHtcclxuICAgICAgICAgICAgICAgICAgICB1bm1hdGNoZWRDb25kaXRpb25zLnB1c2goIGNvdXBvbiApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHVubWF0Y2hlZENvbmRpdGlvbnMuZm9yRWFjaCggY291cG9uID0+IHtcclxuICAgICAgICAgICAgbnNTbmFja0Jhci5lcnJvciggXHJcbiAgICAgICAgICAgICAgICBfXyggJ1RoZSBjb3Vwb25zIFwiJXNcIiBoYXMgYmVlbiByZW1vdmVkIGZyb20gdGhlIGNhcnQsIGFzIGl0XFwncyByZXF1aXJlZCBjb25kaXRpb25zIGFyZSBubyBtb3JlIG1lZXQuJyApXHJcbiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoICclcycsIGNvdXBvbi5uYW1lICksIFxyXG4gICAgICAgICAgICAgICAgX18oICdPa2F5JyApLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IDYwMDBcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKS5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlQ291cG9uKCBjb3Vwb24gKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyByZWZyZXNoQ2FydCgpIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBjaGVjayBpZiBhY2NvcmRpbmcgdG8gdGhlIHByb2R1Y3RcclxuICAgICAgICAgKiBhdmFpbGFibGUgb24gdGhlIGNhcnQgdGhlIGNvdXBvbnMgbXVzdCBcclxuICAgICAgICAgKiByZW1haW5zIHRoZSBzYW1lLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMuY2hlY2tDYXJ0KCk7XHJcblxyXG4gICAgICAgIGNvbnN0IHByb2R1Y3RzICAgICAgPSAgIHRoaXMucHJvZHVjdHMuZ2V0VmFsdWUoKTtcclxuICAgICAgICBsZXQgb3JkZXIgICAgICAgICAgID0gICB0aGlzLm9yZGVyLmdldFZhbHVlKCk7XHJcbiAgICAgICAgY29uc3QgcHJvZHVjdFRvdGFsICA9ICAgcHJvZHVjdHNcclxuICAgICAgICAgICAgLm1hcCggcHJvZHVjdCA9PiBwcm9kdWN0LnRvdGFsX3ByaWNlICk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKCBwcm9kdWN0VG90YWwubGVuZ3RoID4gMCApIHtcclxuICAgICAgICAgICAgb3JkZXIuc3VidG90YWwgID0gICBwcm9kdWN0VG90YWwucmVkdWNlKCAoIGIsIGEgKSA9PiBiICsgYSApO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIG9yZGVyLnN1YnRvdGFsICA9ICAgMDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIHdlJ2xsIGNvbXB1dGUgaGVyZSB0aGUgdmFsdWVcclxuICAgICAgICAgKiBvZiB0aGUgY291cG9uc1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNvbnN0IHRvdGFsVmFsdWUgICAgPSAgIG9yZGVyLmNvdXBvbnMubWFwKCBjdXN0b21lckNvdXBvbiA9PiB7XHJcbiAgICAgICAgICAgIGlmICggY3VzdG9tZXJDb3Vwb24udHlwZSA9PT0gJ3BlcmNlbnRhZ2VfZGlzY291bnQnICkge1xyXG4gICAgICAgICAgICAgICAgY3VzdG9tZXJDb3Vwb24udmFsdWUgICAgPSAgICggb3JkZXIuc3VidG90YWwgKiBjdXN0b21lckNvdXBvbi5kaXNjb3VudF92YWx1ZSApIC8gMTAwO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGN1c3RvbWVyQ291cG9uLnZhbHVlO1xyXG4gICAgICAgICAgICB9IFxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgY3VzdG9tZXJDb3Vwb24udmFsdWUgICAgPSAgIGN1c3RvbWVyQ291cG9uLmRpc2NvdW50X3ZhbHVlO1xyXG4gICAgICAgICAgICByZXR1cm4gY3VzdG9tZXJDb3Vwb24udmFsdWU7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIG9yZGVyLnRvdGFsX2NvdXBvbnMgICAgICAgICA9ICAgMDtcclxuICAgICAgICBpZiAoIHRvdGFsVmFsdWUubGVuZ3RoID4gMCApIHtcclxuICAgICAgICAgICAgb3JkZXIudG90YWxfY291cG9ucyAgICAgPSAgIHRvdGFsVmFsdWUucmVkdWNlKCAoIGJlZm9yZSwgYWZ0ZXIgKSA9PiBiZWZvcmUgKyBhZnRlciApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCBvcmRlci5kaXNjb3VudF90eXBlID09PSAncGVyY2VudGFnZScgKSB7XHJcbiAgICAgICAgICAgIG9yZGVyLmRpc2NvdW50ICAgPSAgICggb3JkZXIuZGlzY291bnRfcGVyY2VudGFnZSAqIG9yZGVyLnN1YnRvdGFsICkgLyAxMDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBpZiB0aGUgZGlzY291bnQgYW1vdW50IGlzIGdyZWF0aGVyXHJcbiAgICAgICAgICogdGhhbiB0aGUgc3VidG90YWwsIHRoZSBkaXNjb3VudCBhbW91bnRcclxuICAgICAgICAgKiB3aWxsIGJlIHNldCB0byB0aGUgb3JkZXIuc3VidG90YWxcclxuICAgICAgICAgKi9cclxuICAgICAgICBpZiAoIG9yZGVyLmRpc2NvdW50ID4gb3JkZXIuc3VidG90YWwgJiYgb3JkZXIudG90YWxfY291cG9ucyA9PT0gMCApIHtcclxuICAgICAgICAgICAgb3JkZXIuZGlzY291bnQgPSBvcmRlci5zdWJ0b3RhbDtcclxuICAgICAgICAgICAgbnNTbmFja0Jhci5pbmZvKCAnVGhlIGRpc2NvdW50IGhhcyBiZWVuIHNldCB0byB0aGUgY2FydCBzdWJ0b3RhbCcgKVxyXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogc2F2ZSBhY3R1YWwgY2hhbmdlIHRvIGVuc3VyZVxyXG4gICAgICAgICAqIGFsbCBsaXN0ZW5lciBhcmUgdXAgdG8gZGF0ZS5cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLm9yZGVyLm5leHQoIG9yZGVyICk7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIHdpbGwgY29tcHV0ZSB0aGUgdGF4ZXMgYmFzZWQgb24gXHJcbiAgICAgICAgICogdGhlIGFjdHVhbCBzdGF0ZSBvZiB0aGUgb3JkZXJcclxuICAgICAgICAgKi9cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSAgPSAgIGF3YWl0IHRoaXMuY29tcHV0ZVRheGVzKCk7XHJcbiAgICAgICAgICAgIG9yZGVyICAgICAgICAgICA9ICAgcmVzcG9uc2VbICdkYXRhJyBdLm9yZGVyO1xyXG4gICAgICAgIH0gY2F0Y2goIGV4Y2VwdGlvbiApIHtcclxuICAgICAgICAgICAgaWYgKCBleGNlcHRpb24gIT09IGZhbHNlICYmIGV4Y2VwdGlvbi5tZXNzYWdlICE9PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBleGNlcHRpb24ubWVzc2FnZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogcmV0cmVpdmUgYWxsIHByb2R1Y3RzIHRheGVzXHJcbiAgICAgICAgICogYW5kIHN1bSB0aGUgdG90YWwuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgY29uc3QgdG90YWxUYXhlcyAgICAgICAgPSAgIHByb2R1Y3RzLm1hcCggKCBwcm9kdWN0OiBPcmRlclByb2R1Y3QgKSA9PiBwcm9kdWN0LnRheF92YWx1ZSApO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiB0YXggbWlnaHQgYmUgY29tcHV0ZWQgYWJvdmUgdGhlIHRheCB0aGF0IGN1cnJlbnRseVxyXG4gICAgICAgICAqIGFwcGxpZSB0byB0aGUgaXRlbXMuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgb3JkZXIudGF4X3ZhbHVlICAgICAgICAgPSAgIDA7XHJcbiAgICAgICAgY29uc3QgdmF0VHlwZSAgICAgICAgICAgPSAgIHRoaXMub3B0aW9ucy5nZXRWYWx1ZSgpLm5zX3Bvc192YXQ7XHJcblxyXG4gICAgICAgIGlmKCBbICdwcm9kdWN0c192YXQnLCAncHJvZHVjdHNfZmxhdF92YXQnLCAncHJvZHVjdHNfdmFyaWFibGVfdmF0JyBdLmluY2x1ZGVzKCB2YXRUeXBlICkgJiYgdG90YWxUYXhlcy5sZW5ndGggPiAwICkge1xyXG4gICAgICAgICAgICBvcmRlci50YXhfdmFsdWUgICAgKz0gICB0b3RhbFRheGVzLnJlZHVjZSggKCBiLCBhICkgPT4gYiArIGEgKTtcclxuICAgICAgICB9IFxyXG4gICAgICAgIFxyXG4gICAgICAgIGlmICggWyAnZmxhdF92YXQnLCAndmFyaWFibGVfdmF0JywgJ3Byb2R1Y3RzX3ZhcmlhYmxlX3ZhdCcgXS5pbmNsdWRlcyggdmF0VHlwZSApICYmIG9yZGVyLnRheGVzICYmIG9yZGVyLnRheGVzLmxlbmd0aCA+IDAgKSB7XHJcbiAgICAgICAgICAgIG9yZGVyLnRheF92YWx1ZSAgICAgKz0gICBvcmRlci50YXhlc1xyXG4gICAgICAgICAgICAgICAgLm1hcCggdGF4ID0+IHRheC50YXhfdmFsdWUgKVxyXG4gICAgICAgICAgICAgICAgLnJlZHVjZSggKCBiZWZvcmUsIGFmdGVyICkgPT4gYmVmb3JlICsgYWZ0ZXIgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIG9yZGVyLnRvdGFsICAgICAgICAgICAgID0gICAoIG9yZGVyLnN1YnRvdGFsICsgb3JkZXIuc2hpcHBpbmcgKyBvcmRlci50YXhfdmFsdWUgKSAtIG9yZGVyLmRpc2NvdW50IC0gb3JkZXIudG90YWxfY291cG9ucztcclxuICAgICAgICBvcmRlci5wcm9kdWN0cyAgICAgICAgICA9ICAgcHJvZHVjdHM7XHJcbiAgICAgICAgb3JkZXIudG90YWxfcHJvZHVjdHMgICAgPSAgIHByb2R1Y3RzLmxlbmd0aFxyXG5cclxuICAgICAgICB0aGlzLm9yZGVyLm5leHQoIG9yZGVyICk7XHJcblxyXG4gICAgICAgIG5zSG9va3MuZG9BY3Rpb24oICducy1jYXJ0LWFmdGVyLXJlZnJlc2hlZCcsIG9yZGVyICk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgYWN0dWFsIHN0b2NrIHVzZWQgYnkgdGhlIHByb2R1Y3RcclxuICAgICAqIHVzaW5nIHRoZSBkZWZpbmVkIHVuaXRcclxuICAgICAqIEBwYXJhbSBwcm9kdWN0X2lkIFxyXG4gICAgICogQHBhcmFtIHVuaXRfaWQgXHJcbiAgICAgKi9cclxuICAgIGdldFN0b2NrVXNhZ2UoIHByb2R1Y3RfaWQ6IG51bWJlciwgdW5pdF9xdWFudGl0eV9pZDogbnVtYmVyICkge1xyXG4gICAgICAgIGNvbnN0IHN0b2NrcyAgICA9ICAgdGhpcy5fcHJvZHVjdHMuZ2V0VmFsdWUoKS5maWx0ZXIoIChwcm9kdWN0OiBPcmRlclByb2R1Y3QgKSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBwcm9kdWN0LnByb2R1Y3RfaWQgPT09IHByb2R1Y3RfaWQgJiYgcHJvZHVjdC51bml0X3F1YW50aXR5X2lkID09PSB1bml0X3F1YW50aXR5X2lkO1xyXG4gICAgICAgIH0pLm1hcCggcHJvZHVjdCA9PiBwcm9kdWN0LnF1YW50aXR5ICk7XHJcblxyXG4gICAgICAgIGlmICggc3RvY2tzLmxlbmd0aCA+IDAgKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBzdG9ja3MucmVkdWNlKCAoIGIsIGEgKSA9PiBiICsgYSApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIDA7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiB0aGlzIGlzIHJlc29sdmVkIHdoZW4gYSBwcm9kdWN0IGlzIGJlaW5nIGFkZGVkIHRvIHRoZVxyXG4gICAgICogY2FydC4gVGhhdCB3aWxsIGhlbHAgdG8gbXV0YXRlIHRoZSBwcm9kdWN0IGJlZm9yZSBcclxuICAgICAqIGl0J3MgYWRkZWQgdGhlIGNhcnQuXHJcbiAgICAgKi9cclxuICAgIGFkZFRvQ2FydFF1ZXVlICA9ICAgW1xyXG4gICAgICAgIFByb2R1Y3RVbml0UHJvbWlzZSxcclxuICAgICAgICBQcm9kdWN0UXVhbnRpdHlQcm9taXNlXHJcbiAgICBdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUHJvY2VzcyB0aGUgaXRlbSB0byBhZGQgaXQgdG8gdGhlIGNhcnRcclxuICAgICAqIEBwYXJhbSBwcm9kdWN0IFxyXG4gICAgICovXHJcbiAgICBhc3luYyBhZGRUb0NhcnQoIHByb2R1Y3QgKSB7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFRoaXMgaXMgd2hlcmUgYWxsIHRoZSBtdXRhdGlvbiBtYWRlIGJ5IHRoZSAgXHJcbiAgICAgICAgICogcXVldWUgcHJvbWlzZXMgYXJlIHN0b3JlZC5cclxuICAgICAgICAgKi9cclxuICAgICAgICBsZXQgcHJvZHVjdERhdGEgICA9ICAgbmV3IE9iamVjdDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogTGV0J3MgY29tYmllbiB0aGUgYnVpbHQgcHJvZHVjdFxyXG4gICAgICAgICAqIHdpdGggdGhlIGRhdGEgcmVzb2x2ZWQgYnkgdGhlIHByb21pc2VzXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgbGV0IGNhcnRQcm9kdWN0OiBPcmRlclByb2R1Y3QgICA9ICB7XHJcbiAgICAgICAgICAgIHByb2R1Y3RfaWQgICAgICAgICAgOiBwcm9kdWN0LmlkLFxyXG4gICAgICAgICAgICBuYW1lICAgICAgICAgICAgICAgIDogcHJvZHVjdC5uYW1lLFxyXG4gICAgICAgICAgICBkaXNjb3VudF90eXBlICAgICAgIDogJ3BlcmNlbnRhZ2UnLFxyXG4gICAgICAgICAgICBkaXNjb3VudCAgICAgICAgICAgIDogMCxcclxuICAgICAgICAgICAgZGlzY291bnRfcGVyY2VudGFnZSA6IDAsXHJcbiAgICAgICAgICAgIHF1YW50aXR5ICAgICAgICAgICAgOiAwLFxyXG4gICAgICAgICAgICB0YXhfZ3JvdXBfaWQgICAgICAgIDogcHJvZHVjdC50YXhfZ3JvdXBfaWQsXHJcbiAgICAgICAgICAgIHRheF92YWx1ZSAgICAgICAgICAgOiAwLCAvLyBpcyBjb21wdXRlZCBhdXRvbWF0aWNhbGx5IHVzaW5nICRvcmlnaW5hbCgpXHJcbiAgICAgICAgICAgIHVuaXRfcHJpY2UgICAgICAgICAgOiAwLFxyXG4gICAgICAgICAgICB0b3RhbF9wcmljZSAgICAgICAgIDogMCxcclxuICAgICAgICAgICAgbW9kZSAgICAgICAgICAgICAgICA6ICdub3JtYWwnLFxyXG4gICAgICAgICAgICAkb3JpZ2luYWwgICAgICAgICAgIDogKCkgPT4gcHJvZHVjdFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIHdpbGwgZGV0ZXJtaW4gaWYgdGhlIFxyXG4gICAgICAgICAqIHNjcmlwdCBpcyBwcm9jZXNzaW5nIHRoZSBhZGQgcXVldWVcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLl9wcm9jZXNzaW5nQWRkUXVldWUgICAgPSAgIHRydWU7XHJcblxyXG4gICAgICAgIGZvciggbGV0IGluZGV4IGluIHRoaXMuYWRkVG9DYXJ0UXVldWUgKSB7XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogdGhlIHBvcHVwIHByb21pc2UgcmVjZWl2ZXMgdGhlIHByb2R1Y3QgdGhhdFxyXG4gICAgICAgICAgICAgKiBpcyBhYm92ZSB0byBiZSBhZGRlZC4gSG9wZWZ1bGx5IGFzIGl0J3MgcGFzc2VkIGJ5IHJlZmVyZW5jZVxyXG4gICAgICAgICAgICAgKiB1cGRhdGluZyB0aGUgcHJvZHVjdCBzaG91bGQgbXV0YXRlIHRoYXQgb25jZSB0aGUgcXVldWUgaXMgaGFuZGxlZC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlSW5zdGFuY2UgICA9ICAgbmV3IHRoaXMuYWRkVG9DYXJ0UXVldWVbIGluZGV4IF0oIGNhcnRQcm9kdWN0ICk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgICAgICAgICAgICA9ICAgPE9iamVjdD4oYXdhaXQgcHJvbWlzZUluc3RhbmNlLnJ1biggcHJvZHVjdERhdGEgKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBXZSBqdXN0IG1peCBib3RoIHRvIG1ha2Ugc3VyZVxyXG4gICAgICAgICAgICAgICAgICogdGhlIG11dGF0ZWQgdmFsdWUgb3ZlcndyaXRlIHByZXZpb3VzbHkgZGVmaW5lZCB2YWx1ZXMuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIHByb2R1Y3REYXRhICAgICAgICAgICAgID0gICB7IC4uLnByb2R1Y3REYXRhLCAuLi5yZXN1bHQgfTtcclxuXHJcbiAgICAgICAgICAgIH0gY2F0Y2goIGJyb2tlblByb21pc2UgKSB7XHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIGlmIGEgcG9wdXAgcmVzb2x2ZSBcImZhbHNlXCIsXHJcbiAgICAgICAgICAgICAgICAgKiB0aGF0IG1lYW5zIGZvciBzb21lIHJlYXNvbiB0aGUgUHJvbWlzZSBoYXNcclxuICAgICAgICAgICAgICAgICAqIGJlZW4gYnJva2VuLCB0aGVyZWZvcmUgd2UgbmVlZCB0byBzdG9wIHRoZSBxdWV1ZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgaWYgKCBicm9rZW5Qcm9taXNlID09PSBmYWxzZSApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wcm9jZXNzaW5nQWRkUXVldWUgICAgPSAgIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBlbmQgcHJvY2Vlc2luZyBhZGQgcXVldWVcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLl9wcm9jZXNzaW5nQWRkUXVldWUgICAgPSAgIGZhbHNlO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBMZXQncyBjb21iaWVuIHRoZSBidWlsdCBwcm9kdWN0XHJcbiAgICAgICAgICogd2l0aCB0aGUgZGF0YSByZXNvbHZlZCBieSB0aGUgcHJvbWlzZXNcclxuICAgICAgICAgKi9cclxuICAgICAgICBjYXJ0UHJvZHVjdCAgID0gICB7IC4uLmNhcnRQcm9kdWN0LCAuLi5wcm9kdWN0RGF0YSB9O1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIHJldHJlaXZlIHByb2R1Y3QgdGhhdCBcclxuICAgICAgICAgKiBhcmUgY3VycmVudGx5IHN0b3JlZFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNvbnN0IHByb2R1Y3RzICAgICAgPSAgIHRoaXMuX3Byb2R1Y3RzLmdldFZhbHVlKCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogcHVzaCB0aGUgbmV3IHByb2R1Y3RcclxuICAgICAgICAgKiBhdCB0aGUgZnJvbnQgb2YgdGhlIGNhcnRcclxuICAgICAgICAgKi9cclxuICAgICAgICBwcm9kdWN0cy51bnNoaWZ0KCBjYXJ0UHJvZHVjdCApO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBPbmNlIHRoZSBwcm9kdWN0IGhhcyBiZWVuIGFkZGVkIHRvIHRoZSBjYXJ0XHJcbiAgICAgICAgICogaXQncyBiZWluZyBjb21wdXRlZFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMucmVmcmVzaFByb2R1Y3RzKCBwcm9kdWN0cyApO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBkaXNwYXRjaCBldmVudCB0aGF0IHRoZSBcclxuICAgICAgICAgKiBwcm9kdWN0IGhhcyBiZWVuIGFkZGVkLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMuX3Byb2R1Y3RzLm5leHQoIHByb2R1Y3RzICk7XHJcbiAgICB9XHJcblxyXG4gICAgZGVmaW5lVHlwZXMoIHR5cGVzICkge1xyXG4gICAgICAgIHRoaXMuX3R5cGVzLm5leHQoIHR5cGVzICk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVtb3ZlUHJvZHVjdCggcHJvZHVjdCApIHtcclxuICAgICAgICBjb25zdCBwcm9kdWN0cyAgPSAgIHRoaXMuX3Byb2R1Y3RzLmdldFZhbHVlKCk7XHJcbiAgICAgICAgY29uc3QgaW5kZXggICAgID0gICBwcm9kdWN0cy5pbmRleE9mKCBwcm9kdWN0ICk7XHJcbiAgICAgICAgcHJvZHVjdHMuc3BsaWNlKCBpbmRleCwgMSApO1xyXG4gICAgICAgIHRoaXMuX3Byb2R1Y3RzLm5leHQoIHByb2R1Y3RzICk7XHJcbiAgICB9XHJcblxyXG4gICAgdXBkYXRlUHJvZHVjdCggcHJvZHVjdCwgZGF0YSwgaW5kZXggPSBudWxsICkge1xyXG4gICAgICAgIGNvbnN0IHByb2R1Y3RzICAgICAgPSAgIHRoaXMuX3Byb2R1Y3RzLmdldFZhbHVlKCk7XHJcbiAgICAgICAgaW5kZXggICAgICAgICAgICAgICA9ICAgaW5kZXggPT09IG51bGwgPyBwcm9kdWN0cy5pbmRleE9mKCBwcm9kdWN0ICkgOiBpbmRleDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogdG8gZW5zdXJlIFZ1ZSB1cGRhdGVzIGFjY29yZGluZ2x5LlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFZ1ZS5zZXQoIHByb2R1Y3RzLCBpbmRleCwgeyAuLi5wcm9kdWN0LCAuLi5kYXRhIH0pO1xyXG5cclxuICAgICAgICB0aGlzLnJlZnJlc2hQcm9kdWN0cyggcHJvZHVjdHMgKTtcclxuICAgICAgICB0aGlzLl9wcm9kdWN0cy5uZXh0KCBwcm9kdWN0cyApO1xyXG4gICAgfVxyXG5cclxuICAgIHJlZnJlc2hQcm9kdWN0cyggcHJvZHVjdHMgKSB7XHJcbiAgICAgICAgcHJvZHVjdHMuZm9yRWFjaCggcHJvZHVjdCA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuY29tcHV0ZVByb2R1Y3QoIHByb2R1Y3QgKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBjb21wdXRlUHJvZHVjdCggcHJvZHVjdDogT3JkZXJQcm9kdWN0ICkge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIGRldGVybWluaW5nIHdoYXQgaXMgdGhlIFxyXG4gICAgICAgICAqIHJlYWwgc2FsZSBwcmljZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGlmICggcHJvZHVjdC5tb2RlID09PSAnbm9ybWFsJyApIHtcclxuICAgICAgICAgICAgcHJvZHVjdC51bml0X3ByaWNlICAgICAgICAgID0gICAgICAgcHJvZHVjdC4kcXVhbnRpdGllcygpLnNhbGVfcHJpY2U7XHJcbiAgICAgICAgICAgIHByb2R1Y3QudGF4X3ZhbHVlICAgICAgICAgICA9ICAgICAgIHByb2R1Y3QuJHF1YW50aXRpZXMoKS5zYWxlX3ByaWNlX3RheCAqIHByb2R1Y3QucXVhbnRpdHk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcHJvZHVjdC51bml0X3ByaWNlICAgICAgICAgID0gICAgICAgcHJvZHVjdC4kcXVhbnRpdGllcygpLndob2xlc2FsZV9wcmljZTtcclxuICAgICAgICAgICAgcHJvZHVjdC50YXhfdmFsdWUgICAgICAgICAgID0gICAgICAgcHJvZHVjdC4kcXVhbnRpdGllcygpLndob2xlc2FsZV9wcmljZV90YXggKiBwcm9kdWN0LnF1YW50aXR5O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogY29tcHV0aW5nIHRoZSBkaXNjb3VudCB3aGVuIGl0J3MgXHJcbiAgICAgICAgICogYmFzZWQgb24gYSBwZXJjZW50YWdlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgaWYgKFsgJ2ZsYXQnLCAncGVyY2VudGFnZScgXS5pbmNsdWRlcyggcHJvZHVjdC5kaXNjb3VudF90eXBlICkgKSB7XHJcbiAgICAgICAgICAgIGlmICggcHJvZHVjdC5kaXNjb3VudF90eXBlID09PSAncGVyY2VudGFnZScgKSB7XHJcbiAgICAgICAgICAgICAgICBwcm9kdWN0LmRpc2NvdW50ICA9ICAgKCAoIHByb2R1Y3QudW5pdF9wcmljZSAqIHByb2R1Y3QuZGlzY291bnRfcGVyY2VudGFnZSApIC8gMTAwICkgKiBwcm9kdWN0LnF1YW50aXR5O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBwcm9kdWN0LnRvdGFsX3ByaWNlICAgICAgICAgPSAgICggcHJvZHVjdC51bml0X3ByaWNlICogcHJvZHVjdC5xdWFudGl0eSApIC0gcHJvZHVjdC5kaXNjb3VudDtcclxuXHJcbiAgICAgICAgbnNIb29rcy5kb0FjdGlvbiggJ25zLWFmdGVyLXByb2R1Y3QtY29tcHV0ZWQnLCBwcm9kdWN0ICk7XHJcbiAgICB9XHJcblxyXG4gICAgbG9hZEN1c3RvbWVyKCBpZCApIHtcclxuICAgICAgICByZXR1cm4gbnNIdHRwQ2xpZW50LmdldCggYC9hcGkvbmV4b3Bvcy92NC9jdXN0b21lcnMvJHtpZH1gICk7XHJcbiAgICB9XHJcblxyXG4gICAgZGVmaW5lU2V0dGluZ3MoIHNldHRpbmdzICkge1xyXG4gICAgICAgIHRoaXMuX3NldHRpbmdzLm5leHQoIHNldHRpbmdzICk7XHJcbiAgICB9XHJcblxyXG4gICAgdm9pZE9yZGVyKCBvcmRlciApIHtcclxuICAgICAgICBpZiAoIG9yZGVyLmlkICE9PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgIGlmICggWyAnaG9sZCcgXS5pbmNsdWRlcyggb3JkZXIucGF5bWVudF9zdGF0dXMgKSApIHtcclxuICAgICAgICAgICAgICAgIFBvcHVwLnNob3coIE5zQ29uZmlybVBvcHVwLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdPcmRlciBEZWxldGlvbicsXHJcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ1RoZSBjdXJyZW50IG9yZGVyIHdpbGwgYmUgZGVsZXRlZCBhcyBubyBwYXltZW50IGhhcyBiZWVuIG1hZGUgc28gZmFyLicsXHJcbiAgICAgICAgICAgICAgICAgICAgb25BY3Rpb246ICggYWN0aW9uICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGFjdGlvbiApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zSHR0cENsaWVudC5kZWxldGUoIGAvYXBpL25leG9wb3MvdjQvb3JkZXJzLyR7b3JkZXIuaWR9YCApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZSggKCByZXN1bHQ6IGFueSApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnNTbmFja0Jhci5zdWNjZXNzKCByZXN1bHQubWVzc2FnZSApLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgKCBlcnJvciApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5zU25hY2tCYXIuZXJyb3IoIGVycm9yLm1lc3NhZ2UgKS5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBQb3B1cC5zaG93KCBOc1Byb21wdFBvcHVwLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdWb2lkIFRoZSBPcmRlcicsXHJcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ1RoZSBjdXJyZW50IG9yZGVyIHdpbGwgYmUgdm9pZC4gVGhpcyB3aWxsIGNhbmNlbCB0aGUgdHJhbnNhY3Rpb24sIGJ1dCB0aGUgb3JkZXIgd29uXFwndCBiZSBkZWxldGVkLiBGdXJ0aGVyIGRldGFpbHMgYWJvdXQgdGhlIG9wZXJhdGlvbiB3aWxsIGJlIHRyYWNrZWQgb24gdGhlIHJlcG9ydC4gQ29uc2lkZXIgcHJvdmlkaW5nIHRoZSByZWFzb24gb2YgdGhpcyBvcGVyYXRpb24uJyxcclxuICAgICAgICAgICAgICAgICAgICBvbkFjdGlvbjogKCByZWFzb24gKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggcmVhc29uICE9PSBmYWxzZSApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zSHR0cENsaWVudC5wb3N0KCBgL2FwaS9uZXhvcG9zL3Y0L29yZGVycy8ke29yZGVyLmlkfS92b2lkYCwgeyByZWFzb24gfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCAoIHJlc3VsdDogYW55ICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuc1NuYWNrQmFyLnN1Y2Nlc3MoIHJlc3VsdC5tZXNzYWdlICkuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCAoIGVycm9yICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnNTbmFja0Jhci5lcnJvciggZXJyb3IubWVzc2FnZSApLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSAgICAgICAgICAgIFxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIG5zU25hY2tCYXIuZXJyb3IoICdVbmFibGUgdG8gdm9pZCBhbiB1bnBhaWQgb3JkZXIuJyApLnN1YnNjcmliZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhc3luYyB0cmlnZ2VyT3JkZXJUeXBlU2VsZWN0aW9uKCBzZWxlY3RlZFR5cGUgKSB7XHJcbiAgICAgICAgZm9yKCBsZXQgaSA9IDA7IGkgPCB0aGlzLm9yZGVyVHlwZVF1ZXVlLmxlbmd0aDsgaSsrICkge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ICAgID0gICBhd2FpdCB0aGlzLm9yZGVyVHlwZVF1ZXVlW2ldLnByb21pc2UoIHNlbGVjdGVkVHlwZSApO1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coIHJlc3VsdCApO1xyXG4gICAgICAgICAgICB9IGNhdGNoKCBleGNlcHRpb24gKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyggZXhjZXB0aW9uICk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgc2V0KCBrZXksIHZhbHVlICkge1xyXG4gICAgICAgIGNvbnN0IHNldHRpbmdzICA9ICAgdGhpcy5zZXR0aW5ncy5nZXRWYWx1ZSgpO1xyXG4gICAgICAgIHNldHRpbmdzWyBrZXkgXSAgICAgPSAgIHZhbHVlO1xyXG4gICAgICAgIHRoaXMuc2V0dGluZ3MubmV4dCggc2V0dGluZ3MgKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQoIGtleSApIHtcclxuICAgICAgICBjb25zdCBzZXR0aW5ncyAgPSAgIHRoaXMuc2V0dGluZ3MuZ2V0VmFsdWUoKTtcclxuICAgICAgICByZXR1cm4gc2V0dGluZ3NbIGtleSBdO1xyXG4gICAgfVxyXG5cclxuICAgIGRlc3Ryb3koKSB7XHJcbiAgICAgICAgdGhpcy5fcHJvZHVjdHMudW5zdWJzY3JpYmUoKTtcclxuICAgICAgICB0aGlzLl9jdXN0b21lcnMudW5zdWJzY3JpYmUoKTtcclxuICAgICAgICB0aGlzLl90eXBlcy51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgIHRoaXMuX2JyZWFkY3J1bWJzLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgdGhpcy5fcGF5bWVudHNUeXBlLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgdGhpcy5fc2NyZWVuLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgdGhpcy5fb3JkZXIudW5zdWJzY3JpYmUoKTtcclxuICAgICAgICB0aGlzLl9zZXR0aW5ncy51bnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG59XHJcblxyXG4oIHdpbmRvdyBhcyBhbnkgKS5QT1MgICAgICAgPSAgIG5ldyBQT1M7XHJcblxyXG5leHBvcnQgY29uc3QgUE9TSW5pdCAgICA9ICAgPFBPUz4oIHdpbmRvdyBhcyBhbnkgKS5QT1M7XHJcbiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./resources/ts/pos-init.ts\n"); - ->>>>>>> 3313f0bf34ae3b3550ee3b8ff27748899eebc41e /***/ }), diff --git a/public/js/pos.js b/public/js/pos.js index a48a2c829..65ed63a7e 100755 --- a/public/js/pos.js +++ b/public/js/pos.js @@ -20,11 +20,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _bab /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -<<<<<<< HEAD -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.common.js\");\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(vue__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../bootstrap */ \"./resources/ts/bootstrap.ts\");\n/* harmony import */ var _libraries_pos_section_switch__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/libraries/pos-section-switch */ \"./resources/ts/libraries/pos-section-switch.ts\");\n/* harmony import */ var _popups_ns_pos_search_product_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/popups/ns-pos-search-product.vue */ \"./resources/ts/popups/ns-pos-search-product.vue\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n name: 'ns-pos-grid',\n data: function data() {\n return {\n products: [],\n categories: [],\n breadcrumbs: [],\n autoFocus: false,\n barcode: '',\n previousCategory: null,\n order: null,\n visibleSection: null,\n breadcrumbsSubsribe: null,\n orderSubscription: null,\n visibleSectionSubscriber: null,\n currentCategory: null,\n interval: null,\n searchTimeout: null\n };\n },\n computed: {\n hasCategories: function hasCategories() {\n return this.categories.length > 0;\n }\n },\n watch: {\n barcode: function barcode() {\n var _this = this;\n\n clearTimeout(this.searchTimeout);\n this.searchTimeout = setTimeout(function () {\n _this.submitSearch(_this.barcode);\n }, 1000);\n }\n },\n mounted: function mounted() {\n var _this2 = this;\n\n this.loadCategories();\n this.breadcrumbsSubsribe = POS.breadcrumbs.subscribe(function (breadcrumbs) {\n _this2.breadcrumbs = breadcrumbs;\n });\n this.visibleSectionSubscriber = POS.visibleSection.subscribe(function (section) {\n _this2.visibleSection = section;\n });\n this.orderSubscription = POS.order.subscribe(function (order) {\n return _this2.order = order;\n });\n this.interval = setInterval(function () {\n return _this2.checkFocus();\n }, 500);\n },\n destroyed: function destroyed() {\n this.orderSubscription.unsubscribe();\n this.breadcrumbsSubsribe.unsubscribe();\n this.visibleSectionSubscriber.unsubscribe();\n clearInterval(this.interval);\n },\n methods: {\n switchTo: _libraries_pos_section_switch__WEBPACK_IMPORTED_MODULE_2__[\"default\"],\n openSearchPopup: function openSearchPopup() {\n Popup.show(_popups_ns_pos_search_product_vue__WEBPACK_IMPORTED_MODULE_3__[\"default\"]);\n },\n submitSearch: function submitSearch(value) {\n var _this3 = this;\n\n if (value.length > 0) {\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"].get(\"/api/nexopos/v4/products/search/using-barcode/\".concat(value)).subscribe(function (result) {\n _this3.barcode = '';\n POS.addToCart(result.product);\n }, function (error) {\n _this3.barcode = '';\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error(error.message).subscribe();\n });\n }\n },\n checkFocus: function checkFocus() {\n if (this.autoFocus) {\n var popup = document.querySelectorAll('.is-popup');\n\n if (popup.length === 0) {\n this.$refs.search.focus();\n }\n }\n },\n loadCategories: function loadCategories(parent) {\n var _this4 = this;\n\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"].get(\"/api/nexopos/v4/categories/pos/\".concat(parent ? parent.id : '')).subscribe(function (result) {\n _this4.categories = result.categories;\n _this4.products = result.products;\n _this4.previousCategory = result.previousCategory;\n _this4.currentCategory = result.currentCategory;\n\n _this4.updateBreadCrumb(_this4.currentCategory);\n });\n },\n updateBreadCrumb: function updateBreadCrumb(parent) {\n if (parent) {\n var index = this.breadcrumb.filter(function (bread) {\n return bread.id === parent.id;\n });\n /**\r\n * this means, we're trying to navigate\r\n * through something that has already been \r\n * added to the breadcrumb\r\n */\n\n if (index.length > 0) {\n var allow = true;\n var prior = this.breadcrumb.filter(function (bread) {\n if (bread.id === index[0].id && allow) {\n allow = false;\n return true;\n }\n\n return allow;\n });\n this.breadcrumb = prior;\n } else {\n this.breadcrumb.push(parent);\n }\n } else {\n this.breadcrumb = [];\n }\n\n POS.breadcrumbs.next(this.breadcrumb);\n },\n addToTheCart: function addToTheCart(product) {\n POS.addToCart(product);\n }\n }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcmVzb3VyY2VzL3RzL3BhZ2VzL2Rhc2hib2FyZC9wb3MvbnMtcG9zLWdyaWQudnVlP2ZjNzUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWdGQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0EscUJBREE7QUFFQSxNQUZBLGtCQUVBO0FBQ0E7QUFDQSxrQkFEQTtBQUVBLG9CQUZBO0FBR0EscUJBSEE7QUFJQSxzQkFKQTtBQUtBLGlCQUxBO0FBTUEsNEJBTkE7QUFPQSxpQkFQQTtBQVFBLDBCQVJBO0FBU0EsK0JBVEE7QUFVQSw2QkFWQTtBQVdBLG9DQVhBO0FBWUEsMkJBWkE7QUFhQSxvQkFiQTtBQWNBO0FBZEE7QUFnQkEsR0FuQkE7QUFvQkE7QUFDQSxpQkFEQSwyQkFDQTtBQUNBO0FBQ0E7QUFIQSxHQXBCQTtBQXlCQTtBQUNBLFdBREEscUJBQ0E7QUFBQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUZBLEVBRUEsSUFGQTtBQUdBO0FBTkEsR0F6QkE7QUFpQ0EsU0FqQ0EscUJBaUNBO0FBQUE7O0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FGQTtBQUdBO0FBQ0E7QUFDQSxLQUZBO0FBR0E7QUFBQTtBQUFBO0FBRUE7QUFBQTtBQUFBO0FBQ0EsR0E1Q0E7QUE2Q0EsV0E3Q0EsdUJBNkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQWxEQTtBQW1EQTtBQUNBLG1GQURBO0FBR0EsbUJBSEEsNkJBR0E7QUFDQTtBQUNBLEtBTEE7QUFPQSxnQkFQQSx3QkFPQSxLQVBBLEVBT0E7QUFBQTs7QUFDQTtBQUNBLG9JQUNBLFNBREEsQ0FDQTtBQUNBO0FBQ0E7QUFDQSxTQUpBLEVBSUE7QUFDQTtBQUNBO0FBQ0EsU0FQQTtBQVFBO0FBQ0EsS0FsQkE7QUFvQkEsY0FwQkEsd0JBb0JBO0FBQ0E7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBM0JBO0FBNkJBLGtCQTdCQSwwQkE2QkEsTUE3QkEsRUE2QkE7QUFBQTs7QUFDQSxxSUFDQSxTQURBLENBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFDQTtBQUNBLE9BUEE7QUFRQSxLQXRDQTtBQXdDQSxvQkF4Q0EsNEJBd0NBLE1BeENBLEVBd0NBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsV0FQQTtBQVFBO0FBQ0EsU0FYQSxNQVdBO0FBQ0E7QUFDQTtBQUVBLE9BdkJBLE1BdUJBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBckVBO0FBdUVBLGdCQXZFQSx3QkF1RUEsT0F2RUEsRUF1RUE7QUFDQTtBQUNBO0FBekVBO0FBbkRBIiwiZmlsZSI6Ii4vbm9kZV9tb2R1bGVzL2JhYmVsLWxvYWRlci9saWIvaW5kZXguanM/IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL2luZGV4LmpzPyEuL3Jlc291cmNlcy90cy9wYWdlcy9kYXNoYm9hcmQvcG9zL25zLXBvcy1ncmlkLnZ1ZT92dWUmdHlwZT1zY3JpcHQmbGFuZz1qcyYuanMiLCJzb3VyY2VzQ29udGVudCI6WyI8dGVtcGxhdGU+XHJcbiAgICA8ZGl2IGlkPVwicG9zLWdyaWRcIiBjbGFzcz1cImZsZXgtYXV0byBmbGV4IGZsZXgtY29sXCI+XHJcbiAgICAgICAgPGRpdiBpZD1cInRvb2xzXCIgY2xhc3M9XCJmbGV4IHBsLTJcIiB2LWlmPVwidmlzaWJsZVNlY3Rpb24gPT09ICdncmlkJ1wiPlxyXG4gICAgICAgICAgICA8ZGl2IEBjbGljaz1cInN3aXRjaFRvKCAnY2FydCcgKVwiIGNsYXNzPVwiZmxleCBjdXJzb3ItcG9pbnRlciByb3VuZGVkLXRsLWxnIHJvdW5kZWQtdHItbGcgcHgtMyBweS0yIGJnLWdyYXktMzAwIGJvcmRlci10IGJvcmRlci1yIGJvcmRlci1sIGJvcmRlci1ncmF5LTMwMCB0ZXh0LWdyYXktNjAwXCI+XHJcbiAgICAgICAgICAgICAgICA8c3Bhbj5DYXJ0PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gdi1pZj1cIm9yZGVyXCIgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciB0ZXh0LXNtIHJvdW5kZWQtZnVsbCBoLTYgdy02IGJnLWdyZWVuLTUwMCB0ZXh0LXdoaXRlIG1sLTFcIj57eyBvcmRlci5wcm9kdWN0cy5sZW5ndGggfX08L3NwYW4+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IEBjbGljaz1cInN3aXRjaFRvKCAnZ3JpZCcgKVwiIGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgcm91bmRlZC10bC1sZyByb3VuZGVkLXRyLWxnIHB4LTMgcHktMiBiZy13aGl0ZSBmb250LXNlbWlib2xkIHRleHQtZ3JheS03MDBcIj5cclxuICAgICAgICAgICAgICAgIFByb2R1Y3RzXHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJyb3VuZGVkIHNoYWRvdyBiZy13aGl0ZSBvdmVyZmxvdy1oaWRkZW4gZmxleC1hdXRvIGZsZXggZmxleC1jb2xcIj5cclxuICAgICAgICAgICAgPGRpdiBpZD1cImdyaWQtaGVhZGVyXCIgY2xhc3M9XCJwLTIgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm9yZGVyIHJvdW5kZWQgZmxleCBib3JkZXItZ3JheS0zMDAgb3ZlcmZsb3ctaGlkZGVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBAY2xpY2s9XCJvcGVuU2VhcmNoUG9wdXAoKVwiIGNsYXNzPVwidy0xMCBoLTEwIGJnLWdyYXktMjAwIGJvcmRlci1yIGJvcmRlci1ncmF5LTMwMCBvdXRsaW5lLW5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJsYXMgbGEtc2VhcmNoXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gQGNsaWNrPVwiYXV0b0ZvY3VzID0gISBhdXRvRm9jdXNcIiA6Y2xhc3M9XCJhdXRvRm9jdXMgPyAncG9zLWJ1dHRvbi1jbGlja2VkIGJnLWdyYXktMzAwJyA6ICdiZy1ncmF5LTIwMCdcIiBjbGFzcz1cIm91dGxpbmUtbm9uZSB3LTEwIGgtMTAgYm9yZGVyLXIgYm9yZGVyLWdyYXktMzAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGFzIGxhLWJhcmNvZGVcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHJlZj1cInNlYXJjaFwiIHYtbW9kZWw9XCJiYXJjb2RlXCIgdHlwZT1cInRleHRcIiBjbGFzcz1cImZsZXgtYXV0byBvdXRsaW5lLW5vbmUgcHgtMiBiZy1ncmF5LTEwMFwiPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGlkPVwiZ3JpZC1icmVhZHNjcnVtYlwiIGNsYXNzPVwicC0yIGJvcmRlci1ncmF5LTIwMFwiPlxyXG4gICAgICAgICAgICAgICAgPHVsIGNsYXNzPVwiZmxleFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxsaT48YSBAY2xpY2s9XCJsb2FkQ2F0ZWdvcmllcygpXCIgaHJlZj1cImphdmFzY3JpcHQ6dm9pZCgwKVwiIGNsYXNzPVwicHgtMyB0ZXh0LWdyYXktNzAwXCI+SG9tZSA8L2E+IDxpIGNsYXNzPVwibGFzIGxhLWFuZ2xlLXJpZ2h0XCI+PC9pPiA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgIDxsaT48YSBAY2xpY2s9XCJsb2FkQ2F0ZWdvcmllcyggYnJlYWQgKVwiIHYtZm9yPVwiYnJlYWQgb2YgYnJlYWRjcnVtYnNcIiA6a2V5PVwiYnJlYWQuaWRcIiBocmVmPVwiamF2YXNjcmlwdDp2b2lkKDApXCIgY2xhc3M9XCJweC0zIHRleHQtZ3JheS03MDBcIj57eyBicmVhZC5uYW1lIH19IDxpIGNsYXNzPVwibGFzIGxhLWFuZ2xlLXJpZ2h0XCI+PC9pPjwvYT48L2xpPlxyXG4gICAgICAgICAgICAgICAgPC91bD5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgaWQ9XCJncmlkLWl0ZW1zXCIgY2xhc3M9XCJvdmVyZmxvdy1oaWRkZW4gaC1mdWxsIGZsZXgtY29sIGZsZXhcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncmlkIGdyaWQtY29scy0yIG1kOmdyaWQtY29scy0zIGxnOmdyaWQtY29scy00IHhsOmdyaWQtY29scy01IGdhcC0wIG92ZXJmbG93LXktYXV0b1wiPlxyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTG9vcCBQcm9kdWN0cyBPciBDYXRlZ29yaWVzIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8dGVtcGxhdGUgdi1pZj1cInByZXZpb3VzQ2F0ZWdvcnkgIT09IGZhbHNlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgQGNsaWNrPVwibG9hZENhdGVnb3JpZXMoIHByZXZpb3VzQ2F0ZWdvcnkgKVwiIGNsYXNzPVwiaG92ZXI6YmctZ3JheS0yMDAgY3Vyc29yLXBvaW50ZXIgYm9yZGVyIGgtMzIgbGc6aC00MCBib3JkZXItZ3JheS0yMDAgZmxleCBmbGV4LWNvbCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoLWZ1bGwgdy1mdWxsIHAtMiBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGFzIGxhLXVuZG8gZm9udC1ib2xkIHRleHQtNXhsXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGVtcGxhdGU+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDx0ZW1wbGF0ZSB2LWlmPVwiaGFzQ2F0ZWdvcmllc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IEBjbGljaz1cImxvYWRDYXRlZ29yaWVzKCBjYXRlZ29yeSApXCIgOmtleT1cImNhdGVnb3J5LmlkXCIgdi1mb3I9XCJjYXRlZ29yeSBvZiBjYXRlZ29yaWVzXCIgY2xhc3M9XCJob3ZlcjpiZy1ncmF5LTIwMCBjdXJzb3ItcG9pbnRlciBib3JkZXIgaC0zMiBsZzpoLTQwIGJvcmRlci1ncmF5LTIwMCBmbGV4IGZsZXgtY29sIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBvdmVyZmxvdy1oaWRkZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoLWZ1bGwgdy1mdWxsIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyB2LWlmPVwiY2F0ZWdvcnkucHJldmlld191cmxcIiA6c3JjPVwiY2F0ZWdvcnkucHJldmlld191cmxcIiBjbGFzcz1cIm9iamVjdC1jb3ZlciBoLWZ1bGxcIiA6YWx0PVwiY2F0ZWdvcnkubmFtZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGFzIGxhLWltYWdlIHRleHQtZ3JheS02MDAgdGV4dC02eGxcIiB2LWlmPVwiISBjYXRlZ29yeS5wcmV2aWV3X3VybFwiPjwvaT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImgtMCB3LWZ1bGxcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVsYXRpdmUgdy1mdWxsIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIC10b3AtMTAgaC0yMCBweS0yXCIgc3R5bGU9XCJiYWNrZ3JvdW5kOnJnYigyNTUgMjU1IDI1NSAvIDczJSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwidGV4dC1zbSBmb250LWJvbGQgdGV4dC1ncmF5LTcwMCBweS0yIHRleHQtY2VudGVyXCI+e3sgY2F0ZWdvcnkubmFtZSB9fTwvaDM+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90ZW1wbGF0ZT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBMb29waW5nIFByb2R1Y3RzIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8dGVtcGxhdGUgdi1pZj1cIiEgaGFzQ2F0ZWdvcmllc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IEBjbGljaz1cImFkZFRvVGhlQ2FydCggcHJvZHVjdCApXCIgOmtleT1cInByb2R1Y3QuaWRcIiB2LWZvcj1cInByb2R1Y3Qgb2YgcHJvZHVjdHNcIiAgY2xhc3M9XCJob3ZlcjpiZy1ncmF5LTIwMCBjdXJzb3ItcG9pbnRlciBib3JkZXIgaC0zMiBsZzpoLTQwIGJvcmRlci1ncmF5LTIwMCBmbGV4IGZsZXgtY29sIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImgtZnVsbCB3LWZ1bGwgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgb3ZlcmZsb3ctaGlkZGVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyB2LWlmPVwicHJvZHVjdC5nYWxsZXJpZXMuZmlsdGVyKCBpID0+IGkuZmVhdHVyZWQgPT09IDEgKS5sZW5ndGggPiAwXCIgOnNyYz1cInByb2R1Y3QuZ2FsbGVyaWVzLmZpbHRlciggaSA9PiBpLmZlYXR1cmVkID09PSAxIClbMF0udXJsXCIgY2xhc3M9XCJvYmplY3QtY292ZXIgaC1mdWxsXCIgOmFsdD1cInByb2R1Y3QubmFtZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIHYtaWY9XCJwcm9kdWN0LmdhbGxlcmllcy5maWx0ZXIoIGkgPT4gaS5mZWF0dXJlZCA9PT0gMSApLmxlbmd0aCA9PT0gMFwiIGNsYXNzPVwibGFzIGxhLWltYWdlIHRleHQtZ3JheS02MDAgdGV4dC02eGxcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoLTAgdy1mdWxsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlbGF0aXZlIHctZnVsbCBmbGV4IGZsZXgtY29sIGl0ZW1zLXN0YXJ0IGp1c3RpZnktY2VudGVyIC10b3AtMTAgaC0yMCBwLTJcIiBzdHlsZT1cImJhY2tncm91bmQ6cmdiKDI1NSAyNTUgMjU1IC8gNzMlKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJ0ZXh0LXNtIHRleHQtZ3JheS03MDAgdGV4dC1jZW50ZXIgdy1mdWxsXCI+e3sgcHJvZHVjdC5uYW1lIH19PC9oMz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L3RlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRW5kIExvb3AgLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbjwvdGVtcGxhdGU+XHJcbjxzY3JpcHQgPlxyXG5pbXBvcnQgVnVlIGZyb20gJ3Z1ZSc7XHJcbmltcG9ydCB7IG5zSHR0cENsaWVudCwgbnNTbmFja0JhciB9IGZyb20gJy4uLy4uLy4uL2Jvb3RzdHJhcCdcclxuaW1wb3J0IHN3aXRjaFRvIGZyb20gXCJAL2xpYnJhcmllcy9wb3Mtc2VjdGlvbi1zd2l0Y2hcIjtcclxuaW1wb3J0IG5zUG9zU2VhcmNoUHJvZHVjdFZ1ZSBmcm9tICdAL3BvcHVwcy9ucy1wb3Mtc2VhcmNoLXByb2R1Y3QudnVlJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIG5hbWU6ICducy1wb3MtZ3JpZCcsXHJcbiAgICBkYXRhKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHByb2R1Y3RzOiBbXSxcclxuICAgICAgICAgICAgY2F0ZWdvcmllczogW10sXHJcbiAgICAgICAgICAgIGJyZWFkY3J1bWJzOiBbXSxcclxuICAgICAgICAgICAgYXV0b0ZvY3VzOiBmYWxzZSxcclxuICAgICAgICAgICAgYmFyY29kZTogJycsXHJcbiAgICAgICAgICAgIHByZXZpb3VzQ2F0ZWdvcnk6IG51bGwsXHJcbiAgICAgICAgICAgIG9yZGVyOiBudWxsLFxyXG4gICAgICAgICAgICB2aXNpYmxlU2VjdGlvbjogbnVsbCxcclxuICAgICAgICAgICAgYnJlYWRjcnVtYnNTdWJzcmliZTogbnVsbCxcclxuICAgICAgICAgICAgb3JkZXJTdWJzY3JpcHRpb246IG51bGwsXHJcbiAgICAgICAgICAgIHZpc2libGVTZWN0aW9uU3Vic2NyaWJlcjogbnVsbCxcclxuICAgICAgICAgICAgY3VycmVudENhdGVnb3J5OiBudWxsLFxyXG4gICAgICAgICAgICBpbnRlcnZhbDogbnVsbCxcclxuICAgICAgICAgICAgc2VhcmNoVGltZW91dDogbnVsbCxcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG4gICAgY29tcHV0ZWQ6IHtcclxuICAgICAgICBoYXNDYXRlZ29yaWVzKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYXRlZ29yaWVzLmxlbmd0aCA+IDA7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIHdhdGNoOiB7XHJcbiAgICAgICAgYmFyY29kZSgpIHtcclxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KCB0aGlzLnNlYXJjaFRpbWVvdXQgKTtcclxuICAgICAgICAgICAgdGhpcy5zZWFyY2hUaW1lb3V0ICA9ICAgc2V0VGltZW91dCggKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zdWJtaXRTZWFyY2goIHRoaXMuYmFyY29kZSApO1xyXG4gICAgICAgICAgICB9LCAxMDAwICk7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIG1vdW50ZWQoKSB7XHJcbiAgICAgICAgdGhpcy5sb2FkQ2F0ZWdvcmllcygpO1xyXG4gICAgICAgIHRoaXMuYnJlYWRjcnVtYnNTdWJzcmliZSAgICA9ICAgUE9TLmJyZWFkY3J1bWJzLnN1YnNjcmliZSggKCBicmVhZGNydW1icyApID0+IHtcclxuICAgICAgICAgICAgdGhpcy5icmVhZGNydW1icyAgICAgPSAgIGJyZWFkY3J1bWJzO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMudmlzaWJsZVNlY3Rpb25TdWJzY3JpYmVyICAgPSAgIFBPUy52aXNpYmxlU2VjdGlvbi5zdWJzY3JpYmUoIHNlY3Rpb24gPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnZpc2libGVTZWN0aW9uICAgICA9ICAgc2VjdGlvbjtcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLm9yZGVyU3Vic2NyaXB0aW9uICAgICAgPSAgIFBPUy5vcmRlci5zdWJzY3JpYmUoIG9yZGVyID0+IHRoaXMub3JkZXIgPSBvcmRlciApO1xyXG5cclxuICAgICAgICB0aGlzLmludGVydmFsICAgPSAgIHNldEludGVydmFsKCAoKSA9PiB0aGlzLmNoZWNrRm9jdXMoKSwgNTAwICk7XHJcbiAgICB9LFxyXG4gICAgZGVzdHJveWVkKCkge1xyXG4gICAgICAgIHRoaXMub3JkZXJTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgICAgICB0aGlzLmJyZWFkY3J1bWJzU3Vic3JpYmUudW5zdWJzY3JpYmUoKTtcclxuICAgICAgICB0aGlzLnZpc2libGVTZWN0aW9uU3Vic2NyaWJlci51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgIGNsZWFySW50ZXJ2YWwoIHRoaXMuaW50ZXJ2YWwgKTtcclxuICAgIH0sXHJcbiAgICBtZXRob2RzOiB7XHJcbiAgICAgICAgc3dpdGNoVG8sXHJcblxyXG4gICAgICAgIG9wZW5TZWFyY2hQb3B1cCgpIHtcclxuICAgICAgICAgICAgUG9wdXAuc2hvdyggbnNQb3NTZWFyY2hQcm9kdWN0VnVlICk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgc3VibWl0U2VhcmNoKCB2YWx1ZSApIHtcclxuICAgICAgICAgICAgaWYgKCB2YWx1ZS5sZW5ndGggPiAwICkge1xyXG4gICAgICAgICAgICAgICAgbnNIdHRwQ2xpZW50LmdldCggYC9hcGkvbmV4b3Bvcy92NC9wcm9kdWN0cy9zZWFyY2gvdXNpbmctYmFyY29kZS8ke3ZhbHVlfWAgKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoIHJlc3VsdCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYmFyY29kZSAgICAgPSAgICcnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBQT1MuYWRkVG9DYXJ0KCByZXN1bHQucHJvZHVjdCApO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sICggZXJyb3IgKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYmFyY29kZSAgICAgPSAgICcnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuc1NuYWNrQmFyLmVycm9yKCBlcnJvci5tZXNzYWdlICkuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIGNoZWNrRm9jdXMoKSB7XHJcbiAgICAgICAgICAgIGlmICggdGhpcy5hdXRvRm9jdXMgKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwb3B1cCAgICAgPSAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoICcuaXMtcG9wdXAnICk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIHBvcHVwLmxlbmd0aCA9PT0gMCApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLiRyZWZzLnNlYXJjaC5mb2N1cygpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBcclxuICAgICAgICBsb2FkQ2F0ZWdvcmllcyggcGFyZW50ICkge1xyXG4gICAgICAgICAgICBuc0h0dHBDbGllbnQuZ2V0KCBgL2FwaS9uZXhvcG9zL3Y0L2NhdGVnb3JpZXMvcG9zLyR7IHBhcmVudCA/IHBhcmVudC5pZCA6ICcnfWAgKVxyXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSggKHJlc3VsdCApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhdGVnb3JpZXMgICAgICAgICA9ICAgcmVzdWx0LmNhdGVnb3JpZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9kdWN0cyAgICAgICAgICAgPSAgIHJlc3VsdC5wcm9kdWN0cztcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZpb3VzQ2F0ZWdvcnkgICA9ICAgcmVzdWx0LnByZXZpb3VzQ2F0ZWdvcnk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50Q2F0ZWdvcnkgICAgPSAgIHJlc3VsdC5jdXJyZW50Q2F0ZWdvcnk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVCcmVhZENydW1iKCB0aGlzLmN1cnJlbnRDYXRlZ29yeSApO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgdXBkYXRlQnJlYWRDcnVtYiggcGFyZW50ICkge1xyXG4gICAgICAgICAgICBpZiAoIHBhcmVudCApIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ICAgICA9ICAgdGhpcy5icmVhZGNydW1iLmZpbHRlciggYnJlYWQgPT4gYnJlYWQuaWQgPT09IHBhcmVudC5pZCApO1xyXG4gICAgXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIHRoaXMgbWVhbnMsIHdlJ3JlIHRyeWluZyB0byBuYXZpZ2F0ZVxyXG4gICAgICAgICAgICAgICAgICogdGhyb3VnaCBzb21ldGhpbmcgdGhhdCBoYXMgYWxyZWFkeSBiZWVuIFxyXG4gICAgICAgICAgICAgICAgICogYWRkZWQgdG8gdGhlIGJyZWFkY3J1bWJcclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgaWYgKCBpbmRleC5sZW5ndGggPiAwICkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBhbGxvdyAgICAgICA9ICAgdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmlvciAgICAgPSAgIHRoaXMuYnJlYWRjcnVtYi5maWx0ZXIoIGJyZWFkID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBicmVhZC5pZCA9PT0gaW5kZXhbMF0uaWQgJiYgYWxsb3cgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxvdyAgID0gICBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWxsb3c7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5icmVhZGNydW1iICAgICA9ICAgcHJpb3I7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYnJlYWRjcnVtYi5wdXNoKCBwYXJlbnQgKTtcclxuICAgICAgICAgICAgICAgIH0gXHJcbiAgICBcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuYnJlYWRjcnVtYiAgICAgPSAgIFtdOyAgICBcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgUE9TLmJyZWFkY3J1bWJzLm5leHQoIHRoaXMuYnJlYWRjcnVtYiApO1xyXG4gICAgICAgIH0sXHJcbiAgICBcclxuICAgICAgICBhZGRUb1RoZUNhcnQoIHByb2R1Y3QgKSB7XHJcbiAgICAgICAgICAgIFBPUy5hZGRUb0NhcnQoIHByb2R1Y3QgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuPC9zY3JpcHQ+Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/ts/pages/dashboard/pos/ns-pos-grid.vue?vue&type=script&lang=js&\n"); -======= eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.common.js\");\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(vue__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../bootstrap */ \"./resources/ts/bootstrap.ts\");\n/* harmony import */ var _libraries_pos_section_switch__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/libraries/pos-section-switch */ \"./resources/ts/libraries/pos-section-switch.ts\");\n/* harmony import */ var _popups_ns_pos_search_product_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/popups/ns-pos-search-product.vue */ \"./resources/ts/popups/ns-pos-search-product.vue\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n name: 'ns-pos-grid',\n data: function data() {\n return {\n products: [],\n categories: [],\n breadcrumbs: [],\n autoFocus: false,\n barcode: '',\n previousCategory: null,\n order: null,\n visibleSection: null,\n breadcrumbsSubsribe: null,\n orderSubscription: null,\n visibleSectionSubscriber: null,\n currentCategory: null,\n interval: null,\n searchTimeout: null\n };\n },\n computed: {\n hasCategories: function hasCategories() {\n return this.categories.length > 0;\n }\n },\n watch: {\n barcode: function barcode() {\n var _this = this;\n\n clearTimeout(this.searchTimeout);\n this.searchTimeout = setTimeout(function () {\n _this.submitSearch(_this.barcode);\n }, 200);\n }\n },\n mounted: function mounted() {\n var _this2 = this;\n\n this.loadCategories();\n this.breadcrumbsSubsribe = POS.breadcrumbs.subscribe(function (breadcrumbs) {\n _this2.breadcrumbs = breadcrumbs;\n });\n this.visibleSectionSubscriber = POS.visibleSection.subscribe(function (section) {\n _this2.visibleSection = section;\n });\n this.orderSubscription = POS.order.subscribe(function (order) {\n return _this2.order = order;\n });\n this.interval = setInterval(function () {\n return _this2.checkFocus();\n }, 500);\n },\n destroyed: function destroyed() {\n this.orderSubscription.unsubscribe();\n this.breadcrumbsSubsribe.unsubscribe();\n this.visibleSectionSubscriber.unsubscribe();\n clearInterval(this.interval);\n },\n methods: {\n switchTo: _libraries_pos_section_switch__WEBPACK_IMPORTED_MODULE_2__[\"default\"],\n openSearchPopup: function openSearchPopup() {\n Popup.show(_popups_ns_pos_search_product_vue__WEBPACK_IMPORTED_MODULE_3__[\"default\"]);\n },\n submitSearch: function submitSearch(value) {\n var _this3 = this;\n\n if (value.length > 0) {\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"].get(\"/api/nexopos/v4/products/search/using-barcode/\".concat(value)).subscribe(function (result) {\n _this3.barcode = '';\n POS.addToCart(result.product);\n }, function (error) {\n _this3.barcode = '';\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsSnackBar\"].error(error.message).subscribe();\n });\n }\n },\n checkFocus: function checkFocus() {\n if (this.autoFocus) {\n var popup = document.querySelectorAll('.is-popup');\n\n if (popup.length === 0) {\n this.$refs.search.focus();\n }\n }\n },\n loadCategories: function loadCategories(parent) {\n var _this4 = this;\n\n _bootstrap__WEBPACK_IMPORTED_MODULE_1__[\"nsHttpClient\"].get(\"/api/nexopos/v4/categories/pos/\".concat(parent ? parent.id : '')).subscribe(function (result) {\n _this4.categories = result.categories;\n _this4.products = result.products;\n _this4.previousCategory = result.previousCategory;\n _this4.currentCategory = result.currentCategory;\n\n _this4.updateBreadCrumb(_this4.currentCategory);\n });\n },\n updateBreadCrumb: function updateBreadCrumb(parent) {\n if (parent) {\n var index = this.breadcrumb.filter(function (bread) {\n return bread.id === parent.id;\n });\n /**\r\n * this means, we're trying to navigate\r\n * through something that has already been \r\n * added to the breadcrumb\r\n */\n\n if (index.length > 0) {\n var allow = true;\n var prior = this.breadcrumb.filter(function (bread) {\n if (bread.id === index[0].id && allow) {\n allow = false;\n return true;\n }\n\n return allow;\n });\n this.breadcrumb = prior;\n } else {\n this.breadcrumb.push(parent);\n }\n } else {\n this.breadcrumb = [];\n }\n\n POS.breadcrumbs.next(this.breadcrumb);\n },\n addToTheCart: function addToTheCart(product) {\n POS.addToCart(product);\n }\n }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcmVzb3VyY2VzL3RzL3BhZ2VzL2Rhc2hib2FyZC9wb3MvbnMtcG9zLWdyaWQudnVlP2ZjNzUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWdGQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0EscUJBREE7QUFFQSxNQUZBLGtCQUVBO0FBQ0E7QUFDQSxrQkFEQTtBQUVBLG9CQUZBO0FBR0EscUJBSEE7QUFJQSxzQkFKQTtBQUtBLGlCQUxBO0FBTUEsNEJBTkE7QUFPQSxpQkFQQTtBQVFBLDBCQVJBO0FBU0EsK0JBVEE7QUFVQSw2QkFWQTtBQVdBLG9DQVhBO0FBWUEsMkJBWkE7QUFhQSxvQkFiQTtBQWNBO0FBZEE7QUFnQkEsR0FuQkE7QUFvQkE7QUFDQSxpQkFEQSwyQkFDQTtBQUNBO0FBQ0E7QUFIQSxHQXBCQTtBQXlCQTtBQUNBLFdBREEscUJBQ0E7QUFBQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUZBLEVBRUEsR0FGQTtBQUdBO0FBTkEsR0F6QkE7QUFpQ0EsU0FqQ0EscUJBaUNBO0FBQUE7O0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FGQTtBQUdBO0FBQ0E7QUFDQSxLQUZBO0FBR0E7QUFBQTtBQUFBO0FBRUE7QUFBQTtBQUFBO0FBQ0EsR0E1Q0E7QUE2Q0EsV0E3Q0EsdUJBNkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQWxEQTtBQW1EQTtBQUNBLG1GQURBO0FBR0EsbUJBSEEsNkJBR0E7QUFDQTtBQUNBLEtBTEE7QUFPQSxnQkFQQSx3QkFPQSxLQVBBLEVBT0E7QUFBQTs7QUFDQTtBQUNBLG9JQUNBLFNBREEsQ0FDQTtBQUNBO0FBQ0E7QUFDQSxTQUpBLEVBSUE7QUFDQTtBQUNBO0FBQ0EsU0FQQTtBQVFBO0FBQ0EsS0FsQkE7QUFvQkEsY0FwQkEsd0JBb0JBO0FBQ0E7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBM0JBO0FBNkJBLGtCQTdCQSwwQkE2QkEsTUE3QkEsRUE2QkE7QUFBQTs7QUFDQSxxSUFDQSxTQURBLENBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFDQTtBQUNBLE9BUEE7QUFRQSxLQXRDQTtBQXdDQSxvQkF4Q0EsNEJBd0NBLE1BeENBLEVBd0NBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsV0FQQTtBQVFBO0FBQ0EsU0FYQSxNQVdBO0FBQ0E7QUFDQTtBQUVBLE9BdkJBLE1BdUJBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBckVBO0FBdUVBLGdCQXZFQSx3QkF1RUEsT0F2RUEsRUF1RUE7QUFDQTtBQUNBO0FBekVBO0FBbkRBIiwiZmlsZSI6Ii4vbm9kZV9tb2R1bGVzL2JhYmVsLWxvYWRlci9saWIvaW5kZXguanM/IS4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL2luZGV4LmpzPyEuL3Jlc291cmNlcy90cy9wYWdlcy9kYXNoYm9hcmQvcG9zL25zLXBvcy1ncmlkLnZ1ZT92dWUmdHlwZT1zY3JpcHQmbGFuZz1qcyYuanMiLCJzb3VyY2VzQ29udGVudCI6WyI8dGVtcGxhdGU+XHJcbiAgICA8ZGl2IGlkPVwicG9zLWdyaWRcIiBjbGFzcz1cImZsZXgtYXV0byBmbGV4IGZsZXgtY29sXCI+XHJcbiAgICAgICAgPGRpdiBpZD1cInRvb2xzXCIgY2xhc3M9XCJmbGV4IHBsLTJcIiB2LWlmPVwidmlzaWJsZVNlY3Rpb24gPT09ICdncmlkJ1wiPlxyXG4gICAgICAgICAgICA8ZGl2IEBjbGljaz1cInN3aXRjaFRvKCAnY2FydCcgKVwiIGNsYXNzPVwiZmxleCBjdXJzb3ItcG9pbnRlciByb3VuZGVkLXRsLWxnIHJvdW5kZWQtdHItbGcgcHgtMyBweS0yIGJnLWdyYXktMzAwIGJvcmRlci10IGJvcmRlci1yIGJvcmRlci1sIGJvcmRlci1ncmF5LTMwMCB0ZXh0LWdyYXktNjAwXCI+XHJcbiAgICAgICAgICAgICAgICA8c3Bhbj5DYXJ0PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gdi1pZj1cIm9yZGVyXCIgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciB0ZXh0LXNtIHJvdW5kZWQtZnVsbCBoLTYgdy02IGJnLWdyZWVuLTUwMCB0ZXh0LXdoaXRlIG1sLTFcIj57eyBvcmRlci5wcm9kdWN0cy5sZW5ndGggfX08L3NwYW4+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IEBjbGljaz1cInN3aXRjaFRvKCAnZ3JpZCcgKVwiIGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgcm91bmRlZC10bC1sZyByb3VuZGVkLXRyLWxnIHB4LTMgcHktMiBiZy13aGl0ZSBmb250LXNlbWlib2xkIHRleHQtZ3JheS03MDBcIj5cclxuICAgICAgICAgICAgICAgIFByb2R1Y3RzXHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJyb3VuZGVkIHNoYWRvdyBiZy13aGl0ZSBvdmVyZmxvdy1oaWRkZW4gZmxleC1hdXRvIGZsZXggZmxleC1jb2xcIj5cclxuICAgICAgICAgICAgPGRpdiBpZD1cImdyaWQtaGVhZGVyXCIgY2xhc3M9XCJwLTIgYm9yZGVyLWIgYm9yZGVyLWdyYXktMjAwXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYm9yZGVyIHJvdW5kZWQgZmxleCBib3JkZXItZ3JheS0zMDAgb3ZlcmZsb3ctaGlkZGVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBAY2xpY2s9XCJvcGVuU2VhcmNoUG9wdXAoKVwiIGNsYXNzPVwidy0xMCBoLTEwIGJnLWdyYXktMjAwIGJvcmRlci1yIGJvcmRlci1ncmF5LTMwMCBvdXRsaW5lLW5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJsYXMgbGEtc2VhcmNoXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gQGNsaWNrPVwiYXV0b0ZvY3VzID0gISBhdXRvRm9jdXNcIiA6Y2xhc3M9XCJhdXRvRm9jdXMgPyAncG9zLWJ1dHRvbi1jbGlja2VkIGJnLWdyYXktMzAwJyA6ICdiZy1ncmF5LTIwMCdcIiBjbGFzcz1cIm91dGxpbmUtbm9uZSB3LTEwIGgtMTAgYm9yZGVyLXIgYm9yZGVyLWdyYXktMzAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGFzIGxhLWJhcmNvZGVcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHJlZj1cInNlYXJjaFwiIHYtbW9kZWw9XCJiYXJjb2RlXCIgdHlwZT1cInRleHRcIiBjbGFzcz1cImZsZXgtYXV0byBvdXRsaW5lLW5vbmUgcHgtMiBiZy1ncmF5LTEwMFwiPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGlkPVwiZ3JpZC1icmVhZHNjcnVtYlwiIGNsYXNzPVwicC0yIGJvcmRlci1ncmF5LTIwMFwiPlxyXG4gICAgICAgICAgICAgICAgPHVsIGNsYXNzPVwiZmxleFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxsaT48YSBAY2xpY2s9XCJsb2FkQ2F0ZWdvcmllcygpXCIgaHJlZj1cImphdmFzY3JpcHQ6dm9pZCgwKVwiIGNsYXNzPVwicHgtMyB0ZXh0LWdyYXktNzAwXCI+SG9tZSA8L2E+IDxpIGNsYXNzPVwibGFzIGxhLWFuZ2xlLXJpZ2h0XCI+PC9pPiA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgIDxsaT48YSBAY2xpY2s9XCJsb2FkQ2F0ZWdvcmllcyggYnJlYWQgKVwiIHYtZm9yPVwiYnJlYWQgb2YgYnJlYWRjcnVtYnNcIiA6a2V5PVwiYnJlYWQuaWRcIiBocmVmPVwiamF2YXNjcmlwdDp2b2lkKDApXCIgY2xhc3M9XCJweC0zIHRleHQtZ3JheS03MDBcIj57eyBicmVhZC5uYW1lIH19IDxpIGNsYXNzPVwibGFzIGxhLWFuZ2xlLXJpZ2h0XCI+PC9pPjwvYT48L2xpPlxyXG4gICAgICAgICAgICAgICAgPC91bD5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgaWQ9XCJncmlkLWl0ZW1zXCIgY2xhc3M9XCJvdmVyZmxvdy1oaWRkZW4gaC1mdWxsIGZsZXgtY29sIGZsZXhcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncmlkIGdyaWQtY29scy0yIG1kOmdyaWQtY29scy0zIGxnOmdyaWQtY29scy00IHhsOmdyaWQtY29scy01IGdhcC0wIG92ZXJmbG93LXktYXV0b1wiPlxyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTG9vcCBQcm9kdWN0cyBPciBDYXRlZ29yaWVzIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8dGVtcGxhdGUgdi1pZj1cInByZXZpb3VzQ2F0ZWdvcnkgIT09IGZhbHNlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgQGNsaWNrPVwibG9hZENhdGVnb3JpZXMoIHByZXZpb3VzQ2F0ZWdvcnkgKVwiIGNsYXNzPVwiaG92ZXI6YmctZ3JheS0yMDAgY3Vyc29yLXBvaW50ZXIgYm9yZGVyIGgtMzIgbGc6aC00MCBib3JkZXItZ3JheS0yMDAgZmxleCBmbGV4LWNvbCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoLWZ1bGwgdy1mdWxsIHAtMiBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGFzIGxhLXVuZG8gZm9udC1ib2xkIHRleHQtNXhsXCI+PC9pPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGVtcGxhdGU+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDx0ZW1wbGF0ZSB2LWlmPVwiaGFzQ2F0ZWdvcmllc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IEBjbGljaz1cImxvYWRDYXRlZ29yaWVzKCBjYXRlZ29yeSApXCIgOmtleT1cImNhdGVnb3J5LmlkXCIgdi1mb3I9XCJjYXRlZ29yeSBvZiBjYXRlZ29yaWVzXCIgY2xhc3M9XCJob3ZlcjpiZy1ncmF5LTIwMCBjdXJzb3ItcG9pbnRlciBib3JkZXIgaC0zMiBsZzpoLTQwIGJvcmRlci1ncmF5LTIwMCBmbGV4IGZsZXgtY29sIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBvdmVyZmxvdy1oaWRkZW5cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoLWZ1bGwgdy1mdWxsIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyB2LWlmPVwiY2F0ZWdvcnkucHJldmlld191cmxcIiA6c3JjPVwiY2F0ZWdvcnkucHJldmlld191cmxcIiBjbGFzcz1cIm9iamVjdC1jb3ZlciBoLWZ1bGxcIiA6YWx0PVwiY2F0ZWdvcnkubmFtZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGFzIGxhLWltYWdlIHRleHQtZ3JheS02MDAgdGV4dC02eGxcIiB2LWlmPVwiISBjYXRlZ29yeS5wcmV2aWV3X3VybFwiPjwvaT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImgtMCB3LWZ1bGxcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVsYXRpdmUgdy1mdWxsIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIC10b3AtMTAgaC0yMCBweS0yXCIgc3R5bGU9XCJiYWNrZ3JvdW5kOnJnYigyNTUgMjU1IDI1NSAvIDczJSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwidGV4dC1zbSBmb250LWJvbGQgdGV4dC1ncmF5LTcwMCBweS0yIHRleHQtY2VudGVyXCI+e3sgY2F0ZWdvcnkubmFtZSB9fTwvaDM+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90ZW1wbGF0ZT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPCEtLSBMb29waW5nIFByb2R1Y3RzIC0tPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8dGVtcGxhdGUgdi1pZj1cIiEgaGFzQ2F0ZWdvcmllc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IEBjbGljaz1cImFkZFRvVGhlQ2FydCggcHJvZHVjdCApXCIgOmtleT1cInByb2R1Y3QuaWRcIiB2LWZvcj1cInByb2R1Y3Qgb2YgcHJvZHVjdHNcIiAgY2xhc3M9XCJob3ZlcjpiZy1ncmF5LTIwMCBjdXJzb3ItcG9pbnRlciBib3JkZXIgaC0zMiBsZzpoLTQwIGJvcmRlci1ncmF5LTIwMCBmbGV4IGZsZXgtY29sIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImgtZnVsbCB3LWZ1bGwgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgb3ZlcmZsb3ctaGlkZGVuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGltZyB2LWlmPVwicHJvZHVjdC5nYWxsZXJpZXMuZmlsdGVyKCBpID0+IGkuZmVhdHVyZWQgPT09IDEgKS5sZW5ndGggPiAwXCIgOnNyYz1cInByb2R1Y3QuZ2FsbGVyaWVzLmZpbHRlciggaSA9PiBpLmZlYXR1cmVkID09PSAxIClbMF0udXJsXCIgY2xhc3M9XCJvYmplY3QtY292ZXIgaC1mdWxsXCIgOmFsdD1cInByb2R1Y3QubmFtZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIHYtaWY9XCJwcm9kdWN0LmdhbGxlcmllcy5maWx0ZXIoIGkgPT4gaS5mZWF0dXJlZCA9PT0gMSApLmxlbmd0aCA9PT0gMFwiIGNsYXNzPVwibGFzIGxhLWltYWdlIHRleHQtZ3JheS02MDAgdGV4dC02eGxcIj48L2k+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoLTAgdy1mdWxsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlbGF0aXZlIHctZnVsbCBmbGV4IGZsZXgtY29sIGl0ZW1zLXN0YXJ0IGp1c3RpZnktY2VudGVyIC10b3AtMTAgaC0yMCBwLTJcIiBzdHlsZT1cImJhY2tncm91bmQ6cmdiKDI1NSAyNTUgMjU1IC8gNzMlKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJ0ZXh0LXNtIHRleHQtZ3JheS03MDAgdGV4dC1jZW50ZXIgdy1mdWxsXCI+e3sgcHJvZHVjdC5uYW1lIH19PC9oMz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L3RlbXBsYXRlPlxyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRW5kIExvb3AgLS0+XHJcblxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbjwvdGVtcGxhdGU+XHJcbjxzY3JpcHQgPlxyXG5pbXBvcnQgVnVlIGZyb20gJ3Z1ZSc7XHJcbmltcG9ydCB7IG5zSHR0cENsaWVudCwgbnNTbmFja0JhciB9IGZyb20gJy4uLy4uLy4uL2Jvb3RzdHJhcCdcclxuaW1wb3J0IHN3aXRjaFRvIGZyb20gXCJAL2xpYnJhcmllcy9wb3Mtc2VjdGlvbi1zd2l0Y2hcIjtcclxuaW1wb3J0IG5zUG9zU2VhcmNoUHJvZHVjdFZ1ZSBmcm9tICdAL3BvcHVwcy9ucy1wb3Mtc2VhcmNoLXByb2R1Y3QudnVlJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIG5hbWU6ICducy1wb3MtZ3JpZCcsXHJcbiAgICBkYXRhKCkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHByb2R1Y3RzOiBbXSxcclxuICAgICAgICAgICAgY2F0ZWdvcmllczogW10sXHJcbiAgICAgICAgICAgIGJyZWFkY3J1bWJzOiBbXSxcclxuICAgICAgICAgICAgYXV0b0ZvY3VzOiBmYWxzZSxcclxuICAgICAgICAgICAgYmFyY29kZTogJycsXHJcbiAgICAgICAgICAgIHByZXZpb3VzQ2F0ZWdvcnk6IG51bGwsXHJcbiAgICAgICAgICAgIG9yZGVyOiBudWxsLFxyXG4gICAgICAgICAgICB2aXNpYmxlU2VjdGlvbjogbnVsbCxcclxuICAgICAgICAgICAgYnJlYWRjcnVtYnNTdWJzcmliZTogbnVsbCxcclxuICAgICAgICAgICAgb3JkZXJTdWJzY3JpcHRpb246IG51bGwsXHJcbiAgICAgICAgICAgIHZpc2libGVTZWN0aW9uU3Vic2NyaWJlcjogbnVsbCxcclxuICAgICAgICAgICAgY3VycmVudENhdGVnb3J5OiBudWxsLFxyXG4gICAgICAgICAgICBpbnRlcnZhbDogbnVsbCxcclxuICAgICAgICAgICAgc2VhcmNoVGltZW91dDogbnVsbCxcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG4gICAgY29tcHV0ZWQ6IHtcclxuICAgICAgICBoYXNDYXRlZ29yaWVzKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYXRlZ29yaWVzLmxlbmd0aCA+IDA7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIHdhdGNoOiB7XHJcbiAgICAgICAgYmFyY29kZSgpIHtcclxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KCB0aGlzLnNlYXJjaFRpbWVvdXQgKTtcclxuICAgICAgICAgICAgdGhpcy5zZWFyY2hUaW1lb3V0ICA9ICAgc2V0VGltZW91dCggKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zdWJtaXRTZWFyY2goIHRoaXMuYmFyY29kZSApO1xyXG4gICAgICAgICAgICB9LCAyMDAgKTtcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG4gICAgbW91bnRlZCgpIHtcclxuICAgICAgICB0aGlzLmxvYWRDYXRlZ29yaWVzKCk7XHJcbiAgICAgICAgdGhpcy5icmVhZGNydW1ic1N1YnNyaWJlICAgID0gICBQT1MuYnJlYWRjcnVtYnMuc3Vic2NyaWJlKCAoIGJyZWFkY3J1bWJzICkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmJyZWFkY3J1bWJzICAgICA9ICAgYnJlYWRjcnVtYnM7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy52aXNpYmxlU2VjdGlvblN1YnNjcmliZXIgICA9ICAgUE9TLnZpc2libGVTZWN0aW9uLnN1YnNjcmliZSggc2VjdGlvbiA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMudmlzaWJsZVNlY3Rpb24gICAgID0gICBzZWN0aW9uO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMub3JkZXJTdWJzY3JpcHRpb24gICAgICA9ICAgUE9TLm9yZGVyLnN1YnNjcmliZSggb3JkZXIgPT4gdGhpcy5vcmRlciA9IG9yZGVyICk7XHJcblxyXG4gICAgICAgIHRoaXMuaW50ZXJ2YWwgICA9ICAgc2V0SW50ZXJ2YWwoICgpID0+IHRoaXMuY2hlY2tGb2N1cygpLCA1MDAgKTtcclxuICAgIH0sXHJcbiAgICBkZXN0cm95ZWQoKSB7XHJcbiAgICAgICAgdGhpcy5vcmRlclN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgIHRoaXMuYnJlYWRjcnVtYnNTdWJzcmliZS51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgIHRoaXMudmlzaWJsZVNlY3Rpb25TdWJzY3JpYmVyLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgY2xlYXJJbnRlcnZhbCggdGhpcy5pbnRlcnZhbCApO1xyXG4gICAgfSxcclxuICAgIG1ldGhvZHM6IHtcclxuICAgICAgICBzd2l0Y2hUbyxcclxuXHJcbiAgICAgICAgb3BlblNlYXJjaFBvcHVwKCkge1xyXG4gICAgICAgICAgICBQb3B1cC5zaG93KCBuc1Bvc1NlYXJjaFByb2R1Y3RWdWUgKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBzdWJtaXRTZWFyY2goIHZhbHVlICkge1xyXG4gICAgICAgICAgICBpZiAoIHZhbHVlLmxlbmd0aCA+IDAgKSB7XHJcbiAgICAgICAgICAgICAgICBuc0h0dHBDbGllbnQuZ2V0KCBgL2FwaS9uZXhvcG9zL3Y0L3Byb2R1Y3RzL3NlYXJjaC91c2luZy1iYXJjb2RlLyR7dmFsdWV9YCApXHJcbiAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZSggcmVzdWx0ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5iYXJjb2RlICAgICA9ICAgJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFBPUy5hZGRUb0NhcnQoIHJlc3VsdC5wcm9kdWN0ICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSwgKCBlcnJvciApID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5iYXJjb2RlICAgICA9ICAgJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5zU25hY2tCYXIuZXJyb3IoIGVycm9yLm1lc3NhZ2UgKS5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgY2hlY2tGb2N1cygpIHtcclxuICAgICAgICAgICAgaWYgKCB0aGlzLmF1dG9Gb2N1cyApIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHBvcHVwICAgICA9ICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCggJy5pcy1wb3B1cCcgKTtcclxuICAgICAgICAgICAgICAgIGlmICggcG9wdXAubGVuZ3RoID09PSAwICkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJHJlZnMuc2VhcmNoLmZvY3VzKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIFxyXG4gICAgICAgIGxvYWRDYXRlZ29yaWVzKCBwYXJlbnQgKSB7XHJcbiAgICAgICAgICAgIG5zSHR0cENsaWVudC5nZXQoIGAvYXBpL25leG9wb3MvdjQvY2F0ZWdvcmllcy9wb3MvJHsgcGFyZW50ID8gcGFyZW50LmlkIDogJyd9YCApXHJcbiAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCAocmVzdWx0ICkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2F0ZWdvcmllcyAgICAgICAgID0gICByZXN1bHQuY2F0ZWdvcmllcztcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2R1Y3RzICAgICAgICAgICA9ICAgcmVzdWx0LnByb2R1Y3RzO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNDYXRlZ29yeSAgID0gICByZXN1bHQucHJldmlvdXNDYXRlZ29yeTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRDYXRlZ29yeSAgICA9ICAgcmVzdWx0LmN1cnJlbnRDYXRlZ29yeTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUJyZWFkQ3J1bWIoIHRoaXMuY3VycmVudENhdGVnb3J5ICk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICB1cGRhdGVCcmVhZENydW1iKCBwYXJlbnQgKSB7XHJcbiAgICAgICAgICAgIGlmICggcGFyZW50ICkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaW5kZXggICAgID0gICB0aGlzLmJyZWFkY3J1bWIuZmlsdGVyKCBicmVhZCA9PiBicmVhZC5pZCA9PT0gcGFyZW50LmlkICk7XHJcbiAgICBcclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogdGhpcyBtZWFucywgd2UncmUgdHJ5aW5nIHRvIG5hdmlnYXRlXHJcbiAgICAgICAgICAgICAgICAgKiB0aHJvdWdoIHNvbWV0aGluZyB0aGF0IGhhcyBhbHJlYWR5IGJlZW4gXHJcbiAgICAgICAgICAgICAgICAgKiBhZGRlZCB0byB0aGUgYnJlYWRjcnVtYlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBpZiAoIGluZGV4Lmxlbmd0aCA+IDAgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGFsbG93ICAgICAgID0gICB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHByaW9yICAgICA9ICAgdGhpcy5icmVhZGNydW1iLmZpbHRlciggYnJlYWQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGJyZWFkLmlkID09PSBpbmRleFswXS5pZCAmJiBhbGxvdyApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93ICAgPSAgIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhbGxvdztcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmJyZWFkY3J1bWIgICAgID0gICBwcmlvcjtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5icmVhZGNydW1iLnB1c2goIHBhcmVudCApO1xyXG4gICAgICAgICAgICAgICAgfSBcclxuICAgIFxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5icmVhZGNydW1iICAgICA9ICAgW107ICAgIFxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBQT1MuYnJlYWRjcnVtYnMubmV4dCggdGhpcy5icmVhZGNydW1iICk7XHJcbiAgICAgICAgfSxcclxuICAgIFxyXG4gICAgICAgIGFkZFRvVGhlQ2FydCggcHJvZHVjdCApIHtcclxuICAgICAgICAgICAgUE9TLmFkZFRvQ2FydCggcHJvZHVjdCApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG48L3NjcmlwdD4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/ts/pages/dashboard/pos/ns-pos-grid.vue?vue&type=script&lang=js&\n"); ->>>>>>> 3313f0bf34ae3b3550ee3b8ff27748899eebc41e /***/ }), diff --git a/public/js/vendor.js b/public/js/vendor.js index dd13332b5..807b73c5d 100755 --- a/public/js/vendor.js +++ b/public/js/vendor.js @@ -747,8 +747,6 @@ eval("__webpack_require__.r(__webpack_exports__);\n//\n//\n//\n//\n//\n//\n//\n/ /***/ (function(module, exports, __webpack_require__) { eval("/*!\n * Chart.js v2.9.3\n * https://www.chartjs.org\n * (c) 2019 Chart.js Contributors\n * Released under the MIT License\n */\n(function (global, factory) {\n true ? module.exports = factory(function() { try { return __webpack_require__(/*! moment */ \"./node_modules/moment/moment.js\"); } catch(e) { } }()) :\nundefined;\n}(this, (function (moment) { 'use strict';\n\nmoment = moment && moment.hasOwnProperty('default') ? moment['default'] : moment;\n\nfunction createCommonjsModule(fn, module) {\n\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n}\n\nfunction getCjsExportFromNamespace (n) {\n\treturn n && n['default'] || n;\n}\n\nvar colorName = {\r\n\t\"aliceblue\": [240, 248, 255],\r\n\t\"antiquewhite\": [250, 235, 215],\r\n\t\"aqua\": [0, 255, 255],\r\n\t\"aquamarine\": [127, 255, 212],\r\n\t\"azure\": [240, 255, 255],\r\n\t\"beige\": [245, 245, 220],\r\n\t\"bisque\": [255, 228, 196],\r\n\t\"black\": [0, 0, 0],\r\n\t\"blanchedalmond\": [255, 235, 205],\r\n\t\"blue\": [0, 0, 255],\r\n\t\"blueviolet\": [138, 43, 226],\r\n\t\"brown\": [165, 42, 42],\r\n\t\"burlywood\": [222, 184, 135],\r\n\t\"cadetblue\": [95, 158, 160],\r\n\t\"chartreuse\": [127, 255, 0],\r\n\t\"chocolate\": [210, 105, 30],\r\n\t\"coral\": [255, 127, 80],\r\n\t\"cornflowerblue\": [100, 149, 237],\r\n\t\"cornsilk\": [255, 248, 220],\r\n\t\"crimson\": [220, 20, 60],\r\n\t\"cyan\": [0, 255, 255],\r\n\t\"darkblue\": [0, 0, 139],\r\n\t\"darkcyan\": [0, 139, 139],\r\n\t\"darkgoldenrod\": [184, 134, 11],\r\n\t\"darkgray\": [169, 169, 169],\r\n\t\"darkgreen\": [0, 100, 0],\r\n\t\"darkgrey\": [169, 169, 169],\r\n\t\"darkkhaki\": [189, 183, 107],\r\n\t\"darkmagenta\": [139, 0, 139],\r\n\t\"darkolivegreen\": [85, 107, 47],\r\n\t\"darkorange\": [255, 140, 0],\r\n\t\"darkorchid\": [153, 50, 204],\r\n\t\"darkred\": [139, 0, 0],\r\n\t\"darksalmon\": [233, 150, 122],\r\n\t\"darkseagreen\": [143, 188, 143],\r\n\t\"darkslateblue\": [72, 61, 139],\r\n\t\"darkslategray\": [47, 79, 79],\r\n\t\"darkslategrey\": [47, 79, 79],\r\n\t\"darkturquoise\": [0, 206, 209],\r\n\t\"darkviolet\": [148, 0, 211],\r\n\t\"deeppink\": [255, 20, 147],\r\n\t\"deepskyblue\": [0, 191, 255],\r\n\t\"dimgray\": [105, 105, 105],\r\n\t\"dimgrey\": [105, 105, 105],\r\n\t\"dodgerblue\": [30, 144, 255],\r\n\t\"firebrick\": [178, 34, 34],\r\n\t\"floralwhite\": [255, 250, 240],\r\n\t\"forestgreen\": [34, 139, 34],\r\n\t\"fuchsia\": [255, 0, 255],\r\n\t\"gainsboro\": [220, 220, 220],\r\n\t\"ghostwhite\": [248, 248, 255],\r\n\t\"gold\": [255, 215, 0],\r\n\t\"goldenrod\": [218, 165, 32],\r\n\t\"gray\": [128, 128, 128],\r\n\t\"green\": [0, 128, 0],\r\n\t\"greenyellow\": [173, 255, 47],\r\n\t\"grey\": [128, 128, 128],\r\n\t\"honeydew\": [240, 255, 240],\r\n\t\"hotpink\": [255, 105, 180],\r\n\t\"indianred\": [205, 92, 92],\r\n\t\"indigo\": [75, 0, 130],\r\n\t\"ivory\": [255, 255, 240],\r\n\t\"khaki\": [240, 230, 140],\r\n\t\"lavender\": [230, 230, 250],\r\n\t\"lavenderblush\": [255, 240, 245],\r\n\t\"lawngreen\": [124, 252, 0],\r\n\t\"lemonchiffon\": [255, 250, 205],\r\n\t\"lightblue\": [173, 216, 230],\r\n\t\"lightcoral\": [240, 128, 128],\r\n\t\"lightcyan\": [224, 255, 255],\r\n\t\"lightgoldenrodyellow\": [250, 250, 210],\r\n\t\"lightgray\": [211, 211, 211],\r\n\t\"lightgreen\": [144, 238, 144],\r\n\t\"lightgrey\": [211, 211, 211],\r\n\t\"lightpink\": [255, 182, 193],\r\n\t\"lightsalmon\": [255, 160, 122],\r\n\t\"lightseagreen\": [32, 178, 170],\r\n\t\"lightskyblue\": [135, 206, 250],\r\n\t\"lightslategray\": [119, 136, 153],\r\n\t\"lightslategrey\": [119, 136, 153],\r\n\t\"lightsteelblue\": [176, 196, 222],\r\n\t\"lightyellow\": [255, 255, 224],\r\n\t\"lime\": [0, 255, 0],\r\n\t\"limegreen\": [50, 205, 50],\r\n\t\"linen\": [250, 240, 230],\r\n\t\"magenta\": [255, 0, 255],\r\n\t\"maroon\": [128, 0, 0],\r\n\t\"mediumaquamarine\": [102, 205, 170],\r\n\t\"mediumblue\": [0, 0, 205],\r\n\t\"mediumorchid\": [186, 85, 211],\r\n\t\"mediumpurple\": [147, 112, 219],\r\n\t\"mediumseagreen\": [60, 179, 113],\r\n\t\"mediumslateblue\": [123, 104, 238],\r\n\t\"mediumspringgreen\": [0, 250, 154],\r\n\t\"mediumturquoise\": [72, 209, 204],\r\n\t\"mediumvioletred\": [199, 21, 133],\r\n\t\"midnightblue\": [25, 25, 112],\r\n\t\"mintcream\": [245, 255, 250],\r\n\t\"mistyrose\": [255, 228, 225],\r\n\t\"moccasin\": [255, 228, 181],\r\n\t\"navajowhite\": [255, 222, 173],\r\n\t\"navy\": [0, 0, 128],\r\n\t\"oldlace\": [253, 245, 230],\r\n\t\"olive\": [128, 128, 0],\r\n\t\"olivedrab\": [107, 142, 35],\r\n\t\"orange\": [255, 165, 0],\r\n\t\"orangered\": [255, 69, 0],\r\n\t\"orchid\": [218, 112, 214],\r\n\t\"palegoldenrod\": [238, 232, 170],\r\n\t\"palegreen\": [152, 251, 152],\r\n\t\"paleturquoise\": [175, 238, 238],\r\n\t\"palevioletred\": [219, 112, 147],\r\n\t\"papayawhip\": [255, 239, 213],\r\n\t\"peachpuff\": [255, 218, 185],\r\n\t\"peru\": [205, 133, 63],\r\n\t\"pink\": [255, 192, 203],\r\n\t\"plum\": [221, 160, 221],\r\n\t\"powderblue\": [176, 224, 230],\r\n\t\"purple\": [128, 0, 128],\r\n\t\"rebeccapurple\": [102, 51, 153],\r\n\t\"red\": [255, 0, 0],\r\n\t\"rosybrown\": [188, 143, 143],\r\n\t\"royalblue\": [65, 105, 225],\r\n\t\"saddlebrown\": [139, 69, 19],\r\n\t\"salmon\": [250, 128, 114],\r\n\t\"sandybrown\": [244, 164, 96],\r\n\t\"seagreen\": [46, 139, 87],\r\n\t\"seashell\": [255, 245, 238],\r\n\t\"sienna\": [160, 82, 45],\r\n\t\"silver\": [192, 192, 192],\r\n\t\"skyblue\": [135, 206, 235],\r\n\t\"slateblue\": [106, 90, 205],\r\n\t\"slategray\": [112, 128, 144],\r\n\t\"slategrey\": [112, 128, 144],\r\n\t\"snow\": [255, 250, 250],\r\n\t\"springgreen\": [0, 255, 127],\r\n\t\"steelblue\": [70, 130, 180],\r\n\t\"tan\": [210, 180, 140],\r\n\t\"teal\": [0, 128, 128],\r\n\t\"thistle\": [216, 191, 216],\r\n\t\"tomato\": [255, 99, 71],\r\n\t\"turquoise\": [64, 224, 208],\r\n\t\"violet\": [238, 130, 238],\r\n\t\"wheat\": [245, 222, 179],\r\n\t\"white\": [255, 255, 255],\r\n\t\"whitesmoke\": [245, 245, 245],\r\n\t\"yellow\": [255, 255, 0],\r\n\t\"yellowgreen\": [154, 205, 50]\r\n};\n\nvar conversions = createCommonjsModule(function (module) {\n/* MIT license */\n\n\n// NOTE: conversions should only return primitive values (i.e. arrays, or\n// values that give correct `typeof` results).\n// do not use box values types (i.e. Number(), String(), etc.)\n\nvar reverseKeywords = {};\nfor (var key in colorName) {\n\tif (colorName.hasOwnProperty(key)) {\n\t\treverseKeywords[colorName[key]] = key;\n\t}\n}\n\nvar convert = module.exports = {\n\trgb: {channels: 3, labels: 'rgb'},\n\thsl: {channels: 3, labels: 'hsl'},\n\thsv: {channels: 3, labels: 'hsv'},\n\thwb: {channels: 3, labels: 'hwb'},\n\tcmyk: {channels: 4, labels: 'cmyk'},\n\txyz: {channels: 3, labels: 'xyz'},\n\tlab: {channels: 3, labels: 'lab'},\n\tlch: {channels: 3, labels: 'lch'},\n\thex: {channels: 1, labels: ['hex']},\n\tkeyword: {channels: 1, labels: ['keyword']},\n\tansi16: {channels: 1, labels: ['ansi16']},\n\tansi256: {channels: 1, labels: ['ansi256']},\n\thcg: {channels: 3, labels: ['h', 'c', 'g']},\n\tapple: {channels: 3, labels: ['r16', 'g16', 'b16']},\n\tgray: {channels: 1, labels: ['gray']}\n};\n\n// hide .channels and .labels properties\nfor (var model in convert) {\n\tif (convert.hasOwnProperty(model)) {\n\t\tif (!('channels' in convert[model])) {\n\t\t\tthrow new Error('missing channels property: ' + model);\n\t\t}\n\n\t\tif (!('labels' in convert[model])) {\n\t\t\tthrow new Error('missing channel labels property: ' + model);\n\t\t}\n\n\t\tif (convert[model].labels.length !== convert[model].channels) {\n\t\t\tthrow new Error('channel and label counts mismatch: ' + model);\n\t\t}\n\n\t\tvar channels = convert[model].channels;\n\t\tvar labels = convert[model].labels;\n\t\tdelete convert[model].channels;\n\t\tdelete convert[model].labels;\n\t\tObject.defineProperty(convert[model], 'channels', {value: channels});\n\t\tObject.defineProperty(convert[model], 'labels', {value: labels});\n\t}\n}\n\nconvert.rgb.hsl = function (rgb) {\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\tvar min = Math.min(r, g, b);\n\tvar max = Math.max(r, g, b);\n\tvar delta = max - min;\n\tvar h;\n\tvar s;\n\tvar l;\n\n\tif (max === min) {\n\t\th = 0;\n\t} else if (r === max) {\n\t\th = (g - b) / delta;\n\t} else if (g === max) {\n\t\th = 2 + (b - r) / delta;\n\t} else if (b === max) {\n\t\th = 4 + (r - g) / delta;\n\t}\n\n\th = Math.min(h * 60, 360);\n\n\tif (h < 0) {\n\t\th += 360;\n\t}\n\n\tl = (min + max) / 2;\n\n\tif (max === min) {\n\t\ts = 0;\n\t} else if (l <= 0.5) {\n\t\ts = delta / (max + min);\n\t} else {\n\t\ts = delta / (2 - max - min);\n\t}\n\n\treturn [h, s * 100, l * 100];\n};\n\nconvert.rgb.hsv = function (rgb) {\n\tvar rdif;\n\tvar gdif;\n\tvar bdif;\n\tvar h;\n\tvar s;\n\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\tvar v = Math.max(r, g, b);\n\tvar diff = v - Math.min(r, g, b);\n\tvar diffc = function (c) {\n\t\treturn (v - c) / 6 / diff + 1 / 2;\n\t};\n\n\tif (diff === 0) {\n\t\th = s = 0;\n\t} else {\n\t\ts = diff / v;\n\t\trdif = diffc(r);\n\t\tgdif = diffc(g);\n\t\tbdif = diffc(b);\n\n\t\tif (r === v) {\n\t\t\th = bdif - gdif;\n\t\t} else if (g === v) {\n\t\t\th = (1 / 3) + rdif - bdif;\n\t\t} else if (b === v) {\n\t\t\th = (2 / 3) + gdif - rdif;\n\t\t}\n\t\tif (h < 0) {\n\t\t\th += 1;\n\t\t} else if (h > 1) {\n\t\t\th -= 1;\n\t\t}\n\t}\n\n\treturn [\n\t\th * 360,\n\t\ts * 100,\n\t\tv * 100\n\t];\n};\n\nconvert.rgb.hwb = function (rgb) {\n\tvar r = rgb[0];\n\tvar g = rgb[1];\n\tvar b = rgb[2];\n\tvar h = convert.rgb.hsl(rgb)[0];\n\tvar w = 1 / 255 * Math.min(r, Math.min(g, b));\n\n\tb = 1 - 1 / 255 * Math.max(r, Math.max(g, b));\n\n\treturn [h, w * 100, b * 100];\n};\n\nconvert.rgb.cmyk = function (rgb) {\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\tvar c;\n\tvar m;\n\tvar y;\n\tvar k;\n\n\tk = Math.min(1 - r, 1 - g, 1 - b);\n\tc = (1 - r - k) / (1 - k) || 0;\n\tm = (1 - g - k) / (1 - k) || 0;\n\ty = (1 - b - k) / (1 - k) || 0;\n\n\treturn [c * 100, m * 100, y * 100, k * 100];\n};\n\n/**\n * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance\n * */\nfunction comparativeDistance(x, y) {\n\treturn (\n\t\tMath.pow(x[0] - y[0], 2) +\n\t\tMath.pow(x[1] - y[1], 2) +\n\t\tMath.pow(x[2] - y[2], 2)\n\t);\n}\n\nconvert.rgb.keyword = function (rgb) {\n\tvar reversed = reverseKeywords[rgb];\n\tif (reversed) {\n\t\treturn reversed;\n\t}\n\n\tvar currentClosestDistance = Infinity;\n\tvar currentClosestKeyword;\n\n\tfor (var keyword in colorName) {\n\t\tif (colorName.hasOwnProperty(keyword)) {\n\t\t\tvar value = colorName[keyword];\n\n\t\t\t// Compute comparative distance\n\t\t\tvar distance = comparativeDistance(rgb, value);\n\n\t\t\t// Check if its less, if so set as closest\n\t\t\tif (distance < currentClosestDistance) {\n\t\t\t\tcurrentClosestDistance = distance;\n\t\t\t\tcurrentClosestKeyword = keyword;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn currentClosestKeyword;\n};\n\nconvert.keyword.rgb = function (keyword) {\n\treturn colorName[keyword];\n};\n\nconvert.rgb.xyz = function (rgb) {\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\n\t// assume sRGB\n\tr = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);\n\tg = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);\n\tb = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);\n\n\tvar x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);\n\tvar y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);\n\tvar z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);\n\n\treturn [x * 100, y * 100, z * 100];\n};\n\nconvert.rgb.lab = function (rgb) {\n\tvar xyz = convert.rgb.xyz(rgb);\n\tvar x = xyz[0];\n\tvar y = xyz[1];\n\tvar z = xyz[2];\n\tvar l;\n\tvar a;\n\tvar b;\n\n\tx /= 95.047;\n\ty /= 100;\n\tz /= 108.883;\n\n\tx = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);\n\ty = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);\n\tz = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);\n\n\tl = (116 * y) - 16;\n\ta = 500 * (x - y);\n\tb = 200 * (y - z);\n\n\treturn [l, a, b];\n};\n\nconvert.hsl.rgb = function (hsl) {\n\tvar h = hsl[0] / 360;\n\tvar s = hsl[1] / 100;\n\tvar l = hsl[2] / 100;\n\tvar t1;\n\tvar t2;\n\tvar t3;\n\tvar rgb;\n\tvar val;\n\n\tif (s === 0) {\n\t\tval = l * 255;\n\t\treturn [val, val, val];\n\t}\n\n\tif (l < 0.5) {\n\t\tt2 = l * (1 + s);\n\t} else {\n\t\tt2 = l + s - l * s;\n\t}\n\n\tt1 = 2 * l - t2;\n\n\trgb = [0, 0, 0];\n\tfor (var i = 0; i < 3; i++) {\n\t\tt3 = h + 1 / 3 * -(i - 1);\n\t\tif (t3 < 0) {\n\t\t\tt3++;\n\t\t}\n\t\tif (t3 > 1) {\n\t\t\tt3--;\n\t\t}\n\n\t\tif (6 * t3 < 1) {\n\t\t\tval = t1 + (t2 - t1) * 6 * t3;\n\t\t} else if (2 * t3 < 1) {\n\t\t\tval = t2;\n\t\t} else if (3 * t3 < 2) {\n\t\t\tval = t1 + (t2 - t1) * (2 / 3 - t3) * 6;\n\t\t} else {\n\t\t\tval = t1;\n\t\t}\n\n\t\trgb[i] = val * 255;\n\t}\n\n\treturn rgb;\n};\n\nconvert.hsl.hsv = function (hsl) {\n\tvar h = hsl[0];\n\tvar s = hsl[1] / 100;\n\tvar l = hsl[2] / 100;\n\tvar smin = s;\n\tvar lmin = Math.max(l, 0.01);\n\tvar sv;\n\tvar v;\n\n\tl *= 2;\n\ts *= (l <= 1) ? l : 2 - l;\n\tsmin *= lmin <= 1 ? lmin : 2 - lmin;\n\tv = (l + s) / 2;\n\tsv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);\n\n\treturn [h, sv * 100, v * 100];\n};\n\nconvert.hsv.rgb = function (hsv) {\n\tvar h = hsv[0] / 60;\n\tvar s = hsv[1] / 100;\n\tvar v = hsv[2] / 100;\n\tvar hi = Math.floor(h) % 6;\n\n\tvar f = h - Math.floor(h);\n\tvar p = 255 * v * (1 - s);\n\tvar q = 255 * v * (1 - (s * f));\n\tvar t = 255 * v * (1 - (s * (1 - f)));\n\tv *= 255;\n\n\tswitch (hi) {\n\t\tcase 0:\n\t\t\treturn [v, t, p];\n\t\tcase 1:\n\t\t\treturn [q, v, p];\n\t\tcase 2:\n\t\t\treturn [p, v, t];\n\t\tcase 3:\n\t\t\treturn [p, q, v];\n\t\tcase 4:\n\t\t\treturn [t, p, v];\n\t\tcase 5:\n\t\t\treturn [v, p, q];\n\t}\n};\n\nconvert.hsv.hsl = function (hsv) {\n\tvar h = hsv[0];\n\tvar s = hsv[1] / 100;\n\tvar v = hsv[2] / 100;\n\tvar vmin = Math.max(v, 0.01);\n\tvar lmin;\n\tvar sl;\n\tvar l;\n\n\tl = (2 - s) * v;\n\tlmin = (2 - s) * vmin;\n\tsl = s * vmin;\n\tsl /= (lmin <= 1) ? lmin : 2 - lmin;\n\tsl = sl || 0;\n\tl /= 2;\n\n\treturn [h, sl * 100, l * 100];\n};\n\n// http://dev.w3.org/csswg/css-color/#hwb-to-rgb\nconvert.hwb.rgb = function (hwb) {\n\tvar h = hwb[0] / 360;\n\tvar wh = hwb[1] / 100;\n\tvar bl = hwb[2] / 100;\n\tvar ratio = wh + bl;\n\tvar i;\n\tvar v;\n\tvar f;\n\tvar n;\n\n\t// wh + bl cant be > 1\n\tif (ratio > 1) {\n\t\twh /= ratio;\n\t\tbl /= ratio;\n\t}\n\n\ti = Math.floor(6 * h);\n\tv = 1 - bl;\n\tf = 6 * h - i;\n\n\tif ((i & 0x01) !== 0) {\n\t\tf = 1 - f;\n\t}\n\n\tn = wh + f * (v - wh); // linear interpolation\n\n\tvar r;\n\tvar g;\n\tvar b;\n\tswitch (i) {\n\t\tdefault:\n\t\tcase 6:\n\t\tcase 0: r = v; g = n; b = wh; break;\n\t\tcase 1: r = n; g = v; b = wh; break;\n\t\tcase 2: r = wh; g = v; b = n; break;\n\t\tcase 3: r = wh; g = n; b = v; break;\n\t\tcase 4: r = n; g = wh; b = v; break;\n\t\tcase 5: r = v; g = wh; b = n; break;\n\t}\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.cmyk.rgb = function (cmyk) {\n\tvar c = cmyk[0] / 100;\n\tvar m = cmyk[1] / 100;\n\tvar y = cmyk[2] / 100;\n\tvar k = cmyk[3] / 100;\n\tvar r;\n\tvar g;\n\tvar b;\n\n\tr = 1 - Math.min(1, c * (1 - k) + k);\n\tg = 1 - Math.min(1, m * (1 - k) + k);\n\tb = 1 - Math.min(1, y * (1 - k) + k);\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.xyz.rgb = function (xyz) {\n\tvar x = xyz[0] / 100;\n\tvar y = xyz[1] / 100;\n\tvar z = xyz[2] / 100;\n\tvar r;\n\tvar g;\n\tvar b;\n\n\tr = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);\n\tg = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);\n\tb = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);\n\n\t// assume sRGB\n\tr = r > 0.0031308\n\t\t? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)\n\t\t: r * 12.92;\n\n\tg = g > 0.0031308\n\t\t? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)\n\t\t: g * 12.92;\n\n\tb = b > 0.0031308\n\t\t? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)\n\t\t: b * 12.92;\n\n\tr = Math.min(Math.max(0, r), 1);\n\tg = Math.min(Math.max(0, g), 1);\n\tb = Math.min(Math.max(0, b), 1);\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.xyz.lab = function (xyz) {\n\tvar x = xyz[0];\n\tvar y = xyz[1];\n\tvar z = xyz[2];\n\tvar l;\n\tvar a;\n\tvar b;\n\n\tx /= 95.047;\n\ty /= 100;\n\tz /= 108.883;\n\n\tx = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);\n\ty = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);\n\tz = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);\n\n\tl = (116 * y) - 16;\n\ta = 500 * (x - y);\n\tb = 200 * (y - z);\n\n\treturn [l, a, b];\n};\n\nconvert.lab.xyz = function (lab) {\n\tvar l = lab[0];\n\tvar a = lab[1];\n\tvar b = lab[2];\n\tvar x;\n\tvar y;\n\tvar z;\n\n\ty = (l + 16) / 116;\n\tx = a / 500 + y;\n\tz = y - b / 200;\n\n\tvar y2 = Math.pow(y, 3);\n\tvar x2 = Math.pow(x, 3);\n\tvar z2 = Math.pow(z, 3);\n\ty = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;\n\tx = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;\n\tz = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;\n\n\tx *= 95.047;\n\ty *= 100;\n\tz *= 108.883;\n\n\treturn [x, y, z];\n};\n\nconvert.lab.lch = function (lab) {\n\tvar l = lab[0];\n\tvar a = lab[1];\n\tvar b = lab[2];\n\tvar hr;\n\tvar h;\n\tvar c;\n\n\thr = Math.atan2(b, a);\n\th = hr * 360 / 2 / Math.PI;\n\n\tif (h < 0) {\n\t\th += 360;\n\t}\n\n\tc = Math.sqrt(a * a + b * b);\n\n\treturn [l, c, h];\n};\n\nconvert.lch.lab = function (lch) {\n\tvar l = lch[0];\n\tvar c = lch[1];\n\tvar h = lch[2];\n\tvar a;\n\tvar b;\n\tvar hr;\n\n\thr = h / 360 * 2 * Math.PI;\n\ta = c * Math.cos(hr);\n\tb = c * Math.sin(hr);\n\n\treturn [l, a, b];\n};\n\nconvert.rgb.ansi16 = function (args) {\n\tvar r = args[0];\n\tvar g = args[1];\n\tvar b = args[2];\n\tvar value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization\n\n\tvalue = Math.round(value / 50);\n\n\tif (value === 0) {\n\t\treturn 30;\n\t}\n\n\tvar ansi = 30\n\t\t+ ((Math.round(b / 255) << 2)\n\t\t| (Math.round(g / 255) << 1)\n\t\t| Math.round(r / 255));\n\n\tif (value === 2) {\n\t\tansi += 60;\n\t}\n\n\treturn ansi;\n};\n\nconvert.hsv.ansi16 = function (args) {\n\t// optimization here; we already know the value and don't need to get\n\t// it converted for us.\n\treturn convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);\n};\n\nconvert.rgb.ansi256 = function (args) {\n\tvar r = args[0];\n\tvar g = args[1];\n\tvar b = args[2];\n\n\t// we use the extended greyscale palette here, with the exception of\n\t// black and white. normal palette only has 4 greyscale shades.\n\tif (r === g && g === b) {\n\t\tif (r < 8) {\n\t\t\treturn 16;\n\t\t}\n\n\t\tif (r > 248) {\n\t\t\treturn 231;\n\t\t}\n\n\t\treturn Math.round(((r - 8) / 247) * 24) + 232;\n\t}\n\n\tvar ansi = 16\n\t\t+ (36 * Math.round(r / 255 * 5))\n\t\t+ (6 * Math.round(g / 255 * 5))\n\t\t+ Math.round(b / 255 * 5);\n\n\treturn ansi;\n};\n\nconvert.ansi16.rgb = function (args) {\n\tvar color = args % 10;\n\n\t// handle greyscale\n\tif (color === 0 || color === 7) {\n\t\tif (args > 50) {\n\t\t\tcolor += 3.5;\n\t\t}\n\n\t\tcolor = color / 10.5 * 255;\n\n\t\treturn [color, color, color];\n\t}\n\n\tvar mult = (~~(args > 50) + 1) * 0.5;\n\tvar r = ((color & 1) * mult) * 255;\n\tvar g = (((color >> 1) & 1) * mult) * 255;\n\tvar b = (((color >> 2) & 1) * mult) * 255;\n\n\treturn [r, g, b];\n};\n\nconvert.ansi256.rgb = function (args) {\n\t// handle greyscale\n\tif (args >= 232) {\n\t\tvar c = (args - 232) * 10 + 8;\n\t\treturn [c, c, c];\n\t}\n\n\targs -= 16;\n\n\tvar rem;\n\tvar r = Math.floor(args / 36) / 5 * 255;\n\tvar g = Math.floor((rem = args % 36) / 6) / 5 * 255;\n\tvar b = (rem % 6) / 5 * 255;\n\n\treturn [r, g, b];\n};\n\nconvert.rgb.hex = function (args) {\n\tvar integer = ((Math.round(args[0]) & 0xFF) << 16)\n\t\t+ ((Math.round(args[1]) & 0xFF) << 8)\n\t\t+ (Math.round(args[2]) & 0xFF);\n\n\tvar string = integer.toString(16).toUpperCase();\n\treturn '000000'.substring(string.length) + string;\n};\n\nconvert.hex.rgb = function (args) {\n\tvar match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);\n\tif (!match) {\n\t\treturn [0, 0, 0];\n\t}\n\n\tvar colorString = match[0];\n\n\tif (match[0].length === 3) {\n\t\tcolorString = colorString.split('').map(function (char) {\n\t\t\treturn char + char;\n\t\t}).join('');\n\t}\n\n\tvar integer = parseInt(colorString, 16);\n\tvar r = (integer >> 16) & 0xFF;\n\tvar g = (integer >> 8) & 0xFF;\n\tvar b = integer & 0xFF;\n\n\treturn [r, g, b];\n};\n\nconvert.rgb.hcg = function (rgb) {\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\tvar max = Math.max(Math.max(r, g), b);\n\tvar min = Math.min(Math.min(r, g), b);\n\tvar chroma = (max - min);\n\tvar grayscale;\n\tvar hue;\n\n\tif (chroma < 1) {\n\t\tgrayscale = min / (1 - chroma);\n\t} else {\n\t\tgrayscale = 0;\n\t}\n\n\tif (chroma <= 0) {\n\t\thue = 0;\n\t} else\n\tif (max === r) {\n\t\thue = ((g - b) / chroma) % 6;\n\t} else\n\tif (max === g) {\n\t\thue = 2 + (b - r) / chroma;\n\t} else {\n\t\thue = 4 + (r - g) / chroma + 4;\n\t}\n\n\thue /= 6;\n\thue %= 1;\n\n\treturn [hue * 360, chroma * 100, grayscale * 100];\n};\n\nconvert.hsl.hcg = function (hsl) {\n\tvar s = hsl[1] / 100;\n\tvar l = hsl[2] / 100;\n\tvar c = 1;\n\tvar f = 0;\n\n\tif (l < 0.5) {\n\t\tc = 2.0 * s * l;\n\t} else {\n\t\tc = 2.0 * s * (1.0 - l);\n\t}\n\n\tif (c < 1.0) {\n\t\tf = (l - 0.5 * c) / (1.0 - c);\n\t}\n\n\treturn [hsl[0], c * 100, f * 100];\n};\n\nconvert.hsv.hcg = function (hsv) {\n\tvar s = hsv[1] / 100;\n\tvar v = hsv[2] / 100;\n\n\tvar c = s * v;\n\tvar f = 0;\n\n\tif (c < 1.0) {\n\t\tf = (v - c) / (1 - c);\n\t}\n\n\treturn [hsv[0], c * 100, f * 100];\n};\n\nconvert.hcg.rgb = function (hcg) {\n\tvar h = hcg[0] / 360;\n\tvar c = hcg[1] / 100;\n\tvar g = hcg[2] / 100;\n\n\tif (c === 0.0) {\n\t\treturn [g * 255, g * 255, g * 255];\n\t}\n\n\tvar pure = [0, 0, 0];\n\tvar hi = (h % 1) * 6;\n\tvar v = hi % 1;\n\tvar w = 1 - v;\n\tvar mg = 0;\n\n\tswitch (Math.floor(hi)) {\n\t\tcase 0:\n\t\t\tpure[0] = 1; pure[1] = v; pure[2] = 0; break;\n\t\tcase 1:\n\t\t\tpure[0] = w; pure[1] = 1; pure[2] = 0; break;\n\t\tcase 2:\n\t\t\tpure[0] = 0; pure[1] = 1; pure[2] = v; break;\n\t\tcase 3:\n\t\t\tpure[0] = 0; pure[1] = w; pure[2] = 1; break;\n\t\tcase 4:\n\t\t\tpure[0] = v; pure[1] = 0; pure[2] = 1; break;\n\t\tdefault:\n\t\t\tpure[0] = 1; pure[1] = 0; pure[2] = w;\n\t}\n\n\tmg = (1.0 - c) * g;\n\n\treturn [\n\t\t(c * pure[0] + mg) * 255,\n\t\t(c * pure[1] + mg) * 255,\n\t\t(c * pure[2] + mg) * 255\n\t];\n};\n\nconvert.hcg.hsv = function (hcg) {\n\tvar c = hcg[1] / 100;\n\tvar g = hcg[2] / 100;\n\n\tvar v = c + g * (1.0 - c);\n\tvar f = 0;\n\n\tif (v > 0.0) {\n\t\tf = c / v;\n\t}\n\n\treturn [hcg[0], f * 100, v * 100];\n};\n\nconvert.hcg.hsl = function (hcg) {\n\tvar c = hcg[1] / 100;\n\tvar g = hcg[2] / 100;\n\n\tvar l = g * (1.0 - c) + 0.5 * c;\n\tvar s = 0;\n\n\tif (l > 0.0 && l < 0.5) {\n\t\ts = c / (2 * l);\n\t} else\n\tif (l >= 0.5 && l < 1.0) {\n\t\ts = c / (2 * (1 - l));\n\t}\n\n\treturn [hcg[0], s * 100, l * 100];\n};\n\nconvert.hcg.hwb = function (hcg) {\n\tvar c = hcg[1] / 100;\n\tvar g = hcg[2] / 100;\n\tvar v = c + g * (1.0 - c);\n\treturn [hcg[0], (v - c) * 100, (1 - v) * 100];\n};\n\nconvert.hwb.hcg = function (hwb) {\n\tvar w = hwb[1] / 100;\n\tvar b = hwb[2] / 100;\n\tvar v = 1 - b;\n\tvar c = v - w;\n\tvar g = 0;\n\n\tif (c < 1) {\n\t\tg = (v - c) / (1 - c);\n\t}\n\n\treturn [hwb[0], c * 100, g * 100];\n};\n\nconvert.apple.rgb = function (apple) {\n\treturn [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];\n};\n\nconvert.rgb.apple = function (rgb) {\n\treturn [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];\n};\n\nconvert.gray.rgb = function (args) {\n\treturn [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];\n};\n\nconvert.gray.hsl = convert.gray.hsv = function (args) {\n\treturn [0, 0, args[0]];\n};\n\nconvert.gray.hwb = function (gray) {\n\treturn [0, 100, gray[0]];\n};\n\nconvert.gray.cmyk = function (gray) {\n\treturn [0, 0, 0, gray[0]];\n};\n\nconvert.gray.lab = function (gray) {\n\treturn [gray[0], 0, 0];\n};\n\nconvert.gray.hex = function (gray) {\n\tvar val = Math.round(gray[0] / 100 * 255) & 0xFF;\n\tvar integer = (val << 16) + (val << 8) + val;\n\n\tvar string = integer.toString(16).toUpperCase();\n\treturn '000000'.substring(string.length) + string;\n};\n\nconvert.rgb.gray = function (rgb) {\n\tvar val = (rgb[0] + rgb[1] + rgb[2]) / 3;\n\treturn [val / 255 * 100];\n};\n});\nvar conversions_1 = conversions.rgb;\nvar conversions_2 = conversions.hsl;\nvar conversions_3 = conversions.hsv;\nvar conversions_4 = conversions.hwb;\nvar conversions_5 = conversions.cmyk;\nvar conversions_6 = conversions.xyz;\nvar conversions_7 = conversions.lab;\nvar conversions_8 = conversions.lch;\nvar conversions_9 = conversions.hex;\nvar conversions_10 = conversions.keyword;\nvar conversions_11 = conversions.ansi16;\nvar conversions_12 = conversions.ansi256;\nvar conversions_13 = conversions.hcg;\nvar conversions_14 = conversions.apple;\nvar conversions_15 = conversions.gray;\n\n/*\n\tthis function routes a model to all other models.\n\n\tall functions that are routed have a property `.conversion` attached\n\tto the returned synthetic function. This property is an array\n\tof strings, each with the steps in between the 'from' and 'to'\n\tcolor models (inclusive).\n\n\tconversions that are not possible simply are not included.\n*/\n\nfunction buildGraph() {\n\tvar graph = {};\n\t// https://jsperf.com/object-keys-vs-for-in-with-closure/3\n\tvar models = Object.keys(conversions);\n\n\tfor (var len = models.length, i = 0; i < len; i++) {\n\t\tgraph[models[i]] = {\n\t\t\t// http://jsperf.com/1-vs-infinity\n\t\t\t// micro-opt, but this is simple.\n\t\t\tdistance: -1,\n\t\t\tparent: null\n\t\t};\n\t}\n\n\treturn graph;\n}\n\n// https://en.wikipedia.org/wiki/Breadth-first_search\nfunction deriveBFS(fromModel) {\n\tvar graph = buildGraph();\n\tvar queue = [fromModel]; // unshift -> queue -> pop\n\n\tgraph[fromModel].distance = 0;\n\n\twhile (queue.length) {\n\t\tvar current = queue.pop();\n\t\tvar adjacents = Object.keys(conversions[current]);\n\n\t\tfor (var len = adjacents.length, i = 0; i < len; i++) {\n\t\t\tvar adjacent = adjacents[i];\n\t\t\tvar node = graph[adjacent];\n\n\t\t\tif (node.distance === -1) {\n\t\t\t\tnode.distance = graph[current].distance + 1;\n\t\t\t\tnode.parent = current;\n\t\t\t\tqueue.unshift(adjacent);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn graph;\n}\n\nfunction link(from, to) {\n\treturn function (args) {\n\t\treturn to(from(args));\n\t};\n}\n\nfunction wrapConversion(toModel, graph) {\n\tvar path = [graph[toModel].parent, toModel];\n\tvar fn = conversions[graph[toModel].parent][toModel];\n\n\tvar cur = graph[toModel].parent;\n\twhile (graph[cur].parent) {\n\t\tpath.unshift(graph[cur].parent);\n\t\tfn = link(conversions[graph[cur].parent][cur], fn);\n\t\tcur = graph[cur].parent;\n\t}\n\n\tfn.conversion = path;\n\treturn fn;\n}\n\nvar route = function (fromModel) {\n\tvar graph = deriveBFS(fromModel);\n\tvar conversion = {};\n\n\tvar models = Object.keys(graph);\n\tfor (var len = models.length, i = 0; i < len; i++) {\n\t\tvar toModel = models[i];\n\t\tvar node = graph[toModel];\n\n\t\tif (node.parent === null) {\n\t\t\t// no possible conversion, or this node is the source model.\n\t\t\tcontinue;\n\t\t}\n\n\t\tconversion[toModel] = wrapConversion(toModel, graph);\n\t}\n\n\treturn conversion;\n};\n\nvar convert = {};\n\nvar models = Object.keys(conversions);\n\nfunction wrapRaw(fn) {\n\tvar wrappedFn = function (args) {\n\t\tif (args === undefined || args === null) {\n\t\t\treturn args;\n\t\t}\n\n\t\tif (arguments.length > 1) {\n\t\t\targs = Array.prototype.slice.call(arguments);\n\t\t}\n\n\t\treturn fn(args);\n\t};\n\n\t// preserve .conversion property if there is one\n\tif ('conversion' in fn) {\n\t\twrappedFn.conversion = fn.conversion;\n\t}\n\n\treturn wrappedFn;\n}\n\nfunction wrapRounded(fn) {\n\tvar wrappedFn = function (args) {\n\t\tif (args === undefined || args === null) {\n\t\t\treturn args;\n\t\t}\n\n\t\tif (arguments.length > 1) {\n\t\t\targs = Array.prototype.slice.call(arguments);\n\t\t}\n\n\t\tvar result = fn(args);\n\n\t\t// we're assuming the result is an array here.\n\t\t// see notice in conversions.js; don't use box types\n\t\t// in conversion functions.\n\t\tif (typeof result === 'object') {\n\t\t\tfor (var len = result.length, i = 0; i < len; i++) {\n\t\t\t\tresult[i] = Math.round(result[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t};\n\n\t// preserve .conversion property if there is one\n\tif ('conversion' in fn) {\n\t\twrappedFn.conversion = fn.conversion;\n\t}\n\n\treturn wrappedFn;\n}\n\nmodels.forEach(function (fromModel) {\n\tconvert[fromModel] = {};\n\n\tObject.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels});\n\tObject.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels});\n\n\tvar routes = route(fromModel);\n\tvar routeModels = Object.keys(routes);\n\n\trouteModels.forEach(function (toModel) {\n\t\tvar fn = routes[toModel];\n\n\t\tconvert[fromModel][toModel] = wrapRounded(fn);\n\t\tconvert[fromModel][toModel].raw = wrapRaw(fn);\n\t});\n});\n\nvar colorConvert = convert;\n\nvar colorName$1 = {\r\n\t\"aliceblue\": [240, 248, 255],\r\n\t\"antiquewhite\": [250, 235, 215],\r\n\t\"aqua\": [0, 255, 255],\r\n\t\"aquamarine\": [127, 255, 212],\r\n\t\"azure\": [240, 255, 255],\r\n\t\"beige\": [245, 245, 220],\r\n\t\"bisque\": [255, 228, 196],\r\n\t\"black\": [0, 0, 0],\r\n\t\"blanchedalmond\": [255, 235, 205],\r\n\t\"blue\": [0, 0, 255],\r\n\t\"blueviolet\": [138, 43, 226],\r\n\t\"brown\": [165, 42, 42],\r\n\t\"burlywood\": [222, 184, 135],\r\n\t\"cadetblue\": [95, 158, 160],\r\n\t\"chartreuse\": [127, 255, 0],\r\n\t\"chocolate\": [210, 105, 30],\r\n\t\"coral\": [255, 127, 80],\r\n\t\"cornflowerblue\": [100, 149, 237],\r\n\t\"cornsilk\": [255, 248, 220],\r\n\t\"crimson\": [220, 20, 60],\r\n\t\"cyan\": [0, 255, 255],\r\n\t\"darkblue\": [0, 0, 139],\r\n\t\"darkcyan\": [0, 139, 139],\r\n\t\"darkgoldenrod\": [184, 134, 11],\r\n\t\"darkgray\": [169, 169, 169],\r\n\t\"darkgreen\": [0, 100, 0],\r\n\t\"darkgrey\": [169, 169, 169],\r\n\t\"darkkhaki\": [189, 183, 107],\r\n\t\"darkmagenta\": [139, 0, 139],\r\n\t\"darkolivegreen\": [85, 107, 47],\r\n\t\"darkorange\": [255, 140, 0],\r\n\t\"darkorchid\": [153, 50, 204],\r\n\t\"darkred\": [139, 0, 0],\r\n\t\"darksalmon\": [233, 150, 122],\r\n\t\"darkseagreen\": [143, 188, 143],\r\n\t\"darkslateblue\": [72, 61, 139],\r\n\t\"darkslategray\": [47, 79, 79],\r\n\t\"darkslategrey\": [47, 79, 79],\r\n\t\"darkturquoise\": [0, 206, 209],\r\n\t\"darkviolet\": [148, 0, 211],\r\n\t\"deeppink\": [255, 20, 147],\r\n\t\"deepskyblue\": [0, 191, 255],\r\n\t\"dimgray\": [105, 105, 105],\r\n\t\"dimgrey\": [105, 105, 105],\r\n\t\"dodgerblue\": [30, 144, 255],\r\n\t\"firebrick\": [178, 34, 34],\r\n\t\"floralwhite\": [255, 250, 240],\r\n\t\"forestgreen\": [34, 139, 34],\r\n\t\"fuchsia\": [255, 0, 255],\r\n\t\"gainsboro\": [220, 220, 220],\r\n\t\"ghostwhite\": [248, 248, 255],\r\n\t\"gold\": [255, 215, 0],\r\n\t\"goldenrod\": [218, 165, 32],\r\n\t\"gray\": [128, 128, 128],\r\n\t\"green\": [0, 128, 0],\r\n\t\"greenyellow\": [173, 255, 47],\r\n\t\"grey\": [128, 128, 128],\r\n\t\"honeydew\": [240, 255, 240],\r\n\t\"hotpink\": [255, 105, 180],\r\n\t\"indianred\": [205, 92, 92],\r\n\t\"indigo\": [75, 0, 130],\r\n\t\"ivory\": [255, 255, 240],\r\n\t\"khaki\": [240, 230, 140],\r\n\t\"lavender\": [230, 230, 250],\r\n\t\"lavenderblush\": [255, 240, 245],\r\n\t\"lawngreen\": [124, 252, 0],\r\n\t\"lemonchiffon\": [255, 250, 205],\r\n\t\"lightblue\": [173, 216, 230],\r\n\t\"lightcoral\": [240, 128, 128],\r\n\t\"lightcyan\": [224, 255, 255],\r\n\t\"lightgoldenrodyellow\": [250, 250, 210],\r\n\t\"lightgray\": [211, 211, 211],\r\n\t\"lightgreen\": [144, 238, 144],\r\n\t\"lightgrey\": [211, 211, 211],\r\n\t\"lightpink\": [255, 182, 193],\r\n\t\"lightsalmon\": [255, 160, 122],\r\n\t\"lightseagreen\": [32, 178, 170],\r\n\t\"lightskyblue\": [135, 206, 250],\r\n\t\"lightslategray\": [119, 136, 153],\r\n\t\"lightslategrey\": [119, 136, 153],\r\n\t\"lightsteelblue\": [176, 196, 222],\r\n\t\"lightyellow\": [255, 255, 224],\r\n\t\"lime\": [0, 255, 0],\r\n\t\"limegreen\": [50, 205, 50],\r\n\t\"linen\": [250, 240, 230],\r\n\t\"magenta\": [255, 0, 255],\r\n\t\"maroon\": [128, 0, 0],\r\n\t\"mediumaquamarine\": [102, 205, 170],\r\n\t\"mediumblue\": [0, 0, 205],\r\n\t\"mediumorchid\": [186, 85, 211],\r\n\t\"mediumpurple\": [147, 112, 219],\r\n\t\"mediumseagreen\": [60, 179, 113],\r\n\t\"mediumslateblue\": [123, 104, 238],\r\n\t\"mediumspringgreen\": [0, 250, 154],\r\n\t\"mediumturquoise\": [72, 209, 204],\r\n\t\"mediumvioletred\": [199, 21, 133],\r\n\t\"midnightblue\": [25, 25, 112],\r\n\t\"mintcream\": [245, 255, 250],\r\n\t\"mistyrose\": [255, 228, 225],\r\n\t\"moccasin\": [255, 228, 181],\r\n\t\"navajowhite\": [255, 222, 173],\r\n\t\"navy\": [0, 0, 128],\r\n\t\"oldlace\": [253, 245, 230],\r\n\t\"olive\": [128, 128, 0],\r\n\t\"olivedrab\": [107, 142, 35],\r\n\t\"orange\": [255, 165, 0],\r\n\t\"orangered\": [255, 69, 0],\r\n\t\"orchid\": [218, 112, 214],\r\n\t\"palegoldenrod\": [238, 232, 170],\r\n\t\"palegreen\": [152, 251, 152],\r\n\t\"paleturquoise\": [175, 238, 238],\r\n\t\"palevioletred\": [219, 112, 147],\r\n\t\"papayawhip\": [255, 239, 213],\r\n\t\"peachpuff\": [255, 218, 185],\r\n\t\"peru\": [205, 133, 63],\r\n\t\"pink\": [255, 192, 203],\r\n\t\"plum\": [221, 160, 221],\r\n\t\"powderblue\": [176, 224, 230],\r\n\t\"purple\": [128, 0, 128],\r\n\t\"rebeccapurple\": [102, 51, 153],\r\n\t\"red\": [255, 0, 0],\r\n\t\"rosybrown\": [188, 143, 143],\r\n\t\"royalblue\": [65, 105, 225],\r\n\t\"saddlebrown\": [139, 69, 19],\r\n\t\"salmon\": [250, 128, 114],\r\n\t\"sandybrown\": [244, 164, 96],\r\n\t\"seagreen\": [46, 139, 87],\r\n\t\"seashell\": [255, 245, 238],\r\n\t\"sienna\": [160, 82, 45],\r\n\t\"silver\": [192, 192, 192],\r\n\t\"skyblue\": [135, 206, 235],\r\n\t\"slateblue\": [106, 90, 205],\r\n\t\"slategray\": [112, 128, 144],\r\n\t\"slategrey\": [112, 128, 144],\r\n\t\"snow\": [255, 250, 250],\r\n\t\"springgreen\": [0, 255, 127],\r\n\t\"steelblue\": [70, 130, 180],\r\n\t\"tan\": [210, 180, 140],\r\n\t\"teal\": [0, 128, 128],\r\n\t\"thistle\": [216, 191, 216],\r\n\t\"tomato\": [255, 99, 71],\r\n\t\"turquoise\": [64, 224, 208],\r\n\t\"violet\": [238, 130, 238],\r\n\t\"wheat\": [245, 222, 179],\r\n\t\"white\": [255, 255, 255],\r\n\t\"whitesmoke\": [245, 245, 245],\r\n\t\"yellow\": [255, 255, 0],\r\n\t\"yellowgreen\": [154, 205, 50]\r\n};\n\n/* MIT license */\n\n\nvar colorString = {\n getRgba: getRgba,\n getHsla: getHsla,\n getRgb: getRgb,\n getHsl: getHsl,\n getHwb: getHwb,\n getAlpha: getAlpha,\n\n hexString: hexString,\n rgbString: rgbString,\n rgbaString: rgbaString,\n percentString: percentString,\n percentaString: percentaString,\n hslString: hslString,\n hslaString: hslaString,\n hwbString: hwbString,\n keyword: keyword\n};\n\nfunction getRgba(string) {\n if (!string) {\n return;\n }\n var abbr = /^#([a-fA-F0-9]{3,4})$/i,\n hex = /^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i,\n rgba = /^rgba?\\(\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)$/i,\n per = /^rgba?\\(\\s*([+-]?[\\d\\.]+)\\%\\s*,\\s*([+-]?[\\d\\.]+)\\%\\s*,\\s*([+-]?[\\d\\.]+)\\%\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)$/i,\n keyword = /(\\w+)/;\n\n var rgb = [0, 0, 0],\n a = 1,\n match = string.match(abbr),\n hexAlpha = \"\";\n if (match) {\n match = match[1];\n hexAlpha = match[3];\n for (var i = 0; i < rgb.length; i++) {\n rgb[i] = parseInt(match[i] + match[i], 16);\n }\n if (hexAlpha) {\n a = Math.round((parseInt(hexAlpha + hexAlpha, 16) / 255) * 100) / 100;\n }\n }\n else if (match = string.match(hex)) {\n hexAlpha = match[2];\n match = match[1];\n for (var i = 0; i < rgb.length; i++) {\n rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16);\n }\n if (hexAlpha) {\n a = Math.round((parseInt(hexAlpha, 16) / 255) * 100) / 100;\n }\n }\n else if (match = string.match(rgba)) {\n for (var i = 0; i < rgb.length; i++) {\n rgb[i] = parseInt(match[i + 1]);\n }\n a = parseFloat(match[4]);\n }\n else if (match = string.match(per)) {\n for (var i = 0; i < rgb.length; i++) {\n rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);\n }\n a = parseFloat(match[4]);\n }\n else if (match = string.match(keyword)) {\n if (match[1] == \"transparent\") {\n return [0, 0, 0, 0];\n }\n rgb = colorName$1[match[1]];\n if (!rgb) {\n return;\n }\n }\n\n for (var i = 0; i < rgb.length; i++) {\n rgb[i] = scale(rgb[i], 0, 255);\n }\n if (!a && a != 0) {\n a = 1;\n }\n else {\n a = scale(a, 0, 1);\n }\n rgb[3] = a;\n return rgb;\n}\n\nfunction getHsla(string) {\n if (!string) {\n return;\n }\n var hsl = /^hsla?\\(\\s*([+-]?\\d+)(?:deg)?\\s*,\\s*([+-]?[\\d\\.]+)%\\s*,\\s*([+-]?[\\d\\.]+)%\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)/;\n var match = string.match(hsl);\n if (match) {\n var alpha = parseFloat(match[4]);\n var h = scale(parseInt(match[1]), 0, 360),\n s = scale(parseFloat(match[2]), 0, 100),\n l = scale(parseFloat(match[3]), 0, 100),\n a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);\n return [h, s, l, a];\n }\n}\n\nfunction getHwb(string) {\n if (!string) {\n return;\n }\n var hwb = /^hwb\\(\\s*([+-]?\\d+)(?:deg)?\\s*,\\s*([+-]?[\\d\\.]+)%\\s*,\\s*([+-]?[\\d\\.]+)%\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)/;\n var match = string.match(hwb);\n if (match) {\n var alpha = parseFloat(match[4]);\n var h = scale(parseInt(match[1]), 0, 360),\n w = scale(parseFloat(match[2]), 0, 100),\n b = scale(parseFloat(match[3]), 0, 100),\n a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);\n return [h, w, b, a];\n }\n}\n\nfunction getRgb(string) {\n var rgba = getRgba(string);\n return rgba && rgba.slice(0, 3);\n}\n\nfunction getHsl(string) {\n var hsla = getHsla(string);\n return hsla && hsla.slice(0, 3);\n}\n\nfunction getAlpha(string) {\n var vals = getRgba(string);\n if (vals) {\n return vals[3];\n }\n else if (vals = getHsla(string)) {\n return vals[3];\n }\n else if (vals = getHwb(string)) {\n return vals[3];\n }\n}\n\n// generators\nfunction hexString(rgba, a) {\n var a = (a !== undefined && rgba.length === 3) ? a : rgba[3];\n return \"#\" + hexDouble(rgba[0]) \n + hexDouble(rgba[1])\n + hexDouble(rgba[2])\n + (\n (a >= 0 && a < 1)\n ? hexDouble(Math.round(a * 255))\n : \"\"\n );\n}\n\nfunction rgbString(rgba, alpha) {\n if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {\n return rgbaString(rgba, alpha);\n }\n return \"rgb(\" + rgba[0] + \", \" + rgba[1] + \", \" + rgba[2] + \")\";\n}\n\nfunction rgbaString(rgba, alpha) {\n if (alpha === undefined) {\n alpha = (rgba[3] !== undefined ? rgba[3] : 1);\n }\n return \"rgba(\" + rgba[0] + \", \" + rgba[1] + \", \" + rgba[2]\n + \", \" + alpha + \")\";\n}\n\nfunction percentString(rgba, alpha) {\n if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {\n return percentaString(rgba, alpha);\n }\n var r = Math.round(rgba[0]/255 * 100),\n g = Math.round(rgba[1]/255 * 100),\n b = Math.round(rgba[2]/255 * 100);\n\n return \"rgb(\" + r + \"%, \" + g + \"%, \" + b + \"%)\";\n}\n\nfunction percentaString(rgba, alpha) {\n var r = Math.round(rgba[0]/255 * 100),\n g = Math.round(rgba[1]/255 * 100),\n b = Math.round(rgba[2]/255 * 100);\n return \"rgba(\" + r + \"%, \" + g + \"%, \" + b + \"%, \" + (alpha || rgba[3] || 1) + \")\";\n}\n\nfunction hslString(hsla, alpha) {\n if (alpha < 1 || (hsla[3] && hsla[3] < 1)) {\n return hslaString(hsla, alpha);\n }\n return \"hsl(\" + hsla[0] + \", \" + hsla[1] + \"%, \" + hsla[2] + \"%)\";\n}\n\nfunction hslaString(hsla, alpha) {\n if (alpha === undefined) {\n alpha = (hsla[3] !== undefined ? hsla[3] : 1);\n }\n return \"hsla(\" + hsla[0] + \", \" + hsla[1] + \"%, \" + hsla[2] + \"%, \"\n + alpha + \")\";\n}\n\n// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax\n// (hwb have alpha optional & 1 is default value)\nfunction hwbString(hwb, alpha) {\n if (alpha === undefined) {\n alpha = (hwb[3] !== undefined ? hwb[3] : 1);\n }\n return \"hwb(\" + hwb[0] + \", \" + hwb[1] + \"%, \" + hwb[2] + \"%\"\n + (alpha !== undefined && alpha !== 1 ? \", \" + alpha : \"\") + \")\";\n}\n\nfunction keyword(rgb) {\n return reverseNames[rgb.slice(0, 3)];\n}\n\n// helpers\nfunction scale(num, min, max) {\n return Math.min(Math.max(min, num), max);\n}\n\nfunction hexDouble(num) {\n var str = num.toString(16).toUpperCase();\n return (str.length < 2) ? \"0\" + str : str;\n}\n\n\n//create a list of reverse color names\nvar reverseNames = {};\nfor (var name in colorName$1) {\n reverseNames[colorName$1[name]] = name;\n}\n\n/* MIT license */\n\n\n\nvar Color = function (obj) {\n\tif (obj instanceof Color) {\n\t\treturn obj;\n\t}\n\tif (!(this instanceof Color)) {\n\t\treturn new Color(obj);\n\t}\n\n\tthis.valid = false;\n\tthis.values = {\n\t\trgb: [0, 0, 0],\n\t\thsl: [0, 0, 0],\n\t\thsv: [0, 0, 0],\n\t\thwb: [0, 0, 0],\n\t\tcmyk: [0, 0, 0, 0],\n\t\talpha: 1\n\t};\n\n\t// parse Color() argument\n\tvar vals;\n\tif (typeof obj === 'string') {\n\t\tvals = colorString.getRgba(obj);\n\t\tif (vals) {\n\t\t\tthis.setValues('rgb', vals);\n\t\t} else if (vals = colorString.getHsla(obj)) {\n\t\t\tthis.setValues('hsl', vals);\n\t\t} else if (vals = colorString.getHwb(obj)) {\n\t\t\tthis.setValues('hwb', vals);\n\t\t}\n\t} else if (typeof obj === 'object') {\n\t\tvals = obj;\n\t\tif (vals.r !== undefined || vals.red !== undefined) {\n\t\t\tthis.setValues('rgb', vals);\n\t\t} else if (vals.l !== undefined || vals.lightness !== undefined) {\n\t\t\tthis.setValues('hsl', vals);\n\t\t} else if (vals.v !== undefined || vals.value !== undefined) {\n\t\t\tthis.setValues('hsv', vals);\n\t\t} else if (vals.w !== undefined || vals.whiteness !== undefined) {\n\t\t\tthis.setValues('hwb', vals);\n\t\t} else if (vals.c !== undefined || vals.cyan !== undefined) {\n\t\t\tthis.setValues('cmyk', vals);\n\t\t}\n\t}\n};\n\nColor.prototype = {\n\tisValid: function () {\n\t\treturn this.valid;\n\t},\n\trgb: function () {\n\t\treturn this.setSpace('rgb', arguments);\n\t},\n\thsl: function () {\n\t\treturn this.setSpace('hsl', arguments);\n\t},\n\thsv: function () {\n\t\treturn this.setSpace('hsv', arguments);\n\t},\n\thwb: function () {\n\t\treturn this.setSpace('hwb', arguments);\n\t},\n\tcmyk: function () {\n\t\treturn this.setSpace('cmyk', arguments);\n\t},\n\n\trgbArray: function () {\n\t\treturn this.values.rgb;\n\t},\n\thslArray: function () {\n\t\treturn this.values.hsl;\n\t},\n\thsvArray: function () {\n\t\treturn this.values.hsv;\n\t},\n\thwbArray: function () {\n\t\tvar values = this.values;\n\t\tif (values.alpha !== 1) {\n\t\t\treturn values.hwb.concat([values.alpha]);\n\t\t}\n\t\treturn values.hwb;\n\t},\n\tcmykArray: function () {\n\t\treturn this.values.cmyk;\n\t},\n\trgbaArray: function () {\n\t\tvar values = this.values;\n\t\treturn values.rgb.concat([values.alpha]);\n\t},\n\thslaArray: function () {\n\t\tvar values = this.values;\n\t\treturn values.hsl.concat([values.alpha]);\n\t},\n\talpha: function (val) {\n\t\tif (val === undefined) {\n\t\t\treturn this.values.alpha;\n\t\t}\n\t\tthis.setValues('alpha', val);\n\t\treturn this;\n\t},\n\n\tred: function (val) {\n\t\treturn this.setChannel('rgb', 0, val);\n\t},\n\tgreen: function (val) {\n\t\treturn this.setChannel('rgb', 1, val);\n\t},\n\tblue: function (val) {\n\t\treturn this.setChannel('rgb', 2, val);\n\t},\n\thue: function (val) {\n\t\tif (val) {\n\t\t\tval %= 360;\n\t\t\tval = val < 0 ? 360 + val : val;\n\t\t}\n\t\treturn this.setChannel('hsl', 0, val);\n\t},\n\tsaturation: function (val) {\n\t\treturn this.setChannel('hsl', 1, val);\n\t},\n\tlightness: function (val) {\n\t\treturn this.setChannel('hsl', 2, val);\n\t},\n\tsaturationv: function (val) {\n\t\treturn this.setChannel('hsv', 1, val);\n\t},\n\twhiteness: function (val) {\n\t\treturn this.setChannel('hwb', 1, val);\n\t},\n\tblackness: function (val) {\n\t\treturn this.setChannel('hwb', 2, val);\n\t},\n\tvalue: function (val) {\n\t\treturn this.setChannel('hsv', 2, val);\n\t},\n\tcyan: function (val) {\n\t\treturn this.setChannel('cmyk', 0, val);\n\t},\n\tmagenta: function (val) {\n\t\treturn this.setChannel('cmyk', 1, val);\n\t},\n\tyellow: function (val) {\n\t\treturn this.setChannel('cmyk', 2, val);\n\t},\n\tblack: function (val) {\n\t\treturn this.setChannel('cmyk', 3, val);\n\t},\n\n\thexString: function () {\n\t\treturn colorString.hexString(this.values.rgb);\n\t},\n\trgbString: function () {\n\t\treturn colorString.rgbString(this.values.rgb, this.values.alpha);\n\t},\n\trgbaString: function () {\n\t\treturn colorString.rgbaString(this.values.rgb, this.values.alpha);\n\t},\n\tpercentString: function () {\n\t\treturn colorString.percentString(this.values.rgb, this.values.alpha);\n\t},\n\thslString: function () {\n\t\treturn colorString.hslString(this.values.hsl, this.values.alpha);\n\t},\n\thslaString: function () {\n\t\treturn colorString.hslaString(this.values.hsl, this.values.alpha);\n\t},\n\thwbString: function () {\n\t\treturn colorString.hwbString(this.values.hwb, this.values.alpha);\n\t},\n\tkeyword: function () {\n\t\treturn colorString.keyword(this.values.rgb, this.values.alpha);\n\t},\n\n\trgbNumber: function () {\n\t\tvar rgb = this.values.rgb;\n\t\treturn (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];\n\t},\n\n\tluminosity: function () {\n\t\t// http://www.w3.org/TR/WCAG20/#relativeluminancedef\n\t\tvar rgb = this.values.rgb;\n\t\tvar lum = [];\n\t\tfor (var i = 0; i < rgb.length; i++) {\n\t\t\tvar chan = rgb[i] / 255;\n\t\t\tlum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4);\n\t\t}\n\t\treturn 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];\n\t},\n\n\tcontrast: function (color2) {\n\t\t// http://www.w3.org/TR/WCAG20/#contrast-ratiodef\n\t\tvar lum1 = this.luminosity();\n\t\tvar lum2 = color2.luminosity();\n\t\tif (lum1 > lum2) {\n\t\t\treturn (lum1 + 0.05) / (lum2 + 0.05);\n\t\t}\n\t\treturn (lum2 + 0.05) / (lum1 + 0.05);\n\t},\n\n\tlevel: function (color2) {\n\t\tvar contrastRatio = this.contrast(color2);\n\t\tif (contrastRatio >= 7.1) {\n\t\t\treturn 'AAA';\n\t\t}\n\n\t\treturn (contrastRatio >= 4.5) ? 'AA' : '';\n\t},\n\n\tdark: function () {\n\t\t// YIQ equation from http://24ways.org/2010/calculating-color-contrast\n\t\tvar rgb = this.values.rgb;\n\t\tvar yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;\n\t\treturn yiq < 128;\n\t},\n\n\tlight: function () {\n\t\treturn !this.dark();\n\t},\n\n\tnegate: function () {\n\t\tvar rgb = [];\n\t\tfor (var i = 0; i < 3; i++) {\n\t\t\trgb[i] = 255 - this.values.rgb[i];\n\t\t}\n\t\tthis.setValues('rgb', rgb);\n\t\treturn this;\n\t},\n\n\tlighten: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[2] += hsl[2] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\tdarken: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[2] -= hsl[2] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\tsaturate: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[1] += hsl[1] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\tdesaturate: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[1] -= hsl[1] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\twhiten: function (ratio) {\n\t\tvar hwb = this.values.hwb;\n\t\thwb[1] += hwb[1] * ratio;\n\t\tthis.setValues('hwb', hwb);\n\t\treturn this;\n\t},\n\n\tblacken: function (ratio) {\n\t\tvar hwb = this.values.hwb;\n\t\thwb[2] += hwb[2] * ratio;\n\t\tthis.setValues('hwb', hwb);\n\t\treturn this;\n\t},\n\n\tgreyscale: function () {\n\t\tvar rgb = this.values.rgb;\n\t\t// http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale\n\t\tvar val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;\n\t\tthis.setValues('rgb', [val, val, val]);\n\t\treturn this;\n\t},\n\n\tclearer: function (ratio) {\n\t\tvar alpha = this.values.alpha;\n\t\tthis.setValues('alpha', alpha - (alpha * ratio));\n\t\treturn this;\n\t},\n\n\topaquer: function (ratio) {\n\t\tvar alpha = this.values.alpha;\n\t\tthis.setValues('alpha', alpha + (alpha * ratio));\n\t\treturn this;\n\t},\n\n\trotate: function (degrees) {\n\t\tvar hsl = this.values.hsl;\n\t\tvar hue = (hsl[0] + degrees) % 360;\n\t\thsl[0] = hue < 0 ? 360 + hue : hue;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\t/**\n\t * Ported from sass implementation in C\n\t * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209\n\t */\n\tmix: function (mixinColor, weight) {\n\t\tvar color1 = this;\n\t\tvar color2 = mixinColor;\n\t\tvar p = weight === undefined ? 0.5 : weight;\n\n\t\tvar w = 2 * p - 1;\n\t\tvar a = color1.alpha() - color2.alpha();\n\n\t\tvar w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;\n\t\tvar w2 = 1 - w1;\n\n\t\treturn this\n\t\t\t.rgb(\n\t\t\t\tw1 * color1.red() + w2 * color2.red(),\n\t\t\t\tw1 * color1.green() + w2 * color2.green(),\n\t\t\t\tw1 * color1.blue() + w2 * color2.blue()\n\t\t\t)\n\t\t\t.alpha(color1.alpha() * p + color2.alpha() * (1 - p));\n\t},\n\n\ttoJSON: function () {\n\t\treturn this.rgb();\n\t},\n\n\tclone: function () {\n\t\t// NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,\n\t\t// making the final build way to big to embed in Chart.js. So let's do it manually,\n\t\t// assuming that values to clone are 1 dimension arrays containing only numbers,\n\t\t// except 'alpha' which is a number.\n\t\tvar result = new Color();\n\t\tvar source = this.values;\n\t\tvar target = result.values;\n\t\tvar value, type;\n\n\t\tfor (var prop in source) {\n\t\t\tif (source.hasOwnProperty(prop)) {\n\t\t\t\tvalue = source[prop];\n\t\t\t\ttype = ({}).toString.call(value);\n\t\t\t\tif (type === '[object Array]') {\n\t\t\t\t\ttarget[prop] = value.slice(0);\n\t\t\t\t} else if (type === '[object Number]') {\n\t\t\t\t\ttarget[prop] = value;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error('unexpected color value:', value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n};\n\nColor.prototype.spaces = {\n\trgb: ['red', 'green', 'blue'],\n\thsl: ['hue', 'saturation', 'lightness'],\n\thsv: ['hue', 'saturation', 'value'],\n\thwb: ['hue', 'whiteness', 'blackness'],\n\tcmyk: ['cyan', 'magenta', 'yellow', 'black']\n};\n\nColor.prototype.maxes = {\n\trgb: [255, 255, 255],\n\thsl: [360, 100, 100],\n\thsv: [360, 100, 100],\n\thwb: [360, 100, 100],\n\tcmyk: [100, 100, 100, 100]\n};\n\nColor.prototype.getValues = function (space) {\n\tvar values = this.values;\n\tvar vals = {};\n\n\tfor (var i = 0; i < space.length; i++) {\n\t\tvals[space.charAt(i)] = values[space][i];\n\t}\n\n\tif (values.alpha !== 1) {\n\t\tvals.a = values.alpha;\n\t}\n\n\t// {r: 255, g: 255, b: 255, a: 0.4}\n\treturn vals;\n};\n\nColor.prototype.setValues = function (space, vals) {\n\tvar values = this.values;\n\tvar spaces = this.spaces;\n\tvar maxes = this.maxes;\n\tvar alpha = 1;\n\tvar i;\n\n\tthis.valid = true;\n\n\tif (space === 'alpha') {\n\t\talpha = vals;\n\t} else if (vals.length) {\n\t\t// [10, 10, 10]\n\t\tvalues[space] = vals.slice(0, space.length);\n\t\talpha = vals[space.length];\n\t} else if (vals[space.charAt(0)] !== undefined) {\n\t\t// {r: 10, g: 10, b: 10}\n\t\tfor (i = 0; i < space.length; i++) {\n\t\t\tvalues[space][i] = vals[space.charAt(i)];\n\t\t}\n\n\t\talpha = vals.a;\n\t} else if (vals[spaces[space][0]] !== undefined) {\n\t\t// {red: 10, green: 10, blue: 10}\n\t\tvar chans = spaces[space];\n\n\t\tfor (i = 0; i < space.length; i++) {\n\t\t\tvalues[space][i] = vals[chans[i]];\n\t\t}\n\n\t\talpha = vals.alpha;\n\t}\n\n\tvalues.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));\n\n\tif (space === 'alpha') {\n\t\treturn false;\n\t}\n\n\tvar capped;\n\n\t// cap values of the space prior converting all values\n\tfor (i = 0; i < space.length; i++) {\n\t\tcapped = Math.max(0, Math.min(maxes[space][i], values[space][i]));\n\t\tvalues[space][i] = Math.round(capped);\n\t}\n\n\t// convert to all the other color spaces\n\tfor (var sname in spaces) {\n\t\tif (sname !== space) {\n\t\t\tvalues[sname] = colorConvert[space][sname](values[space]);\n\t\t}\n\t}\n\n\treturn true;\n};\n\nColor.prototype.setSpace = function (space, args) {\n\tvar vals = args[0];\n\n\tif (vals === undefined) {\n\t\t// color.rgb()\n\t\treturn this.getValues(space);\n\t}\n\n\t// color.rgb(10, 10, 10)\n\tif (typeof vals === 'number') {\n\t\tvals = Array.prototype.slice.call(args);\n\t}\n\n\tthis.setValues(space, vals);\n\treturn this;\n};\n\nColor.prototype.setChannel = function (space, index, val) {\n\tvar svalues = this.values[space];\n\tif (val === undefined) {\n\t\t// color.red()\n\t\treturn svalues[index];\n\t} else if (val === svalues[index]) {\n\t\t// color.red(color.red())\n\t\treturn this;\n\t}\n\n\t// color.red(100)\n\tsvalues[index] = val;\n\tthis.setValues(space, svalues);\n\n\treturn this;\n};\n\nif (typeof window !== 'undefined') {\n\twindow.Color = Color;\n}\n\nvar chartjsColor = Color;\n\n/**\n * @namespace Chart.helpers\n */\nvar helpers = {\n\t/**\n\t * An empty function that can be used, for example, for optional callback.\n\t */\n\tnoop: function() {},\n\n\t/**\n\t * Returns a unique id, sequentially generated from a global variable.\n\t * @returns {number}\n\t * @function\n\t */\n\tuid: (function() {\n\t\tvar id = 0;\n\t\treturn function() {\n\t\t\treturn id++;\n\t\t};\n\t}()),\n\n\t/**\n\t * Returns true if `value` is neither null nor undefined, else returns false.\n\t * @param {*} value - The value to test.\n\t * @returns {boolean}\n\t * @since 2.7.0\n\t */\n\tisNullOrUndef: function(value) {\n\t\treturn value === null || typeof value === 'undefined';\n\t},\n\n\t/**\n\t * Returns true if `value` is an array (including typed arrays), else returns false.\n\t * @param {*} value - The value to test.\n\t * @returns {boolean}\n\t * @function\n\t */\n\tisArray: function(value) {\n\t\tif (Array.isArray && Array.isArray(value)) {\n\t\t\treturn true;\n\t\t}\n\t\tvar type = Object.prototype.toString.call(value);\n\t\tif (type.substr(0, 7) === '[object' && type.substr(-6) === 'Array]') {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t},\n\n\t/**\n\t * Returns true if `value` is an object (excluding null), else returns false.\n\t * @param {*} value - The value to test.\n\t * @returns {boolean}\n\t * @since 2.7.0\n\t */\n\tisObject: function(value) {\n\t\treturn value !== null && Object.prototype.toString.call(value) === '[object Object]';\n\t},\n\n\t/**\n\t * Returns true if `value` is a finite number, else returns false\n\t * @param {*} value - The value to test.\n\t * @returns {boolean}\n\t */\n\tisFinite: function(value) {\n\t\treturn (typeof value === 'number' || value instanceof Number) && isFinite(value);\n\t},\n\n\t/**\n\t * Returns `value` if defined, else returns `defaultValue`.\n\t * @param {*} value - The value to return if defined.\n\t * @param {*} defaultValue - The value to return if `value` is undefined.\n\t * @returns {*}\n\t */\n\tvalueOrDefault: function(value, defaultValue) {\n\t\treturn typeof value === 'undefined' ? defaultValue : value;\n\t},\n\n\t/**\n\t * Returns value at the given `index` in array if defined, else returns `defaultValue`.\n\t * @param {Array} value - The array to lookup for value at `index`.\n\t * @param {number} index - The index in `value` to lookup for value.\n\t * @param {*} defaultValue - The value to return if `value[index]` is undefined.\n\t * @returns {*}\n\t */\n\tvalueAtIndexOrDefault: function(value, index, defaultValue) {\n\t\treturn helpers.valueOrDefault(helpers.isArray(value) ? value[index] : value, defaultValue);\n\t},\n\n\t/**\n\t * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the\n\t * value returned by `fn`. If `fn` is not a function, this method returns undefined.\n\t * @param {function} fn - The function to call.\n\t * @param {Array|undefined|null} args - The arguments with which `fn` should be called.\n\t * @param {object} [thisArg] - The value of `this` provided for the call to `fn`.\n\t * @returns {*}\n\t */\n\tcallback: function(fn, args, thisArg) {\n\t\tif (fn && typeof fn.call === 'function') {\n\t\t\treturn fn.apply(thisArg, args);\n\t\t}\n\t},\n\n\t/**\n\t * Note(SB) for performance sake, this method should only be used when loopable type\n\t * is unknown or in none intensive code (not called often and small loopable). Else\n\t * it's preferable to use a regular for() loop and save extra function calls.\n\t * @param {object|Array} loopable - The object or array to be iterated.\n\t * @param {function} fn - The function to call for each item.\n\t * @param {object} [thisArg] - The value of `this` provided for the call to `fn`.\n\t * @param {boolean} [reverse] - If true, iterates backward on the loopable.\n\t */\n\teach: function(loopable, fn, thisArg, reverse) {\n\t\tvar i, len, keys;\n\t\tif (helpers.isArray(loopable)) {\n\t\t\tlen = loopable.length;\n\t\t\tif (reverse) {\n\t\t\t\tfor (i = len - 1; i >= 0; i--) {\n\t\t\t\t\tfn.call(thisArg, loopable[i], i);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\t\tfn.call(thisArg, loopable[i], i);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (helpers.isObject(loopable)) {\n\t\t\tkeys = Object.keys(loopable);\n\t\t\tlen = keys.length;\n\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\tfn.call(thisArg, loopable[keys[i]], keys[i]);\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Returns true if the `a0` and `a1` arrays have the same content, else returns false.\n\t * @see https://stackoverflow.com/a/14853974\n\t * @param {Array} a0 - The array to compare\n\t * @param {Array} a1 - The array to compare\n\t * @returns {boolean}\n\t */\n\tarrayEquals: function(a0, a1) {\n\t\tvar i, ilen, v0, v1;\n\n\t\tif (!a0 || !a1 || a0.length !== a1.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (i = 0, ilen = a0.length; i < ilen; ++i) {\n\t\t\tv0 = a0[i];\n\t\t\tv1 = a1[i];\n\n\t\t\tif (v0 instanceof Array && v1 instanceof Array) {\n\t\t\t\tif (!helpers.arrayEquals(v0, v1)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else if (v0 !== v1) {\n\t\t\t\t// NOTE: two different object instances will never be equal: {x:20} != {x:20}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t},\n\n\t/**\n\t * Returns a deep copy of `source` without keeping references on objects and arrays.\n\t * @param {*} source - The value to clone.\n\t * @returns {*}\n\t */\n\tclone: function(source) {\n\t\tif (helpers.isArray(source)) {\n\t\t\treturn source.map(helpers.clone);\n\t\t}\n\n\t\tif (helpers.isObject(source)) {\n\t\t\tvar target = {};\n\t\t\tvar keys = Object.keys(source);\n\t\t\tvar klen = keys.length;\n\t\t\tvar k = 0;\n\n\t\t\tfor (; k < klen; ++k) {\n\t\t\t\ttarget[keys[k]] = helpers.clone(source[keys[k]]);\n\t\t\t}\n\n\t\t\treturn target;\n\t\t}\n\n\t\treturn source;\n\t},\n\n\t/**\n\t * The default merger when Chart.helpers.merge is called without merger option.\n\t * Note(SB): also used by mergeConfig and mergeScaleConfig as fallback.\n\t * @private\n\t */\n\t_merger: function(key, target, source, options) {\n\t\tvar tval = target[key];\n\t\tvar sval = source[key];\n\n\t\tif (helpers.isObject(tval) && helpers.isObject(sval)) {\n\t\t\thelpers.merge(tval, sval, options);\n\t\t} else {\n\t\t\ttarget[key] = helpers.clone(sval);\n\t\t}\n\t},\n\n\t/**\n\t * Merges source[key] in target[key] only if target[key] is undefined.\n\t * @private\n\t */\n\t_mergerIf: function(key, target, source) {\n\t\tvar tval = target[key];\n\t\tvar sval = source[key];\n\n\t\tif (helpers.isObject(tval) && helpers.isObject(sval)) {\n\t\t\thelpers.mergeIf(tval, sval);\n\t\t} else if (!target.hasOwnProperty(key)) {\n\t\t\ttarget[key] = helpers.clone(sval);\n\t\t}\n\t},\n\n\t/**\n\t * Recursively deep copies `source` properties into `target` with the given `options`.\n\t * IMPORTANT: `target` is not cloned and will be updated with `source` properties.\n\t * @param {object} target - The target object in which all sources are merged into.\n\t * @param {object|object[]} source - Object(s) to merge into `target`.\n\t * @param {object} [options] - Merging options:\n\t * @param {function} [options.merger] - The merge method (key, target, source, options)\n\t * @returns {object} The `target` object.\n\t */\n\tmerge: function(target, source, options) {\n\t\tvar sources = helpers.isArray(source) ? source : [source];\n\t\tvar ilen = sources.length;\n\t\tvar merge, i, keys, klen, k;\n\n\t\tif (!helpers.isObject(target)) {\n\t\t\treturn target;\n\t\t}\n\n\t\toptions = options || {};\n\t\tmerge = options.merger || helpers._merger;\n\n\t\tfor (i = 0; i < ilen; ++i) {\n\t\t\tsource = sources[i];\n\t\t\tif (!helpers.isObject(source)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tkeys = Object.keys(source);\n\t\t\tfor (k = 0, klen = keys.length; k < klen; ++k) {\n\t\t\t\tmerge(keys[k], target, source, options);\n\t\t\t}\n\t\t}\n\n\t\treturn target;\n\t},\n\n\t/**\n\t * Recursively deep copies `source` properties into `target` *only* if not defined in target.\n\t * IMPORTANT: `target` is not cloned and will be updated with `source` properties.\n\t * @param {object} target - The target object in which all sources are merged into.\n\t * @param {object|object[]} source - Object(s) to merge into `target`.\n\t * @returns {object} The `target` object.\n\t */\n\tmergeIf: function(target, source) {\n\t\treturn helpers.merge(target, source, {merger: helpers._mergerIf});\n\t},\n\n\t/**\n\t * Applies the contents of two or more objects together into the first object.\n\t * @param {object} target - The target object in which all objects are merged into.\n\t * @param {object} arg1 - Object containing additional properties to merge in target.\n\t * @param {object} argN - Additional objects containing properties to merge in target.\n\t * @returns {object} The `target` object.\n\t */\n\textend: Object.assign || function(target) {\n\t\treturn helpers.merge(target, [].slice.call(arguments, 1), {\n\t\t\tmerger: function(key, dst, src) {\n\t\t\t\tdst[key] = src[key];\n\t\t\t}\n\t\t});\n\t},\n\n\t/**\n\t * Basic javascript inheritance based on the model created in Backbone.js\n\t */\n\tinherits: function(extensions) {\n\t\tvar me = this;\n\t\tvar ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() {\n\t\t\treturn me.apply(this, arguments);\n\t\t};\n\n\t\tvar Surrogate = function() {\n\t\t\tthis.constructor = ChartElement;\n\t\t};\n\n\t\tSurrogate.prototype = me.prototype;\n\t\tChartElement.prototype = new Surrogate();\n\t\tChartElement.extend = helpers.inherits;\n\n\t\tif (extensions) {\n\t\t\thelpers.extend(ChartElement.prototype, extensions);\n\t\t}\n\n\t\tChartElement.__super__ = me.prototype;\n\t\treturn ChartElement;\n\t},\n\n\t_deprecated: function(scope, value, previous, current) {\n\t\tif (value !== undefined) {\n\t\t\tconsole.warn(scope + ': \"' + previous +\n\t\t\t\t'\" is deprecated. Please use \"' + current + '\" instead');\n\t\t}\n\t}\n};\n\nvar helpers_core = helpers;\n\n// DEPRECATIONS\n\n/**\n * Provided for backward compatibility, use Chart.helpers.callback instead.\n * @function Chart.helpers.callCallback\n * @deprecated since version 2.6.0\n * @todo remove at version 3\n * @private\n */\nhelpers.callCallback = helpers.callback;\n\n/**\n * Provided for backward compatibility, use Array.prototype.indexOf instead.\n * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+\n * @function Chart.helpers.indexOf\n * @deprecated since version 2.7.0\n * @todo remove at version 3\n * @private\n */\nhelpers.indexOf = function(array, item, fromIndex) {\n\treturn Array.prototype.indexOf.call(array, item, fromIndex);\n};\n\n/**\n * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead.\n * @function Chart.helpers.getValueOrDefault\n * @deprecated since version 2.7.0\n * @todo remove at version 3\n * @private\n */\nhelpers.getValueOrDefault = helpers.valueOrDefault;\n\n/**\n * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead.\n * @function Chart.helpers.getValueAtIndexOrDefault\n * @deprecated since version 2.7.0\n * @todo remove at version 3\n * @private\n */\nhelpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault;\n\n/**\n * Easing functions adapted from Robert Penner's easing equations.\n * @namespace Chart.helpers.easingEffects\n * @see http://www.robertpenner.com/easing/\n */\nvar effects = {\n\tlinear: function(t) {\n\t\treturn t;\n\t},\n\n\teaseInQuad: function(t) {\n\t\treturn t * t;\n\t},\n\n\teaseOutQuad: function(t) {\n\t\treturn -t * (t - 2);\n\t},\n\n\teaseInOutQuad: function(t) {\n\t\tif ((t /= 0.5) < 1) {\n\t\t\treturn 0.5 * t * t;\n\t\t}\n\t\treturn -0.5 * ((--t) * (t - 2) - 1);\n\t},\n\n\teaseInCubic: function(t) {\n\t\treturn t * t * t;\n\t},\n\n\teaseOutCubic: function(t) {\n\t\treturn (t = t - 1) * t * t + 1;\n\t},\n\n\teaseInOutCubic: function(t) {\n\t\tif ((t /= 0.5) < 1) {\n\t\t\treturn 0.5 * t * t * t;\n\t\t}\n\t\treturn 0.5 * ((t -= 2) * t * t + 2);\n\t},\n\n\teaseInQuart: function(t) {\n\t\treturn t * t * t * t;\n\t},\n\n\teaseOutQuart: function(t) {\n\t\treturn -((t = t - 1) * t * t * t - 1);\n\t},\n\n\teaseInOutQuart: function(t) {\n\t\tif ((t /= 0.5) < 1) {\n\t\t\treturn 0.5 * t * t * t * t;\n\t\t}\n\t\treturn -0.5 * ((t -= 2) * t * t * t - 2);\n\t},\n\n\teaseInQuint: function(t) {\n\t\treturn t * t * t * t * t;\n\t},\n\n\teaseOutQuint: function(t) {\n\t\treturn (t = t - 1) * t * t * t * t + 1;\n\t},\n\n\teaseInOutQuint: function(t) {\n\t\tif ((t /= 0.5) < 1) {\n\t\t\treturn 0.5 * t * t * t * t * t;\n\t\t}\n\t\treturn 0.5 * ((t -= 2) * t * t * t * t + 2);\n\t},\n\n\teaseInSine: function(t) {\n\t\treturn -Math.cos(t * (Math.PI / 2)) + 1;\n\t},\n\n\teaseOutSine: function(t) {\n\t\treturn Math.sin(t * (Math.PI / 2));\n\t},\n\n\teaseInOutSine: function(t) {\n\t\treturn -0.5 * (Math.cos(Math.PI * t) - 1);\n\t},\n\n\teaseInExpo: function(t) {\n\t\treturn (t === 0) ? 0 : Math.pow(2, 10 * (t - 1));\n\t},\n\n\teaseOutExpo: function(t) {\n\t\treturn (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1;\n\t},\n\n\teaseInOutExpo: function(t) {\n\t\tif (t === 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (t === 1) {\n\t\t\treturn 1;\n\t\t}\n\t\tif ((t /= 0.5) < 1) {\n\t\t\treturn 0.5 * Math.pow(2, 10 * (t - 1));\n\t\t}\n\t\treturn 0.5 * (-Math.pow(2, -10 * --t) + 2);\n\t},\n\n\teaseInCirc: function(t) {\n\t\tif (t >= 1) {\n\t\t\treturn t;\n\t\t}\n\t\treturn -(Math.sqrt(1 - t * t) - 1);\n\t},\n\n\teaseOutCirc: function(t) {\n\t\treturn Math.sqrt(1 - (t = t - 1) * t);\n\t},\n\n\teaseInOutCirc: function(t) {\n\t\tif ((t /= 0.5) < 1) {\n\t\t\treturn -0.5 * (Math.sqrt(1 - t * t) - 1);\n\t\t}\n\t\treturn 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1);\n\t},\n\n\teaseInElastic: function(t) {\n\t\tvar s = 1.70158;\n\t\tvar p = 0;\n\t\tvar a = 1;\n\t\tif (t === 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (t === 1) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (!p) {\n\t\t\tp = 0.3;\n\t\t}\n\t\tif (a < 1) {\n\t\t\ta = 1;\n\t\t\ts = p / 4;\n\t\t} else {\n\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t}\n\t\treturn -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));\n\t},\n\n\teaseOutElastic: function(t) {\n\t\tvar s = 1.70158;\n\t\tvar p = 0;\n\t\tvar a = 1;\n\t\tif (t === 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (t === 1) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (!p) {\n\t\t\tp = 0.3;\n\t\t}\n\t\tif (a < 1) {\n\t\t\ta = 1;\n\t\t\ts = p / 4;\n\t\t} else {\n\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t}\n\t\treturn a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p) + 1;\n\t},\n\n\teaseInOutElastic: function(t) {\n\t\tvar s = 1.70158;\n\t\tvar p = 0;\n\t\tvar a = 1;\n\t\tif (t === 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tif ((t /= 0.5) === 2) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (!p) {\n\t\t\tp = 0.45;\n\t\t}\n\t\tif (a < 1) {\n\t\t\ta = 1;\n\t\t\ts = p / 4;\n\t\t} else {\n\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t}\n\t\tif (t < 1) {\n\t\t\treturn -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));\n\t\t}\n\t\treturn a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p) * 0.5 + 1;\n\t},\n\teaseInBack: function(t) {\n\t\tvar s = 1.70158;\n\t\treturn t * t * ((s + 1) * t - s);\n\t},\n\n\teaseOutBack: function(t) {\n\t\tvar s = 1.70158;\n\t\treturn (t = t - 1) * t * ((s + 1) * t + s) + 1;\n\t},\n\n\teaseInOutBack: function(t) {\n\t\tvar s = 1.70158;\n\t\tif ((t /= 0.5) < 1) {\n\t\t\treturn 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s));\n\t\t}\n\t\treturn 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);\n\t},\n\n\teaseInBounce: function(t) {\n\t\treturn 1 - effects.easeOutBounce(1 - t);\n\t},\n\n\teaseOutBounce: function(t) {\n\t\tif (t < (1 / 2.75)) {\n\t\t\treturn 7.5625 * t * t;\n\t\t}\n\t\tif (t < (2 / 2.75)) {\n\t\t\treturn 7.5625 * (t -= (1.5 / 2.75)) * t + 0.75;\n\t\t}\n\t\tif (t < (2.5 / 2.75)) {\n\t\t\treturn 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375;\n\t\t}\n\t\treturn 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375;\n\t},\n\n\teaseInOutBounce: function(t) {\n\t\tif (t < 0.5) {\n\t\t\treturn effects.easeInBounce(t * 2) * 0.5;\n\t\t}\n\t\treturn effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5;\n\t}\n};\n\nvar helpers_easing = {\n\teffects: effects\n};\n\n// DEPRECATIONS\n\n/**\n * Provided for backward compatibility, use Chart.helpers.easing.effects instead.\n * @function Chart.helpers.easingEffects\n * @deprecated since version 2.7.0\n * @todo remove at version 3\n * @private\n */\nhelpers_core.easingEffects = effects;\n\nvar PI = Math.PI;\nvar RAD_PER_DEG = PI / 180;\nvar DOUBLE_PI = PI * 2;\nvar HALF_PI = PI / 2;\nvar QUARTER_PI = PI / 4;\nvar TWO_THIRDS_PI = PI * 2 / 3;\n\n/**\n * @namespace Chart.helpers.canvas\n */\nvar exports$1 = {\n\t/**\n\t * Clears the entire canvas associated to the given `chart`.\n\t * @param {Chart} chart - The chart for which to clear the canvas.\n\t */\n\tclear: function(chart) {\n\t\tchart.ctx.clearRect(0, 0, chart.width, chart.height);\n\t},\n\n\t/**\n\t * Creates a \"path\" for a rectangle with rounded corners at position (x, y) with a\n\t * given size (width, height) and the same `radius` for all corners.\n\t * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context.\n\t * @param {number} x - The x axis of the coordinate for the rectangle starting point.\n\t * @param {number} y - The y axis of the coordinate for the rectangle starting point.\n\t * @param {number} width - The rectangle's width.\n\t * @param {number} height - The rectangle's height.\n\t * @param {number} radius - The rounded amount (in pixels) for the four corners.\n\t * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object?\n\t */\n\troundedRect: function(ctx, x, y, width, height, radius) {\n\t\tif (radius) {\n\t\t\tvar r = Math.min(radius, height / 2, width / 2);\n\t\t\tvar left = x + r;\n\t\t\tvar top = y + r;\n\t\t\tvar right = x + width - r;\n\t\t\tvar bottom = y + height - r;\n\n\t\t\tctx.moveTo(x, top);\n\t\t\tif (left < right && top < bottom) {\n\t\t\t\tctx.arc(left, top, r, -PI, -HALF_PI);\n\t\t\t\tctx.arc(right, top, r, -HALF_PI, 0);\n\t\t\t\tctx.arc(right, bottom, r, 0, HALF_PI);\n\t\t\t\tctx.arc(left, bottom, r, HALF_PI, PI);\n\t\t\t} else if (left < right) {\n\t\t\t\tctx.moveTo(left, y);\n\t\t\t\tctx.arc(right, top, r, -HALF_PI, HALF_PI);\n\t\t\t\tctx.arc(left, top, r, HALF_PI, PI + HALF_PI);\n\t\t\t} else if (top < bottom) {\n\t\t\t\tctx.arc(left, top, r, -PI, 0);\n\t\t\t\tctx.arc(left, bottom, r, 0, PI);\n\t\t\t} else {\n\t\t\t\tctx.arc(left, top, r, -PI, PI);\n\t\t\t}\n\t\t\tctx.closePath();\n\t\t\tctx.moveTo(x, y);\n\t\t} else {\n\t\t\tctx.rect(x, y, width, height);\n\t\t}\n\t},\n\n\tdrawPoint: function(ctx, style, radius, x, y, rotation) {\n\t\tvar type, xOffset, yOffset, size, cornerRadius;\n\t\tvar rad = (rotation || 0) * RAD_PER_DEG;\n\n\t\tif (style && typeof style === 'object') {\n\t\t\ttype = style.toString();\n\t\t\tif (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {\n\t\t\t\tctx.save();\n\t\t\t\tctx.translate(x, y);\n\t\t\t\tctx.rotate(rad);\n\t\t\t\tctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height);\n\t\t\t\tctx.restore();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (isNaN(radius) || radius <= 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tctx.beginPath();\n\n\t\tswitch (style) {\n\t\t// Default includes circle\n\t\tdefault:\n\t\t\tctx.arc(x, y, radius, 0, DOUBLE_PI);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'triangle':\n\t\t\tctx.moveTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);\n\t\t\trad += TWO_THIRDS_PI;\n\t\t\tctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);\n\t\t\trad += TWO_THIRDS_PI;\n\t\t\tctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'rectRounded':\n\t\t\t// NOTE: the rounded rect implementation changed to use `arc` instead of\n\t\t\t// `quadraticCurveTo` since it generates better results when rect is\n\t\t\t// almost a circle. 0.516 (instead of 0.5) produces results with visually\n\t\t\t// closer proportion to the previous impl and it is inscribed in the\n\t\t\t// circle with `radius`. For more details, see the following PRs:\n\t\t\t// https://github.com/chartjs/Chart.js/issues/5597\n\t\t\t// https://github.com/chartjs/Chart.js/issues/5858\n\t\t\tcornerRadius = radius * 0.516;\n\t\t\tsize = radius - cornerRadius;\n\t\t\txOffset = Math.cos(rad + QUARTER_PI) * size;\n\t\t\tyOffset = Math.sin(rad + QUARTER_PI) * size;\n\t\t\tctx.arc(x - xOffset, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI);\n\t\t\tctx.arc(x + yOffset, y - xOffset, cornerRadius, rad - HALF_PI, rad);\n\t\t\tctx.arc(x + xOffset, y + yOffset, cornerRadius, rad, rad + HALF_PI);\n\t\t\tctx.arc(x - yOffset, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'rect':\n\t\t\tif (!rotation) {\n\t\t\t\tsize = Math.SQRT1_2 * radius;\n\t\t\t\tctx.rect(x - size, y - size, 2 * size, 2 * size);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\trad += QUARTER_PI;\n\t\t\t/* falls through */\n\t\tcase 'rectRot':\n\t\t\txOffset = Math.cos(rad) * radius;\n\t\t\tyOffset = Math.sin(rad) * radius;\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\n\t\t\tctx.lineTo(x + yOffset, y - xOffset);\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\n\t\t\tctx.lineTo(x - yOffset, y + xOffset);\n\t\t\tctx.closePath();\n\t\t\tbreak;\n\t\tcase 'crossRot':\n\t\t\trad += QUARTER_PI;\n\t\t\t/* falls through */\n\t\tcase 'cross':\n\t\t\txOffset = Math.cos(rad) * radius;\n\t\t\tyOffset = Math.sin(rad) * radius;\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\n\t\t\tctx.moveTo(x + yOffset, y - xOffset);\n\t\t\tctx.lineTo(x - yOffset, y + xOffset);\n\t\t\tbreak;\n\t\tcase 'star':\n\t\t\txOffset = Math.cos(rad) * radius;\n\t\t\tyOffset = Math.sin(rad) * radius;\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\n\t\t\tctx.moveTo(x + yOffset, y - xOffset);\n\t\t\tctx.lineTo(x - yOffset, y + xOffset);\n\t\t\trad += QUARTER_PI;\n\t\t\txOffset = Math.cos(rad) * radius;\n\t\t\tyOffset = Math.sin(rad) * radius;\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\n\t\t\tctx.moveTo(x + yOffset, y - xOffset);\n\t\t\tctx.lineTo(x - yOffset, y + xOffset);\n\t\t\tbreak;\n\t\tcase 'line':\n\t\t\txOffset = Math.cos(rad) * radius;\n\t\t\tyOffset = Math.sin(rad) * radius;\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\n\t\t\tbreak;\n\t\tcase 'dash':\n\t\t\tctx.moveTo(x, y);\n\t\t\tctx.lineTo(x + Math.cos(rad) * radius, y + Math.sin(rad) * radius);\n\t\t\tbreak;\n\t\t}\n\n\t\tctx.fill();\n\t\tctx.stroke();\n\t},\n\n\t/**\n\t * Returns true if the point is inside the rectangle\n\t * @param {object} point - The point to test\n\t * @param {object} area - The rectangle\n\t * @returns {boolean}\n\t * @private\n\t */\n\t_isPointInArea: function(point, area) {\n\t\tvar epsilon = 1e-6; // 1e-6 is margin in pixels for accumulated error.\n\n\t\treturn point.x > area.left - epsilon && point.x < area.right + epsilon &&\n\t\t\tpoint.y > area.top - epsilon && point.y < area.bottom + epsilon;\n\t},\n\n\tclipArea: function(ctx, area) {\n\t\tctx.save();\n\t\tctx.beginPath();\n\t\tctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);\n\t\tctx.clip();\n\t},\n\n\tunclipArea: function(ctx) {\n\t\tctx.restore();\n\t},\n\n\tlineTo: function(ctx, previous, target, flip) {\n\t\tvar stepped = target.steppedLine;\n\t\tif (stepped) {\n\t\t\tif (stepped === 'middle') {\n\t\t\t\tvar midpoint = (previous.x + target.x) / 2.0;\n\t\t\t\tctx.lineTo(midpoint, flip ? target.y : previous.y);\n\t\t\t\tctx.lineTo(midpoint, flip ? previous.y : target.y);\n\t\t\t} else if ((stepped === 'after' && !flip) || (stepped !== 'after' && flip)) {\n\t\t\t\tctx.lineTo(previous.x, target.y);\n\t\t\t} else {\n\t\t\t\tctx.lineTo(target.x, previous.y);\n\t\t\t}\n\t\t\tctx.lineTo(target.x, target.y);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!target.tension) {\n\t\t\tctx.lineTo(target.x, target.y);\n\t\t\treturn;\n\t\t}\n\n\t\tctx.bezierCurveTo(\n\t\t\tflip ? previous.controlPointPreviousX : previous.controlPointNextX,\n\t\t\tflip ? previous.controlPointPreviousY : previous.controlPointNextY,\n\t\t\tflip ? target.controlPointNextX : target.controlPointPreviousX,\n\t\t\tflip ? target.controlPointNextY : target.controlPointPreviousY,\n\t\t\ttarget.x,\n\t\t\ttarget.y);\n\t}\n};\n\nvar helpers_canvas = exports$1;\n\n// DEPRECATIONS\n\n/**\n * Provided for backward compatibility, use Chart.helpers.canvas.clear instead.\n * @namespace Chart.helpers.clear\n * @deprecated since version 2.7.0\n * @todo remove at version 3\n * @private\n */\nhelpers_core.clear = exports$1.clear;\n\n/**\n * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead.\n * @namespace Chart.helpers.drawRoundedRectangle\n * @deprecated since version 2.7.0\n * @todo remove at version 3\n * @private\n */\nhelpers_core.drawRoundedRectangle = function(ctx) {\n\tctx.beginPath();\n\texports$1.roundedRect.apply(exports$1, arguments);\n};\n\nvar defaults = {\n\t/**\n\t * @private\n\t */\n\t_set: function(scope, values) {\n\t\treturn helpers_core.merge(this[scope] || (this[scope] = {}), values);\n\t}\n};\n\n// TODO(v3): remove 'global' from namespace. all default are global and\n// there's inconsistency around which options are under 'global'\ndefaults._set('global', {\n\tdefaultColor: 'rgba(0,0,0,0.1)',\n\tdefaultFontColor: '#666',\n\tdefaultFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\tdefaultFontSize: 12,\n\tdefaultFontStyle: 'normal',\n\tdefaultLineHeight: 1.2,\n\tshowLines: true\n});\n\nvar core_defaults = defaults;\n\nvar valueOrDefault = helpers_core.valueOrDefault;\n\n/**\n * Converts the given font object into a CSS font string.\n * @param {object} font - A font object.\n * @return {string} The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font\n * @private\n */\nfunction toFontString(font) {\n\tif (!font || helpers_core.isNullOrUndef(font.size) || helpers_core.isNullOrUndef(font.family)) {\n\t\treturn null;\n\t}\n\n\treturn (font.style ? font.style + ' ' : '')\n\t\t+ (font.weight ? font.weight + ' ' : '')\n\t\t+ font.size + 'px '\n\t\t+ font.family;\n}\n\n/**\n * @alias Chart.helpers.options\n * @namespace\n */\nvar helpers_options = {\n\t/**\n\t * Converts the given line height `value` in pixels for a specific font `size`.\n\t * @param {number|string} value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em').\n\t * @param {number} size - The font size (in pixels) used to resolve relative `value`.\n\t * @returns {number} The effective line height in pixels (size * 1.2 if value is invalid).\n\t * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height\n\t * @since 2.7.0\n\t */\n\ttoLineHeight: function(value, size) {\n\t\tvar matches = ('' + value).match(/^(normal|(\\d+(?:\\.\\d+)?)(px|em|%)?)$/);\n\t\tif (!matches || matches[1] === 'normal') {\n\t\t\treturn size * 1.2;\n\t\t}\n\n\t\tvalue = +matches[2];\n\n\t\tswitch (matches[3]) {\n\t\tcase 'px':\n\t\t\treturn value;\n\t\tcase '%':\n\t\t\tvalue /= 100;\n\t\t\tbreak;\n\t\t}\n\n\t\treturn size * value;\n\t},\n\n\t/**\n\t * Converts the given value into a padding object with pre-computed width/height.\n\t * @param {number|object} value - If a number, set the value to all TRBL component,\n\t * else, if and object, use defined properties and sets undefined ones to 0.\n\t * @returns {object} The padding values (top, right, bottom, left, width, height)\n\t * @since 2.7.0\n\t */\n\ttoPadding: function(value) {\n\t\tvar t, r, b, l;\n\n\t\tif (helpers_core.isObject(value)) {\n\t\t\tt = +value.top || 0;\n\t\t\tr = +value.right || 0;\n\t\t\tb = +value.bottom || 0;\n\t\t\tl = +value.left || 0;\n\t\t} else {\n\t\t\tt = r = b = l = +value || 0;\n\t\t}\n\n\t\treturn {\n\t\t\ttop: t,\n\t\t\tright: r,\n\t\t\tbottom: b,\n\t\t\tleft: l,\n\t\t\theight: t + b,\n\t\t\twidth: l + r\n\t\t};\n\t},\n\n\t/**\n\t * Parses font options and returns the font object.\n\t * @param {object} options - A object that contains font options to be parsed.\n\t * @return {object} The font object.\n\t * @todo Support font.* options and renamed to toFont().\n\t * @private\n\t */\n\t_parseFont: function(options) {\n\t\tvar globalDefaults = core_defaults.global;\n\t\tvar size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize);\n\t\tvar font = {\n\t\t\tfamily: valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily),\n\t\t\tlineHeight: helpers_core.options.toLineHeight(valueOrDefault(options.lineHeight, globalDefaults.defaultLineHeight), size),\n\t\t\tsize: size,\n\t\t\tstyle: valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle),\n\t\t\tweight: null,\n\t\t\tstring: ''\n\t\t};\n\n\t\tfont.string = toFontString(font);\n\t\treturn font;\n\t},\n\n\t/**\n\t * Evaluates the given `inputs` sequentially and returns the first defined value.\n\t * @param {Array} inputs - An array of values, falling back to the last value.\n\t * @param {object} [context] - If defined and the current value is a function, the value\n\t * is called with `context` as first argument and the result becomes the new input.\n\t * @param {number} [index] - If defined and the current value is an array, the value\n\t * at `index` become the new input.\n\t * @param {object} [info] - object to return information about resolution in\n\t * @param {boolean} [info.cacheable] - Will be set to `false` if option is not cacheable.\n\t * @since 2.7.0\n\t */\n\tresolve: function(inputs, context, index, info) {\n\t\tvar cacheable = true;\n\t\tvar i, ilen, value;\n\n\t\tfor (i = 0, ilen = inputs.length; i < ilen; ++i) {\n\t\t\tvalue = inputs[i];\n\t\t\tif (value === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (context !== undefined && typeof value === 'function') {\n\t\t\t\tvalue = value(context);\n\t\t\t\tcacheable = false;\n\t\t\t}\n\t\t\tif (index !== undefined && helpers_core.isArray(value)) {\n\t\t\t\tvalue = value[index];\n\t\t\t\tcacheable = false;\n\t\t\t}\n\t\t\tif (value !== undefined) {\n\t\t\t\tif (info && !cacheable) {\n\t\t\t\t\tinfo.cacheable = false;\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t}\n};\n\n/**\n * @alias Chart.helpers.math\n * @namespace\n */\nvar exports$2 = {\n\t/**\n\t * Returns an array of factors sorted from 1 to sqrt(value)\n\t * @private\n\t */\n\t_factorize: function(value) {\n\t\tvar result = [];\n\t\tvar sqrt = Math.sqrt(value);\n\t\tvar i;\n\n\t\tfor (i = 1; i < sqrt; i++) {\n\t\t\tif (value % i === 0) {\n\t\t\t\tresult.push(i);\n\t\t\t\tresult.push(value / i);\n\t\t\t}\n\t\t}\n\t\tif (sqrt === (sqrt | 0)) { // if value is a square number\n\t\t\tresult.push(sqrt);\n\t\t}\n\n\t\tresult.sort(function(a, b) {\n\t\t\treturn a - b;\n\t\t}).pop();\n\t\treturn result;\n\t},\n\n\tlog10: Math.log10 || function(x) {\n\t\tvar exponent = Math.log(x) * Math.LOG10E; // Math.LOG10E = 1 / Math.LN10.\n\t\t// Check for whole powers of 10,\n\t\t// which due to floating point rounding error should be corrected.\n\t\tvar powerOf10 = Math.round(exponent);\n\t\tvar isPowerOf10 = x === Math.pow(10, powerOf10);\n\n\t\treturn isPowerOf10 ? powerOf10 : exponent;\n\t}\n};\n\nvar helpers_math = exports$2;\n\n// DEPRECATIONS\n\n/**\n * Provided for backward compatibility, use Chart.helpers.math.log10 instead.\n * @namespace Chart.helpers.log10\n * @deprecated since version 2.9.0\n * @todo remove at version 3\n * @private\n */\nhelpers_core.log10 = exports$2.log10;\n\nvar getRtlAdapter = function(rectX, width) {\n\treturn {\n\t\tx: function(x) {\n\t\t\treturn rectX + rectX + width - x;\n\t\t},\n\t\tsetWidth: function(w) {\n\t\t\twidth = w;\n\t\t},\n\t\ttextAlign: function(align) {\n\t\t\tif (align === 'center') {\n\t\t\t\treturn align;\n\t\t\t}\n\t\t\treturn align === 'right' ? 'left' : 'right';\n\t\t},\n\t\txPlus: function(x, value) {\n\t\t\treturn x - value;\n\t\t},\n\t\tleftForLtr: function(x, itemWidth) {\n\t\t\treturn x - itemWidth;\n\t\t},\n\t};\n};\n\nvar getLtrAdapter = function() {\n\treturn {\n\t\tx: function(x) {\n\t\t\treturn x;\n\t\t},\n\t\tsetWidth: function(w) { // eslint-disable-line no-unused-vars\n\t\t},\n\t\ttextAlign: function(align) {\n\t\t\treturn align;\n\t\t},\n\t\txPlus: function(x, value) {\n\t\t\treturn x + value;\n\t\t},\n\t\tleftForLtr: function(x, _itemWidth) { // eslint-disable-line no-unused-vars\n\t\t\treturn x;\n\t\t},\n\t};\n};\n\nvar getAdapter = function(rtl, rectX, width) {\n\treturn rtl ? getRtlAdapter(rectX, width) : getLtrAdapter();\n};\n\nvar overrideTextDirection = function(ctx, direction) {\n\tvar style, original;\n\tif (direction === 'ltr' || direction === 'rtl') {\n\t\tstyle = ctx.canvas.style;\n\t\toriginal = [\n\t\t\tstyle.getPropertyValue('direction'),\n\t\t\tstyle.getPropertyPriority('direction'),\n\t\t];\n\n\t\tstyle.setProperty('direction', direction, 'important');\n\t\tctx.prevTextDirection = original;\n\t}\n};\n\nvar restoreTextDirection = function(ctx) {\n\tvar original = ctx.prevTextDirection;\n\tif (original !== undefined) {\n\t\tdelete ctx.prevTextDirection;\n\t\tctx.canvas.style.setProperty('direction', original[0], original[1]);\n\t}\n};\n\nvar helpers_rtl = {\n\tgetRtlAdapter: getAdapter,\n\toverrideTextDirection: overrideTextDirection,\n\trestoreTextDirection: restoreTextDirection,\n};\n\nvar helpers$1 = helpers_core;\nvar easing = helpers_easing;\nvar canvas = helpers_canvas;\nvar options = helpers_options;\nvar math = helpers_math;\nvar rtl = helpers_rtl;\nhelpers$1.easing = easing;\nhelpers$1.canvas = canvas;\nhelpers$1.options = options;\nhelpers$1.math = math;\nhelpers$1.rtl = rtl;\n\nfunction interpolate(start, view, model, ease) {\n\tvar keys = Object.keys(model);\n\tvar i, ilen, key, actual, origin, target, type, c0, c1;\n\n\tfor (i = 0, ilen = keys.length; i < ilen; ++i) {\n\t\tkey = keys[i];\n\n\t\ttarget = model[key];\n\n\t\t// if a value is added to the model after pivot() has been called, the view\n\t\t// doesn't contain it, so let's initialize the view to the target value.\n\t\tif (!view.hasOwnProperty(key)) {\n\t\t\tview[key] = target;\n\t\t}\n\n\t\tactual = view[key];\n\n\t\tif (actual === target || key[0] === '_') {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!start.hasOwnProperty(key)) {\n\t\t\tstart[key] = actual;\n\t\t}\n\n\t\torigin = start[key];\n\n\t\ttype = typeof target;\n\n\t\tif (type === typeof origin) {\n\t\t\tif (type === 'string') {\n\t\t\t\tc0 = chartjsColor(origin);\n\t\t\t\tif (c0.valid) {\n\t\t\t\t\tc1 = chartjsColor(target);\n\t\t\t\t\tif (c1.valid) {\n\t\t\t\t\t\tview[key] = c1.mix(c0, ease).rgbString();\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (helpers$1.isFinite(origin) && helpers$1.isFinite(target)) {\n\t\t\t\tview[key] = origin + (target - origin) * ease;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tview[key] = target;\n\t}\n}\n\nvar Element = function(configuration) {\n\thelpers$1.extend(this, configuration);\n\tthis.initialize.apply(this, arguments);\n};\n\nhelpers$1.extend(Element.prototype, {\n\t_type: undefined,\n\n\tinitialize: function() {\n\t\tthis.hidden = false;\n\t},\n\n\tpivot: function() {\n\t\tvar me = this;\n\t\tif (!me._view) {\n\t\t\tme._view = helpers$1.extend({}, me._model);\n\t\t}\n\t\tme._start = {};\n\t\treturn me;\n\t},\n\n\ttransition: function(ease) {\n\t\tvar me = this;\n\t\tvar model = me._model;\n\t\tvar start = me._start;\n\t\tvar view = me._view;\n\n\t\t// No animation -> No Transition\n\t\tif (!model || ease === 1) {\n\t\t\tme._view = helpers$1.extend({}, model);\n\t\t\tme._start = null;\n\t\t\treturn me;\n\t\t}\n\n\t\tif (!view) {\n\t\t\tview = me._view = {};\n\t\t}\n\n\t\tif (!start) {\n\t\t\tstart = me._start = {};\n\t\t}\n\n\t\tinterpolate(start, view, model, ease);\n\n\t\treturn me;\n\t},\n\n\ttooltipPosition: function() {\n\t\treturn {\n\t\t\tx: this._model.x,\n\t\t\ty: this._model.y\n\t\t};\n\t},\n\n\thasValue: function() {\n\t\treturn helpers$1.isNumber(this._model.x) && helpers$1.isNumber(this._model.y);\n\t}\n});\n\nElement.extend = helpers$1.inherits;\n\nvar core_element = Element;\n\nvar exports$3 = core_element.extend({\n\tchart: null, // the animation associated chart instance\n\tcurrentStep: 0, // the current animation step\n\tnumSteps: 60, // default number of steps\n\teasing: '', // the easing to use for this animation\n\trender: null, // render function used by the animation service\n\n\tonAnimationProgress: null, // user specified callback to fire on each step of the animation\n\tonAnimationComplete: null, // user specified callback to fire when the animation finishes\n});\n\nvar core_animation = exports$3;\n\n// DEPRECATIONS\n\n/**\n * Provided for backward compatibility, use Chart.Animation instead\n * @prop Chart.Animation#animationObject\n * @deprecated since version 2.6.0\n * @todo remove at version 3\n */\nObject.defineProperty(exports$3.prototype, 'animationObject', {\n\tget: function() {\n\t\treturn this;\n\t}\n});\n\n/**\n * Provided for backward compatibility, use Chart.Animation#chart instead\n * @prop Chart.Animation#chartInstance\n * @deprecated since version 2.6.0\n * @todo remove at version 3\n */\nObject.defineProperty(exports$3.prototype, 'chartInstance', {\n\tget: function() {\n\t\treturn this.chart;\n\t},\n\tset: function(value) {\n\t\tthis.chart = value;\n\t}\n});\n\ncore_defaults._set('global', {\n\tanimation: {\n\t\tduration: 1000,\n\t\teasing: 'easeOutQuart',\n\t\tonProgress: helpers$1.noop,\n\t\tonComplete: helpers$1.noop\n\t}\n});\n\nvar core_animations = {\n\tanimations: [],\n\trequest: null,\n\n\t/**\n\t * @param {Chart} chart - The chart to animate.\n\t * @param {Chart.Animation} animation - The animation that we will animate.\n\t * @param {number} duration - The animation duration in ms.\n\t * @param {boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions\n\t */\n\taddAnimation: function(chart, animation, duration, lazy) {\n\t\tvar animations = this.animations;\n\t\tvar i, ilen;\n\n\t\tanimation.chart = chart;\n\t\tanimation.startTime = Date.now();\n\t\tanimation.duration = duration;\n\n\t\tif (!lazy) {\n\t\t\tchart.animating = true;\n\t\t}\n\n\t\tfor (i = 0, ilen = animations.length; i < ilen; ++i) {\n\t\t\tif (animations[i].chart === chart) {\n\t\t\t\tanimations[i] = animation;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tanimations.push(animation);\n\n\t\t// If there are no animations queued, manually kickstart a digest, for lack of a better word\n\t\tif (animations.length === 1) {\n\t\t\tthis.requestAnimationFrame();\n\t\t}\n\t},\n\n\tcancelAnimation: function(chart) {\n\t\tvar index = helpers$1.findIndex(this.animations, function(animation) {\n\t\t\treturn animation.chart === chart;\n\t\t});\n\n\t\tif (index !== -1) {\n\t\t\tthis.animations.splice(index, 1);\n\t\t\tchart.animating = false;\n\t\t}\n\t},\n\n\trequestAnimationFrame: function() {\n\t\tvar me = this;\n\t\tif (me.request === null) {\n\t\t\t// Skip animation frame requests until the active one is executed.\n\t\t\t// This can happen when processing mouse events, e.g. 'mousemove'\n\t\t\t// and 'mouseout' events will trigger multiple renders.\n\t\t\tme.request = helpers$1.requestAnimFrame.call(window, function() {\n\t\t\t\tme.request = null;\n\t\t\t\tme.startDigest();\n\t\t\t});\n\t\t}\n\t},\n\n\t/**\n\t * @private\n\t */\n\tstartDigest: function() {\n\t\tvar me = this;\n\n\t\tme.advance();\n\n\t\t// Do we have more stuff to animate?\n\t\tif (me.animations.length > 0) {\n\t\t\tme.requestAnimationFrame();\n\t\t}\n\t},\n\n\t/**\n\t * @private\n\t */\n\tadvance: function() {\n\t\tvar animations = this.animations;\n\t\tvar animation, chart, numSteps, nextStep;\n\t\tvar i = 0;\n\n\t\t// 1 animation per chart, so we are looping charts here\n\t\twhile (i < animations.length) {\n\t\t\tanimation = animations[i];\n\t\t\tchart = animation.chart;\n\t\t\tnumSteps = animation.numSteps;\n\n\t\t\t// Make sure that currentStep starts at 1\n\t\t\t// https://github.com/chartjs/Chart.js/issues/6104\n\t\t\tnextStep = Math.floor((Date.now() - animation.startTime) / animation.duration * numSteps) + 1;\n\t\t\tanimation.currentStep = Math.min(nextStep, numSteps);\n\n\t\t\thelpers$1.callback(animation.render, [chart, animation], chart);\n\t\t\thelpers$1.callback(animation.onAnimationProgress, [animation], chart);\n\n\t\t\tif (animation.currentStep >= numSteps) {\n\t\t\t\thelpers$1.callback(animation.onAnimationComplete, [animation], chart);\n\t\t\t\tchart.animating = false;\n\t\t\t\tanimations.splice(i, 1);\n\t\t\t} else {\n\t\t\t\t++i;\n\t\t\t}\n\t\t}\n\t}\n};\n\nvar resolve = helpers$1.options.resolve;\n\nvar arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];\n\n/**\n * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',\n * 'unshift') and notify the listener AFTER the array has been altered. Listeners are\n * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.\n */\nfunction listenArrayEvents(array, listener) {\n\tif (array._chartjs) {\n\t\tarray._chartjs.listeners.push(listener);\n\t\treturn;\n\t}\n\n\tObject.defineProperty(array, '_chartjs', {\n\t\tconfigurable: true,\n\t\tenumerable: false,\n\t\tvalue: {\n\t\t\tlisteners: [listener]\n\t\t}\n\t});\n\n\tarrayEvents.forEach(function(key) {\n\t\tvar method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);\n\t\tvar base = array[key];\n\n\t\tObject.defineProperty(array, key, {\n\t\t\tconfigurable: true,\n\t\t\tenumerable: false,\n\t\t\tvalue: function() {\n\t\t\t\tvar args = Array.prototype.slice.call(arguments);\n\t\t\t\tvar res = base.apply(this, args);\n\n\t\t\t\thelpers$1.each(array._chartjs.listeners, function(object) {\n\t\t\t\t\tif (typeof object[method] === 'function') {\n\t\t\t\t\t\tobject[method].apply(object, args);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\treturn res;\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Removes the given array event listener and cleanup extra attached properties (such as\n * the _chartjs stub and overridden methods) if array doesn't have any more listeners.\n */\nfunction unlistenArrayEvents(array, listener) {\n\tvar stub = array._chartjs;\n\tif (!stub) {\n\t\treturn;\n\t}\n\n\tvar listeners = stub.listeners;\n\tvar index = listeners.indexOf(listener);\n\tif (index !== -1) {\n\t\tlisteners.splice(index, 1);\n\t}\n\n\tif (listeners.length > 0) {\n\t\treturn;\n\t}\n\n\tarrayEvents.forEach(function(key) {\n\t\tdelete array[key];\n\t});\n\n\tdelete array._chartjs;\n}\n\n// Base class for all dataset controllers (line, bar, etc)\nvar DatasetController = function(chart, datasetIndex) {\n\tthis.initialize(chart, datasetIndex);\n};\n\nhelpers$1.extend(DatasetController.prototype, {\n\n\t/**\n\t * Element type used to generate a meta dataset (e.g. Chart.element.Line).\n\t * @type {Chart.core.element}\n\t */\n\tdatasetElementType: null,\n\n\t/**\n\t * Element type used to generate a meta data (e.g. Chart.element.Point).\n\t * @type {Chart.core.element}\n\t */\n\tdataElementType: null,\n\n\t/**\n\t * Dataset element option keys to be resolved in _resolveDatasetElementOptions.\n\t * A derived controller may override this to resolve controller-specific options.\n\t * The keys defined here are for backward compatibility for legend styles.\n\t * @private\n\t */\n\t_datasetElementOptions: [\n\t\t'backgroundColor',\n\t\t'borderCapStyle',\n\t\t'borderColor',\n\t\t'borderDash',\n\t\t'borderDashOffset',\n\t\t'borderJoinStyle',\n\t\t'borderWidth'\n\t],\n\n\t/**\n\t * Data element option keys to be resolved in _resolveDataElementOptions.\n\t * A derived controller may override this to resolve controller-specific options.\n\t * The keys defined here are for backward compatibility for legend styles.\n\t * @private\n\t */\n\t_dataElementOptions: [\n\t\t'backgroundColor',\n\t\t'borderColor',\n\t\t'borderWidth',\n\t\t'pointStyle'\n\t],\n\n\tinitialize: function(chart, datasetIndex) {\n\t\tvar me = this;\n\t\tme.chart = chart;\n\t\tme.index = datasetIndex;\n\t\tme.linkScales();\n\t\tme.addElements();\n\t\tme._type = me.getMeta().type;\n\t},\n\n\tupdateIndex: function(datasetIndex) {\n\t\tthis.index = datasetIndex;\n\t},\n\n\tlinkScales: function() {\n\t\tvar me = this;\n\t\tvar meta = me.getMeta();\n\t\tvar chart = me.chart;\n\t\tvar scales = chart.scales;\n\t\tvar dataset = me.getDataset();\n\t\tvar scalesOpts = chart.options.scales;\n\n\t\tif (meta.xAxisID === null || !(meta.xAxisID in scales) || dataset.xAxisID) {\n\t\t\tmeta.xAxisID = dataset.xAxisID || scalesOpts.xAxes[0].id;\n\t\t}\n\t\tif (meta.yAxisID === null || !(meta.yAxisID in scales) || dataset.yAxisID) {\n\t\t\tmeta.yAxisID = dataset.yAxisID || scalesOpts.yAxes[0].id;\n\t\t}\n\t},\n\n\tgetDataset: function() {\n\t\treturn this.chart.data.datasets[this.index];\n\t},\n\n\tgetMeta: function() {\n\t\treturn this.chart.getDatasetMeta(this.index);\n\t},\n\n\tgetScaleForId: function(scaleID) {\n\t\treturn this.chart.scales[scaleID];\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_getValueScaleId: function() {\n\t\treturn this.getMeta().yAxisID;\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_getIndexScaleId: function() {\n\t\treturn this.getMeta().xAxisID;\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_getValueScale: function() {\n\t\treturn this.getScaleForId(this._getValueScaleId());\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_getIndexScale: function() {\n\t\treturn this.getScaleForId(this._getIndexScaleId());\n\t},\n\n\treset: function() {\n\t\tthis._update(true);\n\t},\n\n\t/**\n\t * @private\n\t */\n\tdestroy: function() {\n\t\tif (this._data) {\n\t\t\tunlistenArrayEvents(this._data, this);\n\t\t}\n\t},\n\n\tcreateMetaDataset: function() {\n\t\tvar me = this;\n\t\tvar type = me.datasetElementType;\n\t\treturn type && new type({\n\t\t\t_chart: me.chart,\n\t\t\t_datasetIndex: me.index\n\t\t});\n\t},\n\n\tcreateMetaData: function(index) {\n\t\tvar me = this;\n\t\tvar type = me.dataElementType;\n\t\treturn type && new type({\n\t\t\t_chart: me.chart,\n\t\t\t_datasetIndex: me.index,\n\t\t\t_index: index\n\t\t});\n\t},\n\n\taddElements: function() {\n\t\tvar me = this;\n\t\tvar meta = me.getMeta();\n\t\tvar data = me.getDataset().data || [];\n\t\tvar metaData = meta.data;\n\t\tvar i, ilen;\n\n\t\tfor (i = 0, ilen = data.length; i < ilen; ++i) {\n\t\t\tmetaData[i] = metaData[i] || me.createMetaData(i);\n\t\t}\n\n\t\tmeta.dataset = meta.dataset || me.createMetaDataset();\n\t},\n\n\taddElementAndReset: function(index) {\n\t\tvar element = this.createMetaData(index);\n\t\tthis.getMeta().data.splice(index, 0, element);\n\t\tthis.updateElement(element, index, true);\n\t},\n\n\tbuildOrUpdateElements: function() {\n\t\tvar me = this;\n\t\tvar dataset = me.getDataset();\n\t\tvar data = dataset.data || (dataset.data = []);\n\n\t\t// In order to correctly handle data addition/deletion animation (an thus simulate\n\t\t// real-time charts), we need to monitor these data modifications and synchronize\n\t\t// the internal meta data accordingly.\n\t\tif (me._data !== data) {\n\t\t\tif (me._data) {\n\t\t\t\t// This case happens when the user replaced the data array instance.\n\t\t\t\tunlistenArrayEvents(me._data, me);\n\t\t\t}\n\n\t\t\tif (data && Object.isExtensible(data)) {\n\t\t\t\tlistenArrayEvents(data, me);\n\t\t\t}\n\t\t\tme._data = data;\n\t\t}\n\n\t\t// Re-sync meta data in case the user replaced the data array or if we missed\n\t\t// any updates and so make sure that we handle number of datapoints changing.\n\t\tme.resyncElements();\n\t},\n\n\t/**\n\t * Returns the merged user-supplied and default dataset-level options\n\t * @private\n\t */\n\t_configure: function() {\n\t\tvar me = this;\n\t\tme._config = helpers$1.merge({}, [\n\t\t\tme.chart.options.datasets[me._type],\n\t\t\tme.getDataset(),\n\t\t], {\n\t\t\tmerger: function(key, target, source) {\n\t\t\t\tif (key !== '_meta' && key !== 'data') {\n\t\t\t\t\thelpers$1._merger(key, target, source);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\t_update: function(reset) {\n\t\tvar me = this;\n\t\tme._configure();\n\t\tme._cachedDataOpts = null;\n\t\tme.update(reset);\n\t},\n\n\tupdate: helpers$1.noop,\n\n\ttransition: function(easingValue) {\n\t\tvar meta = this.getMeta();\n\t\tvar elements = meta.data || [];\n\t\tvar ilen = elements.length;\n\t\tvar i = 0;\n\n\t\tfor (; i < ilen; ++i) {\n\t\t\telements[i].transition(easingValue);\n\t\t}\n\n\t\tif (meta.dataset) {\n\t\t\tmeta.dataset.transition(easingValue);\n\t\t}\n\t},\n\n\tdraw: function() {\n\t\tvar meta = this.getMeta();\n\t\tvar elements = meta.data || [];\n\t\tvar ilen = elements.length;\n\t\tvar i = 0;\n\n\t\tif (meta.dataset) {\n\t\t\tmeta.dataset.draw();\n\t\t}\n\n\t\tfor (; i < ilen; ++i) {\n\t\t\telements[i].draw();\n\t\t}\n\t},\n\n\t/**\n\t * Returns a set of predefined style properties that should be used to represent the dataset\n\t * or the data if the index is specified\n\t * @param {number} index - data index\n\t * @return {IStyleInterface} style object\n\t */\n\tgetStyle: function(index) {\n\t\tvar me = this;\n\t\tvar meta = me.getMeta();\n\t\tvar dataset = meta.dataset;\n\t\tvar style;\n\n\t\tme._configure();\n\t\tif (dataset && index === undefined) {\n\t\t\tstyle = me._resolveDatasetElementOptions(dataset || {});\n\t\t} else {\n\t\t\tindex = index || 0;\n\t\t\tstyle = me._resolveDataElementOptions(meta.data[index] || {}, index);\n\t\t}\n\n\t\tif (style.fill === false || style.fill === null) {\n\t\t\tstyle.backgroundColor = style.borderColor;\n\t\t}\n\n\t\treturn style;\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_resolveDatasetElementOptions: function(element, hover) {\n\t\tvar me = this;\n\t\tvar chart = me.chart;\n\t\tvar datasetOpts = me._config;\n\t\tvar custom = element.custom || {};\n\t\tvar options = chart.options.elements[me.datasetElementType.prototype._type] || {};\n\t\tvar elementOptions = me._datasetElementOptions;\n\t\tvar values = {};\n\t\tvar i, ilen, key, readKey;\n\n\t\t// Scriptable options\n\t\tvar context = {\n\t\t\tchart: chart,\n\t\t\tdataset: me.getDataset(),\n\t\t\tdatasetIndex: me.index,\n\t\t\thover: hover\n\t\t};\n\n\t\tfor (i = 0, ilen = elementOptions.length; i < ilen; ++i) {\n\t\t\tkey = elementOptions[i];\n\t\t\treadKey = hover ? 'hover' + key.charAt(0).toUpperCase() + key.slice(1) : key;\n\t\t\tvalues[key] = resolve([\n\t\t\t\tcustom[readKey],\n\t\t\t\tdatasetOpts[readKey],\n\t\t\t\toptions[readKey]\n\t\t\t], context);\n\t\t}\n\n\t\treturn values;\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_resolveDataElementOptions: function(element, index) {\n\t\tvar me = this;\n\t\tvar custom = element && element.custom;\n\t\tvar cached = me._cachedDataOpts;\n\t\tif (cached && !custom) {\n\t\t\treturn cached;\n\t\t}\n\t\tvar chart = me.chart;\n\t\tvar datasetOpts = me._config;\n\t\tvar options = chart.options.elements[me.dataElementType.prototype._type] || {};\n\t\tvar elementOptions = me._dataElementOptions;\n\t\tvar values = {};\n\n\t\t// Scriptable options\n\t\tvar context = {\n\t\t\tchart: chart,\n\t\t\tdataIndex: index,\n\t\t\tdataset: me.getDataset(),\n\t\t\tdatasetIndex: me.index\n\t\t};\n\n\t\t// `resolve` sets cacheable to `false` if any option is indexed or scripted\n\t\tvar info = {cacheable: !custom};\n\n\t\tvar keys, i, ilen, key;\n\n\t\tcustom = custom || {};\n\n\t\tif (helpers$1.isArray(elementOptions)) {\n\t\t\tfor (i = 0, ilen = elementOptions.length; i < ilen; ++i) {\n\t\t\t\tkey = elementOptions[i];\n\t\t\t\tvalues[key] = resolve([\n\t\t\t\t\tcustom[key],\n\t\t\t\t\tdatasetOpts[key],\n\t\t\t\t\toptions[key]\n\t\t\t\t], context, index, info);\n\t\t\t}\n\t\t} else {\n\t\t\tkeys = Object.keys(elementOptions);\n\t\t\tfor (i = 0, ilen = keys.length; i < ilen; ++i) {\n\t\t\t\tkey = keys[i];\n\t\t\t\tvalues[key] = resolve([\n\t\t\t\t\tcustom[key],\n\t\t\t\t\tdatasetOpts[elementOptions[key]],\n\t\t\t\t\tdatasetOpts[key],\n\t\t\t\t\toptions[key]\n\t\t\t\t], context, index, info);\n\t\t\t}\n\t\t}\n\n\t\tif (info.cacheable) {\n\t\t\tme._cachedDataOpts = Object.freeze(values);\n\t\t}\n\n\t\treturn values;\n\t},\n\n\tremoveHoverStyle: function(element) {\n\t\thelpers$1.merge(element._model, element.$previousStyle || {});\n\t\tdelete element.$previousStyle;\n\t},\n\n\tsetHoverStyle: function(element) {\n\t\tvar dataset = this.chart.data.datasets[element._datasetIndex];\n\t\tvar index = element._index;\n\t\tvar custom = element.custom || {};\n\t\tvar model = element._model;\n\t\tvar getHoverColor = helpers$1.getHoverColor;\n\n\t\telement.$previousStyle = {\n\t\t\tbackgroundColor: model.backgroundColor,\n\t\t\tborderColor: model.borderColor,\n\t\t\tborderWidth: model.borderWidth\n\t\t};\n\n\t\tmodel.backgroundColor = resolve([custom.hoverBackgroundColor, dataset.hoverBackgroundColor, getHoverColor(model.backgroundColor)], undefined, index);\n\t\tmodel.borderColor = resolve([custom.hoverBorderColor, dataset.hoverBorderColor, getHoverColor(model.borderColor)], undefined, index);\n\t\tmodel.borderWidth = resolve([custom.hoverBorderWidth, dataset.hoverBorderWidth, model.borderWidth], undefined, index);\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_removeDatasetHoverStyle: function() {\n\t\tvar element = this.getMeta().dataset;\n\n\t\tif (element) {\n\t\t\tthis.removeHoverStyle(element);\n\t\t}\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_setDatasetHoverStyle: function() {\n\t\tvar element = this.getMeta().dataset;\n\t\tvar prev = {};\n\t\tvar i, ilen, key, keys, hoverOptions, model;\n\n\t\tif (!element) {\n\t\t\treturn;\n\t\t}\n\n\t\tmodel = element._model;\n\t\thoverOptions = this._resolveDatasetElementOptions(element, true);\n\n\t\tkeys = Object.keys(hoverOptions);\n\t\tfor (i = 0, ilen = keys.length; i < ilen; ++i) {\n\t\t\tkey = keys[i];\n\t\t\tprev[key] = model[key];\n\t\t\tmodel[key] = hoverOptions[key];\n\t\t}\n\n\t\telement.$previousStyle = prev;\n\t},\n\n\t/**\n\t * @private\n\t */\n\tresyncElements: function() {\n\t\tvar me = this;\n\t\tvar meta = me.getMeta();\n\t\tvar data = me.getDataset().data;\n\t\tvar numMeta = meta.data.length;\n\t\tvar numData = data.length;\n\n\t\tif (numData < numMeta) {\n\t\t\tmeta.data.splice(numData, numMeta - numData);\n\t\t} else if (numData > numMeta) {\n\t\t\tme.insertElements(numMeta, numData - numMeta);\n\t\t}\n\t},\n\n\t/**\n\t * @private\n\t */\n\tinsertElements: function(start, count) {\n\t\tfor (var i = 0; i < count; ++i) {\n\t\t\tthis.addElementAndReset(start + i);\n\t\t}\n\t},\n\n\t/**\n\t * @private\n\t */\n\tonDataPush: function() {\n\t\tvar count = arguments.length;\n\t\tthis.insertElements(this.getDataset().data.length - count, count);\n\t},\n\n\t/**\n\t * @private\n\t */\n\tonDataPop: function() {\n\t\tthis.getMeta().data.pop();\n\t},\n\n\t/**\n\t * @private\n\t */\n\tonDataShift: function() {\n\t\tthis.getMeta().data.shift();\n\t},\n\n\t/**\n\t * @private\n\t */\n\tonDataSplice: function(start, count) {\n\t\tthis.getMeta().data.splice(start, count);\n\t\tthis.insertElements(start, arguments.length - 2);\n\t},\n\n\t/**\n\t * @private\n\t */\n\tonDataUnshift: function() {\n\t\tthis.insertElements(0, arguments.length);\n\t}\n});\n\nDatasetController.extend = helpers$1.inherits;\n\nvar core_datasetController = DatasetController;\n\nvar TAU = Math.PI * 2;\n\ncore_defaults._set('global', {\n\telements: {\n\t\tarc: {\n\t\t\tbackgroundColor: core_defaults.global.defaultColor,\n\t\t\tborderColor: '#fff',\n\t\t\tborderWidth: 2,\n\t\t\tborderAlign: 'center'\n\t\t}\n\t}\n});\n\nfunction clipArc(ctx, arc) {\n\tvar startAngle = arc.startAngle;\n\tvar endAngle = arc.endAngle;\n\tvar pixelMargin = arc.pixelMargin;\n\tvar angleMargin = pixelMargin / arc.outerRadius;\n\tvar x = arc.x;\n\tvar y = arc.y;\n\n\t// Draw an inner border by cliping the arc and drawing a double-width border\n\t// Enlarge the clipping arc by 0.33 pixels to eliminate glitches between borders\n\tctx.beginPath();\n\tctx.arc(x, y, arc.outerRadius, startAngle - angleMargin, endAngle + angleMargin);\n\tif (arc.innerRadius > pixelMargin) {\n\t\tangleMargin = pixelMargin / arc.innerRadius;\n\t\tctx.arc(x, y, arc.innerRadius - pixelMargin, endAngle + angleMargin, startAngle - angleMargin, true);\n\t} else {\n\t\tctx.arc(x, y, pixelMargin, endAngle + Math.PI / 2, startAngle - Math.PI / 2);\n\t}\n\tctx.closePath();\n\tctx.clip();\n}\n\nfunction drawFullCircleBorders(ctx, vm, arc, inner) {\n\tvar endAngle = arc.endAngle;\n\tvar i;\n\n\tif (inner) {\n\t\tarc.endAngle = arc.startAngle + TAU;\n\t\tclipArc(ctx, arc);\n\t\tarc.endAngle = endAngle;\n\t\tif (arc.endAngle === arc.startAngle && arc.fullCircles) {\n\t\t\tarc.endAngle += TAU;\n\t\t\tarc.fullCircles--;\n\t\t}\n\t}\n\n\tctx.beginPath();\n\tctx.arc(arc.x, arc.y, arc.innerRadius, arc.startAngle + TAU, arc.startAngle, true);\n\tfor (i = 0; i < arc.fullCircles; ++i) {\n\t\tctx.stroke();\n\t}\n\n\tctx.beginPath();\n\tctx.arc(arc.x, arc.y, vm.outerRadius, arc.startAngle, arc.startAngle + TAU);\n\tfor (i = 0; i < arc.fullCircles; ++i) {\n\t\tctx.stroke();\n\t}\n}\n\nfunction drawBorder(ctx, vm, arc) {\n\tvar inner = vm.borderAlign === 'inner';\n\n\tif (inner) {\n\t\tctx.lineWidth = vm.borderWidth * 2;\n\t\tctx.lineJoin = 'round';\n\t} else {\n\t\tctx.lineWidth = vm.borderWidth;\n\t\tctx.lineJoin = 'bevel';\n\t}\n\n\tif (arc.fullCircles) {\n\t\tdrawFullCircleBorders(ctx, vm, arc, inner);\n\t}\n\n\tif (inner) {\n\t\tclipArc(ctx, arc);\n\t}\n\n\tctx.beginPath();\n\tctx.arc(arc.x, arc.y, vm.outerRadius, arc.startAngle, arc.endAngle);\n\tctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true);\n\tctx.closePath();\n\tctx.stroke();\n}\n\nvar element_arc = core_element.extend({\n\t_type: 'arc',\n\n\tinLabelRange: function(mouseX) {\n\t\tvar vm = this._view;\n\n\t\tif (vm) {\n\t\t\treturn (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));\n\t\t}\n\t\treturn false;\n\t},\n\n\tinRange: function(chartX, chartY) {\n\t\tvar vm = this._view;\n\n\t\tif (vm) {\n\t\t\tvar pointRelativePosition = helpers$1.getAngleFromPoint(vm, {x: chartX, y: chartY});\n\t\t\tvar angle = pointRelativePosition.angle;\n\t\t\tvar distance = pointRelativePosition.distance;\n\n\t\t\t// Sanitise angle range\n\t\t\tvar startAngle = vm.startAngle;\n\t\t\tvar endAngle = vm.endAngle;\n\t\t\twhile (endAngle < startAngle) {\n\t\t\t\tendAngle += TAU;\n\t\t\t}\n\t\t\twhile (angle > endAngle) {\n\t\t\t\tangle -= TAU;\n\t\t\t}\n\t\t\twhile (angle < startAngle) {\n\t\t\t\tangle += TAU;\n\t\t\t}\n\n\t\t\t// Check if within the range of the open/close angle\n\t\t\tvar betweenAngles = (angle >= startAngle && angle <= endAngle);\n\t\t\tvar withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);\n\n\t\t\treturn (betweenAngles && withinRadius);\n\t\t}\n\t\treturn false;\n\t},\n\n\tgetCenterPoint: function() {\n\t\tvar vm = this._view;\n\t\tvar halfAngle = (vm.startAngle + vm.endAngle) / 2;\n\t\tvar halfRadius = (vm.innerRadius + vm.outerRadius) / 2;\n\t\treturn {\n\t\t\tx: vm.x + Math.cos(halfAngle) * halfRadius,\n\t\t\ty: vm.y + Math.sin(halfAngle) * halfRadius\n\t\t};\n\t},\n\n\tgetArea: function() {\n\t\tvar vm = this._view;\n\t\treturn Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2));\n\t},\n\n\ttooltipPosition: function() {\n\t\tvar vm = this._view;\n\t\tvar centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2);\n\t\tvar rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;\n\n\t\treturn {\n\t\t\tx: vm.x + (Math.cos(centreAngle) * rangeFromCentre),\n\t\t\ty: vm.y + (Math.sin(centreAngle) * rangeFromCentre)\n\t\t};\n\t},\n\n\tdraw: function() {\n\t\tvar ctx = this._chart.ctx;\n\t\tvar vm = this._view;\n\t\tvar pixelMargin = (vm.borderAlign === 'inner') ? 0.33 : 0;\n\t\tvar arc = {\n\t\t\tx: vm.x,\n\t\t\ty: vm.y,\n\t\t\tinnerRadius: vm.innerRadius,\n\t\t\touterRadius: Math.max(vm.outerRadius - pixelMargin, 0),\n\t\t\tpixelMargin: pixelMargin,\n\t\t\tstartAngle: vm.startAngle,\n\t\t\tendAngle: vm.endAngle,\n\t\t\tfullCircles: Math.floor(vm.circumference / TAU)\n\t\t};\n\t\tvar i;\n\n\t\tctx.save();\n\n\t\tctx.fillStyle = vm.backgroundColor;\n\t\tctx.strokeStyle = vm.borderColor;\n\n\t\tif (arc.fullCircles) {\n\t\t\tarc.endAngle = arc.startAngle + TAU;\n\t\t\tctx.beginPath();\n\t\t\tctx.arc(arc.x, arc.y, arc.outerRadius, arc.startAngle, arc.endAngle);\n\t\t\tctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true);\n\t\t\tctx.closePath();\n\t\t\tfor (i = 0; i < arc.fullCircles; ++i) {\n\t\t\t\tctx.fill();\n\t\t\t}\n\t\t\tarc.endAngle = arc.startAngle + vm.circumference % TAU;\n\t\t}\n\n\t\tctx.beginPath();\n\t\tctx.arc(arc.x, arc.y, arc.outerRadius, arc.startAngle, arc.endAngle);\n\t\tctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true);\n\t\tctx.closePath();\n\t\tctx.fill();\n\n\t\tif (vm.borderWidth) {\n\t\t\tdrawBorder(ctx, vm, arc);\n\t\t}\n\n\t\tctx.restore();\n\t}\n});\n\nvar valueOrDefault$1 = helpers$1.valueOrDefault;\n\nvar defaultColor = core_defaults.global.defaultColor;\n\ncore_defaults._set('global', {\n\telements: {\n\t\tline: {\n\t\t\ttension: 0.4,\n\t\t\tbackgroundColor: defaultColor,\n\t\t\tborderWidth: 3,\n\t\t\tborderColor: defaultColor,\n\t\t\tborderCapStyle: 'butt',\n\t\t\tborderDash: [],\n\t\t\tborderDashOffset: 0.0,\n\t\t\tborderJoinStyle: 'miter',\n\t\t\tcapBezierPoints: true,\n\t\t\tfill: true, // do we fill in the area between the line and its base axis\n\t\t}\n\t}\n});\n\nvar element_line = core_element.extend({\n\t_type: 'line',\n\n\tdraw: function() {\n\t\tvar me = this;\n\t\tvar vm = me._view;\n\t\tvar ctx = me._chart.ctx;\n\t\tvar spanGaps = vm.spanGaps;\n\t\tvar points = me._children.slice(); // clone array\n\t\tvar globalDefaults = core_defaults.global;\n\t\tvar globalOptionLineElements = globalDefaults.elements.line;\n\t\tvar lastDrawnIndex = -1;\n\t\tvar closePath = me._loop;\n\t\tvar index, previous, currentVM;\n\n\t\tif (!points.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (me._loop) {\n\t\t\tfor (index = 0; index < points.length; ++index) {\n\t\t\t\tprevious = helpers$1.previousItem(points, index);\n\t\t\t\t// If the line has an open path, shift the point array\n\t\t\t\tif (!points[index]._view.skip && previous._view.skip) {\n\t\t\t\t\tpoints = points.slice(index).concat(points.slice(0, index));\n\t\t\t\t\tclosePath = spanGaps;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If the line has a close path, add the first point again\n\t\t\tif (closePath) {\n\t\t\t\tpoints.push(points[0]);\n\t\t\t}\n\t\t}\n\n\t\tctx.save();\n\n\t\t// Stroke Line Options\n\t\tctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;\n\n\t\t// IE 9 and 10 do not support line dash\n\t\tif (ctx.setLineDash) {\n\t\t\tctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);\n\t\t}\n\n\t\tctx.lineDashOffset = valueOrDefault$1(vm.borderDashOffset, globalOptionLineElements.borderDashOffset);\n\t\tctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;\n\t\tctx.lineWidth = valueOrDefault$1(vm.borderWidth, globalOptionLineElements.borderWidth);\n\t\tctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;\n\n\t\t// Stroke Line\n\t\tctx.beginPath();\n\n\t\t// First point moves to it's starting position no matter what\n\t\tcurrentVM = points[0]._view;\n\t\tif (!currentVM.skip) {\n\t\t\tctx.moveTo(currentVM.x, currentVM.y);\n\t\t\tlastDrawnIndex = 0;\n\t\t}\n\n\t\tfor (index = 1; index < points.length; ++index) {\n\t\t\tcurrentVM = points[index]._view;\n\t\t\tprevious = lastDrawnIndex === -1 ? helpers$1.previousItem(points, index) : points[lastDrawnIndex];\n\n\t\t\tif (!currentVM.skip) {\n\t\t\t\tif ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) {\n\t\t\t\t\t// There was a gap and this is the first point after the gap\n\t\t\t\t\tctx.moveTo(currentVM.x, currentVM.y);\n\t\t\t\t} else {\n\t\t\t\t\t// Line to next point\n\t\t\t\t\thelpers$1.canvas.lineTo(ctx, previous._view, currentVM);\n\t\t\t\t}\n\t\t\t\tlastDrawnIndex = index;\n\t\t\t}\n\t\t}\n\n\t\tif (closePath) {\n\t\t\tctx.closePath();\n\t\t}\n\n\t\tctx.stroke();\n\t\tctx.restore();\n\t}\n});\n\nvar valueOrDefault$2 = helpers$1.valueOrDefault;\n\nvar defaultColor$1 = core_defaults.global.defaultColor;\n\ncore_defaults._set('global', {\n\telements: {\n\t\tpoint: {\n\t\t\tradius: 3,\n\t\t\tpointStyle: 'circle',\n\t\t\tbackgroundColor: defaultColor$1,\n\t\t\tborderColor: defaultColor$1,\n\t\t\tborderWidth: 1,\n\t\t\t// Hover\n\t\t\thitRadius: 1,\n\t\t\thoverRadius: 4,\n\t\t\thoverBorderWidth: 1\n\t\t}\n\t}\n});\n\nfunction xRange(mouseX) {\n\tvar vm = this._view;\n\treturn vm ? (Math.abs(mouseX - vm.x) < vm.radius + vm.hitRadius) : false;\n}\n\nfunction yRange(mouseY) {\n\tvar vm = this._view;\n\treturn vm ? (Math.abs(mouseY - vm.y) < vm.radius + vm.hitRadius) : false;\n}\n\nvar element_point = core_element.extend({\n\t_type: 'point',\n\n\tinRange: function(mouseX, mouseY) {\n\t\tvar vm = this._view;\n\t\treturn vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;\n\t},\n\n\tinLabelRange: xRange,\n\tinXRange: xRange,\n\tinYRange: yRange,\n\n\tgetCenterPoint: function() {\n\t\tvar vm = this._view;\n\t\treturn {\n\t\t\tx: vm.x,\n\t\t\ty: vm.y\n\t\t};\n\t},\n\n\tgetArea: function() {\n\t\treturn Math.PI * Math.pow(this._view.radius, 2);\n\t},\n\n\ttooltipPosition: function() {\n\t\tvar vm = this._view;\n\t\treturn {\n\t\t\tx: vm.x,\n\t\t\ty: vm.y,\n\t\t\tpadding: vm.radius + vm.borderWidth\n\t\t};\n\t},\n\n\tdraw: function(chartArea) {\n\t\tvar vm = this._view;\n\t\tvar ctx = this._chart.ctx;\n\t\tvar pointStyle = vm.pointStyle;\n\t\tvar rotation = vm.rotation;\n\t\tvar radius = vm.radius;\n\t\tvar x = vm.x;\n\t\tvar y = vm.y;\n\t\tvar globalDefaults = core_defaults.global;\n\t\tvar defaultColor = globalDefaults.defaultColor; // eslint-disable-line no-shadow\n\n\t\tif (vm.skip) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clipping for Points.\n\t\tif (chartArea === undefined || helpers$1.canvas._isPointInArea(vm, chartArea)) {\n\t\t\tctx.strokeStyle = vm.borderColor || defaultColor;\n\t\t\tctx.lineWidth = valueOrDefault$2(vm.borderWidth, globalDefaults.elements.point.borderWidth);\n\t\t\tctx.fillStyle = vm.backgroundColor || defaultColor;\n\t\t\thelpers$1.canvas.drawPoint(ctx, pointStyle, radius, x, y, rotation);\n\t\t}\n\t}\n});\n\nvar defaultColor$2 = core_defaults.global.defaultColor;\n\ncore_defaults._set('global', {\n\telements: {\n\t\trectangle: {\n\t\t\tbackgroundColor: defaultColor$2,\n\t\t\tborderColor: defaultColor$2,\n\t\t\tborderSkipped: 'bottom',\n\t\t\tborderWidth: 0\n\t\t}\n\t}\n});\n\nfunction isVertical(vm) {\n\treturn vm && vm.width !== undefined;\n}\n\n/**\n * Helper function to get the bounds of the bar regardless of the orientation\n * @param bar {Chart.Element.Rectangle} the bar\n * @return {Bounds} bounds of the bar\n * @private\n */\nfunction getBarBounds(vm) {\n\tvar x1, x2, y1, y2, half;\n\n\tif (isVertical(vm)) {\n\t\thalf = vm.width / 2;\n\t\tx1 = vm.x - half;\n\t\tx2 = vm.x + half;\n\t\ty1 = Math.min(vm.y, vm.base);\n\t\ty2 = Math.max(vm.y, vm.base);\n\t} else {\n\t\thalf = vm.height / 2;\n\t\tx1 = Math.min(vm.x, vm.base);\n\t\tx2 = Math.max(vm.x, vm.base);\n\t\ty1 = vm.y - half;\n\t\ty2 = vm.y + half;\n\t}\n\n\treturn {\n\t\tleft: x1,\n\t\ttop: y1,\n\t\tright: x2,\n\t\tbottom: y2\n\t};\n}\n\nfunction swap(orig, v1, v2) {\n\treturn orig === v1 ? v2 : orig === v2 ? v1 : orig;\n}\n\nfunction parseBorderSkipped(vm) {\n\tvar edge = vm.borderSkipped;\n\tvar res = {};\n\n\tif (!edge) {\n\t\treturn res;\n\t}\n\n\tif (vm.horizontal) {\n\t\tif (vm.base > vm.x) {\n\t\t\tedge = swap(edge, 'left', 'right');\n\t\t}\n\t} else if (vm.base < vm.y) {\n\t\tedge = swap(edge, 'bottom', 'top');\n\t}\n\n\tres[edge] = true;\n\treturn res;\n}\n\nfunction parseBorderWidth(vm, maxW, maxH) {\n\tvar value = vm.borderWidth;\n\tvar skip = parseBorderSkipped(vm);\n\tvar t, r, b, l;\n\n\tif (helpers$1.isObject(value)) {\n\t\tt = +value.top || 0;\n\t\tr = +value.right || 0;\n\t\tb = +value.bottom || 0;\n\t\tl = +value.left || 0;\n\t} else {\n\t\tt = r = b = l = +value || 0;\n\t}\n\n\treturn {\n\t\tt: skip.top || (t < 0) ? 0 : t > maxH ? maxH : t,\n\t\tr: skip.right || (r < 0) ? 0 : r > maxW ? maxW : r,\n\t\tb: skip.bottom || (b < 0) ? 0 : b > maxH ? maxH : b,\n\t\tl: skip.left || (l < 0) ? 0 : l > maxW ? maxW : l\n\t};\n}\n\nfunction boundingRects(vm) {\n\tvar bounds = getBarBounds(vm);\n\tvar width = bounds.right - bounds.left;\n\tvar height = bounds.bottom - bounds.top;\n\tvar border = parseBorderWidth(vm, width / 2, height / 2);\n\n\treturn {\n\t\touter: {\n\t\t\tx: bounds.left,\n\t\t\ty: bounds.top,\n\t\t\tw: width,\n\t\t\th: height\n\t\t},\n\t\tinner: {\n\t\t\tx: bounds.left + border.l,\n\t\t\ty: bounds.top + border.t,\n\t\t\tw: width - border.l - border.r,\n\t\t\th: height - border.t - border.b\n\t\t}\n\t};\n}\n\nfunction inRange(vm, x, y) {\n\tvar skipX = x === null;\n\tvar skipY = y === null;\n\tvar bounds = !vm || (skipX && skipY) ? false : getBarBounds(vm);\n\n\treturn bounds\n\t\t&& (skipX || x >= bounds.left && x <= bounds.right)\n\t\t&& (skipY || y >= bounds.top && y <= bounds.bottom);\n}\n\nvar element_rectangle = core_element.extend({\n\t_type: 'rectangle',\n\n\tdraw: function() {\n\t\tvar ctx = this._chart.ctx;\n\t\tvar vm = this._view;\n\t\tvar rects = boundingRects(vm);\n\t\tvar outer = rects.outer;\n\t\tvar inner = rects.inner;\n\n\t\tctx.fillStyle = vm.backgroundColor;\n\t\tctx.fillRect(outer.x, outer.y, outer.w, outer.h);\n\n\t\tif (outer.w === inner.w && outer.h === inner.h) {\n\t\t\treturn;\n\t\t}\n\n\t\tctx.save();\n\t\tctx.beginPath();\n\t\tctx.rect(outer.x, outer.y, outer.w, outer.h);\n\t\tctx.clip();\n\t\tctx.fillStyle = vm.borderColor;\n\t\tctx.rect(inner.x, inner.y, inner.w, inner.h);\n\t\tctx.fill('evenodd');\n\t\tctx.restore();\n\t},\n\n\theight: function() {\n\t\tvar vm = this._view;\n\t\treturn vm.base - vm.y;\n\t},\n\n\tinRange: function(mouseX, mouseY) {\n\t\treturn inRange(this._view, mouseX, mouseY);\n\t},\n\n\tinLabelRange: function(mouseX, mouseY) {\n\t\tvar vm = this._view;\n\t\treturn isVertical(vm)\n\t\t\t? inRange(vm, mouseX, null)\n\t\t\t: inRange(vm, null, mouseY);\n\t},\n\n\tinXRange: function(mouseX) {\n\t\treturn inRange(this._view, mouseX, null);\n\t},\n\n\tinYRange: function(mouseY) {\n\t\treturn inRange(this._view, null, mouseY);\n\t},\n\n\tgetCenterPoint: function() {\n\t\tvar vm = this._view;\n\t\tvar x, y;\n\t\tif (isVertical(vm)) {\n\t\t\tx = vm.x;\n\t\t\ty = (vm.y + vm.base) / 2;\n\t\t} else {\n\t\t\tx = (vm.x + vm.base) / 2;\n\t\t\ty = vm.y;\n\t\t}\n\n\t\treturn {x: x, y: y};\n\t},\n\n\tgetArea: function() {\n\t\tvar vm = this._view;\n\n\t\treturn isVertical(vm)\n\t\t\t? vm.width * Math.abs(vm.y - vm.base)\n\t\t\t: vm.height * Math.abs(vm.x - vm.base);\n\t},\n\n\ttooltipPosition: function() {\n\t\tvar vm = this._view;\n\t\treturn {\n\t\t\tx: vm.x,\n\t\t\ty: vm.y\n\t\t};\n\t}\n});\n\nvar elements = {};\nvar Arc = element_arc;\nvar Line = element_line;\nvar Point = element_point;\nvar Rectangle = element_rectangle;\nelements.Arc = Arc;\nelements.Line = Line;\nelements.Point = Point;\nelements.Rectangle = Rectangle;\n\nvar deprecated = helpers$1._deprecated;\nvar valueOrDefault$3 = helpers$1.valueOrDefault;\n\ncore_defaults._set('bar', {\n\thover: {\n\t\tmode: 'label'\n\t},\n\n\tscales: {\n\t\txAxes: [{\n\t\t\ttype: 'category',\n\t\t\toffset: true,\n\t\t\tgridLines: {\n\t\t\t\toffsetGridLines: true\n\t\t\t}\n\t\t}],\n\n\t\tyAxes: [{\n\t\t\ttype: 'linear'\n\t\t}]\n\t}\n});\n\ncore_defaults._set('global', {\n\tdatasets: {\n\t\tbar: {\n\t\t\tcategoryPercentage: 0.8,\n\t\t\tbarPercentage: 0.9\n\t\t}\n\t}\n});\n\n/**\n * Computes the \"optimal\" sample size to maintain bars equally sized while preventing overlap.\n * @private\n */\nfunction computeMinSampleSize(scale, pixels) {\n\tvar min = scale._length;\n\tvar prev, curr, i, ilen;\n\n\tfor (i = 1, ilen = pixels.length; i < ilen; ++i) {\n\t\tmin = Math.min(min, Math.abs(pixels[i] - pixels[i - 1]));\n\t}\n\n\tfor (i = 0, ilen = scale.getTicks().length; i < ilen; ++i) {\n\t\tcurr = scale.getPixelForTick(i);\n\t\tmin = i > 0 ? Math.min(min, Math.abs(curr - prev)) : min;\n\t\tprev = curr;\n\t}\n\n\treturn min;\n}\n\n/**\n * Computes an \"ideal\" category based on the absolute bar thickness or, if undefined or null,\n * uses the smallest interval (see computeMinSampleSize) that prevents bar overlapping. This\n * mode currently always generates bars equally sized (until we introduce scriptable options?).\n * @private\n */\nfunction computeFitCategoryTraits(index, ruler, options) {\n\tvar thickness = options.barThickness;\n\tvar count = ruler.stackCount;\n\tvar curr = ruler.pixels[index];\n\tvar min = helpers$1.isNullOrUndef(thickness)\n\t\t? computeMinSampleSize(ruler.scale, ruler.pixels)\n\t\t: -1;\n\tvar size, ratio;\n\n\tif (helpers$1.isNullOrUndef(thickness)) {\n\t\tsize = min * options.categoryPercentage;\n\t\tratio = options.barPercentage;\n\t} else {\n\t\t// When bar thickness is enforced, category and bar percentages are ignored.\n\t\t// Note(SB): we could add support for relative bar thickness (e.g. barThickness: '50%')\n\t\t// and deprecate barPercentage since this value is ignored when thickness is absolute.\n\t\tsize = thickness * count;\n\t\tratio = 1;\n\t}\n\n\treturn {\n\t\tchunk: size / count,\n\t\tratio: ratio,\n\t\tstart: curr - (size / 2)\n\t};\n}\n\n/**\n * Computes an \"optimal\" category that globally arranges bars side by side (no gap when\n * percentage options are 1), based on the previous and following categories. This mode\n * generates bars with different widths when data are not evenly spaced.\n * @private\n */\nfunction computeFlexCategoryTraits(index, ruler, options) {\n\tvar pixels = ruler.pixels;\n\tvar curr = pixels[index];\n\tvar prev = index > 0 ? pixels[index - 1] : null;\n\tvar next = index < pixels.length - 1 ? pixels[index + 1] : null;\n\tvar percent = options.categoryPercentage;\n\tvar start, size;\n\n\tif (prev === null) {\n\t\t// first data: its size is double based on the next point or,\n\t\t// if it's also the last data, we use the scale size.\n\t\tprev = curr - (next === null ? ruler.end - ruler.start : next - curr);\n\t}\n\n\tif (next === null) {\n\t\t// last data: its size is also double based on the previous point.\n\t\tnext = curr + curr - prev;\n\t}\n\n\tstart = curr - (curr - Math.min(prev, next)) / 2 * percent;\n\tsize = Math.abs(next - prev) / 2 * percent;\n\n\treturn {\n\t\tchunk: size / ruler.stackCount,\n\t\tratio: options.barPercentage,\n\t\tstart: start\n\t};\n}\n\nvar controller_bar = core_datasetController.extend({\n\n\tdataElementType: elements.Rectangle,\n\n\t/**\n\t * @private\n\t */\n\t_dataElementOptions: [\n\t\t'backgroundColor',\n\t\t'borderColor',\n\t\t'borderSkipped',\n\t\t'borderWidth',\n\t\t'barPercentage',\n\t\t'barThickness',\n\t\t'categoryPercentage',\n\t\t'maxBarThickness',\n\t\t'minBarLength'\n\t],\n\n\tinitialize: function() {\n\t\tvar me = this;\n\t\tvar meta, scaleOpts;\n\n\t\tcore_datasetController.prototype.initialize.apply(me, arguments);\n\n\t\tmeta = me.getMeta();\n\t\tmeta.stack = me.getDataset().stack;\n\t\tmeta.bar = true;\n\n\t\tscaleOpts = me._getIndexScale().options;\n\t\tdeprecated('bar chart', scaleOpts.barPercentage, 'scales.[x/y]Axes.barPercentage', 'dataset.barPercentage');\n\t\tdeprecated('bar chart', scaleOpts.barThickness, 'scales.[x/y]Axes.barThickness', 'dataset.barThickness');\n\t\tdeprecated('bar chart', scaleOpts.categoryPercentage, 'scales.[x/y]Axes.categoryPercentage', 'dataset.categoryPercentage');\n\t\tdeprecated('bar chart', me._getValueScale().options.minBarLength, 'scales.[x/y]Axes.minBarLength', 'dataset.minBarLength');\n\t\tdeprecated('bar chart', scaleOpts.maxBarThickness, 'scales.[x/y]Axes.maxBarThickness', 'dataset.maxBarThickness');\n\t},\n\n\tupdate: function(reset) {\n\t\tvar me = this;\n\t\tvar rects = me.getMeta().data;\n\t\tvar i, ilen;\n\n\t\tme._ruler = me.getRuler();\n\n\t\tfor (i = 0, ilen = rects.length; i < ilen; ++i) {\n\t\t\tme.updateElement(rects[i], i, reset);\n\t\t}\n\t},\n\n\tupdateElement: function(rectangle, index, reset) {\n\t\tvar me = this;\n\t\tvar meta = me.getMeta();\n\t\tvar dataset = me.getDataset();\n\t\tvar options = me._resolveDataElementOptions(rectangle, index);\n\n\t\trectangle._xScale = me.getScaleForId(meta.xAxisID);\n\t\trectangle._yScale = me.getScaleForId(meta.yAxisID);\n\t\trectangle._datasetIndex = me.index;\n\t\trectangle._index = index;\n\t\trectangle._model = {\n\t\t\tbackgroundColor: options.backgroundColor,\n\t\t\tborderColor: options.borderColor,\n\t\t\tborderSkipped: options.borderSkipped,\n\t\t\tborderWidth: options.borderWidth,\n\t\t\tdatasetLabel: dataset.label,\n\t\t\tlabel: me.chart.data.labels[index]\n\t\t};\n\n\t\tif (helpers$1.isArray(dataset.data[index])) {\n\t\t\trectangle._model.borderSkipped = null;\n\t\t}\n\n\t\tme._updateElementGeometry(rectangle, index, reset, options);\n\n\t\trectangle.pivot();\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_updateElementGeometry: function(rectangle, index, reset, options) {\n\t\tvar me = this;\n\t\tvar model = rectangle._model;\n\t\tvar vscale = me._getValueScale();\n\t\tvar base = vscale.getBasePixel();\n\t\tvar horizontal = vscale.isHorizontal();\n\t\tvar ruler = me._ruler || me.getRuler();\n\t\tvar vpixels = me.calculateBarValuePixels(me.index, index, options);\n\t\tvar ipixels = me.calculateBarIndexPixels(me.index, index, ruler, options);\n\n\t\tmodel.horizontal = horizontal;\n\t\tmodel.base = reset ? base : vpixels.base;\n\t\tmodel.x = horizontal ? reset ? base : vpixels.head : ipixels.center;\n\t\tmodel.y = horizontal ? ipixels.center : reset ? base : vpixels.head;\n\t\tmodel.height = horizontal ? ipixels.size : undefined;\n\t\tmodel.width = horizontal ? undefined : ipixels.size;\n\t},\n\n\t/**\n\t * Returns the stacks based on groups and bar visibility.\n\t * @param {number} [last] - The dataset index\n\t * @returns {string[]} The list of stack IDs\n\t * @private\n\t */\n\t_getStacks: function(last) {\n\t\tvar me = this;\n\t\tvar scale = me._getIndexScale();\n\t\tvar metasets = scale._getMatchingVisibleMetas(me._type);\n\t\tvar stacked = scale.options.stacked;\n\t\tvar ilen = metasets.length;\n\t\tvar stacks = [];\n\t\tvar i, meta;\n\n\t\tfor (i = 0; i < ilen; ++i) {\n\t\t\tmeta = metasets[i];\n\t\t\t// stacked | meta.stack\n\t\t\t// | found | not found | undefined\n\t\t\t// false | x | x | x\n\t\t\t// true | | x |\n\t\t\t// undefined | | x | x\n\t\t\tif (stacked === false || stacks.indexOf(meta.stack) === -1 ||\n\t\t\t\t(stacked === undefined && meta.stack === undefined)) {\n\t\t\t\tstacks.push(meta.stack);\n\t\t\t}\n\t\t\tif (meta.index === last) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn stacks;\n\t},\n\n\t/**\n\t * Returns the effective number of stacks based on groups and bar visibility.\n\t * @private\n\t */\n\tgetStackCount: function() {\n\t\treturn this._getStacks().length;\n\t},\n\n\t/**\n\t * Returns the stack index for the given dataset based on groups and bar visibility.\n\t * @param {number} [datasetIndex] - The dataset index\n\t * @param {string} [name] - The stack name to find\n\t * @returns {number} The stack index\n\t * @private\n\t */\n\tgetStackIndex: function(datasetIndex, name) {\n\t\tvar stacks = this._getStacks(datasetIndex);\n\t\tvar index = (name !== undefined)\n\t\t\t? stacks.indexOf(name)\n\t\t\t: -1; // indexOf returns -1 if element is not present\n\n\t\treturn (index === -1)\n\t\t\t? stacks.length - 1\n\t\t\t: index;\n\t},\n\n\t/**\n\t * @private\n\t */\n\tgetRuler: function() {\n\t\tvar me = this;\n\t\tvar scale = me._getIndexScale();\n\t\tvar pixels = [];\n\t\tvar i, ilen;\n\n\t\tfor (i = 0, ilen = me.getMeta().data.length; i < ilen; ++i) {\n\t\t\tpixels.push(scale.getPixelForValue(null, i, me.index));\n\t\t}\n\n\t\treturn {\n\t\t\tpixels: pixels,\n\t\t\tstart: scale._startPixel,\n\t\t\tend: scale._endPixel,\n\t\t\tstackCount: me.getStackCount(),\n\t\t\tscale: scale\n\t\t};\n\t},\n\n\t/**\n\t * Note: pixel values are not clamped to the scale area.\n\t * @private\n\t */\n\tcalculateBarValuePixels: function(datasetIndex, index, options) {\n\t\tvar me = this;\n\t\tvar chart = me.chart;\n\t\tvar scale = me._getValueScale();\n\t\tvar isHorizontal = scale.isHorizontal();\n\t\tvar datasets = chart.data.datasets;\n\t\tvar metasets = scale._getMatchingVisibleMetas(me._type);\n\t\tvar value = scale._parseValue(datasets[datasetIndex].data[index]);\n\t\tvar minBarLength = options.minBarLength;\n\t\tvar stacked = scale.options.stacked;\n\t\tvar stack = me.getMeta().stack;\n\t\tvar start = value.start === undefined ? 0 : value.max >= 0 && value.min >= 0 ? value.min : value.max;\n\t\tvar length = value.start === undefined ? value.end : value.max >= 0 && value.min >= 0 ? value.max - value.min : value.min - value.max;\n\t\tvar ilen = metasets.length;\n\t\tvar i, imeta, ivalue, base, head, size, stackLength;\n\n\t\tif (stacked || (stacked === undefined && stack !== undefined)) {\n\t\t\tfor (i = 0; i < ilen; ++i) {\n\t\t\t\timeta = metasets[i];\n\n\t\t\t\tif (imeta.index === datasetIndex) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (imeta.stack === stack) {\n\t\t\t\t\tstackLength = scale._parseValue(datasets[imeta.index].data[index]);\n\t\t\t\t\tivalue = stackLength.start === undefined ? stackLength.end : stackLength.min >= 0 && stackLength.max >= 0 ? stackLength.max : stackLength.min;\n\n\t\t\t\t\tif ((value.min < 0 && ivalue < 0) || (value.max >= 0 && ivalue > 0)) {\n\t\t\t\t\t\tstart += ivalue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbase = scale.getPixelForValue(start);\n\t\thead = scale.getPixelForValue(start + length);\n\t\tsize = head - base;\n\n\t\tif (minBarLength !== undefined && Math.abs(size) < minBarLength) {\n\t\t\tsize = minBarLength;\n\t\t\tif (length >= 0 && !isHorizontal || length < 0 && isHorizontal) {\n\t\t\t\thead = base - minBarLength;\n\t\t\t} else {\n\t\t\t\thead = base + minBarLength;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tsize: size,\n\t\t\tbase: base,\n\t\t\thead: head,\n\t\t\tcenter: head + size / 2\n\t\t};\n\t},\n\n\t/**\n\t * @private\n\t */\n\tcalculateBarIndexPixels: function(datasetIndex, index, ruler, options) {\n\t\tvar me = this;\n\t\tvar range = options.barThickness === 'flex'\n\t\t\t? computeFlexCategoryTraits(index, ruler, options)\n\t\t\t: computeFitCategoryTraits(index, ruler, options);\n\n\t\tvar stackIndex = me.getStackIndex(datasetIndex, me.getMeta().stack);\n\t\tvar center = range.start + (range.chunk * stackIndex) + (range.chunk / 2);\n\t\tvar size = Math.min(\n\t\t\tvalueOrDefault$3(options.maxBarThickness, Infinity),\n\t\t\trange.chunk * range.ratio);\n\n\t\treturn {\n\t\t\tbase: center - size / 2,\n\t\t\thead: center + size / 2,\n\t\t\tcenter: center,\n\t\t\tsize: size\n\t\t};\n\t},\n\n\tdraw: function() {\n\t\tvar me = this;\n\t\tvar chart = me.chart;\n\t\tvar scale = me._getValueScale();\n\t\tvar rects = me.getMeta().data;\n\t\tvar dataset = me.getDataset();\n\t\tvar ilen = rects.length;\n\t\tvar i = 0;\n\n\t\thelpers$1.canvas.clipArea(chart.ctx, chart.chartArea);\n\n\t\tfor (; i < ilen; ++i) {\n\t\t\tvar val = scale._parseValue(dataset.data[i]);\n\t\t\tif (!isNaN(val.min) && !isNaN(val.max)) {\n\t\t\t\trects[i].draw();\n\t\t\t}\n\t\t}\n\n\t\thelpers$1.canvas.unclipArea(chart.ctx);\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_resolveDataElementOptions: function() {\n\t\tvar me = this;\n\t\tvar values = helpers$1.extend({}, core_datasetController.prototype._resolveDataElementOptions.apply(me, arguments));\n\t\tvar indexOpts = me._getIndexScale().options;\n\t\tvar valueOpts = me._getValueScale().options;\n\n\t\tvalues.barPercentage = valueOrDefault$3(indexOpts.barPercentage, values.barPercentage);\n\t\tvalues.barThickness = valueOrDefault$3(indexOpts.barThickness, values.barThickness);\n\t\tvalues.categoryPercentage = valueOrDefault$3(indexOpts.categoryPercentage, values.categoryPercentage);\n\t\tvalues.maxBarThickness = valueOrDefault$3(indexOpts.maxBarThickness, values.maxBarThickness);\n\t\tvalues.minBarLength = valueOrDefault$3(valueOpts.minBarLength, values.minBarLength);\n\n\t\treturn values;\n\t}\n\n});\n\nvar valueOrDefault$4 = helpers$1.valueOrDefault;\nvar resolve$1 = helpers$1.options.resolve;\n\ncore_defaults._set('bubble', {\n\thover: {\n\t\tmode: 'single'\n\t},\n\n\tscales: {\n\t\txAxes: [{\n\t\t\ttype: 'linear', // bubble should probably use a linear scale by default\n\t\t\tposition: 'bottom',\n\t\t\tid: 'x-axis-0' // need an ID so datasets can reference the scale\n\t\t}],\n\t\tyAxes: [{\n\t\t\ttype: 'linear',\n\t\t\tposition: 'left',\n\t\t\tid: 'y-axis-0'\n\t\t}]\n\t},\n\n\ttooltips: {\n\t\tcallbacks: {\n\t\t\ttitle: function() {\n\t\t\t\t// Title doesn't make sense for scatter since we format the data as a point\n\t\t\t\treturn '';\n\t\t\t},\n\t\t\tlabel: function(item, data) {\n\t\t\t\tvar datasetLabel = data.datasets[item.datasetIndex].label || '';\n\t\t\t\tvar dataPoint = data.datasets[item.datasetIndex].data[item.index];\n\t\t\t\treturn datasetLabel + ': (' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.r + ')';\n\t\t\t}\n\t\t}\n\t}\n});\n\nvar controller_bubble = core_datasetController.extend({\n\t/**\n\t * @protected\n\t */\n\tdataElementType: elements.Point,\n\n\t/**\n\t * @private\n\t */\n\t_dataElementOptions: [\n\t\t'backgroundColor',\n\t\t'borderColor',\n\t\t'borderWidth',\n\t\t'hoverBackgroundColor',\n\t\t'hoverBorderColor',\n\t\t'hoverBorderWidth',\n\t\t'hoverRadius',\n\t\t'hitRadius',\n\t\t'pointStyle',\n\t\t'rotation'\n\t],\n\n\t/**\n\t * @protected\n\t */\n\tupdate: function(reset) {\n\t\tvar me = this;\n\t\tvar meta = me.getMeta();\n\t\tvar points = meta.data;\n\n\t\t// Update Points\n\t\thelpers$1.each(points, function(point, index) {\n\t\t\tme.updateElement(point, index, reset);\n\t\t});\n\t},\n\n\t/**\n\t * @protected\n\t */\n\tupdateElement: function(point, index, reset) {\n\t\tvar me = this;\n\t\tvar meta = me.getMeta();\n\t\tvar custom = point.custom || {};\n\t\tvar xScale = me.getScaleForId(meta.xAxisID);\n\t\tvar yScale = me.getScaleForId(meta.yAxisID);\n\t\tvar options = me._resolveDataElementOptions(point, index);\n\t\tvar data = me.getDataset().data[index];\n\t\tvar dsIndex = me.index;\n\n\t\tvar x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex);\n\t\tvar y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex);\n\n\t\tpoint._xScale = xScale;\n\t\tpoint._yScale = yScale;\n\t\tpoint._options = options;\n\t\tpoint._datasetIndex = dsIndex;\n\t\tpoint._index = index;\n\t\tpoint._model = {\n\t\t\tbackgroundColor: options.backgroundColor,\n\t\t\tborderColor: options.borderColor,\n\t\t\tborderWidth: options.borderWidth,\n\t\t\thitRadius: options.hitRadius,\n\t\t\tpointStyle: options.pointStyle,\n\t\t\trotation: options.rotation,\n\t\t\tradius: reset ? 0 : options.radius,\n\t\t\tskip: custom.skip || isNaN(x) || isNaN(y),\n\t\t\tx: x,\n\t\t\ty: y,\n\t\t};\n\n\t\tpoint.pivot();\n\t},\n\n\t/**\n\t * @protected\n\t */\n\tsetHoverStyle: function(point) {\n\t\tvar model = point._model;\n\t\tvar options = point._options;\n\t\tvar getHoverColor = helpers$1.getHoverColor;\n\n\t\tpoint.$previousStyle = {\n\t\t\tbackgroundColor: model.backgroundColor,\n\t\t\tborderColor: model.borderColor,\n\t\t\tborderWidth: model.borderWidth,\n\t\t\tradius: model.radius\n\t\t};\n\n\t\tmodel.backgroundColor = valueOrDefault$4(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));\n\t\tmodel.borderColor = valueOrDefault$4(options.hoverBorderColor, getHoverColor(options.borderColor));\n\t\tmodel.borderWidth = valueOrDefault$4(options.hoverBorderWidth, options.borderWidth);\n\t\tmodel.radius = options.radius + options.hoverRadius;\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_resolveDataElementOptions: function(point, index) {\n\t\tvar me = this;\n\t\tvar chart = me.chart;\n\t\tvar dataset = me.getDataset();\n\t\tvar custom = point.custom || {};\n\t\tvar data = dataset.data[index] || {};\n\t\tvar values = core_datasetController.prototype._resolveDataElementOptions.apply(me, arguments);\n\n\t\t// Scriptable options\n\t\tvar context = {\n\t\t\tchart: chart,\n\t\t\tdataIndex: index,\n\t\t\tdataset: dataset,\n\t\t\tdatasetIndex: me.index\n\t\t};\n\n\t\t// In case values were cached (and thus frozen), we need to clone the values\n\t\tif (me._cachedDataOpts === values) {\n\t\t\tvalues = helpers$1.extend({}, values);\n\t\t}\n\n\t\t// Custom radius resolution\n\t\tvalues.radius = resolve$1([\n\t\t\tcustom.radius,\n\t\t\tdata.r,\n\t\t\tme._config.radius,\n\t\t\tchart.options.elements.point.radius\n\t\t], context, index);\n\n\t\treturn values;\n\t}\n});\n\nvar valueOrDefault$5 = helpers$1.valueOrDefault;\n\nvar PI$1 = Math.PI;\nvar DOUBLE_PI$1 = PI$1 * 2;\nvar HALF_PI$1 = PI$1 / 2;\n\ncore_defaults._set('doughnut', {\n\tanimation: {\n\t\t// Boolean - Whether we animate the rotation of the Doughnut\n\t\tanimateRotate: true,\n\t\t// Boolean - Whether we animate scaling the Doughnut from the centre\n\t\tanimateScale: false\n\t},\n\thover: {\n\t\tmode: 'single'\n\t},\n\tlegendCallback: function(chart) {\n\t\tvar list = document.createElement('ul');\n\t\tvar data = chart.data;\n\t\tvar datasets = data.datasets;\n\t\tvar labels = data.labels;\n\t\tvar i, ilen, listItem, listItemSpan;\n\n\t\tlist.setAttribute('class', chart.id + '-legend');\n\t\tif (datasets.length) {\n\t\t\tfor (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) {\n\t\t\t\tlistItem = list.appendChild(document.createElement('li'));\n\t\t\t\tlistItemSpan = listItem.appendChild(document.createElement('span'));\n\t\t\t\tlistItemSpan.style.backgroundColor = datasets[0].backgroundColor[i];\n\t\t\t\tif (labels[i]) {\n\t\t\t\t\tlistItem.appendChild(document.createTextNode(labels[i]));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn list.outerHTML;\n\t},\n\tlegend: {\n\t\tlabels: {\n\t\t\tgenerateLabels: function(chart) {\n\t\t\t\tvar data = chart.data;\n\t\t\t\tif (data.labels.length && data.datasets.length) {\n\t\t\t\t\treturn data.labels.map(function(label, i) {\n\t\t\t\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\t\t\t\tvar style = meta.controller.getStyle(i);\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttext: label,\n\t\t\t\t\t\t\tfillStyle: style.backgroundColor,\n\t\t\t\t\t\t\tstrokeStyle: style.borderColor,\n\t\t\t\t\t\t\tlineWidth: style.borderWidth,\n\t\t\t\t\t\t\thidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden,\n\n\t\t\t\t\t\t\t// Extra data used for toggling the correct item\n\t\t\t\t\t\t\tindex: i\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn [];\n\t\t\t}\n\t\t},\n\n\t\tonClick: function(e, legendItem) {\n\t\t\tvar index = legendItem.index;\n\t\t\tvar chart = this.chart;\n\t\t\tvar i, ilen, meta;\n\n\t\t\tfor (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\n\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\t// toggle visibility of index if exists\n\t\t\t\tif (meta.data[index]) {\n\t\t\t\t\tmeta.data[index].hidden = !meta.data[index].hidden;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tchart.update();\n\t\t}\n\t},\n\n\t// The percentage of the chart that we cut out of the middle.\n\tcutoutPercentage: 50,\n\n\t// The rotation of the chart, where the first data arc begins.\n\trotation: -HALF_PI$1,\n\n\t// The total circumference of the chart.\n\tcircumference: DOUBLE_PI$1,\n\n\t// Need to override these to give a nice default\n\ttooltips: {\n\t\tcallbacks: {\n\t\t\ttitle: function() {\n\t\t\t\treturn '';\n\t\t\t},\n\t\t\tlabel: function(tooltipItem, data) {\n\t\t\t\tvar dataLabel = data.labels[tooltipItem.index];\n\t\t\t\tvar value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\n\n\t\t\t\tif (helpers$1.isArray(dataLabel)) {\n\t\t\t\t\t// show value on first line of multiline label\n\t\t\t\t\t// need to clone because we are changing the value\n\t\t\t\t\tdataLabel = dataLabel.slice();\n\t\t\t\t\tdataLabel[0] += value;\n\t\t\t\t} else {\n\t\t\t\t\tdataLabel += value;\n\t\t\t\t}\n\n\t\t\t\treturn dataLabel;\n\t\t\t}\n\t\t}\n\t}\n});\n\nvar controller_doughnut = core_datasetController.extend({\n\n\tdataElementType: elements.Arc,\n\n\tlinkScales: helpers$1.noop,\n\n\t/**\n\t * @private\n\t */\n\t_dataElementOptions: [\n\t\t'backgroundColor',\n\t\t'borderColor',\n\t\t'borderWidth',\n\t\t'borderAlign',\n\t\t'hoverBackgroundColor',\n\t\t'hoverBorderColor',\n\t\t'hoverBorderWidth',\n\t],\n\n\t// Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly\n\tgetRingIndex: function(datasetIndex) {\n\t\tvar ringIndex = 0;\n\n\t\tfor (var j = 0; j < datasetIndex; ++j) {\n\t\t\tif (this.chart.isDatasetVisible(j)) {\n\t\t\t\t++ringIndex;\n\t\t\t}\n\t\t}\n\n\t\treturn ringIndex;\n\t},\n\n\tupdate: function(reset) {\n\t\tvar me = this;\n\t\tvar chart = me.chart;\n\t\tvar chartArea = chart.chartArea;\n\t\tvar opts = chart.options;\n\t\tvar ratioX = 1;\n\t\tvar ratioY = 1;\n\t\tvar offsetX = 0;\n\t\tvar offsetY = 0;\n\t\tvar meta = me.getMeta();\n\t\tvar arcs = meta.data;\n\t\tvar cutout = opts.cutoutPercentage / 100 || 0;\n\t\tvar circumference = opts.circumference;\n\t\tvar chartWeight = me._getRingWeight(me.index);\n\t\tvar maxWidth, maxHeight, i, ilen;\n\n\t\t// If the chart's circumference isn't a full circle, calculate size as a ratio of the width/height of the arc\n\t\tif (circumference < DOUBLE_PI$1) {\n\t\t\tvar startAngle = opts.rotation % DOUBLE_PI$1;\n\t\t\tstartAngle += startAngle >= PI$1 ? -DOUBLE_PI$1 : startAngle < -PI$1 ? DOUBLE_PI$1 : 0;\n\t\t\tvar endAngle = startAngle + circumference;\n\t\t\tvar startX = Math.cos(startAngle);\n\t\t\tvar startY = Math.sin(startAngle);\n\t\t\tvar endX = Math.cos(endAngle);\n\t\t\tvar endY = Math.sin(endAngle);\n\t\t\tvar contains0 = (startAngle <= 0 && endAngle >= 0) || endAngle >= DOUBLE_PI$1;\n\t\t\tvar contains90 = (startAngle <= HALF_PI$1 && endAngle >= HALF_PI$1) || endAngle >= DOUBLE_PI$1 + HALF_PI$1;\n\t\t\tvar contains180 = startAngle === -PI$1 || endAngle >= PI$1;\n\t\t\tvar contains270 = (startAngle <= -HALF_PI$1 && endAngle >= -HALF_PI$1) || endAngle >= PI$1 + HALF_PI$1;\n\t\t\tvar minX = contains180 ? -1 : Math.min(startX, startX * cutout, endX, endX * cutout);\n\t\t\tvar minY = contains270 ? -1 : Math.min(startY, startY * cutout, endY, endY * cutout);\n\t\t\tvar maxX = contains0 ? 1 : Math.max(startX, startX * cutout, endX, endX * cutout);\n\t\t\tvar maxY = contains90 ? 1 : Math.max(startY, startY * cutout, endY, endY * cutout);\n\t\t\tratioX = (maxX - minX) / 2;\n\t\t\tratioY = (maxY - minY) / 2;\n\t\t\toffsetX = -(maxX + minX) / 2;\n\t\t\toffsetY = -(maxY + minY) / 2;\n\t\t}\n\n\t\tfor (i = 0, ilen = arcs.length; i < ilen; ++i) {\n\t\t\tarcs[i]._options = me._resolveDataElementOptions(arcs[i], i);\n\t\t}\n\n\t\tchart.borderWidth = me.getMaxBorderWidth();\n\t\tmaxWidth = (chartArea.right - chartArea.left - chart.borderWidth) / ratioX;\n\t\tmaxHeight = (chartArea.bottom - chartArea.top - chart.borderWidth) / ratioY;\n\t\tchart.outerRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0);\n\t\tchart.innerRadius = Math.max(chart.outerRadius * cutout, 0);\n\t\tchart.radiusLength = (chart.outerRadius - chart.innerRadius) / (me._getVisibleDatasetWeightTotal() || 1);\n\t\tchart.offsetX = offsetX * chart.outerRadius;\n\t\tchart.offsetY = offsetY * chart.outerRadius;\n\n\t\tmeta.total = me.calculateTotal();\n\n\t\tme.outerRadius = chart.outerRadius - chart.radiusLength * me._getRingWeightOffset(me.index);\n\t\tme.innerRadius = Math.max(me.outerRadius - chart.radiusLength * chartWeight, 0);\n\n\t\tfor (i = 0, ilen = arcs.length; i < ilen; ++i) {\n\t\t\tme.updateElement(arcs[i], i, reset);\n\t\t}\n\t},\n\n\tupdateElement: function(arc, index, reset) {\n\t\tvar me = this;\n\t\tvar chart = me.chart;\n\t\tvar chartArea = chart.chartArea;\n\t\tvar opts = chart.options;\n\t\tvar animationOpts = opts.animation;\n\t\tvar centerX = (chartArea.left + chartArea.right) / 2;\n\t\tvar centerY = (chartArea.top + chartArea.bottom) / 2;\n\t\tvar startAngle = opts.rotation; // non reset case handled later\n\t\tvar endAngle = opts.rotation; // non reset case handled later\n\t\tvar dataset = me.getDataset();\n\t\tvar circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / DOUBLE_PI$1);\n\t\tvar innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius;\n\t\tvar outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius;\n\t\tvar options = arc._options || {};\n\n\t\thelpers$1.extend(arc, {\n\t\t\t// Utility\n\t\t\t_datasetIndex: me.index,\n\t\t\t_index: index,\n\n\t\t\t// Desired view properties\n\t\t\t_model: {\n\t\t\t\tbackgroundColor: options.backgroundColor,\n\t\t\t\tborderColor: options.borderColor,\n\t\t\t\tborderWidth: options.borderWidth,\n\t\t\t\tborderAlign: options.borderAlign,\n\t\t\t\tx: centerX + chart.offsetX,\n\t\t\t\ty: centerY + chart.offsetY,\n\t\t\t\tstartAngle: startAngle,\n\t\t\t\tendAngle: endAngle,\n\t\t\t\tcircumference: circumference,\n\t\t\t\touterRadius: outerRadius,\n\t\t\t\tinnerRadius: innerRadius,\n\t\t\t\tlabel: helpers$1.valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])\n\t\t\t}\n\t\t});\n\n\t\tvar model = arc._model;\n\n\t\t// Set correct angles if not resetting\n\t\tif (!reset || !animationOpts.animateRotate) {\n\t\t\tif (index === 0) {\n\t\t\t\tmodel.startAngle = opts.rotation;\n\t\t\t} else {\n\t\t\t\tmodel.startAngle = me.getMeta().data[index - 1]._model.endAngle;\n\t\t\t}\n\n\t\t\tmodel.endAngle = model.startAngle + model.circumference;\n\t\t}\n\n\t\tarc.pivot();\n\t},\n\n\tcalculateTotal: function() {\n\t\tvar dataset = this.getDataset();\n\t\tvar meta = this.getMeta();\n\t\tvar total = 0;\n\t\tvar value;\n\n\t\thelpers$1.each(meta.data, function(element, index) {\n\t\t\tvalue = dataset.data[index];\n\t\t\tif (!isNaN(value) && !element.hidden) {\n\t\t\t\ttotal += Math.abs(value);\n\t\t\t}\n\t\t});\n\n\t\t/* if (total === 0) {\n\t\t\ttotal = NaN;\n\t\t}*/\n\n\t\treturn total;\n\t},\n\n\tcalculateCircumference: function(value) {\n\t\tvar total = this.getMeta().total;\n\t\tif (total > 0 && !isNaN(value)) {\n\t\t\treturn DOUBLE_PI$1 * (Math.abs(value) / total);\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// gets the max border or hover width to properly scale pie charts\n\tgetMaxBorderWidth: function(arcs) {\n\t\tvar me = this;\n\t\tvar max = 0;\n\t\tvar chart = me.chart;\n\t\tvar i, ilen, meta, arc, controller, options, borderWidth, hoverWidth;\n\n\t\tif (!arcs) {\n\t\t\t// Find the outmost visible dataset\n\t\t\tfor (i = 0, ilen = chart.data.datasets.length; i < ilen; ++i) {\n\t\t\t\tif (chart.isDatasetVisible(i)) {\n\t\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\t\tarcs = meta.data;\n\t\t\t\t\tif (i !== me.index) {\n\t\t\t\t\t\tcontroller = meta.controller;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!arcs) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tfor (i = 0, ilen = arcs.length; i < ilen; ++i) {\n\t\t\tarc = arcs[i];\n\t\t\tif (controller) {\n\t\t\t\tcontroller._configure();\n\t\t\t\toptions = controller._resolveDataElementOptions(arc, i);\n\t\t\t} else {\n\t\t\t\toptions = arc._options;\n\t\t\t}\n\t\t\tif (options.borderAlign !== 'inner') {\n\t\t\t\tborderWidth = options.borderWidth;\n\t\t\t\thoverWidth = options.hoverBorderWidth;\n\n\t\t\t\tmax = borderWidth > max ? borderWidth : max;\n\t\t\t\tmax = hoverWidth > max ? hoverWidth : max;\n\t\t\t}\n\t\t}\n\t\treturn max;\n\t},\n\n\t/**\n\t * @protected\n\t */\n\tsetHoverStyle: function(arc) {\n\t\tvar model = arc._model;\n\t\tvar options = arc._options;\n\t\tvar getHoverColor = helpers$1.getHoverColor;\n\n\t\tarc.$previousStyle = {\n\t\t\tbackgroundColor: model.backgroundColor,\n\t\t\tborderColor: model.borderColor,\n\t\t\tborderWidth: model.borderWidth,\n\t\t};\n\n\t\tmodel.backgroundColor = valueOrDefault$5(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));\n\t\tmodel.borderColor = valueOrDefault$5(options.hoverBorderColor, getHoverColor(options.borderColor));\n\t\tmodel.borderWidth = valueOrDefault$5(options.hoverBorderWidth, options.borderWidth);\n\t},\n\n\t/**\n\t * Get radius length offset of the dataset in relation to the visible datasets weights. This allows determining the inner and outer radius correctly\n\t * @private\n\t */\n\t_getRingWeightOffset: function(datasetIndex) {\n\t\tvar ringWeightOffset = 0;\n\n\t\tfor (var i = 0; i < datasetIndex; ++i) {\n\t\t\tif (this.chart.isDatasetVisible(i)) {\n\t\t\t\tringWeightOffset += this._getRingWeight(i);\n\t\t\t}\n\t\t}\n\n\t\treturn ringWeightOffset;\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_getRingWeight: function(dataSetIndex) {\n\t\treturn Math.max(valueOrDefault$5(this.chart.data.datasets[dataSetIndex].weight, 1), 0);\n\t},\n\n\t/**\n\t * Returns the sum of all visibile data set weights. This value can be 0.\n\t * @private\n\t */\n\t_getVisibleDatasetWeightTotal: function() {\n\t\treturn this._getRingWeightOffset(this.chart.data.datasets.length);\n\t}\n});\n\ncore_defaults._set('horizontalBar', {\n\thover: {\n\t\tmode: 'index',\n\t\taxis: 'y'\n\t},\n\n\tscales: {\n\t\txAxes: [{\n\t\t\ttype: 'linear',\n\t\t\tposition: 'bottom'\n\t\t}],\n\n\t\tyAxes: [{\n\t\t\ttype: 'category',\n\t\t\tposition: 'left',\n\t\t\toffset: true,\n\t\t\tgridLines: {\n\t\t\t\toffsetGridLines: true\n\t\t\t}\n\t\t}]\n\t},\n\n\telements: {\n\t\trectangle: {\n\t\t\tborderSkipped: 'left'\n\t\t}\n\t},\n\n\ttooltips: {\n\t\tmode: 'index',\n\t\taxis: 'y'\n\t}\n});\n\ncore_defaults._set('global', {\n\tdatasets: {\n\t\thorizontalBar: {\n\t\t\tcategoryPercentage: 0.8,\n\t\t\tbarPercentage: 0.9\n\t\t}\n\t}\n});\n\nvar controller_horizontalBar = controller_bar.extend({\n\t/**\n\t * @private\n\t */\n\t_getValueScaleId: function() {\n\t\treturn this.getMeta().xAxisID;\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_getIndexScaleId: function() {\n\t\treturn this.getMeta().yAxisID;\n\t}\n});\n\nvar valueOrDefault$6 = helpers$1.valueOrDefault;\nvar resolve$2 = helpers$1.options.resolve;\nvar isPointInArea = helpers$1.canvas._isPointInArea;\n\ncore_defaults._set('line', {\n\tshowLines: true,\n\tspanGaps: false,\n\n\thover: {\n\t\tmode: 'label'\n\t},\n\n\tscales: {\n\t\txAxes: [{\n\t\t\ttype: 'category',\n\t\t\tid: 'x-axis-0'\n\t\t}],\n\t\tyAxes: [{\n\t\t\ttype: 'linear',\n\t\t\tid: 'y-axis-0'\n\t\t}]\n\t}\n});\n\nfunction scaleClip(scale, halfBorderWidth) {\n\tvar tickOpts = scale && scale.options.ticks || {};\n\tvar reverse = tickOpts.reverse;\n\tvar min = tickOpts.min === undefined ? halfBorderWidth : 0;\n\tvar max = tickOpts.max === undefined ? halfBorderWidth : 0;\n\treturn {\n\t\tstart: reverse ? max : min,\n\t\tend: reverse ? min : max\n\t};\n}\n\nfunction defaultClip(xScale, yScale, borderWidth) {\n\tvar halfBorderWidth = borderWidth / 2;\n\tvar x = scaleClip(xScale, halfBorderWidth);\n\tvar y = scaleClip(yScale, halfBorderWidth);\n\n\treturn {\n\t\ttop: y.end,\n\t\tright: x.end,\n\t\tbottom: y.start,\n\t\tleft: x.start\n\t};\n}\n\nfunction toClip(value) {\n\tvar t, r, b, l;\n\n\tif (helpers$1.isObject(value)) {\n\t\tt = value.top;\n\t\tr = value.right;\n\t\tb = value.bottom;\n\t\tl = value.left;\n\t} else {\n\t\tt = r = b = l = value;\n\t}\n\n\treturn {\n\t\ttop: t,\n\t\tright: r,\n\t\tbottom: b,\n\t\tleft: l\n\t};\n}\n\n\nvar controller_line = core_datasetController.extend({\n\n\tdatasetElementType: elements.Line,\n\n\tdataElementType: elements.Point,\n\n\t/**\n\t * @private\n\t */\n\t_datasetElementOptions: [\n\t\t'backgroundColor',\n\t\t'borderCapStyle',\n\t\t'borderColor',\n\t\t'borderDash',\n\t\t'borderDashOffset',\n\t\t'borderJoinStyle',\n\t\t'borderWidth',\n\t\t'cubicInterpolationMode',\n\t\t'fill'\n\t],\n\n\t/**\n\t * @private\n\t */\n\t_dataElementOptions: {\n\t\tbackgroundColor: 'pointBackgroundColor',\n\t\tborderColor: 'pointBorderColor',\n\t\tborderWidth: 'pointBorderWidth',\n\t\thitRadius: 'pointHitRadius',\n\t\thoverBackgroundColor: 'pointHoverBackgroundColor',\n\t\thoverBorderColor: 'pointHoverBorderColor',\n\t\thoverBorderWidth: 'pointHoverBorderWidth',\n\t\thoverRadius: 'pointHoverRadius',\n\t\tpointStyle: 'pointStyle',\n\t\tradius: 'pointRadius',\n\t\trotation: 'pointRotation'\n\t},\n\n\tupdate: function(reset) {\n\t\tvar me = this;\n\t\tvar meta = me.getMeta();\n\t\tvar line = meta.dataset;\n\t\tvar points = meta.data || [];\n\t\tvar options = me.chart.options;\n\t\tvar config = me._config;\n\t\tvar showLine = me._showLine = valueOrDefault$6(config.showLine, options.showLines);\n\t\tvar i, ilen;\n\n\t\tme._xScale = me.getScaleForId(meta.xAxisID);\n\t\tme._yScale = me.getScaleForId(meta.yAxisID);\n\n\t\t// Update Line\n\t\tif (showLine) {\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\t\tif (config.tension !== undefined && config.lineTension === undefined) {\n\t\t\t\tconfig.lineTension = config.tension;\n\t\t\t}\n\n\t\t\t// Utility\n\t\t\tline._scale = me._yScale;\n\t\t\tline._datasetIndex = me.index;\n\t\t\t// Data\n\t\t\tline._children = points;\n\t\t\t// Model\n\t\t\tline._model = me._resolveDatasetElementOptions(line);\n\n\t\t\tline.pivot();\n\t\t}\n\n\t\t// Update Points\n\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\tme.updateElement(points[i], i, reset);\n\t\t}\n\n\t\tif (showLine && line._model.tension !== 0) {\n\t\t\tme.updateBezierControlPoints();\n\t\t}\n\n\t\t// Now pivot the point for animation\n\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\tpoints[i].pivot();\n\t\t}\n\t},\n\n\tupdateElement: function(point, index, reset) {\n\t\tvar me = this;\n\t\tvar meta = me.getMeta();\n\t\tvar custom = point.custom || {};\n\t\tvar dataset = me.getDataset();\n\t\tvar datasetIndex = me.index;\n\t\tvar value = dataset.data[index];\n\t\tvar xScale = me._xScale;\n\t\tvar yScale = me._yScale;\n\t\tvar lineModel = meta.dataset._model;\n\t\tvar x, y;\n\n\t\tvar options = me._resolveDataElementOptions(point, index);\n\n\t\tx = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex);\n\t\ty = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);\n\n\t\t// Utility\n\t\tpoint._xScale = xScale;\n\t\tpoint._yScale = yScale;\n\t\tpoint._options = options;\n\t\tpoint._datasetIndex = datasetIndex;\n\t\tpoint._index = index;\n\n\t\t// Desired view properties\n\t\tpoint._model = {\n\t\t\tx: x,\n\t\t\ty: y,\n\t\t\tskip: custom.skip || isNaN(x) || isNaN(y),\n\t\t\t// Appearance\n\t\t\tradius: options.radius,\n\t\t\tpointStyle: options.pointStyle,\n\t\t\trotation: options.rotation,\n\t\t\tbackgroundColor: options.backgroundColor,\n\t\t\tborderColor: options.borderColor,\n\t\t\tborderWidth: options.borderWidth,\n\t\t\ttension: valueOrDefault$6(custom.tension, lineModel ? lineModel.tension : 0),\n\t\t\tsteppedLine: lineModel ? lineModel.steppedLine : false,\n\t\t\t// Tooltip\n\t\t\thitRadius: options.hitRadius\n\t\t};\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_resolveDatasetElementOptions: function(element) {\n\t\tvar me = this;\n\t\tvar config = me._config;\n\t\tvar custom = element.custom || {};\n\t\tvar options = me.chart.options;\n\t\tvar lineOptions = options.elements.line;\n\t\tvar values = core_datasetController.prototype._resolveDatasetElementOptions.apply(me, arguments);\n\n\t\t// The default behavior of lines is to break at null values, according\n\t\t// to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158\n\t\t// This option gives lines the ability to span gaps\n\t\tvalues.spanGaps = valueOrDefault$6(config.spanGaps, options.spanGaps);\n\t\tvalues.tension = valueOrDefault$6(config.lineTension, lineOptions.tension);\n\t\tvalues.steppedLine = resolve$2([custom.steppedLine, config.steppedLine, lineOptions.stepped]);\n\t\tvalues.clip = toClip(valueOrDefault$6(config.clip, defaultClip(me._xScale, me._yScale, values.borderWidth)));\n\n\t\treturn values;\n\t},\n\n\tcalculatePointY: function(value, index, datasetIndex) {\n\t\tvar me = this;\n\t\tvar chart = me.chart;\n\t\tvar yScale = me._yScale;\n\t\tvar sumPos = 0;\n\t\tvar sumNeg = 0;\n\t\tvar i, ds, dsMeta, stackedRightValue, rightValue, metasets, ilen;\n\n\t\tif (yScale.options.stacked) {\n\t\t\trightValue = +yScale.getRightValue(value);\n\t\t\tmetasets = chart._getSortedVisibleDatasetMetas();\n\t\t\tilen = metasets.length;\n\n\t\t\tfor (i = 0; i < ilen; ++i) {\n\t\t\t\tdsMeta = metasets[i];\n\t\t\t\tif (dsMeta.index === datasetIndex) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tds = chart.data.datasets[dsMeta.index];\n\t\t\t\tif (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id) {\n\t\t\t\t\tstackedRightValue = +yScale.getRightValue(ds.data[index]);\n\t\t\t\t\tif (stackedRightValue < 0) {\n\t\t\t\t\t\tsumNeg += stackedRightValue || 0;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsumPos += stackedRightValue || 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rightValue < 0) {\n\t\t\t\treturn yScale.getPixelForValue(sumNeg + rightValue);\n\t\t\t}\n\t\t\treturn yScale.getPixelForValue(sumPos + rightValue);\n\t\t}\n\t\treturn yScale.getPixelForValue(value);\n\t},\n\n\tupdateBezierControlPoints: function() {\n\t\tvar me = this;\n\t\tvar chart = me.chart;\n\t\tvar meta = me.getMeta();\n\t\tvar lineModel = meta.dataset._model;\n\t\tvar area = chart.chartArea;\n\t\tvar points = meta.data || [];\n\t\tvar i, ilen, model, controlPoints;\n\n\t\t// Only consider points that are drawn in case the spanGaps option is used\n\t\tif (lineModel.spanGaps) {\n\t\t\tpoints = points.filter(function(pt) {\n\t\t\t\treturn !pt._model.skip;\n\t\t\t});\n\t\t}\n\n\t\tfunction capControlPoint(pt, min, max) {\n\t\t\treturn Math.max(Math.min(pt, max), min);\n\t\t}\n\n\t\tif (lineModel.cubicInterpolationMode === 'monotone') {\n\t\t\thelpers$1.splineCurveMonotone(points);\n\t\t} else {\n\t\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\t\tmodel = points[i]._model;\n\t\t\t\tcontrolPoints = helpers$1.splineCurve(\n\t\t\t\t\thelpers$1.previousItem(points, i)._model,\n\t\t\t\t\tmodel,\n\t\t\t\t\thelpers$1.nextItem(points, i)._model,\n\t\t\t\t\tlineModel.tension\n\t\t\t\t);\n\t\t\t\tmodel.controlPointPreviousX = controlPoints.previous.x;\n\t\t\t\tmodel.controlPointPreviousY = controlPoints.previous.y;\n\t\t\t\tmodel.controlPointNextX = controlPoints.next.x;\n\t\t\t\tmodel.controlPointNextY = controlPoints.next.y;\n\t\t\t}\n\t\t}\n\n\t\tif (chart.options.elements.line.capBezierPoints) {\n\t\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\t\tmodel = points[i]._model;\n\t\t\t\tif (isPointInArea(model, area)) {\n\t\t\t\t\tif (i > 0 && isPointInArea(points[i - 1]._model, area)) {\n\t\t\t\t\t\tmodel.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right);\n\t\t\t\t\t\tmodel.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom);\n\t\t\t\t\t}\n\t\t\t\t\tif (i < points.length - 1 && isPointInArea(points[i + 1]._model, area)) {\n\t\t\t\t\t\tmodel.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right);\n\t\t\t\t\t\tmodel.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tdraw: function() {\n\t\tvar me = this;\n\t\tvar chart = me.chart;\n\t\tvar meta = me.getMeta();\n\t\tvar points = meta.data || [];\n\t\tvar area = chart.chartArea;\n\t\tvar canvas = chart.canvas;\n\t\tvar i = 0;\n\t\tvar ilen = points.length;\n\t\tvar clip;\n\n\t\tif (me._showLine) {\n\t\t\tclip = meta.dataset._model.clip;\n\n\t\t\thelpers$1.canvas.clipArea(chart.ctx, {\n\t\t\t\tleft: clip.left === false ? 0 : area.left - clip.left,\n\t\t\t\tright: clip.right === false ? canvas.width : area.right + clip.right,\n\t\t\t\ttop: clip.top === false ? 0 : area.top - clip.top,\n\t\t\t\tbottom: clip.bottom === false ? canvas.height : area.bottom + clip.bottom\n\t\t\t});\n\n\t\t\tmeta.dataset.draw();\n\n\t\t\thelpers$1.canvas.unclipArea(chart.ctx);\n\t\t}\n\n\t\t// Draw the points\n\t\tfor (; i < ilen; ++i) {\n\t\t\tpoints[i].draw(area);\n\t\t}\n\t},\n\n\t/**\n\t * @protected\n\t */\n\tsetHoverStyle: function(point) {\n\t\tvar model = point._model;\n\t\tvar options = point._options;\n\t\tvar getHoverColor = helpers$1.getHoverColor;\n\n\t\tpoint.$previousStyle = {\n\t\t\tbackgroundColor: model.backgroundColor,\n\t\t\tborderColor: model.borderColor,\n\t\t\tborderWidth: model.borderWidth,\n\t\t\tradius: model.radius\n\t\t};\n\n\t\tmodel.backgroundColor = valueOrDefault$6(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));\n\t\tmodel.borderColor = valueOrDefault$6(options.hoverBorderColor, getHoverColor(options.borderColor));\n\t\tmodel.borderWidth = valueOrDefault$6(options.hoverBorderWidth, options.borderWidth);\n\t\tmodel.radius = valueOrDefault$6(options.hoverRadius, options.radius);\n\t},\n});\n\nvar resolve$3 = helpers$1.options.resolve;\n\ncore_defaults._set('polarArea', {\n\tscale: {\n\t\ttype: 'radialLinear',\n\t\tangleLines: {\n\t\t\tdisplay: false\n\t\t},\n\t\tgridLines: {\n\t\t\tcircular: true\n\t\t},\n\t\tpointLabels: {\n\t\t\tdisplay: false\n\t\t},\n\t\tticks: {\n\t\t\tbeginAtZero: true\n\t\t}\n\t},\n\n\t// Boolean - Whether to animate the rotation of the chart\n\tanimation: {\n\t\tanimateRotate: true,\n\t\tanimateScale: true\n\t},\n\n\tstartAngle: -0.5 * Math.PI,\n\tlegendCallback: function(chart) {\n\t\tvar list = document.createElement('ul');\n\t\tvar data = chart.data;\n\t\tvar datasets = data.datasets;\n\t\tvar labels = data.labels;\n\t\tvar i, ilen, listItem, listItemSpan;\n\n\t\tlist.setAttribute('class', chart.id + '-legend');\n\t\tif (datasets.length) {\n\t\t\tfor (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) {\n\t\t\t\tlistItem = list.appendChild(document.createElement('li'));\n\t\t\t\tlistItemSpan = listItem.appendChild(document.createElement('span'));\n\t\t\t\tlistItemSpan.style.backgroundColor = datasets[0].backgroundColor[i];\n\t\t\t\tif (labels[i]) {\n\t\t\t\t\tlistItem.appendChild(document.createTextNode(labels[i]));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn list.outerHTML;\n\t},\n\tlegend: {\n\t\tlabels: {\n\t\t\tgenerateLabels: function(chart) {\n\t\t\t\tvar data = chart.data;\n\t\t\t\tif (data.labels.length && data.datasets.length) {\n\t\t\t\t\treturn data.labels.map(function(label, i) {\n\t\t\t\t\t\tvar meta = chart.getDatasetMeta(0);\n\t\t\t\t\t\tvar style = meta.controller.getStyle(i);\n\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttext: label,\n\t\t\t\t\t\t\tfillStyle: style.backgroundColor,\n\t\t\t\t\t\t\tstrokeStyle: style.borderColor,\n\t\t\t\t\t\t\tlineWidth: style.borderWidth,\n\t\t\t\t\t\t\thidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden,\n\n\t\t\t\t\t\t\t// Extra data used for toggling the correct item\n\t\t\t\t\t\t\tindex: i\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn [];\n\t\t\t}\n\t\t},\n\n\t\tonClick: function(e, legendItem) {\n\t\t\tvar index = legendItem.index;\n\t\t\tvar chart = this.chart;\n\t\t\tvar i, ilen, meta;\n\n\t\t\tfor (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\n\t\t\t\tmeta = chart.getDatasetMeta(i);\n\t\t\t\tmeta.data[index].hidden = !meta.data[index].hidden;\n\t\t\t}\n\n\t\t\tchart.update();\n\t\t}\n\t},\n\n\t// Need to override these to give a nice default\n\ttooltips: {\n\t\tcallbacks: {\n\t\t\ttitle: function() {\n\t\t\t\treturn '';\n\t\t\t},\n\t\t\tlabel: function(item, data) {\n\t\t\t\treturn data.labels[item.index] + ': ' + item.yLabel;\n\t\t\t}\n\t\t}\n\t}\n});\n\nvar controller_polarArea = core_datasetController.extend({\n\n\tdataElementType: elements.Arc,\n\n\tlinkScales: helpers$1.noop,\n\n\t/**\n\t * @private\n\t */\n\t_dataElementOptions: [\n\t\t'backgroundColor',\n\t\t'borderColor',\n\t\t'borderWidth',\n\t\t'borderAlign',\n\t\t'hoverBackgroundColor',\n\t\t'hoverBorderColor',\n\t\t'hoverBorderWidth',\n\t],\n\n\t/**\n\t * @private\n\t */\n\t_getIndexScaleId: function() {\n\t\treturn this.chart.scale.id;\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_getValueScaleId: function() {\n\t\treturn this.chart.scale.id;\n\t},\n\n\tupdate: function(reset) {\n\t\tvar me = this;\n\t\tvar dataset = me.getDataset();\n\t\tvar meta = me.getMeta();\n\t\tvar start = me.chart.options.startAngle || 0;\n\t\tvar starts = me._starts = [];\n\t\tvar angles = me._angles = [];\n\t\tvar arcs = meta.data;\n\t\tvar i, ilen, angle;\n\n\t\tme._updateRadius();\n\n\t\tmeta.count = me.countVisibleElements();\n\n\t\tfor (i = 0, ilen = dataset.data.length; i < ilen; i++) {\n\t\t\tstarts[i] = start;\n\t\t\tangle = me._computeAngle(i);\n\t\t\tangles[i] = angle;\n\t\t\tstart += angle;\n\t\t}\n\n\t\tfor (i = 0, ilen = arcs.length; i < ilen; ++i) {\n\t\t\tarcs[i]._options = me._resolveDataElementOptions(arcs[i], i);\n\t\t\tme.updateElement(arcs[i], i, reset);\n\t\t}\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_updateRadius: function() {\n\t\tvar me = this;\n\t\tvar chart = me.chart;\n\t\tvar chartArea = chart.chartArea;\n\t\tvar opts = chart.options;\n\t\tvar minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);\n\n\t\tchart.outerRadius = Math.max(minSize / 2, 0);\n\t\tchart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);\n\t\tchart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\n\n\t\tme.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);\n\t\tme.innerRadius = me.outerRadius - chart.radiusLength;\n\t},\n\n\tupdateElement: function(arc, index, reset) {\n\t\tvar me = this;\n\t\tvar chart = me.chart;\n\t\tvar dataset = me.getDataset();\n\t\tvar opts = chart.options;\n\t\tvar animationOpts = opts.animation;\n\t\tvar scale = chart.scale;\n\t\tvar labels = chart.data.labels;\n\n\t\tvar centerX = scale.xCenter;\n\t\tvar centerY = scale.yCenter;\n\n\t\t// var negHalfPI = -0.5 * Math.PI;\n\t\tvar datasetStartAngle = opts.startAngle;\n\t\tvar distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\n\t\tvar startAngle = me._starts[index];\n\t\tvar endAngle = startAngle + (arc.hidden ? 0 : me._angles[index]);\n\n\t\tvar resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\n\t\tvar options = arc._options || {};\n\n\t\thelpers$1.extend(arc, {\n\t\t\t// Utility\n\t\t\t_datasetIndex: me.index,\n\t\t\t_index: index,\n\t\t\t_scale: scale,\n\n\t\t\t// Desired view properties\n\t\t\t_model: {\n\t\t\t\tbackgroundColor: options.backgroundColor,\n\t\t\t\tborderColor: options.borderColor,\n\t\t\t\tborderWidth: options.borderWidth,\n\t\t\t\tborderAlign: options.borderAlign,\n\t\t\t\tx: centerX,\n\t\t\t\ty: centerY,\n\t\t\t\tinnerRadius: 0,\n\t\t\t\touterRadius: reset ? resetRadius : distance,\n\t\t\t\tstartAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,\n\t\t\t\tendAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,\n\t\t\t\tlabel: helpers$1.valueAtIndexOrDefault(labels, index, labels[index])\n\t\t\t}\n\t\t});\n\n\t\tarc.pivot();\n\t},\n\n\tcountVisibleElements: function() {\n\t\tvar dataset = this.getDataset();\n\t\tvar meta = this.getMeta();\n\t\tvar count = 0;\n\n\t\thelpers$1.each(meta.data, function(element, index) {\n\t\t\tif (!isNaN(dataset.data[index]) && !element.hidden) {\n\t\t\t\tcount++;\n\t\t\t}\n\t\t});\n\n\t\treturn count;\n\t},\n\n\t/**\n\t * @protected\n\t */\n\tsetHoverStyle: function(arc) {\n\t\tvar model = arc._model;\n\t\tvar options = arc._options;\n\t\tvar getHoverColor = helpers$1.getHoverColor;\n\t\tvar valueOrDefault = helpers$1.valueOrDefault;\n\n\t\tarc.$previousStyle = {\n\t\t\tbackgroundColor: model.backgroundColor,\n\t\t\tborderColor: model.borderColor,\n\t\t\tborderWidth: model.borderWidth,\n\t\t};\n\n\t\tmodel.backgroundColor = valueOrDefault(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));\n\t\tmodel.borderColor = valueOrDefault(options.hoverBorderColor, getHoverColor(options.borderColor));\n\t\tmodel.borderWidth = valueOrDefault(options.hoverBorderWidth, options.borderWidth);\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_computeAngle: function(index) {\n\t\tvar me = this;\n\t\tvar count = this.getMeta().count;\n\t\tvar dataset = me.getDataset();\n\t\tvar meta = me.getMeta();\n\n\t\tif (isNaN(dataset.data[index]) || meta.data[index].hidden) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Scriptable options\n\t\tvar context = {\n\t\t\tchart: me.chart,\n\t\t\tdataIndex: index,\n\t\t\tdataset: dataset,\n\t\t\tdatasetIndex: me.index\n\t\t};\n\n\t\treturn resolve$3([\n\t\t\tme.chart.options.elements.arc.angle,\n\t\t\t(2 * Math.PI) / count\n\t\t], context, index);\n\t}\n});\n\ncore_defaults._set('pie', helpers$1.clone(core_defaults.doughnut));\ncore_defaults._set('pie', {\n\tcutoutPercentage: 0\n});\n\n// Pie charts are Doughnut chart with different defaults\nvar controller_pie = controller_doughnut;\n\nvar valueOrDefault$7 = helpers$1.valueOrDefault;\n\ncore_defaults._set('radar', {\n\tspanGaps: false,\n\tscale: {\n\t\ttype: 'radialLinear'\n\t},\n\telements: {\n\t\tline: {\n\t\t\tfill: 'start',\n\t\t\ttension: 0 // no bezier in radar\n\t\t}\n\t}\n});\n\nvar controller_radar = core_datasetController.extend({\n\tdatasetElementType: elements.Line,\n\n\tdataElementType: elements.Point,\n\n\tlinkScales: helpers$1.noop,\n\n\t/**\n\t * @private\n\t */\n\t_datasetElementOptions: [\n\t\t'backgroundColor',\n\t\t'borderWidth',\n\t\t'borderColor',\n\t\t'borderCapStyle',\n\t\t'borderDash',\n\t\t'borderDashOffset',\n\t\t'borderJoinStyle',\n\t\t'fill'\n\t],\n\n\t/**\n\t * @private\n\t */\n\t_dataElementOptions: {\n\t\tbackgroundColor: 'pointBackgroundColor',\n\t\tborderColor: 'pointBorderColor',\n\t\tborderWidth: 'pointBorderWidth',\n\t\thitRadius: 'pointHitRadius',\n\t\thoverBackgroundColor: 'pointHoverBackgroundColor',\n\t\thoverBorderColor: 'pointHoverBorderColor',\n\t\thoverBorderWidth: 'pointHoverBorderWidth',\n\t\thoverRadius: 'pointHoverRadius',\n\t\tpointStyle: 'pointStyle',\n\t\tradius: 'pointRadius',\n\t\trotation: 'pointRotation'\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_getIndexScaleId: function() {\n\t\treturn this.chart.scale.id;\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_getValueScaleId: function() {\n\t\treturn this.chart.scale.id;\n\t},\n\n\tupdate: function(reset) {\n\t\tvar me = this;\n\t\tvar meta = me.getMeta();\n\t\tvar line = meta.dataset;\n\t\tvar points = meta.data || [];\n\t\tvar scale = me.chart.scale;\n\t\tvar config = me._config;\n\t\tvar i, ilen;\n\n\t\t// Compatibility: If the properties are defined with only the old name, use those values\n\t\tif (config.tension !== undefined && config.lineTension === undefined) {\n\t\t\tconfig.lineTension = config.tension;\n\t\t}\n\n\t\t// Utility\n\t\tline._scale = scale;\n\t\tline._datasetIndex = me.index;\n\t\t// Data\n\t\tline._children = points;\n\t\tline._loop = true;\n\t\t// Model\n\t\tline._model = me._resolveDatasetElementOptions(line);\n\n\t\tline.pivot();\n\n\t\t// Update Points\n\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\tme.updateElement(points[i], i, reset);\n\t\t}\n\n\t\t// Update bezier control points\n\t\tme.updateBezierControlPoints();\n\n\t\t// Now pivot the point for animation\n\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\tpoints[i].pivot();\n\t\t}\n\t},\n\n\tupdateElement: function(point, index, reset) {\n\t\tvar me = this;\n\t\tvar custom = point.custom || {};\n\t\tvar dataset = me.getDataset();\n\t\tvar scale = me.chart.scale;\n\t\tvar pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);\n\t\tvar options = me._resolveDataElementOptions(point, index);\n\t\tvar lineModel = me.getMeta().dataset._model;\n\t\tvar x = reset ? scale.xCenter : pointPosition.x;\n\t\tvar y = reset ? scale.yCenter : pointPosition.y;\n\n\t\t// Utility\n\t\tpoint._scale = scale;\n\t\tpoint._options = options;\n\t\tpoint._datasetIndex = me.index;\n\t\tpoint._index = index;\n\n\t\t// Desired view properties\n\t\tpoint._model = {\n\t\t\tx: x, // value not used in dataset scale, but we want a consistent API between scales\n\t\t\ty: y,\n\t\t\tskip: custom.skip || isNaN(x) || isNaN(y),\n\t\t\t// Appearance\n\t\t\tradius: options.radius,\n\t\t\tpointStyle: options.pointStyle,\n\t\t\trotation: options.rotation,\n\t\t\tbackgroundColor: options.backgroundColor,\n\t\t\tborderColor: options.borderColor,\n\t\t\tborderWidth: options.borderWidth,\n\t\t\ttension: valueOrDefault$7(custom.tension, lineModel ? lineModel.tension : 0),\n\n\t\t\t// Tooltip\n\t\t\thitRadius: options.hitRadius\n\t\t};\n\t},\n\n\t/**\n\t * @private\n\t */\n\t_resolveDatasetElementOptions: function() {\n\t\tvar me = this;\n\t\tvar config = me._config;\n\t\tvar options = me.chart.options;\n\t\tvar values = core_datasetController.prototype._resolveDatasetElementOptions.apply(me, arguments);\n\n\t\tvalues.spanGaps = valueOrDefault$7(config.spanGaps, options.spanGaps);\n\t\tvalues.tension = valueOrDefault$7(config.lineTension, options.elements.line.tension);\n\n\t\treturn values;\n\t},\n\n\tupdateBezierControlPoints: function() {\n\t\tvar me = this;\n\t\tvar meta = me.getMeta();\n\t\tvar area = me.chart.chartArea;\n\t\tvar points = meta.data || [];\n\t\tvar i, ilen, model, controlPoints;\n\n\t\t// Only consider points that are drawn in case the spanGaps option is used\n\t\tif (meta.dataset._model.spanGaps) {\n\t\t\tpoints = points.filter(function(pt) {\n\t\t\t\treturn !pt._model.skip;\n\t\t\t});\n\t\t}\n\n\t\tfunction capControlPoint(pt, min, max) {\n\t\t\treturn Math.max(Math.min(pt, max), min);\n\t\t}\n\n\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\n\t\t\tmodel = points[i]._model;\n\t\t\tcontrolPoints = helpers$1.splineCurve(\n\t\t\t\thelpers$1.previousItem(points, i, true)._model,\n\t\t\t\tmodel,\n\t\t\t\thelpers$1.nextItem(points, i, true)._model,\n\t\t\t\tmodel.tension\n\t\t\t);\n\n\t\t\t// Prevent the bezier going outside of the bounds of the graph\n\t\t\tmodel.controlPointPreviousX = capControlPoint(controlPoints.previous.x, area.left, area.right);\n\t\t\tmodel.controlPointPreviousY = capControlPoint(controlPoints.previous.y, area.top, area.bottom);\n\t\t\tmodel.controlPointNextX = capControlPoint(controlPoints.next.x, area.left, area.right);\n\t\t\tmodel.controlPointNextY = capControlPoint(controlPoints.next.y, area.top, area.bottom);\n\t\t}\n\t},\n\n\tsetHoverStyle: function(point) {\n\t\tvar model = point._model;\n\t\tvar options = point._options;\n\t\tvar getHoverColor = helpers$1.getHoverColor;\n\n\t\tpoint.$previousStyle = {\n\t\t\tbackgroundColor: model.backgroundColor,\n\t\t\tborderColor: model.borderColor,\n\t\t\tborderWidth: model.borderWidth,\n\t\t\tradius: model.radius\n\t\t};\n\n\t\tmodel.backgroundColor = valueOrDefault$7(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));\n\t\tmodel.borderColor = valueOrDefault$7(options.hoverBorderColor, getHoverColor(options.borderColor));\n\t\tmodel.borderWidth = valueOrDefault$7(options.hoverBorderWidth, options.borderWidth);\n\t\tmodel.radius = valueOrDefault$7(options.hoverRadius, options.radius);\n\t}\n});\n\ncore_defaults._set('scatter', {\n\thover: {\n\t\tmode: 'single'\n\t},\n\n\tscales: {\n\t\txAxes: [{\n\t\t\tid: 'x-axis-1', // need an ID so datasets can reference the scale\n\t\t\ttype: 'linear', // scatter should not use a category axis\n\t\t\tposition: 'bottom'\n\t\t}],\n\t\tyAxes: [{\n\t\t\tid: 'y-axis-1',\n\t\t\ttype: 'linear',\n\t\t\tposition: 'left'\n\t\t}]\n\t},\n\n\ttooltips: {\n\t\tcallbacks: {\n\t\t\ttitle: function() {\n\t\t\t\treturn ''; // doesn't make sense for scatter since data are formatted as a point\n\t\t\t},\n\t\t\tlabel: function(item) {\n\t\t\t\treturn '(' + item.xLabel + ', ' + item.yLabel + ')';\n\t\t\t}\n\t\t}\n\t}\n});\n\ncore_defaults._set('global', {\n\tdatasets: {\n\t\tscatter: {\n\t\t\tshowLine: false\n\t\t}\n\t}\n});\n\n// Scatter charts use line controllers\nvar controller_scatter = controller_line;\n\n// NOTE export a map in which the key represents the controller type, not\n// the class, and so must be CamelCase in order to be correctly retrieved\n// by the controller in core.controller.js (`controllers[meta.type]`).\n\nvar controllers = {\n\tbar: controller_bar,\n\tbubble: controller_bubble,\n\tdoughnut: controller_doughnut,\n\thorizontalBar: controller_horizontalBar,\n\tline: controller_line,\n\tpolarArea: controller_polarArea,\n\tpie: controller_pie,\n\tradar: controller_radar,\n\tscatter: controller_scatter\n};\n\n/**\n * Helper function to get relative position for an event\n * @param {Event|IEvent} event - The event to get the position for\n * @param {Chart} chart - The chart\n * @returns {object} the event position\n */\nfunction getRelativePosition(e, chart) {\n\tif (e.native) {\n\t\treturn {\n\t\t\tx: e.x,\n\t\t\ty: e.y\n\t\t};\n\t}\n\n\treturn helpers$1.getRelativePosition(e, chart);\n}\n\n/**\n * Helper function to traverse all of the visible elements in the chart\n * @param {Chart} chart - the chart\n * @param {function} handler - the callback to execute for each visible item\n */\nfunction parseVisibleItems(chart, handler) {\n\tvar metasets = chart._getSortedVisibleDatasetMetas();\n\tvar metadata, i, j, ilen, jlen, element;\n\n\tfor (i = 0, ilen = metasets.length; i < ilen; ++i) {\n\t\tmetadata = metasets[i].data;\n\t\tfor (j = 0, jlen = metadata.length; j < jlen; ++j) {\n\t\t\telement = metadata[j];\n\t\t\tif (!element._view.skip) {\n\t\t\t\thandler(element);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Helper function to get the items that intersect the event position\n * @param {ChartElement[]} items - elements to filter\n * @param {object} position - the point to be nearest to\n * @return {ChartElement[]} the nearest items\n */\nfunction getIntersectItems(chart, position) {\n\tvar elements = [];\n\n\tparseVisibleItems(chart, function(element) {\n\t\tif (element.inRange(position.x, position.y)) {\n\t\t\telements.push(element);\n\t\t}\n\t});\n\n\treturn elements;\n}\n\n/**\n * Helper function to get the items nearest to the event position considering all visible items in teh chart\n * @param {Chart} chart - the chart to look at elements from\n * @param {object} position - the point to be nearest to\n * @param {boolean} intersect - if true, only consider items that intersect the position\n * @param {function} distanceMetric - function to provide the distance between points\n * @return {ChartElement[]} the nearest items\n */\nfunction getNearestItems(chart, position, intersect, distanceMetric) {\n\tvar minDistance = Number.POSITIVE_INFINITY;\n\tvar nearestItems = [];\n\n\tparseVisibleItems(chart, function(element) {\n\t\tif (intersect && !element.inRange(position.x, position.y)) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar center = element.getCenterPoint();\n\t\tvar distance = distanceMetric(position, center);\n\t\tif (distance < minDistance) {\n\t\t\tnearestItems = [element];\n\t\t\tminDistance = distance;\n\t\t} else if (distance === minDistance) {\n\t\t\t// Can have multiple items at the same distance in which case we sort by size\n\t\t\tnearestItems.push(element);\n\t\t}\n\t});\n\n\treturn nearestItems;\n}\n\n/**\n * Get a distance metric function for two points based on the\n * axis mode setting\n * @param {string} axis - the axis mode. x|y|xy\n */\nfunction getDistanceMetricForAxis(axis) {\n\tvar useX = axis.indexOf('x') !== -1;\n\tvar useY = axis.indexOf('y') !== -1;\n\n\treturn function(pt1, pt2) {\n\t\tvar deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0;\n\t\tvar deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0;\n\t\treturn Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));\n\t};\n}\n\nfunction indexMode(chart, e, options) {\n\tvar position = getRelativePosition(e, chart);\n\t// Default axis for index mode is 'x' to match old behaviour\n\toptions.axis = options.axis || 'x';\n\tvar distanceMetric = getDistanceMetricForAxis(options.axis);\n\tvar items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);\n\tvar elements = [];\n\n\tif (!items.length) {\n\t\treturn [];\n\t}\n\n\tchart._getSortedVisibleDatasetMetas().forEach(function(meta) {\n\t\tvar element = meta.data[items[0]._index];\n\n\t\t// don't count items that are skipped (null data)\n\t\tif (element && !element._view.skip) {\n\t\t\telements.push(element);\n\t\t}\n\t});\n\n\treturn elements;\n}\n\n/**\n * @interface IInteractionOptions\n */\n/**\n * If true, only consider items that intersect the point\n * @name IInterfaceOptions#boolean\n * @type Boolean\n */\n\n/**\n * Contains interaction related functions\n * @namespace Chart.Interaction\n */\nvar core_interaction = {\n\t// Helper function for different modes\n\tmodes: {\n\t\tsingle: function(chart, e) {\n\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\tvar elements = [];\n\n\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\telements.push(element);\n\t\t\t\t\treturn elements;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn elements.slice(0, 1);\n\t\t},\n\n\t\t/**\n\t\t * @function Chart.Interaction.modes.label\n\t\t * @deprecated since version 2.4.0\n\t\t * @todo remove at version 3\n\t\t * @private\n\t\t */\n\t\tlabel: indexMode,\n\n\t\t/**\n\t\t * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something\n\t\t * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item\n\t\t * @function Chart.Interaction.modes.index\n\t\t * @since v2.4.0\n\t\t * @param {Chart} chart - the chart we are returning items from\n\t\t * @param {Event} e - the event we are find things at\n\t\t * @param {IInteractionOptions} options - options to use during interaction\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t */\n\t\tindex: indexMode,\n\n\t\t/**\n\t\t * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something\n\t\t * If the options.intersect is false, we find the nearest item and return the items in that dataset\n\t\t * @function Chart.Interaction.modes.dataset\n\t\t * @param {Chart} chart - the chart we are returning items from\n\t\t * @param {Event} e - the event we are find things at\n\t\t * @param {IInteractionOptions} options - options to use during interaction\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t */\n\t\tdataset: function(chart, e, options) {\n\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\toptions.axis = options.axis || 'xy';\n\t\t\tvar distanceMetric = getDistanceMetricForAxis(options.axis);\n\t\t\tvar items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);\n\n\t\t\tif (items.length > 0) {\n\t\t\t\titems = chart.getDatasetMeta(items[0]._datasetIndex).data;\n\t\t\t}\n\n\t\t\treturn items;\n\t\t},\n\n\t\t/**\n\t\t * @function Chart.Interaction.modes.x-axis\n\t\t * @deprecated since version 2.4.0. Use index mode and intersect == true\n\t\t * @todo remove at version 3\n\t\t * @private\n\t\t */\n\t\t'x-axis': function(chart, e) {\n\t\t\treturn indexMode(chart, e, {intersect: false});\n\t\t},\n\n\t\t/**\n\t\t * Point mode returns all elements that hit test based on the event position\n\t\t * of the event\n\t\t * @function Chart.Interaction.modes.intersect\n\t\t * @param {Chart} chart - the chart we are returning items from\n\t\t * @param {Event} e - the event we are find things at\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t */\n\t\tpoint: function(chart, e) {\n\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\treturn getIntersectItems(chart, position);\n\t\t},\n\n\t\t/**\n\t\t * nearest mode returns the element closest to the point\n\t\t * @function Chart.Interaction.modes.intersect\n\t\t * @param {Chart} chart - the chart we are returning items from\n\t\t * @param {Event} e - the event we are find things at\n\t\t * @param {IInteractionOptions} options - options to use\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t */\n\t\tnearest: function(chart, e, options) {\n\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\toptions.axis = options.axis || 'xy';\n\t\t\tvar distanceMetric = getDistanceMetricForAxis(options.axis);\n\t\t\treturn getNearestItems(chart, position, options.intersect, distanceMetric);\n\t\t},\n\n\t\t/**\n\t\t * x mode returns the elements that hit-test at the current x coordinate\n\t\t * @function Chart.Interaction.modes.x\n\t\t * @param {Chart} chart - the chart we are returning items from\n\t\t * @param {Event} e - the event we are find things at\n\t\t * @param {IInteractionOptions} options - options to use\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t */\n\t\tx: function(chart, e, options) {\n\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\tvar items = [];\n\t\t\tvar intersectsItem = false;\n\n\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\tif (element.inXRange(position.x)) {\n\t\t\t\t\titems.push(element);\n\t\t\t\t}\n\n\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\tintersectsItem = true;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// If we want to trigger on an intersect and we don't have any items\n\t\t\t// that intersect the position, return nothing\n\t\t\tif (options.intersect && !intersectsItem) {\n\t\t\t\titems = [];\n\t\t\t}\n\t\t\treturn items;\n\t\t},\n\n\t\t/**\n\t\t * y mode returns the elements that hit-test at the current y coordinate\n\t\t * @function Chart.Interaction.modes.y\n\t\t * @param {Chart} chart - the chart we are returning items from\n\t\t * @param {Event} e - the event we are find things at\n\t\t * @param {IInteractionOptions} options - options to use\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\n\t\t */\n\t\ty: function(chart, e, options) {\n\t\t\tvar position = getRelativePosition(e, chart);\n\t\t\tvar items = [];\n\t\t\tvar intersectsItem = false;\n\n\t\t\tparseVisibleItems(chart, function(element) {\n\t\t\t\tif (element.inYRange(position.y)) {\n\t\t\t\t\titems.push(element);\n\t\t\t\t}\n\n\t\t\t\tif (element.inRange(position.x, position.y)) {\n\t\t\t\t\tintersectsItem = true;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// If we want to trigger on an intersect and we don't have any items\n\t\t\t// that intersect the position, return nothing\n\t\t\tif (options.intersect && !intersectsItem) {\n\t\t\t\titems = [];\n\t\t\t}\n\t\t\treturn items;\n\t\t}\n\t}\n};\n\nvar extend = helpers$1.extend;\n\nfunction filterByPosition(array, position) {\n\treturn helpers$1.where(array, function(v) {\n\t\treturn v.pos === position;\n\t});\n}\n\nfunction sortByWeight(array, reverse) {\n\treturn array.sort(function(a, b) {\n\t\tvar v0 = reverse ? b : a;\n\t\tvar v1 = reverse ? a : b;\n\t\treturn v0.weight === v1.weight ?\n\t\t\tv0.index - v1.index :\n\t\t\tv0.weight - v1.weight;\n\t});\n}\n\nfunction wrapBoxes(boxes) {\n\tvar layoutBoxes = [];\n\tvar i, ilen, box;\n\n\tfor (i = 0, ilen = (boxes || []).length; i < ilen; ++i) {\n\t\tbox = boxes[i];\n\t\tlayoutBoxes.push({\n\t\t\tindex: i,\n\t\t\tbox: box,\n\t\t\tpos: box.position,\n\t\t\thorizontal: box.isHorizontal(),\n\t\t\tweight: box.weight\n\t\t});\n\t}\n\treturn layoutBoxes;\n}\n\nfunction setLayoutDims(layouts, params) {\n\tvar i, ilen, layout;\n\tfor (i = 0, ilen = layouts.length; i < ilen; ++i) {\n\t\tlayout = layouts[i];\n\t\t// store width used instead of chartArea.w in fitBoxes\n\t\tlayout.width = layout.horizontal\n\t\t\t? layout.box.fullWidth && params.availableWidth\n\t\t\t: params.vBoxMaxWidth;\n\t\t// store height used instead of chartArea.h in fitBoxes\n\t\tlayout.height = layout.horizontal && params.hBoxMaxHeight;\n\t}\n}\n\nfunction buildLayoutBoxes(boxes) {\n\tvar layoutBoxes = wrapBoxes(boxes);\n\tvar left = sortByWeight(filterByPosition(layoutBoxes, 'left'), true);\n\tvar right = sortByWeight(filterByPosition(layoutBoxes, 'right'));\n\tvar top = sortByWeight(filterByPosition(layoutBoxes, 'top'), true);\n\tvar bottom = sortByWeight(filterByPosition(layoutBoxes, 'bottom'));\n\n\treturn {\n\t\tleftAndTop: left.concat(top),\n\t\trightAndBottom: right.concat(bottom),\n\t\tchartArea: filterByPosition(layoutBoxes, 'chartArea'),\n\t\tvertical: left.concat(right),\n\t\thorizontal: top.concat(bottom)\n\t};\n}\n\nfunction getCombinedMax(maxPadding, chartArea, a, b) {\n\treturn Math.max(maxPadding[a], chartArea[a]) + Math.max(maxPadding[b], chartArea[b]);\n}\n\nfunction updateDims(chartArea, params, layout) {\n\tvar box = layout.box;\n\tvar maxPadding = chartArea.maxPadding;\n\tvar newWidth, newHeight;\n\n\tif (layout.size) {\n\t\t// this layout was already counted for, lets first reduce old size\n\t\tchartArea[layout.pos] -= layout.size;\n\t}\n\tlayout.size = layout.horizontal ? box.height : box.width;\n\tchartArea[layout.pos] += layout.size;\n\n\tif (box.getPadding) {\n\t\tvar boxPadding = box.getPadding();\n\t\tmaxPadding.top = Math.max(maxPadding.top, boxPadding.top);\n\t\tmaxPadding.left = Math.max(maxPadding.left, boxPadding.left);\n\t\tmaxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom);\n\t\tmaxPadding.right = Math.max(maxPadding.right, boxPadding.right);\n\t}\n\n\tnewWidth = params.outerWidth - getCombinedMax(maxPadding, chartArea, 'left', 'right');\n\tnewHeight = params.outerHeight - getCombinedMax(maxPadding, chartArea, 'top', 'bottom');\n\n\tif (newWidth !== chartArea.w || newHeight !== chartArea.h) {\n\t\tchartArea.w = newWidth;\n\t\tchartArea.h = newHeight;\n\n\t\t// return true if chart area changed in layout's direction\n\t\treturn layout.horizontal ? newWidth !== chartArea.w : newHeight !== chartArea.h;\n\t}\n}\n\nfunction handleMaxPadding(chartArea) {\n\tvar maxPadding = chartArea.maxPadding;\n\n\tfunction updatePos(pos) {\n\t\tvar change = Math.max(maxPadding[pos] - chartArea[pos], 0);\n\t\tchartArea[pos] += change;\n\t\treturn change;\n\t}\n\tchartArea.y += updatePos('top');\n\tchartArea.x += updatePos('left');\n\tupdatePos('right');\n\tupdatePos('bottom');\n}\n\nfunction getMargins(horizontal, chartArea) {\n\tvar maxPadding = chartArea.maxPadding;\n\n\tfunction marginForPositions(positions) {\n\t\tvar margin = {left: 0, top: 0, right: 0, bottom: 0};\n\t\tpositions.forEach(function(pos) {\n\t\t\tmargin[pos] = Math.max(chartArea[pos], maxPadding[pos]);\n\t\t});\n\t\treturn margin;\n\t}\n\n\treturn horizontal\n\t\t? marginForPositions(['left', 'right'])\n\t\t: marginForPositions(['top', 'bottom']);\n}\n\nfunction fitBoxes(boxes, chartArea, params) {\n\tvar refitBoxes = [];\n\tvar i, ilen, layout, box, refit, changed;\n\n\tfor (i = 0, ilen = boxes.length; i < ilen; ++i) {\n\t\tlayout = boxes[i];\n\t\tbox = layout.box;\n\n\t\tbox.update(\n\t\t\tlayout.width || chartArea.w,\n\t\t\tlayout.height || chartArea.h,\n\t\t\tgetMargins(layout.horizontal, chartArea)\n\t\t);\n\t\tif (updateDims(chartArea, params, layout)) {\n\t\t\tchanged = true;\n\t\t\tif (refitBoxes.length) {\n\t\t\t\t// Dimensions changed and there were non full width boxes before this\n\t\t\t\t// -> we have to refit those\n\t\t\t\trefit = true;\n\t\t\t}\n\t\t}\n\t\tif (!box.fullWidth) { // fullWidth boxes don't need to be re-fitted in any case\n\t\t\trefitBoxes.push(layout);\n\t\t}\n\t}\n\n\treturn refit ? fitBoxes(refitBoxes, chartArea, params) || changed : changed;\n}\n\nfunction placeBoxes(boxes, chartArea, params) {\n\tvar userPadding = params.padding;\n\tvar x = chartArea.x;\n\tvar y = chartArea.y;\n\tvar i, ilen, layout, box;\n\n\tfor (i = 0, ilen = boxes.length; i < ilen; ++i) {\n\t\tlayout = boxes[i];\n\t\tbox = layout.box;\n\t\tif (layout.horizontal) {\n\t\t\tbox.left = box.fullWidth ? userPadding.left : chartArea.left;\n\t\t\tbox.right = box.fullWidth ? params.outerWidth - userPadding.right : chartArea.left + chartArea.w;\n\t\t\tbox.top = y;\n\t\t\tbox.bottom = y + box.height;\n\t\t\tbox.width = box.right - box.left;\n\t\t\ty = box.bottom;\n\t\t} else {\n\t\t\tbox.left = x;\n\t\t\tbox.right = x + box.width;\n\t\t\tbox.top = chartArea.top;\n\t\t\tbox.bottom = chartArea.top + chartArea.h;\n\t\t\tbox.height = box.bottom - box.top;\n\t\t\tx = box.right;\n\t\t}\n\t}\n\n\tchartArea.x = x;\n\tchartArea.y = y;\n}\n\ncore_defaults._set('global', {\n\tlayout: {\n\t\tpadding: {\n\t\t\ttop: 0,\n\t\t\tright: 0,\n\t\t\tbottom: 0,\n\t\t\tleft: 0\n\t\t}\n\t}\n});\n\n/**\n * @interface ILayoutItem\n * @prop {string} position - The position of the item in the chart layout. Possible values are\n * 'left', 'top', 'right', 'bottom', and 'chartArea'\n * @prop {number} weight - The weight used to sort the item. Higher weights are further away from the chart area\n * @prop {boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down\n * @prop {function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom)\n * @prop {function} update - Takes two parameters: width and height. Returns size of item\n * @prop {function} getPadding - Returns an object with padding on the edges\n * @prop {number} width - Width of item. Must be valid after update()\n * @prop {number} height - Height of item. Must be valid after update()\n * @prop {number} left - Left edge of the item. Set by layout system and cannot be used in update\n * @prop {number} top - Top edge of the item. Set by layout system and cannot be used in update\n * @prop {number} right - Right edge of the item. Set by layout system and cannot be used in update\n * @prop {number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update\n */\n\n// The layout service is very self explanatory. It's responsible for the layout within a chart.\n// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need\n// It is this service's responsibility of carrying out that layout.\nvar core_layouts = {\n\tdefaults: {},\n\n\t/**\n\t * Register a box to a chart.\n\t * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title.\n\t * @param {Chart} chart - the chart to use\n\t * @param {ILayoutItem} item - the item to add to be layed out\n\t */\n\taddBox: function(chart, item) {\n\t\tif (!chart.boxes) {\n\t\t\tchart.boxes = [];\n\t\t}\n\n\t\t// initialize item with default values\n\t\titem.fullWidth = item.fullWidth || false;\n\t\titem.position = item.position || 'top';\n\t\titem.weight = item.weight || 0;\n\t\titem._layers = item._layers || function() {\n\t\t\treturn [{\n\t\t\t\tz: 0,\n\t\t\t\tdraw: function() {\n\t\t\t\t\titem.draw.apply(item, arguments);\n\t\t\t\t}\n\t\t\t}];\n\t\t};\n\n\t\tchart.boxes.push(item);\n\t},\n\n\t/**\n\t * Remove a layoutItem from a chart\n\t * @param {Chart} chart - the chart to remove the box from\n\t * @param {ILayoutItem} layoutItem - the item to remove from the layout\n\t */\n\tremoveBox: function(chart, layoutItem) {\n\t\tvar index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1;\n\t\tif (index !== -1) {\n\t\t\tchart.boxes.splice(index, 1);\n\t\t}\n\t},\n\n\t/**\n\t * Sets (or updates) options on the given `item`.\n\t * @param {Chart} chart - the chart in which the item lives (or will be added to)\n\t * @param {ILayoutItem} item - the item to configure with the given options\n\t * @param {object} options - the new item options.\n\t */\n\tconfigure: function(chart, item, options) {\n\t\tvar props = ['fullWidth', 'position', 'weight'];\n\t\tvar ilen = props.length;\n\t\tvar i = 0;\n\t\tvar prop;\n\n\t\tfor (; i < ilen; ++i) {\n\t\t\tprop = props[i];\n\t\t\tif (options.hasOwnProperty(prop)) {\n\t\t\t\titem[prop] = options[prop];\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Fits boxes of the given chart into the given size by having each box measure itself\n\t * then running a fitting algorithm\n\t * @param {Chart} chart - the chart\n\t * @param {number} width - the width to fit into\n\t * @param {number} height - the height to fit into\n\t */\n\tupdate: function(chart, width, height) {\n\t\tif (!chart) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar layoutOptions = chart.options.layout || {};\n\t\tvar padding = helpers$1.options.toPadding(layoutOptions.padding);\n\n\t\tvar availableWidth = width - padding.width;\n\t\tvar availableHeight = height - padding.height;\n\t\tvar boxes = buildLayoutBoxes(chart.boxes);\n\t\tvar verticalBoxes = boxes.vertical;\n\t\tvar horizontalBoxes = boxes.horizontal;\n\n\t\t// Essentially we now have any number of boxes on each of the 4 sides.\n\t\t// Our canvas looks like the following.\n\t\t// The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and\n\t\t// B1 is the bottom axis\n\t\t// There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays\n\t\t// These locations are single-box locations only, when trying to register a chartArea location that is already taken,\n\t\t// an error will be thrown.\n\t\t//\n\t\t// |----------------------------------------------------|\n\t\t// | T1 (Full Width) |\n\t\t// |----------------------------------------------------|\n\t\t// | | | T2 | |\n\t\t// | |----|-------------------------------------|----|\n\t\t// | | | C1 | | C2 | |\n\t\t// | | |----| |----| |\n\t\t// | | | | |\n\t\t// | L1 | L2 | ChartArea (C0) | R1 |\n\t\t// | | | | |\n\t\t// | | |----| |----| |\n\t\t// | | | C3 | | C4 | |\n\t\t// | |----|-------------------------------------|----|\n\t\t// | | | B1 | |\n\t\t// |----------------------------------------------------|\n\t\t// | B2 (Full Width) |\n\t\t// |----------------------------------------------------|\n\t\t//\n\n\t\tvar params = Object.freeze({\n\t\t\touterWidth: width,\n\t\t\touterHeight: height,\n\t\t\tpadding: padding,\n\t\t\tavailableWidth: availableWidth,\n\t\t\tvBoxMaxWidth: availableWidth / 2 / verticalBoxes.length,\n\t\t\thBoxMaxHeight: availableHeight / 2\n\t\t});\n\t\tvar chartArea = extend({\n\t\t\tmaxPadding: extend({}, padding),\n\t\t\tw: availableWidth,\n\t\t\th: availableHeight,\n\t\t\tx: padding.left,\n\t\t\ty: padding.top\n\t\t}, padding);\n\n\t\tsetLayoutDims(verticalBoxes.concat(horizontalBoxes), params);\n\n\t\t// First fit vertical boxes\n\t\tfitBoxes(verticalBoxes, chartArea, params);\n\n\t\t// Then fit horizontal boxes\n\t\tif (fitBoxes(horizontalBoxes, chartArea, params)) {\n\t\t\t// if the area changed, re-fit vertical boxes\n\t\t\tfitBoxes(verticalBoxes, chartArea, params);\n\t\t}\n\n\t\thandleMaxPadding(chartArea);\n\n\t\t// Finally place the boxes to correct coordinates\n\t\tplaceBoxes(boxes.leftAndTop, chartArea, params);\n\n\t\t// Move to opposite side of chart\n\t\tchartArea.x += chartArea.w;\n\t\tchartArea.y += chartArea.h;\n\n\t\tplaceBoxes(boxes.rightAndBottom, chartArea, params);\n\n\t\tchart.chartArea = {\n\t\t\tleft: chartArea.left,\n\t\t\ttop: chartArea.top,\n\t\t\tright: chartArea.left + chartArea.w,\n\t\t\tbottom: chartArea.top + chartArea.h\n\t\t};\n\n\t\t// Finally update boxes in chartArea (radial scale for example)\n\t\thelpers$1.each(boxes.chartArea, function(layout) {\n\t\t\tvar box = layout.box;\n\t\t\textend(box, chart.chartArea);\n\t\t\tbox.update(chartArea.w, chartArea.h);\n\t\t});\n\t}\n};\n\n/**\n * Platform fallback implementation (minimal).\n * @see https://github.com/chartjs/Chart.js/pull/4591#issuecomment-319575939\n */\n\nvar platform_basic = {\n\tacquireContext: function(item) {\n\t\tif (item && item.canvas) {\n\t\t\t// Support for any object associated to a canvas (including a context2d)\n\t\t\titem = item.canvas;\n\t\t}\n\n\t\treturn item && item.getContext('2d') || null;\n\t}\n};\n\nvar platform_dom = \"/*\\n * DOM element rendering detection\\n * https://davidwalsh.name/detect-node-insertion\\n */\\n@keyframes chartjs-render-animation {\\n\\tfrom { opacity: 0.99; }\\n\\tto { opacity: 1; }\\n}\\n\\n.chartjs-render-monitor {\\n\\tanimation: chartjs-render-animation 0.001s;\\n}\\n\\n/*\\n * DOM element resizing detection\\n * https://github.com/marcj/css-element-queries\\n */\\n.chartjs-size-monitor,\\n.chartjs-size-monitor-expand,\\n.chartjs-size-monitor-shrink {\\n\\tposition: absolute;\\n\\tdirection: ltr;\\n\\tleft: 0;\\n\\ttop: 0;\\n\\tright: 0;\\n\\tbottom: 0;\\n\\toverflow: hidden;\\n\\tpointer-events: none;\\n\\tvisibility: hidden;\\n\\tz-index: -1;\\n}\\n\\n.chartjs-size-monitor-expand > div {\\n\\tposition: absolute;\\n\\twidth: 1000000px;\\n\\theight: 1000000px;\\n\\tleft: 0;\\n\\ttop: 0;\\n}\\n\\n.chartjs-size-monitor-shrink > div {\\n\\tposition: absolute;\\n\\twidth: 200%;\\n\\theight: 200%;\\n\\tleft: 0;\\n\\ttop: 0;\\n}\\n\";\n\nvar platform_dom$1 = /*#__PURE__*/Object.freeze({\n__proto__: null,\n'default': platform_dom\n});\n\nvar stylesheet = getCjsExportFromNamespace(platform_dom$1);\n\nvar EXPANDO_KEY = '$chartjs';\nvar CSS_PREFIX = 'chartjs-';\nvar CSS_SIZE_MONITOR = CSS_PREFIX + 'size-monitor';\nvar CSS_RENDER_MONITOR = CSS_PREFIX + 'render-monitor';\nvar CSS_RENDER_ANIMATION = CSS_PREFIX + 'render-animation';\nvar ANIMATION_START_EVENTS = ['animationstart', 'webkitAnimationStart'];\n\n/**\n * DOM event types -> Chart.js event types.\n * Note: only events with different types are mapped.\n * @see https://developer.mozilla.org/en-US/docs/Web/Events\n */\nvar EVENT_TYPES = {\n\ttouchstart: 'mousedown',\n\ttouchmove: 'mousemove',\n\ttouchend: 'mouseup',\n\tpointerenter: 'mouseenter',\n\tpointerdown: 'mousedown',\n\tpointermove: 'mousemove',\n\tpointerup: 'mouseup',\n\tpointerleave: 'mouseout',\n\tpointerout: 'mouseout'\n};\n\n/**\n * The \"used\" size is the final value of a dimension property after all calculations have\n * been performed. This method uses the computed style of `element` but returns undefined\n * if the computed style is not expressed in pixels. That can happen in some cases where\n * `element` has a size relative to its parent and this last one is not yet displayed,\n * for example because of `display: none` on a parent node.\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value\n * @returns {number} Size in pixels or undefined if unknown.\n */\nfunction readUsedSize(element, property) {\n\tvar value = helpers$1.getStyle(element, property);\n\tvar matches = value && value.match(/^(\\d+)(\\.\\d+)?px$/);\n\treturn matches ? Number(matches[1]) : undefined;\n}\n\n/**\n * Initializes the canvas style and render size without modifying the canvas display size,\n * since responsiveness is handled by the controller.resize() method. The config is used\n * to determine the aspect ratio to apply in case no explicit height has been specified.\n */\nfunction initCanvas(canvas, config) {\n\tvar style = canvas.style;\n\n\t// NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it\n\t// returns null or '' if no explicit value has been set to the canvas attribute.\n\tvar renderHeight = canvas.getAttribute('height');\n\tvar renderWidth = canvas.getAttribute('width');\n\n\t// Chart.js modifies some canvas values that we want to restore on destroy\n\tcanvas[EXPANDO_KEY] = {\n\t\tinitial: {\n\t\t\theight: renderHeight,\n\t\t\twidth: renderWidth,\n\t\t\tstyle: {\n\t\t\t\tdisplay: style.display,\n\t\t\t\theight: style.height,\n\t\t\t\twidth: style.width\n\t\t\t}\n\t\t}\n\t};\n\n\t// Force canvas to display as block to avoid extra space caused by inline\n\t// elements, which would interfere with the responsive resize process.\n\t// https://github.com/chartjs/Chart.js/issues/2538\n\tstyle.display = style.display || 'block';\n\n\tif (renderWidth === null || renderWidth === '') {\n\t\tvar displayWidth = readUsedSize(canvas, 'width');\n\t\tif (displayWidth !== undefined) {\n\t\t\tcanvas.width = displayWidth;\n\t\t}\n\t}\n\n\tif (renderHeight === null || renderHeight === '') {\n\t\tif (canvas.style.height === '') {\n\t\t\t// If no explicit render height and style height, let's apply the aspect ratio,\n\t\t\t// which one can be specified by the user but also by charts as default option\n\t\t\t// (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2.\n\t\t\tcanvas.height = canvas.width / (config.options.aspectRatio || 2);\n\t\t} else {\n\t\t\tvar displayHeight = readUsedSize(canvas, 'height');\n\t\t\tif (displayWidth !== undefined) {\n\t\t\t\tcanvas.height = displayHeight;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn canvas;\n}\n\n/**\n * Detects support for options object argument in addEventListener.\n * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support\n * @private\n */\nvar supportsEventListenerOptions = (function() {\n\tvar supports = false;\n\ttry {\n\t\tvar options = Object.defineProperty({}, 'passive', {\n\t\t\t// eslint-disable-next-line getter-return\n\t\t\tget: function() {\n\t\t\t\tsupports = true;\n\t\t\t}\n\t\t});\n\t\twindow.addEventListener('e', null, options);\n\t} catch (e) {\n\t\t// continue regardless of error\n\t}\n\treturn supports;\n}());\n\n// Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events.\n// https://github.com/chartjs/Chart.js/issues/4287\nvar eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false;\n\nfunction addListener(node, type, listener) {\n\tnode.addEventListener(type, listener, eventListenerOptions);\n}\n\nfunction removeListener(node, type, listener) {\n\tnode.removeEventListener(type, listener, eventListenerOptions);\n}\n\nfunction createEvent(type, chart, x, y, nativeEvent) {\n\treturn {\n\t\ttype: type,\n\t\tchart: chart,\n\t\tnative: nativeEvent || null,\n\t\tx: x !== undefined ? x : null,\n\t\ty: y !== undefined ? y : null,\n\t};\n}\n\nfunction fromNativeEvent(event, chart) {\n\tvar type = EVENT_TYPES[event.type] || event.type;\n\tvar pos = helpers$1.getRelativePosition(event, chart);\n\treturn createEvent(type, chart, pos.x, pos.y, event);\n}\n\nfunction throttled(fn, thisArg) {\n\tvar ticking = false;\n\tvar args = [];\n\n\treturn function() {\n\t\targs = Array.prototype.slice.call(arguments);\n\t\tthisArg = thisArg || this;\n\n\t\tif (!ticking) {\n\t\t\tticking = true;\n\t\t\thelpers$1.requestAnimFrame.call(window, function() {\n\t\t\t\tticking = false;\n\t\t\t\tfn.apply(thisArg, args);\n\t\t\t});\n\t\t}\n\t};\n}\n\nfunction createDiv(cls) {\n\tvar el = document.createElement('div');\n\tel.className = cls || '';\n\treturn el;\n}\n\n// Implementation based on https://github.com/marcj/css-element-queries\nfunction createResizer(handler) {\n\tvar maxSize = 1000000;\n\n\t// NOTE(SB) Don't use innerHTML because it could be considered unsafe.\n\t// https://github.com/chartjs/Chart.js/issues/5902\n\tvar resizer = createDiv(CSS_SIZE_MONITOR);\n\tvar expand = createDiv(CSS_SIZE_MONITOR + '-expand');\n\tvar shrink = createDiv(CSS_SIZE_MONITOR + '-shrink');\n\n\texpand.appendChild(createDiv());\n\tshrink.appendChild(createDiv());\n\n\tresizer.appendChild(expand);\n\tresizer.appendChild(shrink);\n\tresizer._reset = function() {\n\t\texpand.scrollLeft = maxSize;\n\t\texpand.scrollTop = maxSize;\n\t\tshrink.scrollLeft = maxSize;\n\t\tshrink.scrollTop = maxSize;\n\t};\n\n\tvar onScroll = function() {\n\t\tresizer._reset();\n\t\thandler();\n\t};\n\n\taddListener(expand, 'scroll', onScroll.bind(expand, 'expand'));\n\taddListener(shrink, 'scroll', onScroll.bind(shrink, 'shrink'));\n\n\treturn resizer;\n}\n\n// https://davidwalsh.name/detect-node-insertion\nfunction watchForRender(node, handler) {\n\tvar expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {});\n\tvar proxy = expando.renderProxy = function(e) {\n\t\tif (e.animationName === CSS_RENDER_ANIMATION) {\n\t\t\thandler();\n\t\t}\n\t};\n\n\thelpers$1.each(ANIMATION_START_EVENTS, function(type) {\n\t\taddListener(node, type, proxy);\n\t});\n\n\t// #4737: Chrome might skip the CSS animation when the CSS_RENDER_MONITOR class\n\t// is removed then added back immediately (same animation frame?). Accessing the\n\t// `offsetParent` property will force a reflow and re-evaluate the CSS animation.\n\t// https://gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics\n\t// https://github.com/chartjs/Chart.js/issues/4737\n\texpando.reflow = !!node.offsetParent;\n\n\tnode.classList.add(CSS_RENDER_MONITOR);\n}\n\nfunction unwatchForRender(node) {\n\tvar expando = node[EXPANDO_KEY] || {};\n\tvar proxy = expando.renderProxy;\n\n\tif (proxy) {\n\t\thelpers$1.each(ANIMATION_START_EVENTS, function(type) {\n\t\t\tremoveListener(node, type, proxy);\n\t\t});\n\n\t\tdelete expando.renderProxy;\n\t}\n\n\tnode.classList.remove(CSS_RENDER_MONITOR);\n}\n\nfunction addResizeListener(node, listener, chart) {\n\tvar expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {});\n\n\t// Let's keep track of this added resizer and thus avoid DOM query when removing it.\n\tvar resizer = expando.resizer = createResizer(throttled(function() {\n\t\tif (expando.resizer) {\n\t\t\tvar container = chart.options.maintainAspectRatio && node.parentNode;\n\t\t\tvar w = container ? container.clientWidth : 0;\n\t\t\tlistener(createEvent('resize', chart));\n\t\t\tif (container && container.clientWidth < w && chart.canvas) {\n\t\t\t\t// If the container size shrank during chart resize, let's assume\n\t\t\t\t// scrollbar appeared. So we resize again with the scrollbar visible -\n\t\t\t\t// effectively making chart smaller and the scrollbar hidden again.\n\t\t\t\t// Because we are inside `throttled`, and currently `ticking`, scroll\n\t\t\t\t// events are ignored during this whole 2 resize process.\n\t\t\t\t// If we assumed wrong and something else happened, we are resizing\n\t\t\t\t// twice in a frame (potential performance issue)\n\t\t\t\tlistener(createEvent('resize', chart));\n\t\t\t}\n\t\t}\n\t}));\n\n\t// The resizer needs to be attached to the node parent, so we first need to be\n\t// sure that `node` is attached to the DOM before injecting the resizer element.\n\twatchForRender(node, function() {\n\t\tif (expando.resizer) {\n\t\t\tvar container = node.parentNode;\n\t\t\tif (container && container !== resizer.parentNode) {\n\t\t\t\tcontainer.insertBefore(resizer, container.firstChild);\n\t\t\t}\n\n\t\t\t// The container size might have changed, let's reset the resizer state.\n\t\t\tresizer._reset();\n\t\t}\n\t});\n}\n\nfunction removeResizeListener(node) {\n\tvar expando = node[EXPANDO_KEY] || {};\n\tvar resizer = expando.resizer;\n\n\tdelete expando.resizer;\n\tunwatchForRender(node);\n\n\tif (resizer && resizer.parentNode) {\n\t\tresizer.parentNode.removeChild(resizer);\n\t}\n}\n\n/**\n * Injects CSS styles inline if the styles are not already present.\n * @param {HTMLDocument|ShadowRoot} rootNode - the node to contain the