UNPKG

kepler.gl

Version:

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

337 lines (335 loc) 57.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.AiAssistantConfig = AiAssistantConfig; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral")); var _react = _interopRequireWildcard(require("react")); var _styledComponents = _interopRequireDefault(require("styled-components")); var _reactRedux = require("react-redux"); var _components = require("@kepler.gl/components"); var _apiKey = _interopRequireDefault(require("../icons/api-key")); var _models = _interopRequireDefault(require("../config/models.json")); var _usehooksTs = require("usehooks-ts"); var _core = require("@openassistant/core"); var _actions = require("../actions"); var _reactIntl = require("react-intl"); var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8; // SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } var SectionTitle = _styledComponents["default"].div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2["default"])(["\n font-size: ", ";\n color: ", ";\n text-transform: capitalize;\n"])), function (props) { return props.theme.inputFontSize; }, function (props) { return props.theme.effectPanelTextSecondary1; }); var StyledAiAssistantConfig = _styledComponents["default"].div(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2["default"])(["\n padding: 12px;\n font-size: ", ";\n display: flex;\n flex-direction: column;\n gap: 12px;\n width: 100%;\n height: 100%;\n\n .api-key-input {\n box-shadow: ", ";\n width: 100%;\n .api-key-input__icon {\n position: absolute;\n height: ", "px;\n width: 30px;\n padding-left: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: ", ";\n }\n\n input {\n padding: 4px 36px;\n height: ", "px;\n caret-color: unset;\n }\n }\n"])), function (props) { return props.theme.primaryBtnFontSizeDefault; }, function (props) { return props.theme.boxShadow; }, function (props) { return props.theme.geocoderInputHeight; }, function (props) { return props.theme.subtextColor; }, function (props) { return props.theme.geocoderInputHeight; }); // Ollama model input wrapper: checkbox + 'Input Model Name:' + input // all children element have width based on the content var OllamaModelInputWrapper = _styledComponents["default"].div(_templateObject3 || (_templateObject3 = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n flex-direction: row;\n gap: 4px;\n align-items: center;\n"]))); var StyledWrapper = _styledComponents["default"].div(_templateObject4 || (_templateObject4 = (0, _taggedTemplateLiteral2["default"])(["\n display: flex;\n justify-content: space-between;\n align-items: center;\n"]))); var StyledItemSelector = (0, _styledComponents["default"])(_components.ItemSelector)(_templateObject5 || (_templateObject5 = (0, _taggedTemplateLiteral2["default"])(["\n .item-selector__dropdown {\n padding-left: 10px;\n border-radius: 4px;\n }\n .active {\n border-color: ", ";\n border-radius: 4px 4px 0px 0px !important;\n }\n width: 100%;\n"])), function (props) { return props.theme.activeColor; }); var StyleSliderWrapper = _styledComponents["default"].div(_templateObject6 || (_templateObject6 = (0, _taggedTemplateLiteral2["default"])(["\n width: 100%;\n align-self: flex-start;\n height: 32px;\n display: flex;\n align-items: center;\n .kg-range-slider__input {\n height: 32px;\n text-align: center;\n padding: 3px 6px;\n }\n .kg-slider {\n padding-left: 6px;\n }\n .kg-range-slider {\n padding: 0px !important;\n }\n"]))); var StyledButton = _styledComponents["default"].div(_templateObject7 || (_templateObject7 = (0, _taggedTemplateLiteral2["default"])(["\n width: 100%;\n align-self: flex-start;\n margin-top: 12px;\n\n button div {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: 4px;\n }\n"]))); var StyleErrorMessage = _styledComponents["default"].div(_templateObject8 || (_templateObject8 = (0, _taggedTemplateLiteral2["default"])(["\n font-size: ", ";\n background-color: ", ";\n border-radius: 4px;\n padding: 4px 8px;\n color: ", ";\n"])), function (props) { return props.theme.primaryBtnFontSizeDefault; }, function (props) { return props.theme.errorColor; }, function (props) { return props.theme.errorTextColor; }); var RangeSlider = _components.appInjector.get(_components.RangeSliderFactory); function AiAssistantConfig() { var dispatch = (0, _reactRedux.useDispatch)(); var aiAssistantConfig = (0, _reactRedux.useSelector)(function (state) { return state.demo.aiAssistant.config; }); var intl = (0, _reactIntl.useIntl)(); var _useLocalStorage = (0, _usehooksTs.useLocalStorage)('ai-assistant-provider', aiAssistantConfig.provider || 'openai'), _useLocalStorage2 = (0, _slicedToArray2["default"])(_useLocalStorage, 2), provider = _useLocalStorage2[0], setProvider = _useLocalStorage2[1]; var _useLocalStorage3 = (0, _usehooksTs.useLocalStorage)('ai-assistant-model', aiAssistantConfig.model || _models["default"][provider][0]), _useLocalStorage4 = (0, _slicedToArray2["default"])(_useLocalStorage3, 2), model = _useLocalStorage4[0], setModel = _useLocalStorage4[1]; var _useLocalStorage5 = (0, _usehooksTs.useLocalStorage)('ai-assistant-api-key', aiAssistantConfig.apiKey || ''), _useLocalStorage6 = (0, _slicedToArray2["default"])(_useLocalStorage5, 2), apiKey = _useLocalStorage6[0], setApiKey = _useLocalStorage6[1]; var _useLocalStorage7 = (0, _usehooksTs.useLocalStorage)('ai-assistant-temperature', aiAssistantConfig.temperature || 0.0), _useLocalStorage8 = (0, _slicedToArray2["default"])(_useLocalStorage7, 2), temperature = _useLocalStorage8[0], setTemperature = _useLocalStorage8[1]; var _useLocalStorage9 = (0, _usehooksTs.useLocalStorage)('ai-assistant-top-p', aiAssistantConfig.topP || 1.0), _useLocalStorage10 = (0, _slicedToArray2["default"])(_useLocalStorage9, 2), topP = _useLocalStorage10[0], setTopP = _useLocalStorage10[1]; var _useLocalStorage11 = (0, _usehooksTs.useLocalStorage)('ai-assistant-base-url', aiAssistantConfig.baseUrl || 'http://localhost:11434/api'), _useLocalStorage12 = (0, _slicedToArray2["default"])(_useLocalStorage11, 2), baseUrl = _useLocalStorage12[0], setBaseUrl = _useLocalStorage12[1]; var _useLocalStorage13 = (0, _usehooksTs.useLocalStorage)('ai-assistant-mapbox-token', aiAssistantConfig.mapboxToken || ''), _useLocalStorage14 = (0, _slicedToArray2["default"])(_useLocalStorage13, 2), mapboxToken = _useLocalStorage14[0], setMapboxToken = _useLocalStorage14[1]; var _useState = (0, _react.useState)(false), _useState2 = (0, _slicedToArray2["default"])(_useState, 2), ollamaModelInputChecked = _useState2[0], setOllamaModelInputChecked = _useState2[1]; var _useState3 = (0, _react.useState)(''), _useState4 = (0, _slicedToArray2["default"])(_useState3, 2), ollamaModelInputValue = _useState4[0], setOllamaModelInputValue = _useState4[1]; var _useState5 = (0, _react.useState)(false), _useState6 = (0, _slicedToArray2["default"])(_useState5, 2), connectionError = _useState6[0], setConnectionError = _useState6[1]; var _useState7 = (0, _react.useState)(''), _useState8 = (0, _slicedToArray2["default"])(_useState7, 2), errorMessage = _useState8[0], setErrorMessage = _useState8[1]; var _useState9 = (0, _react.useState)(false), _useState10 = (0, _slicedToArray2["default"])(_useState9, 2), isRunning = _useState10[0], setIsRunning = _useState10[1]; var onAiProviderSelect = function onAiProviderSelect(value) { if (typeof value === 'string') { setProvider(value); setModel(_models["default"][value][0]); setConnectionError(false); setErrorMessage(''); } }; var onLLMModelSelect = function onLLMModelSelect(value) { if (typeof value === 'string') { setModel(value); } }; var onApiKeyChange = function onApiKeyChange(e) { setApiKey(e.target.value); // reset previous key error if any setConnectionError(false); setErrorMessage(''); }; var onTemperatureChange = function onTemperatureChange(value) { setTemperature(value[1]); }; var onTopPChange = function onTopPChange(value) { setTopP(value[1]); }; var onBaseUrlChange = function onBaseUrlChange(e) { setBaseUrl(e.target.value); setConnectionError(false); setErrorMessage(''); }; var onMapboxTokenChange = function onMapboxTokenChange(e) { setMapboxToken(e.target.value); }; var onOllamaModelInputChecked = function onOllamaModelInputChecked(e) { setOllamaModelInputChecked(e.target.checked); if (!e.target.checked) { // use model from selector setModel(''); } }; var onOllamaModelInputValueChange = function onOllamaModelInputValueChange(e) { setOllamaModelInputValue(e.target.value); setModel(e.target.value); }; var onStartChat = /*#__PURE__*/function () { var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() { var timeoutPromise, AssistantModel, success, _errorMessage; return _regenerator["default"].wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: setIsRunning(true); _context.prev = 1; timeoutPromise = new Promise(function (_, reject) { setTimeout(function () { return reject(new Error('Connection timeout after 15 seconds')); }, 15000); }); AssistantModel = (0, _core.GetAssistantModelByProvider)({ provider: provider }); _context.next = 6; return Promise.race([AssistantModel === null || AssistantModel === void 0 ? void 0 : AssistantModel.testConnection(apiKey, model), timeoutPromise]); case 6: success = _context.sent; _errorMessage = !success ? provider === 'ollama' ? 'Connection failed: maybe invalid Ollama Base URL' : 'Connection failed: maybe invalid API Key' : ''; setConnectionError(!success); setErrorMessage(_errorMessage); dispatch((0, _actions.updateAiAssistantConfig)({ provider: provider, model: model, apiKey: apiKey, baseUrl: baseUrl, isReady: success, temperature: temperature, topP: topP, mapboxToken: mapboxToken })); _context.next = 17; break; case 13: _context.prev = 13; _context.t0 = _context["catch"](1); setConnectionError(true); setErrorMessage(_context.t0 instanceof Error ? _context.t0.message : 'Connection failed'); case 17: _context.prev = 17; setIsRunning(false); return _context.finish(17); case 20: case "end": return _context.stop(); } }, _callee, null, [[1, 13, 17, 20]]); })); return function onStartChat() { return _ref.apply(this, arguments); }; }(); return /*#__PURE__*/_react["default"].createElement(StyledAiAssistantConfig, { className: "ai-assistant-config__type" }, /*#__PURE__*/_react["default"].createElement(_components.PanelLabelWrapper, null, /*#__PURE__*/_react["default"].createElement(SectionTitle, null, /*#__PURE__*/_react["default"].createElement(_reactIntl.FormattedMessage, { id: "aiAssistantManager.aiProvider" }))), /*#__PURE__*/_react["default"].createElement(StyledWrapper, null, /*#__PURE__*/_react["default"].createElement(StyledItemSelector, { selectedItems: provider, options: Object.keys(_models["default"]), multiSelect: false, disabled: false, onChange: onAiProviderSelect, filterOption: "name", getOptionValue: function getOptionValue(op) { return op; }, displayOption: function displayOption(op) { return op; }, searchable: false, showArrow: true })), /*#__PURE__*/_react["default"].createElement(_components.PanelLabelWrapper, null, /*#__PURE__*/_react["default"].createElement(SectionTitle, null, /*#__PURE__*/_react["default"].createElement(_reactIntl.FormattedMessage, { id: "aiAssistantManager.llmModel.title" }))), (provider === 'ollama' && !ollamaModelInputChecked || provider !== 'ollama') && /*#__PURE__*/_react["default"].createElement(StyledWrapper, null, /*#__PURE__*/_react["default"].createElement(StyledItemSelector, { selectedItems: model, options: _models["default"][provider], multiSelect: false, disabled: provider === 'ollama' ? ollamaModelInputChecked : false, placeholder: "Select LLM Model", onChange: onLLMModelSelect, filterOption: "name", getOptionValue: function getOptionValue(op) { return op; }, displayOption: function displayOption(op) { return op; }, searchable: false, showArrow: true })), provider === 'ollama' && /*#__PURE__*/_react["default"].createElement(OllamaModelInputWrapper, null, /*#__PURE__*/_react["default"].createElement("div", { style: { width: '250px' } }, /*#__PURE__*/_react["default"].createElement(_components.Checkbox, { id: "ollama-model-input", label: "Input Model Name", onChange: onOllamaModelInputChecked, checked: ollamaModelInputChecked })), /*#__PURE__*/_react["default"].createElement(_components.Input, { type: "text", onChange: onOllamaModelInputValueChange, placeholder: "Enter Model Name", value: ollamaModelInputValue, disabled: !ollamaModelInputChecked })), provider !== 'ollama' ? /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(_components.PanelLabelWrapper, null, /*#__PURE__*/_react["default"].createElement(SectionTitle, null, /*#__PURE__*/_react["default"].createElement(_reactIntl.FormattedMessage, { id: "aiAssistantManager.apiKey.placeholder" }))), /*#__PURE__*/_react["default"].createElement("div", { className: "api-key-input" }, /*#__PURE__*/_react["default"].createElement("div", { className: "api-key-input__icon" }, /*#__PURE__*/_react["default"].createElement(_apiKey["default"], { height: "20px" })), /*#__PURE__*/_react["default"].createElement(_components.Input, { type: "text", onChange: onApiKeyChange, placeholder: intl.formatMessage({ id: 'aiAssistantManager.apiKey.placeholder' }), value: apiKey }))) : /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(_components.PanelLabelWrapper, null, /*#__PURE__*/_react["default"].createElement(SectionTitle, null, /*#__PURE__*/_react["default"].createElement(_reactIntl.FormattedMessage, { id: "aiAssistantManager.baseUrl.placeholder" }))), /*#__PURE__*/_react["default"].createElement("div", { className: "api-key-input" }, /*#__PURE__*/_react["default"].createElement("div", { className: "api-key-input__icon" }, /*#__PURE__*/_react["default"].createElement(_apiKey["default"], { height: "20px" })), /*#__PURE__*/_react["default"].createElement(_components.Input, { type: "text", onChange: onBaseUrlChange, placeholder: intl.formatMessage({ id: 'aiAssistantManager.baseUrl.placeholder' }), value: baseUrl }))), connectionError && /*#__PURE__*/_react["default"].createElement(StyleErrorMessage, { className: "error-message" }, errorMessage), /*#__PURE__*/_react["default"].createElement(_components.PanelLabelWrapper, null, /*#__PURE__*/_react["default"].createElement(SectionTitle, null, /*#__PURE__*/_react["default"].createElement(_reactIntl.FormattedMessage, { id: "aiAssistantManager.temperature.title" }))), /*#__PURE__*/_react["default"].createElement(StyleSliderWrapper, null, /*#__PURE__*/_react["default"].createElement(RangeSlider, { showInput: true, isRanged: false, value0: 0, value1: temperature, onChange: onTemperatureChange, range: [0, 2], step: 0.1 })), /*#__PURE__*/_react["default"].createElement(_components.PanelLabelWrapper, null, /*#__PURE__*/_react["default"].createElement(SectionTitle, null, /*#__PURE__*/_react["default"].createElement(_reactIntl.FormattedMessage, { id: "aiAssistantManager.topP.title" }))), /*#__PURE__*/_react["default"].createElement(StyleSliderWrapper, null, /*#__PURE__*/_react["default"].createElement(RangeSlider, { showInput: true, isRanged: false, value0: 0, value1: topP, onChange: onTopPChange, range: [0, 1], step: 0.1 })), /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(_components.PanelLabelWrapper, null, /*#__PURE__*/_react["default"].createElement(SectionTitle, null, "Mapbox Token (optional for route/isochrone)")), /*#__PURE__*/_react["default"].createElement("div", { className: "api-key-input" }, /*#__PURE__*/_react["default"].createElement("div", { className: "api-key-input__icon" }, /*#__PURE__*/_react["default"].createElement(_apiKey["default"], { height: "20px" })), /*#__PURE__*/_react["default"].createElement(_components.Input, { type: "text", onChange: onMapboxTokenChange, placeholder: "Enter your Mapbox Token", value: mapboxToken }))), /*#__PURE__*/_react["default"].createElement(StyledButton, null, /*#__PURE__*/_react["default"].createElement(_components.Button, { onClick: onStartChat, width: '100%' }, isRunning && /*#__PURE__*/_react["default"].createElement(_components.LoadingSpinner, { size: 12 }), /*#__PURE__*/_react["default"].createElement(_reactIntl.FormattedMessage, { id: "aiAssistantManager.startChat" })))); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfc3R5bGVkQ29tcG9uZW50cyIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfcmVhY3RSZWR1eCIsIl9jb21wb25lbnRzIiwiX2FwaUtleSIsIl9tb2RlbHMiLCJfdXNlaG9va3NUcyIsIl9jb3JlIiwiX2FjdGlvbnMiLCJfcmVhY3RJbnRsIiwiX3RlbXBsYXRlT2JqZWN0IiwiX3RlbXBsYXRlT2JqZWN0MiIsIl90ZW1wbGF0ZU9iamVjdDMiLCJfdGVtcGxhdGVPYmplY3Q0IiwiX3RlbXBsYXRlT2JqZWN0NSIsIl90ZW1wbGF0ZU9iamVjdDYiLCJfdGVtcGxhdGVPYmplY3Q3IiwiX3RlbXBsYXRlT2JqZWN0OCIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiX3R5cGVvZiIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIlNlY3Rpb25UaXRsZSIsInN0eWxlZCIsImRpdiIsIl90YWdnZWRUZW1wbGF0ZUxpdGVyYWwyIiwicHJvcHMiLCJ0aGVtZSIsImlucHV0Rm9udFNpemUiLCJlZmZlY3RQYW5lbFRleHRTZWNvbmRhcnkxIiwiU3R5bGVkQWlBc3Npc3RhbnRDb25maWciLCJwcmltYXJ5QnRuRm9udFNpemVEZWZhdWx0IiwiYm94U2hhZG93IiwiZ2VvY29kZXJJbnB1dEhlaWdodCIsInN1YnRleHRDb2xvciIsIk9sbGFtYU1vZGVsSW5wdXRXcmFwcGVyIiwiU3R5bGVkV3JhcHBlciIsIlN0eWxlZEl0ZW1TZWxlY3RvciIsIkl0ZW1TZWxlY3RvciIsImFjdGl2ZUNvbG9yIiwiU3R5bGVTbGlkZXJXcmFwcGVyIiwiU3R5bGVkQnV0dG9uIiwiU3R5bGVFcnJvck1lc3NhZ2UiLCJlcnJvckNvbG9yIiwiZXJyb3JUZXh0Q29sb3IiLCJSYW5nZVNsaWRlciIsImFwcEluamVjdG9yIiwiUmFuZ2VTbGlkZXJGYWN0b3J5IiwiQWlBc3Npc3RhbnRDb25maWciLCJkaXNwYXRjaCIsInVzZURpc3BhdGNoIiwiYWlBc3Npc3RhbnRDb25maWciLCJ1c2VTZWxlY3RvciIsInN0YXRlIiwiZGVtbyIsImFpQXNzaXN0YW50IiwiY29uZmlnIiwiaW50bCIsInVzZUludGwiLCJfdXNlTG9jYWxTdG9yYWdlIiwidXNlTG9jYWxTdG9yYWdlIiwicHJvdmlkZXIiLCJfdXNlTG9jYWxTdG9yYWdlMiIsIl9zbGljZWRUb0FycmF5MiIsInNldFByb3ZpZGVyIiwiX3VzZUxvY2FsU3RvcmFnZTMiLCJtb2RlbCIsIlBST1ZJREVSX01PREVMUyIsIl91c2VMb2NhbFN0b3JhZ2U0Iiwic2V0TW9kZWwiLCJfdXNlTG9jYWxTdG9yYWdlNSIsImFwaUtleSIsIl91c2VMb2NhbFN0b3JhZ2U2Iiwic2V0QXBpS2V5IiwiX3VzZUxvY2FsU3RvcmFnZTciLCJ0ZW1wZXJhdHVyZSIsIl91c2VMb2NhbFN0b3JhZ2U4Iiwic2V0VGVtcGVyYXR1cmUiLCJfdXNlTG9jYWxTdG9yYWdlOSIsInRvcFAiLCJfdXNlTG9jYWxTdG9yYWdlMTAiLCJzZXRUb3BQIiwiX3VzZUxvY2FsU3RvcmFnZTExIiwiYmFzZVVybCIsIl91c2VMb2NhbFN0b3JhZ2UxMiIsInNldEJhc2VVcmwiLCJfdXNlTG9jYWxTdG9yYWdlMTMiLCJtYXBib3hUb2tlbiIsIl91c2VMb2NhbFN0b3JhZ2UxNCIsInNldE1hcGJveFRva2VuIiwiX3VzZVN0YXRlIiwidXNlU3RhdGUiLCJfdXNlU3RhdGUyIiwib2xsYW1hTW9kZWxJbnB1dENoZWNrZWQiLCJzZXRPbGxhbWFNb2RlbElucHV0Q2hlY2tlZCIsIl91c2VTdGF0ZTMiLCJfdXNlU3RhdGU0Iiwib2xsYW1hTW9kZWxJbnB1dFZhbHVlIiwic2V0T2xsYW1hTW9kZWxJbnB1dFZhbHVlIiwiX3VzZVN0YXRlNSIsIl91c2VTdGF0ZTYiLCJjb25uZWN0aW9uRXJyb3IiLCJzZXRDb25uZWN0aW9uRXJyb3IiLCJfdXNlU3RhdGU3IiwiX3VzZVN0YXRlOCIsImVycm9yTWVzc2FnZSIsInNldEVycm9yTWVzc2FnZSIsIl91c2VTdGF0ZTkiLCJfdXNlU3RhdGUxMCIsImlzUnVubmluZyIsInNldElzUnVubmluZyIsIm9uQWlQcm92aWRlclNlbGVjdCIsInZhbHVlIiwib25MTE1Nb2RlbFNlbGVjdCIsIm9uQXBpS2V5Q2hhbmdlIiwidGFyZ2V0Iiwib25UZW1wZXJhdHVyZUNoYW5nZSIsIm9uVG9wUENoYW5nZSIsIm9uQmFzZVVybENoYW5nZSIsIm9uTWFwYm94VG9rZW5DaGFuZ2UiLCJvbk9sbGFtYU1vZGVsSW5wdXRDaGVja2VkIiwiY2hlY2tlZCIsIm9uT2xsYW1hTW9kZWxJbnB1dFZhbHVlQ2hhbmdlIiwib25TdGFydENoYXQiLCJfcmVmIiwiX2FzeW5jVG9HZW5lcmF0b3IyIiwiX3JlZ2VuZXJhdG9yIiwibWFyayIsIl9jYWxsZWUiLCJ0aW1lb3V0UHJvbWlzZSIsIkFzc2lzdGFudE1vZGVsIiwic3VjY2VzcyIsIl9lcnJvck1lc3NhZ2UiLCJ3cmFwIiwiX2NhbGxlZSQiLCJfY29udGV4dCIsInByZXYiLCJuZXh0IiwiUHJvbWlzZSIsIl8iLCJyZWplY3QiLCJzZXRUaW1lb3V0IiwiRXJyb3IiLCJHZXRBc3Npc3RhbnRNb2RlbEJ5UHJvdmlkZXIiLCJyYWNlIiwidGVzdENvbm5lY3Rpb24iLCJzZW50IiwidXBkYXRlQWlBc3Npc3RhbnRDb25maWciLCJpc1JlYWR5IiwidDAiLCJtZXNzYWdlIiwiZmluaXNoIiwic3RvcCIsImFwcGx5IiwiYXJndW1lbnRzIiwiY3JlYXRlRWxlbWVudCIsImNsYXNzTmFtZSIsIlBhbmVsTGFiZWxXcmFwcGVyIiwiRm9ybWF0dGVkTWVzc2FnZSIsImlkIiwic2VsZWN0ZWRJdGVtcyIsIm9wdGlvbnMiLCJrZXlzIiwibXVsdGlTZWxlY3QiLCJkaXNhYmxlZCIsIm9uQ2hhbmdlIiwiZmlsdGVyT3B0aW9uIiwiZ2V0T3B0aW9uVmFsdWUiLCJvcCIsImRpc3BsYXlPcHRpb24iLCJzZWFyY2hhYmxlIiwic2hvd0Fycm93IiwicGxhY2Vob2xkZXIiLCJzdHlsZSIsIndpZHRoIiwiQ2hlY2tib3giLCJsYWJlbCIsIklucHV0IiwidHlwZSIsIkZyYWdtZW50IiwiaGVpZ2h0IiwiZm9ybWF0TWVzc2FnZSIsInNob3dJbnB1dCIsImlzUmFuZ2VkIiwidmFsdWUwIiwidmFsdWUxIiwicmFuZ2UiLCJzdGVwIiwiQnV0dG9uIiwib25DbGljayIsIkxvYWRpbmdTcGlubmVyIiwic2l6ZSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21wb25lbnRzL2FpLWFzc2lzdGFudC1jb25maWcudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVRcbi8vIENvcHlyaWdodCBjb250cmlidXRvcnMgdG8gdGhlIGtlcGxlci5nbCBwcm9qZWN0XG5cbmltcG9ydCBSZWFjdCwge3VzZVN0YXRlfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgc3R5bGVkIGZyb20gJ3N0eWxlZC1jb21wb25lbnRzJztcbmltcG9ydCB7dXNlU2VsZWN0b3IsIHVzZURpc3BhdGNofSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQge1xuICBJbnB1dCxcbiAgUGFuZWxMYWJlbFdyYXBwZXIsXG4gIEl0ZW1TZWxlY3RvcixcbiAgUmFuZ2VTbGlkZXJGYWN0b3J5LFxuICBCdXR0b24sXG4gIExvYWRpbmdTcGlubmVyLFxuICBhcHBJbmplY3RvcixcbiAgQ2hlY2tib3hcbn0gZnJvbSAnQGtlcGxlci5nbC9jb21wb25lbnRzJztcbmltcG9ydCB7U3RhdGV9IGZyb20gJy4uL2luZGV4JztcbmltcG9ydCBBcGlLZXkgZnJvbSAnLi4vaWNvbnMvYXBpLWtleSc7XG5pbXBvcnQgUFJPVklERVJfTU9ERUxTIGZyb20gJy4uL2NvbmZpZy9tb2RlbHMuanNvbic7XG5pbXBvcnQge3VzZUxvY2FsU3RvcmFnZX0gZnJvbSAndXNlaG9va3MtdHMnO1xuaW1wb3J0IHtHZXRBc3Npc3RhbnRNb2RlbEJ5UHJvdmlkZXJ9IGZyb20gJ0BvcGVuYXNzaXN0YW50L2NvcmUnO1xuaW1wb3J0IHt1cGRhdGVBaUFzc2lzdGFudENvbmZpZ30gZnJvbSAnLi4vYWN0aW9ucyc7XG5pbXBvcnQge0Zvcm1hdHRlZE1lc3NhZ2UsIHVzZUludGx9IGZyb20gJ3JlYWN0LWludGwnO1xuXG5jb25zdCBTZWN0aW9uVGl0bGUgPSBzdHlsZWQuZGl2YFxuICBmb250LXNpemU6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuaW5wdXRGb250U2l6ZX07XG4gIGNvbG9yOiAke3Byb3BzID0+IHByb3BzLnRoZW1lLmVmZmVjdFBhbmVsVGV4dFNlY29uZGFyeTF9O1xuICB0ZXh0LXRyYW5zZm9ybTogY2FwaXRhbGl6ZTtcbmA7XG5cbmNvbnN0IFN0eWxlZEFpQXNzaXN0YW50Q29uZmlnID0gc3R5bGVkLmRpdmBcbiAgcGFkZGluZzogMTJweDtcbiAgZm9udC1zaXplOiAke3Byb3BzID0+IHByb3BzLnRoZW1lLnByaW1hcnlCdG5Gb250U2l6ZURlZmF1bHR9O1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICBnYXA6IDEycHg7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG5cbiAgLmFwaS1rZXktaW5wdXQge1xuICAgIGJveC1zaGFkb3c6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuYm94U2hhZG93fTtcbiAgICB3aWR0aDogMTAwJTtcbiAgICAuYXBpLWtleS1pbnB1dF9faWNvbiB7XG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICBoZWlnaHQ6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuZ2VvY29kZXJJbnB1dEhlaWdodH1weDtcbiAgICAgIHdpZHRoOiAzMHB4O1xuICAgICAgcGFkZGluZy1sZWZ0OiA2cHg7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgICAgY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuc3VidGV4dENvbG9yfTtcbiAgICB9XG5cbiAgICBpbnB1dCB7XG4gICAgICBwYWRkaW5nOiA0cHggMzZweDtcbiAgICAgIGhlaWdodDogJHtwcm9wcyA9PiBwcm9wcy50aGVtZS5nZW9jb2RlcklucHV0SGVpZ2h0fXB4O1xuICAgICAgY2FyZXQtY29sb3I6IHVuc2V0O1xuICAgIH1cbiAgfVxuYDtcblxuLy8gT2xsYW1hIG1vZGVsIGlucHV0IHdyYXBwZXI6IGNoZWNrYm94ICsgJ0lucHV0IE1vZGVsIE5hbWU6JyArIGlucHV0XG4vLyBhbGwgY2hpbGRyZW4gZWxlbWVudCBoYXZlIHdpZHRoIGJhc2VkIG9uIHRoZSBjb250ZW50XG5jb25zdCBPbGxhbWFNb2RlbElucHV0V3JhcHBlciA9IHN0eWxlZC5kaXZgXG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gIGdhcDogNHB4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuYDtcblxuY29uc3QgU3R5bGVkV3JhcHBlciA9IHN0eWxlZC5kaXZgXG4gIGRpc3BsYXk6IGZsZXg7XG4gIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbmA7XG5cbmNvbnN0IFN0eWxlZEl0ZW1TZWxlY3RvciA9IHN0eWxlZChJdGVtU2VsZWN0b3IpYFxuICAuaXRlbS1zZWxlY3Rvcl9fZHJvcGRvd24ge1xuICAgIHBhZGRpbmctbGVmdDogMTBweDtcbiAgICBib3JkZXItcmFkaXVzOiA0cHg7XG4gIH1cbiAgLmFjdGl2ZSB7XG4gICAgYm9yZGVyLWNvbG9yOiAke3Byb3BzID0+IHByb3BzLnRoZW1lLmFjdGl2ZUNvbG9yfTtcbiAgICBib3JkZXItcmFkaXVzOiA0cHggNHB4IDBweCAwcHggIWltcG9ydGFudDtcbiAgfVxuICB3aWR0aDogMTAwJTtcbmA7XG5cbmNvbnN0IFN0eWxlU2xpZGVyV3JhcHBlciA9IHN0eWxlZC5kaXZgXG4gIHdpZHRoOiAxMDAlO1xuICBhbGlnbi1zZWxmOiBmbGV4LXN0YXJ0O1xuICBoZWlnaHQ6IDMycHg7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIC5rZy1yYW5nZS1zbGlkZXJfX2lucHV0IHtcbiAgICBoZWlnaHQ6IDMycHg7XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgIHBhZGRpbmc6IDNweCA2cHg7XG4gIH1cbiAgLmtnLXNsaWRlciB7XG4gICAgcGFkZGluZy1sZWZ0OiA2cHg7XG4gIH1cbiAgLmtnLXJhbmdlLXNsaWRlciB7XG4gICAgcGFkZGluZzogMHB4ICFpbXBvcnRhbnQ7XG4gIH1cbmA7XG5cbmNvbnN0IFN0eWxlZEJ1dHRvbiA9IHN0eWxlZC5kaXZgXG4gIHdpZHRoOiAxMDAlO1xuICBhbGlnbi1zZWxmOiBmbGV4LXN0YXJ0O1xuICBtYXJnaW4tdG9wOiAxMnB4O1xuXG4gIGJ1dHRvbiBkaXYge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDRweDtcbiAgICBtYXJnaW4tcmlnaHQ6IDRweDtcbiAgfVxuYDtcblxuY29uc3QgU3R5bGVFcnJvck1lc3NhZ2UgPSBzdHlsZWQuZGl2YFxuICBmb250LXNpemU6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUucHJpbWFyeUJ0bkZvbnRTaXplRGVmYXVsdH07XG4gIGJhY2tncm91bmQtY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuZXJyb3JDb2xvcn07XG4gIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgcGFkZGluZzogNHB4IDhweDtcbiAgY29sb3I6ICR7cHJvcHMgPT4gcHJvcHMudGhlbWUuZXJyb3JUZXh0Q29sb3J9O1xuYDtcblxuY29uc3QgUmFuZ2VTbGlkZXIgPSBhcHBJbmplY3Rvci5nZXQoUmFuZ2VTbGlkZXJGYWN0b3J5KTtcblxuZXhwb3J0IGZ1bmN0aW9uIEFpQXNzaXN0YW50Q29uZmlnKCkge1xuICBjb25zdCBkaXNwYXRjaCA9IHVzZURpc3BhdGNoKCk7XG4gIGNvbnN0IGFpQXNzaXN0YW50Q29uZmlnID0gdXNlU2VsZWN0b3IoKHN0YXRlOiBTdGF0ZSkgPT4gc3RhdGUuZGVtby5haUFzc2lzdGFudC5jb25maWcpO1xuICBjb25zdCBpbnRsID0gdXNlSW50bCgpO1xuXG4gIGNvbnN0IFtwcm92aWRlciwgc2V0UHJvdmlkZXJdID0gdXNlTG9jYWxTdG9yYWdlKFxuICAgICdhaS1hc3Npc3RhbnQtcHJvdmlkZXInLFxuICAgIGFpQXNzaXN0YW50Q29uZmlnLnByb3ZpZGVyIHx8ICdvcGVuYWknXG4gICk7XG4gIGNvbnN0IFttb2RlbCwgc2V0TW9kZWxdID0gdXNlTG9jYWxTdG9yYWdlKFxuICAgICdhaS1hc3Npc3RhbnQtbW9kZWwnLFxuICAgIGFpQXNzaXN0YW50Q29uZmlnLm1vZGVsIHx8IFBST1ZJREVSX01PREVMU1twcm92aWRlcl1bMF1cbiAgKTtcbiAgY29uc3QgW2FwaUtleSwgc2V0QXBpS2V5XSA9IHVzZUxvY2FsU3RvcmFnZShcbiAgICAnYWktYXNzaXN0YW50LWFwaS1rZXknLFxuICAgIGFpQXNzaXN0YW50Q29uZmlnLmFwaUtleSB8fCAnJ1xuICApO1xuICBjb25zdCBbdGVtcGVyYXR1cmUsIHNldFRlbXBlcmF0dXJlXSA9IHVzZUxvY2FsU3RvcmFnZShcbiAgICAnYWktYXNzaXN0YW50LXRlbXBlcmF0dXJlJyxcbiAgICBhaUFzc2lzdGFudENvbmZpZy50ZW1wZXJhdHVyZSB8fCAwLjBcbiAgKTtcbiAgY29uc3QgW3RvcFAsIHNldFRvcFBdID0gdXNlTG9jYWxTdG9yYWdlKCdhaS1hc3Npc3RhbnQtdG9wLXAnLCBhaUFzc2lzdGFudENvbmZpZy50b3BQIHx8IDEuMCk7XG4gIGNvbnN0IFtiYXNlVXJsLCBzZXRCYXNlVXJsXSA9IHVzZUxvY2FsU3RvcmFnZShcbiAgICAnYWktYXNzaXN0YW50LWJhc2UtdXJsJyxcbiAgICBhaUFzc2lzdGFudENvbmZpZy5iYXNlVXJsIHx8ICdodHRwOi8vbG9jYWxob3N0OjExNDM0L2FwaSdcbiAgKTtcbiAgY29uc3QgW21hcGJveFRva2VuLCBzZXRNYXBib3hUb2tlbl0gPSB1c2VMb2NhbFN0b3JhZ2UoXG4gICAgJ2FpLWFzc2lzdGFudC1tYXBib3gtdG9rZW4nLFxuICAgIGFpQXNzaXN0YW50Q29uZmlnLm1hcGJveFRva2VuIHx8ICcnXG4gICk7XG4gIGNvbnN0IFtvbGxhbWFNb2RlbElucHV0Q2hlY2tlZCwgc2V0T2xsYW1hTW9kZWxJbnB1dENoZWNrZWRdID0gdXNlU3RhdGUoZmFsc2UpO1xuICBjb25zdCBbb2xsYW1hTW9kZWxJbnB1dFZhbHVlLCBzZXRPbGxhbWFNb2RlbElucHV0VmFsdWVdID0gdXNlU3RhdGUoJycpO1xuICBjb25zdCBbY29ubmVjdGlvbkVycm9yLCBzZXRDb25uZWN0aW9uRXJyb3JdID0gdXNlU3RhdGUoZmFsc2UpO1xuICBjb25zdCBbZXJyb3JNZXNzYWdlLCBzZXRFcnJvck1lc3NhZ2VdID0gdXNlU3RhdGUoJycpO1xuICBjb25zdCBbaXNSdW5uaW5nLCBzZXRJc1J1bm5pbmddID0gdXNlU3RhdGUoZmFsc2UpO1xuXG4gIGNvbnN0IG9uQWlQcm92aWRlclNlbGVjdCA9ICh2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IG9iamVjdCB8IG51bGwpID0+IHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgc2V0UHJvdmlkZXIodmFsdWUpO1xuICAgICAgc2V0TW9kZWwoUFJPVklERVJfTU9ERUxTW3ZhbHVlXVswXSk7XG4gICAgICBzZXRDb25uZWN0aW9uRXJyb3IoZmFsc2UpO1xuICAgICAgc2V0RXJyb3JNZXNzYWdlKCcnKTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3Qgb25MTE1Nb2RlbFNlbGVjdCA9ICh2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IG9iamVjdCB8IG51bGwpID0+IHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgc2V0TW9kZWwodmFsdWUpO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBvbkFwaUtleUNoYW5nZSA9IChlOiBSZWFjdC5DaGFuZ2VFdmVudDxIVE1MSW5wdXRFbGVtZW50PikgPT4ge1xuICAgIHNldEFwaUtleShlLnRhcmdldC52YWx1ZSk7XG4gICAgLy8gcmVzZXQgcHJldmlvdXMga2V5IGVycm9yIGlmIGFueVxuICAgIHNldENvbm5lY3Rpb25FcnJvcihmYWxzZSk7XG4gICAgc2V0RXJyb3JNZXNzYWdlKCcnKTtcbiAgfTtcblxuICBjb25zdCBvblRlbXBlcmF0dXJlQ2hhbmdlID0gKHZhbHVlOiBudW1iZXJbXSkgPT4ge1xuICAgIHNldFRlbXBlcmF0dXJlKHZhbHVlWzFdKTtcbiAgfTtcblxuICBjb25zdCBvblRvcFBDaGFuZ2UgPSAodmFsdWU6IG51bWJlcltdKSA9PiB7XG4gICAgc2V0VG9wUCh2YWx1ZVsxXSk7XG4gIH07XG5cbiAgY29uc3Qgb25CYXNlVXJsQ2hhbmdlID0gKGU6IFJlYWN0LkNoYW5nZUV2ZW50PEhUTUxJbnB1dEVsZW1lbnQ+KSA9PiB7XG4gICAgc2V0QmFzZVVybChlLnRhcmdldC52YWx1ZSk7XG4gICAgc2V0Q29ubmVjdGlvbkVycm9yKGZhbHNlKTtcbiAgICBzZXRFcnJvck1lc3NhZ2UoJycpO1xuICB9O1xuXG4gIGNvbnN0IG9uTWFwYm94VG9rZW5DaGFuZ2UgPSAoZTogUmVhY3QuQ2hhbmdlRXZlbnQ8SFRNTElucHV0RWxlbWVudD4pID0+IHtcbiAgICBzZXRNYXBib3hUb2tlbihlLnRhcmdldC52YWx1ZSk7XG4gIH07XG5cbiAgY29uc3Qgb25PbGxhbWFNb2RlbElucHV0Q2hlY2tlZCA9IChlOiBSZWFjdC5DaGFuZ2VFdmVudDxIVE1MSW5wdXRFbGVtZW50PikgPT4ge1xuICAgIHNldE9sbGFtYU1vZGVsSW5wdXRDaGVja2VkKGUudGFyZ2V0LmNoZWNrZWQpO1xuICAgIGlmICghZS50YXJnZXQuY2hlY2tlZCkge1xuICAgICAgLy8gdXNlIG1vZGVsIGZyb20gc2VsZWN0b3JcbiAgICAgIHNldE1vZGVsKCcnKTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3Qgb25PbGxhbWFNb2RlbElucHV0VmFsdWVDaGFuZ2UgPSAoZTogUmVhY3QuQ2hhbmdlRXZlbnQ8SFRNTElucHV0RWxlbWVudD4pID0+IHtcbiAgICBzZXRPbGxhbWFNb2RlbElucHV0VmFsdWUoZS50YXJnZXQudmFsdWUpO1xuICAgIHNldE1vZGVsKGUudGFyZ2V0LnZhbHVlKTtcbiAgfTtcblxuICBjb25zdCBvblN0YXJ0Q2hhdCA9IGFzeW5jICgpID0+IHtcbiAgICBzZXRJc1J1bm5pbmcodHJ1ZSk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRpbWVvdXRQcm9taXNlID0gbmV3IFByb21pc2UoKF8sIHJlamVjdCkgPT4ge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHJlamVjdChuZXcgRXJyb3IoJ0Nvbm5lY3Rpb24gdGltZW91dCBhZnRlciAxNSBzZWNvbmRzJykpLCAxNTAwMCk7XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgQXNzaXN0YW50TW9kZWwgPSBHZXRBc3Npc3RhbnRNb2RlbEJ5UHJvdmlkZXIoe1xuICAgICAgICBwcm92aWRlcjogcHJvdmlkZXJcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBzdWNjZXNzID0gKGF3YWl0IFByb21pc2UucmFjZShbXG4gICAgICAgIEFzc2lzdGFudE1vZGVsPy50ZXN0Q29ubmVjdGlvbihhcGlLZXksIG1vZGVsKSxcbiAgICAgICAgdGltZW91dFByb21pc2VcbiAgICAgIF0pKSBhcyBib29sZWFuO1xuXG4gICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSAhc3VjY2Vzc1xuICAgICAgICA/IHByb3ZpZGVyID09PSAnb2xsYW1hJ1xuICAgICAgICAgID8gJ0Nvbm5lY3Rpb24gZmFpbGVkOiBtYXliZSBpbnZhbGlkIE9sbGFtYSBCYXNlIFVSTCdcbiAgICAgICAgICA6ICdDb25uZWN0aW9uIGZhaWxlZDogbWF5YmUgaW52YWxpZCBBUEkgS2V5J1xuICAgICAgICA6ICcnO1xuICAgICAgc2V0Q29ubmVjdGlvbkVycm9yKCFzdWNjZXNzKTtcbiAgICAgIHNldEVycm9yTWVzc2FnZShlcnJvck1lc3NhZ2UpO1xuICAgICAgZGlzcGF0Y2goXG4gICAgICAgIHVwZGF0ZUFpQXNzaXN0YW50Q29uZmlnKHtcbiAgICAgICAgICBwcm92aWRlcjogcHJvdmlkZXIsXG4gICAgICAgICAgbW9kZWw6IG1vZGVsLFxuICAgICAgICAgIGFwaUtleTogYXBpS2V5LFxuICAgICAgICAgIGJhc2VVcmw6IGJhc2VVcmwsXG4gICAgICAgICAgaXNSZWFkeTogc3VjY2VzcyxcbiAgICAgICAgICB0ZW1wZXJhdHVyZTogdGVtcGVyYXR1cmUsXG4gICAgICAgICAgdG9wUDogdG9wUCxcbiAgICAgICAgICBtYXBib3hUb2tlbjogbWFwYm94VG9rZW5cbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHNldENvbm5lY3Rpb25FcnJvcih0cnVlKTtcbiAgICAgIHNldEVycm9yTWVzc2FnZShlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6ICdDb25uZWN0aW9uIGZhaWxlZCcpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBzZXRJc1J1bm5pbmcoZmFsc2UpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gKFxuICAgIDxTdHlsZWRBaUFzc2lzdGFudENvbmZpZyBjbGFzc05hbWU9XCJhaS1hc3Npc3RhbnQtY29uZmlnX190eXBlXCI+XG4gICAgICA8UGFuZWxMYWJlbFdyYXBwZXI+XG4gICAgICAgIDxTZWN0aW9uVGl0bGU+XG4gICAgICAgICAgPEZvcm1hdHRlZE1lc3NhZ2UgaWQ9XCJhaUFzc2lzdGFudE1hbmFnZXIuYWlQcm92aWRlclwiIC8+XG4gICAgICAgIDwvU2VjdGlvblRpdGxlPlxuICAgICAgPC9QYW5lbExhYmVsV3JhcHBlcj5cbiAgICAgIDxTdHlsZWRXcmFwcGVyPlxuICAgICAgICA8U3R5bGVkSXRlbVNlbGVjdG9yXG4gICAgICAgICAgc2VsZWN0ZWRJdGVtcz17cHJvdmlkZXJ9XG4gICAgICAgICAgb3B0aW9ucz17T2JqZWN0LmtleXMoUFJPVklERVJfTU9ERUxTKX1cbiAgICAgICAgICBtdWx0aVNlbGVjdD17ZmFsc2V9XG4gICAgICAgICAgZGlzYWJsZWQ9e2ZhbHNlfVxuICAgICAgICAgIG9uQ2hhbmdlPXtvbkFpUHJvdmlkZXJTZWxlY3R9XG4gICAgICAgICAgZmlsdGVyT3B0aW9uPVwibmFtZVwiXG4gICAgICAgICAgZ2V0T3B0aW9uVmFsdWU9e29wID0+IG9wfVxuICAgICAgICAgIGRpc3BsYXlPcHRpb249e29wID0+IG9wfVxuICAgICAgICAgIHNlYXJjaGFibGU9e2ZhbHNlfVxuICAgICAgICAgIHNob3dBcnJvdz17dHJ1ZX1cbiAgICAgICAgLz5cbiAgICAgIDwvU3R5bGVkV3JhcHBlcj5cbiAgICAgIDxQYW5lbExhYmVsV3JhcHBlcj5cbiAgICAgICAgPFNlY3Rpb25UaXRsZT5cbiAgICAgICAgICA8Rm9ybWF0dGVkTWVzc2FnZSBpZD1cImFpQXNzaXN0YW50TWFuYWdlci5sbG1Nb2RlbC50aXRsZVwiIC8+XG4gICAgICAgIDwvU2VjdGlvblRpdGxlPlxuICAgICAgPC9QYW5lbExhYmVsV3JhcHBlcj5cbiAgICAgIHsoKHByb3ZpZGVyID09PSAnb2xsYW1hJyAmJiAhb2xsYW1hTW9kZWxJbnB1dENoZWNrZWQpIHx8IHByb3ZpZGVyICE9PSAnb2xsYW1hJykgJiYgKFxuICAgICAgICA8U3R5bGVkV3JhcHBlcj5cbiAgICAgICAgICA8U3R5bGVkSXRlbVNlbGVjdG9yXG4gICAgICAgICAgICBzZWxlY3RlZEl0ZW1zPXttb2RlbH1cbiAgICAgICAgICAgIG9wdGlvbnM9e1BST1ZJREVSX01PREVMU1twcm92aWRlcl19XG4gICAgICAgICAgICBtdWx0aVNlbGVjdD17ZmFsc2V9XG4gICAgICAgICAgICBkaXNhYmxlZD17cHJvdmlkZXIgPT09ICdvbGxhbWEnID8gb2xsYW1hTW9kZWxJbnB1dENoZWNrZWQgOiBmYWxzZX1cbiAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VsZWN0IExMTSBNb2RlbFwiXG4gICAgICAgICAgICBvbkNoYW5nZT17b25MTE1Nb2RlbFNlbGVjdH1cbiAgICAgICAgICAgIGZpbHRlck9wdGlvbj1cIm5hbWVcIlxuICAgICAgICAgICAgZ2V0T3B0aW9uVmFsdWU9e29wID0+IG9wfVxuICAgICAgICAgICAgZGlzcGxheU9wdGlvbj17b3AgPT4gb3B9XG4gICAgICAgICAgICBzZWFyY2hhYmxlPXtmYWxzZX1cbiAgICAgICAgICAgIHNob3dBcnJvdz17dHJ1ZX1cbiAgICAgICAgICAvPlxuICAgICAgICA8L1N0eWxlZFdyYXBwZXI+XG4gICAgICApfVxuICAgICAge3Byb3ZpZGVyID09PSAnb2xsYW1hJyAmJiAoXG4gICAgICAgIDxPbGxhbWFNb2RlbElucHV0V3JhcHBlcj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPXt7d2lkdGg6ICcyNTBweCd9fT5cbiAgICAgICAgICAgIDxDaGVja2JveFxuICAgICAgICAgICAgICBpZD1cIm9sbGFtYS1tb2RlbC1pbnB1dFwiXG4gICAgICAgICAgICAgIGxhYmVsPVwiSW5wdXQgTW9kZWwgTmFtZVwiXG4gICAgICAgICAgICAgIG9uQ2hhbmdlPXtvbk9sbGFtYU1vZGVsSW5wdXRDaGVja2VkfVxuICAgICAgICAgICAgICBjaGVja2VkPXtvbGxhbWFNb2RlbElucHV0Q2hlY2tlZH1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPElucHV0XG4gICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICBvbkNoYW5nZT17b25PbGxhbWFNb2RlbElucHV0VmFsdWVDaGFuZ2V9XG4gICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkVudGVyIE1vZGVsIE5hbWVcIlxuICAgICAgICAgICAgdmFsdWU9e29sbGFtYU1vZGVsSW5wdXRWYWx1ZX1cbiAgICAgICAgICAgIGRpc2FibGVkPXshb2xsYW1hTW9kZWxJbnB1dENoZWNrZWR9XG4gICAgICAgICAgLz5cbiAgICAgICAgPC9PbGxhbWFNb2RlbElucHV0V3JhcHBlcj5cbiAgICAgICl9XG4gICAgICB7cHJvdmlkZXIgIT09ICdvbGxhbWEnID8gKFxuICAgICAgICA8PlxuICAgICAgICAgIDxQYW5lbExhYmVsV3JhcHBlcj5cbiAgICAgICAgICAgIDxTZWN0aW9uVGl0bGU+XG4gICAgICAgICAgICAgIDxGb3JtYXR0ZWRNZXNzYWdlIGlkPVwiYWlBc3Npc3RhbnRNYW5hZ2VyLmFwaUtleS5wbGFjZWhvbGRlclwiIC8+XG4gICAgICAgICAgICA8L1NlY3Rpb25UaXRsZT5cbiAgICAgICAgICA8L1BhbmVsTGFiZWxXcmFwcGVyPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYXBpLWtleS1pbnB1dFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJhcGkta2V5LWlucHV0X19pY29uXCI+XG4gICAgICAgICAgICAgIDxBcGlLZXkgaGVpZ2h0PVwiMjBweFwiIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxJbnB1dFxuICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgIG9uQ2hhbmdlPXtvbkFwaUtleUNoYW5nZX1cbiAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9e2ludGwuZm9ybWF0TWVzc2FnZSh7aWQ6ICdhaUFzc2lzdGFudE1hbmFnZXIuYXBpS2V5LnBsYWNlaG9sZGVyJ30pfVxuICAgICAgICAgICAgICB2YWx1ZT17YXBpS2V5fVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC8+XG4gICAgICApIDogKFxuICAgICAgICA8PlxuICAgICAgICAgIDxQYW5lbExhYmVsV3JhcHBlcj5cbiAgICAgICAgICAgIDxTZWN0aW9uVGl0bGU+XG4gICAgICAgICAgICAgIDxGb3JtYXR0ZWRNZXNzYWdlIGlkPVwiYWlBc3Npc3RhbnRNYW5hZ2VyLmJhc2VVcmwucGxhY2Vob2xkZXJcIiAvPlxuICAgICAgICAgICAgPC9TZWN0aW9uVGl0bGU+XG4gICAgICAgICAgPC9QYW5lbExhYmVsV3JhcHBlcj5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImFwaS1rZXktaW5wdXRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYXBpLWtleS1pbnB1dF9faWNvblwiPlxuICAgICAgICAgICAgICA8QXBpS2V5IGhlaWdodD1cIjIwcHhcIiAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8SW5wdXRcbiAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICBvbkNoYW5nZT17b25CYXNlVXJsQ2hhbmdlfVxuICAgICAgICAgICAgICBwbGFjZWhvbGRlcj17aW50bC5mb3JtYXRNZXNzYWdlKHtpZDogJ2FpQXNzaXN0YW50TWFuYWdlci5iYXNlVXJsLnBsYWNlaG9sZGVyJ30pfVxuICAgICAgICAgICAgICB2YWx1ZT17YmFzZVVybH1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvPlxuICAgICAgKX1cbiAgICAgIHtjb25uZWN0aW9uRXJyb3IgJiYgKFxuICAgICAgICA8U3R5bGVFcnJvck1lc3NhZ2UgY2xhc3NOYW1lPVwiZXJyb3ItbWVzc2FnZVwiPntlcnJvck1lc3NhZ2V9PC9TdHlsZUVycm9yTWVzc2FnZT5cbiAgICAgICl9XG4gICAgICA8UGFuZWxMYWJlbFdyYXBwZXI+XG4gICAgICAgIDxTZWN0aW9uVGl0bGU+XG4gICAgICAgICAgPEZvcm1hdHRlZE1lc3NhZ2UgaWQ9XCJhaUFzc2lzdGFudE1hbmFnZXIudGVtcGVyYXR1cmUudGl0bGVcIiAvPlxuICAgICAgICA8L1NlY3Rpb25UaXRsZT5cbiAgICAgIDwvUGFuZWxMYWJlbFdyYXBwZXI+XG4gICAgICA8U3R5bGVTbGlkZXJXcmFwcGVyPlxuICAgICAgICA8UmFuZ2VTbGlkZXJcbiAgICAgICAgICBzaG93SW5wdXQ9e3RydWV9XG4gICAgICAgICAgaXNSYW5nZWQ9e2ZhbHNlfVxuICAgICAgICAgIHZhbHVlMD17MH1cbiAgICAgICAgICB2YWx1ZTE9e3RlbXBlcmF0dXJlfVxuICAgICAgICAgIG9uQ2hhbmdlPXtvblRlbXBlcmF0dXJlQ2hhbmdlfVxuICAgICAgICAgIHJhbmdlPXtbMCwgMl19XG4gICAgICAgICAgc3RlcD17MC4xfVxuICAgICAgICAvPlxuICAgICAgPC9TdHlsZVNsaWRlcldyYXBwZXI+XG4gICAgICA8UGFuZWxMYWJlbFdyYXBwZXI+XG4gICAgICAgIDxTZWN0aW9uVGl0bGU+XG4gICAgICAgICAgPEZvcm1hdHRlZE1lc3NhZ2UgaWQ9XCJhaUFzc2lzdGFudE1hbmFnZXIudG9wUC50aXRsZVwiIC8+XG4gICAgICAgIDwvU2VjdGlvblRpdGxlPlxuICAgICAgPC9QYW5lbExhYmVsV3JhcHBlcj5cbiAgICAgIDxTdHlsZVNsaWRlcldyYXBwZXI+XG4gICAgICAgIDxSYW5nZVNsaWRlclxuICAgICAgICAgIHNob3dJbnB1dD17dHJ1ZX1cbiAgICAgICAgICBpc1JhbmdlZD17ZmFsc2V9XG4gICAgICAgICAgdmFsdWUwPXswfVxuICAgICAgICAgIHZhbHVlMT17dG9wUH1cbiAgICAgICAgICBvbkNoYW5nZT17b25Ub3BQQ2hhbmdlfVxuICAgICAgICAgIHJhbmdlPXtbMCwgMV19XG4gICAgICAgICAgc3RlcD17MC4xfVxuICAgICAgICAvPlxuICAgICAgPC9TdHlsZVNsaWRlcldyYXBwZXI+XG4gICAgICA8PlxuICAgICAgICA8UGFuZWxMYWJlbFdyYXBwZXI+XG4gICAgICAgICAgPFNlY3Rpb25UaXRsZT5NYXBib3ggVG9rZW4gKG9wdGlvbmFsIGZvciByb3V0ZS9pc29jaHJvbmUpPC9TZWN0aW9uVGl0bGU+XG4gICAgICAgIDwvUGFuZWxMYWJlbFdyYXBwZXI+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYXBpLWtleS1pbnB1dFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYXBpLWtleS1pbnB1dF9faWNvblwiPlxuICAgICAgICAgICAgPEFwaUtleSBoZWlnaHQ9XCIyMHB4XCIgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8SW5wdXRcbiAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgIG9uQ2hhbmdlPXtvbk1hcGJveFRva2VuQ2hhbmdlfVxuICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJFbnRlciB5b3VyIE1hcGJveCBUb2tlblwiXG4gICAgICAgICAgICB2YWx1ZT17bWFwYm94VG9rZW59XG4gICAgICAgICAgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8Lz5cbiAgICAgIDxTdHlsZWRCdXR0b24+XG4gICAgICAgIDxCdXR0b24gb25DbGljaz17b25TdGFydENoYXR9IHdpZHRoPXsnMTAwJSd9PlxuICAgICAgICAgIHtpc1J1bm5pbmcgJiYgPExvYWRpbmdTcGlubmVyIHNpemU9ezEyfSAvPn1cbiAgICAgICAgICA8Rm9ybWF0dGVkTWVzc2FnZSBpZD1cImFpQXNzaXN0YW50TWFuYWdlci5zdGFydENoYXRcIiAvPlxuICAgICAgICA8L0J1dHRvbj5cbiAgICAgIDwvU3R5bGVkQnV0dG9uPlxuICAgIDwvU3R5bGVkQWlBc3Npc3RhbnRDb25maWc+XG4gICk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUdBLElBQUFBLE1BQUEsR0FBQUMsdUJBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLGlCQUFBLEdBQUFDLHNCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBRyxXQUFBLEdBQUFILE9BQUE7QUFDQSxJQUFBSSxXQUFBLEdBQUFKLE9BQUE7QUFXQSxJQUFBSyxPQUFBLEdBQUFILHNCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBTSxPQUFBLEdBQUFKLHNCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBTyxXQUFBLEdBQUFQLE9BQUE7QUFDQSxJQUFBUSxLQUFBLEdBQUFSLE9BQUE7QUFDQSxJQUFBUyxRQUFBLEdBQUFULE9BQUE7QUFDQSxJQUFBVSxVQUFBLEdBQUFWLE9BQUE7QUFBcUQsSUFBQVcsZUFBQSxFQUFBQyxnQkFBQSxFQUFBQyxnQkFBQSxFQUFBQyxnQkFBQSxFQUFBQyxnQkFBQSxFQUFBQyxnQkFBQSxFQUFBQyxnQkFBQSxFQUFBQyxnQkFBQSxFQXRCckQ7QUFDQTtBQUFBLFNBQUFDLHlCQUFBQyxDQUFBLDZCQUFBQyxPQUFBLG1CQUFBQyxDQUFBLE9BQUFELE9BQUEsSUFBQUUsQ0FBQSxPQUFBRixPQUFBLFlBQUFGLHdCQUFBLFlBQUFBLHlCQUFBQyxDQUFBLFdBQUFBLENBQUEsR0FBQUcsQ0FBQSxHQUFBRCxDQUFBLEtBQUFGLENBQUE7QUFBQSxTQUFBckIsd0JBQUFxQixDQUFBLEVBQUFFLENBQUEsU0FBQUEsQ0FBQSxJQUFBRixDQUFBLElBQUFBLENBQUEsQ0FBQUksVUFBQSxTQUFBSixDQUFBLGVBQUFBLENBQUEsZ0JBQUFLLE9BQUEsQ0FBQUwsQ0FBQSwwQkFBQUEsQ0FBQSxzQkFBQUEsQ0FBQSxRQUFBRyxDQUFBLEdBQUFKLHdCQUFBLENBQUFHLENBQUEsT0FBQUMsQ0FBQSxJQUFBQSxDQUFBLENBQUFHLEdBQUEsQ0FBQU4sQ0FBQSxVQUFBRyxDQUFBLENBQUFJLEdBQUEsQ0FBQVAsQ0FBQSxPQUFBUSxDQUFBLEtBQUFDLFNBQUEsVUFBQUMsQ0FBQSxHQUFBQyxNQUFBLENBQUFDLGNBQUEsSUFBQUQsTUFBQSxDQUFBRSx3QkFBQSxXQUFBQyxDQUFBLElBQUFkLENBQUEsb0JBQUFjLENBQUEsT0FBQUMsY0FBQSxDQUFBQyxJQUFBLENBQUFoQixDQUFBLEVBQUFjLENBQUEsU0FBQUcsQ0FBQSxHQUFBUCxDQUFBLEdBQUFDLE1BQUEsQ0FBQUUsd0JBQUEsQ0FBQWIsQ0FBQSxFQUFBYyxDQUFBLFVBQUFHLENBQUEsS0FBQUEsQ0FBQSxDQUFBVixHQUFBLElBQUFVLENBQUEsQ0FBQUMsR0FBQSxJQUFBUCxNQUFBLENBQUFDLGNBQUEsQ0FBQUosQ0FBQSxFQUFBTSxDQUFBLEVBQUFHLENBQUEsSUFBQVQsQ0FBQSxDQUFBTSxDQUFBLElBQUFkLENBQUEsQ0FBQWMsQ0FBQSxZQUFBTixDQUFBLGNBQUFSLENBQUEsRUFBQUcsQ0FBQSxJQUFBQSxDQUFBLENBQUFlLEdBQUEsQ0FBQWxCLENBQUEsRUFBQVEsQ0FBQSxHQUFBQSxDQUFBO0FBdUJBLElBQU1XLFlBQVksR0FBR0MsNEJBQU0sQ0FBQ0MsR0FBRyxDQUFBOUIsZUFBQSxLQUFBQSxlQUFBLE9BQUErQix1QkFBQSwwRkFDaEIsVUFBQUMsS0FBSztFQUFBLE9BQUlBLEtBQUssQ0FBQ0MsS0FBSyxDQUFDQyxhQUFhO0FBQUEsR0FDdEMsVUFBQUYsS0FBSztFQUFBLE9BQUlBLEtBQUssQ0FBQ0MsS0FBSyxDQUFDRSx5QkFBeUI7QUFBQSxFQUV4RDtBQUVELElBQU1DLHVCQUF1QixHQUFHUCw0QkFBTSxDQUFDQyxHQUFHLENBQUE3QixnQkFBQSxLQUFBQSxnQkFBQSxPQUFBOEIsdUJBQUEsd2lCQUUzQixVQUFBQyxLQUFLO0VBQUEsT0FBSUEsS0FBSyxDQUFDQyxLQUFLLENBQUNJLHlCQUF5QjtBQUFBLEdBUTNDLFVBQUFMLEtBQUs7RUFBQSxPQUFJQSxLQUFLLENBQUNDLEtBQUssQ0FBQ0ssU0FBUztBQUFBLEdBSWhDLFVBQUFOLEtBQUs7RUFBQSxPQUFJQSxLQUFLLENBQUNDLEtBQUssQ0FBQ00sbUJBQW1CO0FBQUEsR0FNekMsVUFBQVAsS0FBSztFQUFBLE9BQUlBLEtBQUssQ0FBQ0MsS0FBSyxDQUFDTyxZQUFZO0FBQUEsR0FLaEMsVUFBQVIsS0FBSztFQUFBLE9BQUlBLEtBQUssQ0FBQ0MsS0FBSyxDQUFDTSxtQkFBbUI7QUFBQSxFQUl2RDs7QUFFRDtBQUNBO0FBQ0EsSUFBTUUsdUJBQXVCLEdBQUdaLDRCQUFNLENBQUNDLEdBQUcsQ0FBQTVCLGdCQUFBLEtBQUFBLGdCQUFBLE9BQUE2Qix1QkFBQSxxR0FLekM7QUFFRCxJQUFNVyxhQUFhLEdBQUdiLDRCQUFNLENBQUNDLEdBQUcsQ0FBQTNCLGdCQUFBLEtBQUFBLGdCQUFBLE9BQUE0Qix1QkFBQSxtR0FJL0I7QUFFRCxJQUFNWSxrQkFBa0IsR0FBRyxJQUFBZCw0QkFBTSxFQUFDZSx3QkFBWSxDQUFDLENBQUF4QyxnQkFBQSxLQUFBQSxnQkFBQSxPQUFBMkIsdUJBQUEsdU5BTTNCLFVBQUFDLEtBQUs7RUFBQSxPQUFJQSxLQUFLLENBQUNDLEtBQUssQ0FBQ1ksV0FBVztBQUFBLEVBSW5EO0FBRUQsSUFBTUMsa0JBQWtCLEdBQUdqQiw0QkFBTSxDQUFDQyxHQUFHLENBQUF6QixnQkFBQSxLQUFBQSxnQkFBQSxPQUFBMEIsdUJBQUEsdVVBaUJwQztBQUVELElBQU1nQixZQUFZLEdBQUdsQiw0QkFBTSxDQUFDQyxHQUFHLENBQUF4QixnQkFBQSxLQUFBQSxnQkFBQSxPQUFBeUIsdUJBQUEsa01BVzlCO0FBRUQsSUFBTWlCLGlCQUFpQixHQUFHbkIsNEJBQU0sQ0FBQ0MsR0FBRyxDQUFBdkIsZ0JBQUEsS0FBQUEsZ0JBQUEsT0FBQXdCLHVCQUFBLGtJQUNyQixVQUFBQyxLQUFLO0VBQUEsT0FBSUEsS0FBSyxDQUFDQyxLQUFLLENBQUNJLHlCQUF5QjtBQUFBLEdBQ3ZDLFVBQUFMLEtBQUs7RUFBQSxPQUFJQSxLQUFLLENBQUNDLEtBQUssQ0FBQ2dCLFVBQVU7QUFBQSxHQUcxQyxVQUFBakIsS0FBSztFQUFBLE9BQUlBLEtBQUssQ0FBQ0MsS0FBSyxDQUFDaUIsY0FBYztBQUFBLEVBQzdDO0FBRUQsSUFBTUMsV0FBVyxHQUFHQyx1QkFBVyxDQUFDcEMsR0FBRyxDQUFDcUMsOEJBQWtCLENBQUM7QUFFaEQsU0FBU0MsaUJBQWlCQSxDQUFBLEVBQUc7RUFDbEMsSUFBTUMsUUFBUSxHQUFHLElBQUFDLHVCQUFXLEVBQUMsQ0FBQztFQUM5QixJQUFNQyxpQkFBaUIsR0FBRyxJQUFBQyx1QkFBVyxFQUFDLFVBQUNDLEtBQVk7SUFBQSxPQUFLQSxLQUFLLENBQUNDLElBQUksQ0FBQ0MsV0FBVyxDQUFDQyxNQUFNO0VBQUEsRUFBQztFQUN0RixJQUFNQyxJQUFJLEdBQUcsSUFBQUMsa0JBQU8sRUFBQyxDQUFDO0VBRXRCLElBQUFDLGdCQUFBLEdBQWdDLElBQUFDLDJCQUFlLEVBQzdDLHVCQUF1QixFQUN2QlQsaUJBQWlCLENBQUNVLFFBQVEsSUFBSSxRQUNoQyxDQUFDO0lBQUFDLGlCQUFBLE9BQUFDLGVBQUEsYUFBQUosZ0JBQUE7SUFITUUsUUFBUSxHQUFBQyxpQkFBQTtJQUFFRSxXQUFXLEdBQUFGLGlCQUFBO0VBSTVCLElBQUFHLGlCQUFBLEdBQTBCLElBQUFMLDJCQUFlLEVBQ3ZDLG9CQUFvQixFQUNwQlQsaUJBQWlCLENBQUNlLEtBQUssSUFBSUMsa0JBQWUsQ0FBQ04sUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUN4RCxDQUFDO0lBQUFPLGlCQUFBLE9BQUFMLGVBQUEsYUFBQUUsaUJBQUE7SUFITUMsS0FBSyxHQUFBRSxpQkFBQTtJQUFFQyxRQUFRLEdBQUFELGlCQUFBO0VBSXRCLElBQUFFLGlCQUFBLEdBQTRCLElBQUFWLDJCQUFlLEVBQ3pDLHNCQUFzQixFQUN0QlQsaUJBQWlCLENBQUNvQixNQUFNLElBQUksRUFDOUIsQ0FBQztJQUFBQyxpQkFBQSxPQUFBVCxlQUFBLGFBQUFPLGlCQUFBO0lBSE1DLE1BQU0sR0FBQUMsaUJBQUE7SUFBRUMsU0FBUyxHQUFBRCxpQkFBQTtFQUl4QixJQUFBRSxpQkFBQSxHQUFzQyxJQUFBZCwyQkFBZSxFQUNuRCwwQkFBMEIsRUFDMUJULGlCQUFpQixDQUFDd0IsV0FBVyxJQUFJLEdBQ25DLENBQUM7SUFBQUMsaUJBQUEsT0FBQWIsZUFBQSxhQUFBVyxpQkFBQTtJQUhNQyxXQUFXLEdBQUFDLGlCQUFBO0lBQUVDLGNBQWMsR0FBQUQsaUJBQUE7RUFJbEMsSUFBQUUsaUJBQUEsR0FBd0IsSUFBQWxCLDJCQUFlLEVBQUMsb0JBQW9CLEVBQUVULGlCQUFpQixDQUFDNEIsSUFBSSxJQUFJLEdBQUcsQ0FBQztJQUFBQyxrQkFBQSxPQUFBakIsZUFBQSxhQUFBZSxpQkFBQTtJQUFyRkMsSUFBSSxHQUFBQyxrQkFBQTtJQUFFQyxPQUFPLEdBQUFELGtCQUFBO0VBQ3BCLElBQUFFLGtCQUFBLEdBQThCLElBQUF0QiwyQkFBZSxFQUMzQyx1QkFBdUIsRUFDdkJULGlCQUFpQixDQUFDZ0MsT0FBTyxJQUFJLDRCQUMvQixDQUFDO0lBQUFDLGtCQUFBLE9BQUFyQixlQUFBLGFBQUFtQixrQkFBQTtJQUhNQyxPQUFPLEdBQUFDLGtCQUFBO0lBQUVDLFVBQVUsR0FBQUQsa0JBQUE7RUFJMUIsSUFBQUUsa0JBQUEsR0FBc0MsSUFBQTFCLDJCQUFlLEVBQ25ELDJCQUEyQixFQUMzQlQsaUJBQWlCLENBQUNvQyxXQUFXLElBQUksRUFDbkMsQ0FBQztJQUFBQyxrQkFBQSxPQUFBekIsZUFBQSxhQUFBdUIsa0JBQUE7SUFITUMsV0FBVyxHQUFBQyxrQkFBQTtJQUFFQyxjQUFjLEdBQUFELGtCQUFBO0VBSWxDLElBQUFFLFNBQUEsR0FBOEQsSUFBQUMsZUFBUSxFQUFDLEtBQUssQ0FBQztJQUFBQyxVQUFBLE9BQUE3QixlQUFBLGFBQUEyQixTQUFBO0lBQXRFRyx1QkFBdUIsR0FBQUQsVUFBQTtJQUFFRSwwQkFBMEIsR0FBQUYsVUFBQTtFQUMxRCxJQUFBRyxVQUFBLEdBQTBELElBQUFKLGVBQVEsRUFBQyxFQUFFLENBQUM7SUFBQUssVUFBQSxPQUFBakMsZUFBQSxhQUFBZ0MsVUFBQTtJQUEvREUscUJBQXFCLEdBQUFELFVBQUE7SUFBRUUsd0JBQXdCLEdBQUFGLFVBQUE7RUFDdEQsSUFBQUcsVUFBQSxHQUE4QyxJQUFBUixlQUFRLEVBQUMsS0FBSyxDQUFDO0lBQUFTLFVBQUEsT0FBQXJDLGVBQUEsYUFBQW9DLFVBQUE7SUFBdERFLGVBQWUsR0FBQUQsVUFBQTtJQUFFRSxrQkFBa0IsR0FBQUYsVUFBQTtFQUMxQyxJQUFBRyxVQUFBLEdBQXdDLElBQUFaLGVBQVEsRUFBQyxFQUFFLENBQUM7SUFBQWEsVUFBQSxPQUFBekMsZUFBQSxhQUFBd0MsVUFBQTtJQUE3Q0UsWUFBWSxHQUFBRCxVQUFBO0lBQUVFLGVBQWUsR0FBQUYsVUFBQTtFQUNwQyxJQUFBRyxVQUFBLEdBQWtDLElBQUFoQixlQUFRLEVBQUMsS0FBSyxDQUFDO0lBQUFpQixXQUFBLE9BQUE3QyxlQUFBLGFBQUE0QyxVQUFBO0lBQTFDRSxTQUFTLEdBQUFELFdBQUE7SUFBRUUsWUFBWSxHQUFBRixXQUFBO0VBRTlCLElBQU1HLGtCQUFrQixHQUFHLFNBQXJCQSxrQkFBa0JBLENBQUlDLEtBQWdELEVBQUs7SUFDL0UsSUFBSSxPQUFPQSxLQUFLLEtBQUssUUFBUSxFQUFFO01BQzdCaEQsV0FBVyxDQUFDZ0QsS0FBSyxDQUFDO01BQ2xCM0MsUUFBUSxDQUFDRixrQkFBZSxDQUFDNkMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7TUFDbkNWLGtCQUFrQixDQUFDLEtBQUssQ0FBQztNQUN6QkksZUFBZSxDQUFDLEVBQUUsQ0FBQztJQUNyQjtFQUNGLENBQUM7RUFFRCxJQUFNTyxnQkFBZ0IsR0FBRyxTQUFuQkEsZ0JBQWdCQSxDQUFJRCxLQUFnRCxFQUFLO0lBQzdFLElBQUksT0FBT0EsS0FBSyxLQUFLLFFBQVEsRUFBRTtNQUM3QjNDLFFBQVEsQ0FBQzJDLEtBQUssQ0FBQztJQUNqQjtFQUNGLENBQUM7RUFFRCxJQUFNRSxjQUFjLEdBQUcsU0FBakJBLGNBQWNBLENBQUkvRyxDQUFzQyxFQUFLO0lBQ2pFc0UsU0FBUyxDQUFDdEUsQ0FBQyxDQUFDZ0gsTUFBTSxDQUFDSCxLQUFLLENBQUM7SUFDekI7SUFDQVYsa0JBQWtCLENBQUMsS0FBSyxDQUFDO0lBQ3pCSSxlQUFlLENBQUMsRUFBRSxDQUFDO0VBQ3JCLENBQUM7RUFFRCxJQUFNVSxtQkFBbUIsR0FBRyxTQUF0QkEsbUJBQW1CQSxDQUFJSixLQUFlLEVBQUs7SUFDL0NuQyxjQUFjLENBQUNtQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7RUFDMUIsQ0FBQztFQUVELElBQU1LLFlBQVksR0FBRyxTQUFmQSxZQUFZQSxDQUFJTCxLQUFlLEVBQUs7SUFDeEMvQixPQUFPLENBQUMrQixLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7RUFDbkIsQ0FBQztFQUVELElBQU1NLGVBQWUsR0FBRyxTQUFsQkEsZUFBZUEsQ0FBSW5ILENBQXNDLEVBQUs7SUFDbEVrRixVQUFVLENBQUNsRixDQUFDLENBQUNnSCxNQUFNLENBQUNILEtBQUssQ0FBQztJQUMxQlYsa0JBQWtCLENBQUMsS0FBSyxDQUFDO0lBQ3pCSSxlQUFlLENBQUMsRUFBRSxDQUFDO0VBQ3JCLENBQUM7RUFFRCxJQUFNYSxtQkFBbUIsR0FBRyxTQUF0QkEsbUJBQW1CQSxDQUFJcEgsQ0FBc0MsRUFBSztJQUN0RXNGLGNBQWMsQ0FBQ3RGLENBQUMsQ0FBQ2dILE1BQU0sQ0FBQ0gsS0FBSyxDQUFDO0VBQ2hDLENBQUM7RUFFRCxJQUFNUSx5QkFBeUIsR0FBRyxTQUE1QkEseUJBQXlCQSxDQUFJckgsQ0FBc0MsRUFBSztJQUM1RTJGLDBCQUEwQixDQUFDM0YsQ0FBQyxDQUFDZ0gsTUFBTSxDQUFDTSxPQUFPLENBQUM7SUFDNUMsSUFBSSxDQUFDdEgsQ0FBQyxDQUFDZ0gsTUFBTSxDQUFDTSxPQUFPLEVBQUU7TUFDckI7TUFDQXBELFFBQVEsQ0FBQyxFQUFFLENBQUM7SUFDZDtFQUNGLENBQUM7RUFFRCxJQUFNcUQsNkJBQTZCLEdBQUcsU0FBaENBLDZCQUE2QkEsQ0FBSXZILENBQXNDLEVBQUs7SUFDaEYrRix3QkFBd0IsQ0FBQy9GLENBQUMsQ0FBQ2dILE1BQU0sQ0FBQ0gsS0FBSyxDQUFDO0lBQ3hDM0MsUUFBUSxDQUFDbEUsQ0FBQyxDQUFDZ0gsTUFBTSxDQUFDSCxLQUFLLENBQUM7RUFDMUIsQ0FBQztFQUVELElBQU1XLFdBQVc7SUFBQSxJQUFBQyxJQUFBLE9BQUFDLGtCQUFBLDJCQUFBQyxZQUFBLFlBQUFDLElBQUEsQ0FBRyxTQUFBQyxRQUFBO01BQUEsSUFBQUMsY0FBQSxFQUFBQyxjQUFBLEVBQUFDLE9BQUEsRUFBQUMsYUFBQTtNQUFBLE9BQUFOLFlBQUEsWUFBQU8sSUFBQSxVQUFBQyxTQUFBQyxRQUFBO1FBQUEsa0JBQUFBLFFBQUEsQ0FBQUMsSUFBQSxHQUFBRCxRQUFBLENBQUFFLElBQUE7VUFBQTtZQUNsQjNCLFlBQVksQ0FBQyxJQUFJLENBQUM7WUFBQ3lCLFFBQUEsQ0FBQUMsSUFBQTtZQUVYUCxjQUFjLEdBQUcsSUFBSVMsT0FBTyxDQUFDLFVBQUNDLENBQUMsRUFBRUMsTUFBTSxFQUFLO2NBQ2hEQyxVQUFVLENBQUM7Z0JBQUEsT0FBTUQsTUFBTSxDQUFDLElBQUlFLEtBQUssQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO2NBQUEsR0FBRSxLQUFLLENBQUM7WUFDbkYsQ0FBQyxDQUFDO1lBRUlaLGNBQWMsR0FBRyxJQUFBYSxpQ0FBMkIsRUFBQztjQUNqRGxGLFFBQVEsRUFBRUE7WUFDWixDQUFDLENBQUM7WUFBQTBFLFFBQUEsQ0FBQUUsSUFBQTtZQUFBLE9BRXFCQyxPQUFPLENBQUNNLElBQUksQ0FBQyxDQUNsQ2QsY0FBYyxhQUFkQSxjQUFjLHVCQUFkQSxjQUFjLENBQUVlLGNBQWMsQ0FBQzFFLE1BQU0sRUFBRUwsS0FB