(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.PydioComponents = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o child into a function."))}function a(){!d&&p&&(d=!0,console.error("With React 0.13, you need to wrap child into a function."))}function l(e){return e<0?0:e}function s(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(e){return e},n={};for(var o in e)e.hasOwnProperty(o)&&(n[o]=t(e[o]));return n}function u(e){var t=e.version;if("string"!=typeof t)return!0;var n=t.split("."),o=parseInt(n[0],10),r=parseInt(n[1],10);return 0===o&&13===r}Object.defineProperty(t,"__esModule",{value:!0}),t.findDOMNode=r,t.warnAboutFunctionChild=i,t.warnAboutElementChild=a,t.positiveOrZero=l,t.modifyObjValues=s,t.isReact13=u;var c=n(1),f=o(c),p=u(f.default),d=!1},function(e,t){"use strict";t.__esModule=!0,t.default={noWobble:{stiffness:170,damping:26},gentle:{stiffness:120,damping:14},wobbly:{stiffness:180,damping:12},stiff:{stiffness:210,damping:20}},e.exports=t.default},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e.default:e}t.__esModule=!0;var r=n(18);t.Motion=o(r);var i=n(19);t.StaggeredMotion=o(i);var a=n(20);t.TransitionMotion=o(a);var l=n(23);t.spring=o(l);var s=n(9);t.presets=o(s);var u=n(22);t.reorderKeys=o(u)},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},s=Object.assign||function(e){for(var t=1;tt.realHeight-t.containerHeight&&(e=t.realHeight-t.containerHeight),e<0&&(e=0),e}},{key:"normalizeLeftPosition",value:function(e,t){return e>t.realWidth-t.containerWidth?e=t.realWidth-t.containerWidth:e<0&&(e=0),e}},{key:"computeSizes",value:function(){var e=this.content.offsetHeight,t=this.wrapper.offsetHeight,n=this.content.offsetWidth,o=this.wrapper.offsetWidth;return{realHeight:e,containerHeight:t,realWidth:n,containerWidth:o}}},{key:"setSizesToState",value:function(){var e=this.computeSizes();e.realHeight===this.state.realHeight&&e.realWidth===this.state.realWidth||this.setStateFromEvent(this.getModifiedPositionsIfNeeded(e))}},{key:"scrollTop",value:function(){this.scrollYTo(0)}},{key:"scrollBottom",value:function(){this.scrollYTo(this.state.realHeight-this.state.containerHeight)}},{key:"scrollLeft",value:function(){this.scrollXTo(0)}},{key:"scrollRight",value:function(){this.scrollXTo(this.state.realWidth-this.state.containerWidth)}},{key:"scrollYTo",value:function(e){if(this.canScrollY()){var t=this.normalizeTopPosition(e,this.computeSizes());this.setStateFromEvent({topPosition:t},S.api)}}},{key:"scrollXTo",value:function(e){if(this.canScrollX()){var t=this.normalizeLeftPosition(e,this.computeSizes());this.setStateFromEvent({leftPosition:t},S.api)}}},{key:"canScrollY",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.state,t=e.realHeight>e.containerHeight;return t&&this.props.vertical}},{key:"canScrollX",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.state,t=e.realWidth>e.containerWidth;return t&&this.props.horizontal}},{key:"getModifiedPositionsIfNeeded",value:function(e){var t=e.realHeight-e.containerHeight;this.state.topPosition>=t&&(e.topPosition=this.canScrollY(e)?(0,h.positiveOrZero)(t):0);var n=e.realWidth-e.containerWidth;return this.state.leftPosition>=n&&(e.leftPosition=this.canScrollX(e)?(0,h.positiveOrZero)(n):0),e}},{key:"focusContent",value:function(){this.content&&(0,h.findDOMNode)(this.content).focus()}}]),t}(f.default.Component);t.default=g,g.childContextTypes={scrollArea:f.default.PropTypes.object},g.propTypes={className:f.default.PropTypes.string,style:f.default.PropTypes.object,speed:f.default.PropTypes.number,contentClassName:f.default.PropTypes.string,contentStyle:f.default.PropTypes.object,vertical:f.default.PropTypes.bool,verticalContainerStyle:f.default.PropTypes.object,verticalScrollbarStyle:f.default.PropTypes.object,horizontal:f.default.PropTypes.bool,horizontalContainerStyle:f.default.PropTypes.object,horizontalScrollbarStyle:f.default.PropTypes.object,onScroll:f.default.PropTypes.func,contentWindow:f.default.PropTypes.any,ownerDocument:f.default.PropTypes.any,smoothScrolling:f.default.PropTypes.bool,minScrollSize:f.default.PropTypes.number,swapWheelAxes:f.default.PropTypes.bool,stopScrollPropagation:f.default.PropTypes.bool,focusableTabIndex:f.default.PropTypes.number},g.defaultProps={speed:1,vertical:!0,horizontal:!0,smoothScrolling:!1,swapWheelAxes:!1,contentWindow:"object"===("undefined"==typeof window?"undefined":l(window))?window:void 0,ownerDocument:"object"===("undefined"==typeof document?"undefined":l(document))?document:void 0,focusableTabIndex:1}},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var l=Object.assign||function(e){for(var t=1;t1)for(var n=1;n10*g&&(e.accumulatedTime=0),0===e.accumulatedTime)return e.animationID=null,void e.startAnimationIfNecessary();var i=(e.accumulatedTime-Math.floor(e.accumulatedTime/g)*g)/g,a=Math.floor(e.accumulatedTime/g),l={},s={},u={},f={};for(var d in n)if(Object.prototype.hasOwnProperty.call(n,d)){var h=n[d];if("number"==typeof h)u[d]=h,f[d]=0,l[d]=h,s[d]=0;else{for(var y=e.state.lastIdealStyle[d],m=e.state.lastIdealVelocity[d],S=0;S10*b&&(e.accumulatedTime=0),0===e.accumulatedTime)return e.animationID=null,void e.startAnimationIfNecessary();for(var a=(e.accumulatedTime-Math.floor(e.accumulatedTime/b)*b)/b,l=Math.floor(e.accumulatedTime/b),s=[],u=[],c=[],p=[],h=0;h10*k&&(e.accumulatedTime=0),0===e.accumulatedTime)return e.animationID=null,void e.startAnimationIfNecessary();for(var u=(e.accumulatedTime-Math.floor(e.accumulatedTime/k)*k)/k,c=Math.floor(e.accumulatedTime/k),f=a(e.props.willEnter,e.props.willLeave,e.state.mergedPropsStyles,o,e.state.currentStyles,e.state.currentVelocities,e.state.lastIdealStyles,e.state.lastIdealVelocities),p=f[0],h=f[1],y=f[2],v=f[3],S=f[4],g=0;go[c])return-1;if(r>i[c]&&so[c])return 1;if(a>i[c]&&l=0&&g.splice(t,1)}function l(e){var t=document.createElement("style");return t.type="text/css",i(e,t),t}function s(e){var t=document.createElement("link");return t.rel="stylesheet",i(e,t),t}function u(e,t){var n,o,r;if(t.singleton){var i=S++;n=m||(m=l(t)),o=c.bind(null,n,i,!1),r=c.bind(null,n,i,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=s(t),o=p.bind(null,n),r=function(){a(n),n.href&&URL.revokeObjectURL(n.href)}):(n=l(t),o=f.bind(null,n),r=function(){a(n)});return o(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;o(e=t)}else r()}}function c(e,t,n,o){var r=n?"":o.css;if(e.styleSheet)e.styleSheet.cssText=b(t,r);else{var i=document.createTextNode(r),a=e.childNodes;a[t]&&e.removeChild(a[t]),a.length?e.insertBefore(i,a[t]):e.appendChild(i)}}function f(e,t){var n=t.css,o=t.media;if(o&&e.setAttribute("media",o),e.styleSheet)e.styleSheet.cssText=n;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(n))}}function p(e,t){var n=t.css,o=t.sourceMap;o&&(n+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(o))))+" */");var r=new Blob([n],{type:"text/css"}),i=e.href;e.href=URL.createObjectURL(r),i&&URL.revokeObjectURL(i)}var d={},h=function(e){var t;return function(){return"undefined"==typeof t&&(t=e.apply(this,arguments)),t}},y=h(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),v=h(function(){return document.head||document.getElementsByTagName("head")[0]}),m=null,S=0,g=[];e.exports=function(e,t){t=t||{},"undefined"==typeof t.singleton&&(t.singleton=y()),"undefined"==typeof t.insertAt&&(t.insertAt="bottom");var n=r(e);return o(n,t),function(e){for(var i=[],a=0;a * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _Store = require('./Store'); var _Store2 = _interopRequireDefault(_Store); var _GridBuilder = require('./GridBuilder'); var _GridBuilder2 = _interopRequireDefault(_GridBuilder); /** * Automatic layout for presenting draggable cards to users. Used for user and admin dashboard. */ var React = require('react'); var Pydio = require('pydio'); var _require = require('react-grid-layout'); var Responsive = _require.Responsive; var WidthProvider = _require.WidthProvider; var _Pydio$requireLib = Pydio.requireLib('boot'); var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer; var CardsGrid = React.createClass({ displayName: 'CardsGrid', /** * Save layouts in the users preference. * * @param {object} allLayouts Responsive layouts passed for saving */ saveFullLayouts: function saveFullLayouts(allLayouts) { var savedPref = this.props.store.getUserPreference('Layout'); // Compare JSON versions to avoid saving unnecessary changes if (savedPref && this.previousLayout && this.previousLayout == JSON.stringify(allLayouts)) { return; } this.previousLayout = JSON.stringify(allLayouts); this.props.store.saveUserPreference('Layout', allLayouts); }, onLayoutChange: function onLayoutChange(currentLayout, allLayouts) { if (this._blockLayoutSave) return; this.saveFullLayouts(allLayouts); }, componentWillUnmount: function componentWillUnmount() { this.props.store.stopObserving("cards", this._storeObserver); }, componentWillReceiveProps: function componentWillReceiveProps(nextProps) { if (this.props && nextProps.editMode !== this.props.editMode) { Object.keys(this.refs).forEach((function (k) { this.refs[k].toggleEditMode(nextProps.editMode); }).bind(this)); } }, shouldComponentUpdate: function shouldComponentUpdate(nextProps, nextState) { return this._forceUpdate || false; }, getInitialState: function getInitialState() { this._storeObserver = (function (e) { var _this = this; this._forceUpdate = true; this.setState({ cards: this.props.store.getCards() }, function () { _this._forceUpdate = false; }); }).bind(this); this.props.store.observe("cards", this._storeObserver); return { cards: this.props.store.getCards() }; }, removeCard: function removeCard(itemKey) { this.props.removeCard(itemKey); }, buildCards: function buildCards(cards) { var index = 0; var layouts = { lg: [], md: [], sm: [], xs: [], xxs: [] }; var items = []; var additionalNamespaces = []; var rand = Math.random(); var savedLayouts = this.props.store.getUserPreference('Layout'); var buildLayout = function buildLayout(classObject, itemKey, item, x, y) { var layout = classObject.getGridLayout(x, y); layout['handle'] = 'h4'; if (item['gridHandle']) { layout['handle'] = item['gridHandle']; } layout['i'] = itemKey; return layout; }; cards.map((function (item) { var parts = item.componentClass.split("."); var classNS = parts[0]; var className = parts[1]; var classObject; if (global[classNS] && global[classNS][className]) { classObject = global[classNS][className]; } else { if (!global[classNS]) { additionalNamespaces.push(classNS); } return; } var props = _extends({}, item.props); var itemKey = props['key'] = item['id'] || 'item_' + index; props.ref = itemKey; props.pydio = this.props.pydio; props.onCloseAction = (function () { this.removeCard(itemKey); }).bind(this); props.preferencesProvider = this.props.store; var defaultX = 0, defaultY = 0; if (item.defaultPosition) { defaultX = item.defaultPosition.x; defaultY = item.defaultPosition.y; } var defaultLayout = buildLayout(classObject, itemKey, item, defaultX, defaultY); for (var breakpoint in layouts) { if (!layouts.hasOwnProperty(breakpoint)) continue; var breakLayout = layouts[breakpoint]; // Find corresponding element in preference var existing; if (savedLayouts && savedLayouts[breakpoint]) { savedLayouts[breakpoint].map(function (gridData) { if (gridData['i'] == itemKey && gridData['h'] == defaultLayout['h']) { existing = gridData; } }); } if (existing) { breakLayout.push(existing); } else if (item.defaultLayouts && item.defaultLayouts[breakpoint]) { var crtLayout = buildLayout(classObject, itemKey, item, item.defaultLayouts[breakpoint].x, item.defaultLayouts[breakpoint].y); breakLayout.push(crtLayout); } else { breakLayout.push(defaultLayout); } } index++; items.push(React.createElement(classObject, props)); }).bind(this)); if (additionalNamespaces.length) { this._blockLayoutSave = true; ResourcesManager.loadClassesAndApply(additionalNamespaces, (function () { this.setState({ additionalNamespacesLoaded: additionalNamespaces }, (function () { this._blockLayoutSave = false; }).bind(this)); }).bind(this)); } return { cards: items, layouts: layouts }; }, render: function render() { var _buildCards = this.buildCards(this.state.cards); var cards = _buildCards.cards; var layouts = _buildCards.layouts; var ResponsiveGridLayout = WidthProvider(Responsive); return React.createElement( ResponsiveGridLayout, { className: 'dashboard-layout', cols: this.props.cols || { lg: 10, md: 8, sm: 8, xs: 4, xxs: 2 }, layouts: layouts, rowHeight: 5, onLayoutChange: this.onLayoutChange, isDraggable: !this.props.disableDrag, style: this.props.style, autoSize: false }, cards ); } }); var DynamicGrid = React.createClass({ displayName: 'DynamicGrid', propTypes: { storeNamespace: React.PropTypes.string.isRequired, builderNamespaces: React.PropTypes.array, defaultCards: React.PropTypes.array, pydio: React.PropTypes.instanceOf(Pydio), disableDrag: React.PropTypes.bool }, removeCard: function removeCard(cardId) { this.state.store.removeCard(cardId); }, addCard: function addCard(cardDefinition) { this.state.store.addCard(cardDefinition); }, resetCardsAndLayout: function resetCardsAndLayout() { this.state.store.saveUserPreference('Layout', null); this.state.store.setCards(this.props.defaultCards); }, getInitialState: function getInitialState() { var store = new _Store2['default'](this.props.storeNamespace, this.props.defaultCards, this.props.pydio); return { editMode: false, store: store }; }, toggleEditMode: function toggleEditMode() { this.setState({ editMode: !this.state.editMode }); }, render: function render() { var _this2 = this; var monitorWidgetEditing = (function (status) { this.setState({ widgetEditing: status }); }).bind(this); var builder = undefined; if (this.props.builderNamespaces && this.state.editMode) { builder = React.createElement(_GridBuilder2['default'], { className: 'admin-helper-panel', namespaces: this.props.builderNamespaces, onCreateCard: this.addCard, onResetLayout: this.resetCardsAndLayout, onEditStatusChange: monitorWidgetEditing, getMessage: function (id) { var ns = arguments.length <= 1 || arguments[1] === undefined ? 'ajxp_admin' : arguments[1]; return _this2.props.getMessage(id, ns); } }); } var propStyle = this.props.style || {}; var rglStyle = this.props.rglStyle || {}; return React.createElement( 'div', { style: _extends({}, this.props.style, { width: '100%', flex: '1' }), className: this.state.editMode ? "builder-open" : "" }, React.createElement( 'div', { style: { position: 'absolute', bottom: 30, right: 18, zIndex: 11 } }, React.createElement(MaterialUI.FloatingActionButton, { tooltip: this.props.getMessage('home.49'), onClick: this.toggleEditMode, iconClassName: this.state.editMode ? "icon-ok" : "mdi mdi-pencil", mini: this.state.editMode, disabled: this.state.editMode && this.state.widgetEditing }) ), builder, React.createElement( 'div', { className: 'home-dashboard', style: { height: '100%' } }, React.createElement(CardsGrid, { disableDrag: this.props.disableDrag, cols: this.props.cols, store: this.state.store, style: rglStyle, pydio: this.props.pydio, editMode: this.state.editMode, removeCard: this.removeCard }) ) ); } }); exports['default'] = DynamicGrid = PydioContextConsumer(DynamicGrid); exports['default'] = DynamicGrid; module.exports = exports['default']; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./GridBuilder":3,"./Store":5,"pydio":"pydio","react":"react","react-grid-layout":"react-grid-layout"}],3:[function(require,module,exports){ (function (global){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var React = require('react'); var Pydio = require('pydio'); var _Pydio$requireLib = Pydio.requireLib('boot'); var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer; var AsyncComponent = _Pydio$requireLib.AsyncComponent; var GridBuilder = React.createClass({ displayName: 'GridBuilder', propTypes: { namespaces: React.PropTypes.array, onCreateCard: React.PropTypes.func, onEditStatusChange: React.PropTypes.func }, getInitialState: function getInitialState() { return { selectedIndex: 0, availableWidgets: this.listAvailableWidgets() }; }, listAvailableWidgets: function listAvailableWidgets() { var secondPass = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0]; var widgets = []; var additionalNamespaces = []; this.props.namespaces.map(function (ns) { if (!global[ns]) { additionalNamespaces.push(ns); return; } for (var k in global[ns]) { if (global[ns].hasOwnProperty(k)) { var widgetClass = global[ns][k]; if (widgetClass.hasBuilderFields && widgetClass.hasBuilderFields()) { widgets.push({ reactClass: widgetClass, fullName: ns + '.' + widgetClass.displayName }); } } } }); if (additionalNamespaces.length && !secondPass) { ResourcesManager.loadClassesAndApply(additionalNamespaces, (function () { this.setState({ availableWidgets: this.listAvailableWidgets(true) }); }).bind(this)); } return widgets; }, onDropDownChange: function onDropDownChange(event, index, item) { var defaultValues = {}; if (index != 0) { item.payload['reactClass'].getBuilderFields().map(function (f) { if (f['default']) defaultValues[f.name] = f['default']; }); } if (this.props.onEditStatusChange) { this.props.onEditStatusChange(index != 0); } this.setState({ selectedIndex: index, selectedWidget: item.payload, currentFormValues: defaultValues }); }, cancel: function cancel() { if (this.props.onEditStatusChange) { this.props.onEditStatusChange(false); } this.setState({ selectedIndex: 0 }); }, onFormValueChange: function onFormValueChange(newValues) { this.setState({ currentFormValues: newValues }); }, onFormSubmit: function onFormSubmit() { var values = this.state.currentFormValues; var selectedWidget = this.state.selectedWidget; var title = values.title ? values.title : values.legend; if (!title) title = this.state.selectedWidget['reactClass'].builderDisplayName; this.props.onCreateCard({ componentClass: selectedWidget.fullName, title: title, props: values }); this.cancel(); }, resetLayout: function resetLayout() { if (window.confirm(this.props.getMessage('home.51'))) { this.props.onResetLayout(); } }, render: function render() { var getMessage = this.props.getMessage; var selectorItems = [{ payload: 0, text: getMessage('home.50') }].concat(this.state.availableWidgets.map(function (w, index) { return { payload: w, text: w['reactClass'].builderDisplayName }; })); var selector = React.createElement(ReactMUI.DropDownMenu, { menuItems: selectorItems, onChange: this.onDropDownChange, selectedIndex: this.state.selectedIndex, autoWidth: false, className: 'widget-type-selector' }); var form, add; if (this.state.selectedIndex != 0) { var fields = this.state.selectedWidget['reactClass'].getBuilderFields(); var defaultValues = {}; fields.map(function (f) { if (f['default']) defaultValues[f.name] = f['default']; }); if (this.state.currentFormValues) { defaultValues = LangUtils.mergeObjectsRecursive(defaultValues, this.state.currentFormValues); } form = React.createElement(AsyncComponent, { namespace: 'PydioForm', componentName: 'FormPanel', parameters: fields, depth: -1, values: defaultValues, onChange: this.onFormValueChange }); add = React.createElement( 'div', { style: { textAlign: 'center', paddingBottom: 100 } }, React.createElement(ReactMUI.RaisedButton, { label: getMessage('home.52'), onClick: this.onFormSubmit }), ' ', React.createElement(ReactMUI.RaisedButton, { label: getMessage('54', ''), onClick: this.cancel }) ); } return React.createElement( ReactMUI.Paper, _extends({}, this.props, { zDepth: 3 }), React.createElement( 'h3', null, getMessage('home.53') ), React.createElement( 'div', { className: 'legend' }, getMessage('home.54'), React.createElement('br', null), getMessage('home.55') ), selector, form, add, React.createElement( 'div', { style: { position: 'absolute', bottom: 30, left: 10 } }, React.createElement(ReactMUI.FlatButton, { disabled: this.state.selectedIndex != 0, label: getMessage('home.56'), secondary: true, onClick: this.resetLayout }) ) ); } }); exports['default'] = GridBuilder = PydioContextConsumer(GridBuilder); exports['default'] = GridBuilder; module.exports = exports['default']; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"pydio":"pydio","react":"react"}],4:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; exports['default'] = { propTypes: { showCloseAction: React.PropTypes.bool, onCloseAction: React.PropTypes.func }, focusItem: function focusItem() { this.setState({ focus: true }); }, blurItem: function blurItem() { this.setState({ focus: false }); }, mergeStyleWithFocus: function mergeStyleWithFocus() { return _extends({}, this.props.style, { zIndex: this.state.focus ? 1 : null }); }, getInitialSate: function getInitialSate() { return { focus: false, showCloseAction: false }; }, toggleEditMode: function toggleEditMode() { var value = arguments.length <= 0 || arguments[0] === undefined ? undefined : arguments[0]; if (value === undefined) { this.setState({ showCloseAction: !(this.state && this.state.showCloseAction) }); } else { this.setState({ showCloseAction: value }); } }, getCloseButton: function getCloseButton() { if (this.state && this.state.showCloseAction) { var closeAction = this.props.onCloseAction || function () {}; var overlayStyle = { position: 'absolute', backgroundColor: 'rgba(0,0,0,0.53)', zIndex: 10, top: 0, left: 0, bottom: 0, right: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }; return React.createElement( 'div', { style: overlayStyle }, React.createElement(MaterialUI.FlatButton, { label: pydio.MessageHash['ajxp_admin.home.48'], className: 'card-close-button', onTouchTap: closeAction, style: { color: 'white' } }) ); } else { return null; } }, statics: { getGridLayout: function getGridLayout(x, y) { return { x: x || 0, y: y || 0, w: this.gridWidth || 4, h: this.gridHeight || 12, isResizable: false }; }, hasBuilderFields: function hasBuilderFields() { return this.builderFields ? true : false; }, getBuilderFields: function getBuilderFields() { return this.builderFields; } } }; module.exports = exports['default']; },{}],5:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Store = (function (_Observable) { _inherits(Store, _Observable); /** * Init a card store * @param prefNamespace Namespace for getting/setting user preferences * @param defaultCards Array of cards to be displayed by default */ function Store(prefNamespace, defaultCards, pydioObject) { _classCallCheck(this, Store); _Observable.call(this); this._namespace = prefNamespace; this._pydio = pydioObject; this._cards = this.getUserPreference("Cards"); if (!this._cards) { this._cards = defaultCards; } } Store.prototype.getUserPreference = function getUserPreference(prefName) { var prefKey = this._namespace + prefName; var guiPrefs = this._pydio.user.getPreference('gui_preferences', true); if (guiPrefs && guiPrefs[prefKey]) { return guiPrefs[prefKey]; } else { return null; } }; Store.prototype.saveUserPreference = function saveUserPreference(prefName, prefValue) { var prefKey = this._namespace + prefName; var guiPrefs = this._pydio.user.getPreference('gui_preferences', true); if (!guiPrefs) guiPrefs = {}; guiPrefs[prefKey] = prefValue; this._pydio.user.setPreference('gui_preferences', guiPrefs, true); this._pydio.user.savePreference('gui_preferences'); }; Store.prototype.saveCards = function saveCards(cards) { this.saveUserPreference('Cards', cards); }; Store.prototype.resetCards = function resetCards() { this.saveUserPreference('Cards', null); }; Store.prototype.setCards = function setCards(newCards) { this._cards = newCards; this.notify("cards", this._cards); this.saveCards(newCards); }; Store.prototype.getCards = function getCards() { return this._cards; }; Store.prototype.removeCard = function removeCard(cardId) { var index = -1; var currentCards = this.getCards(); currentCards.map(function (card, arrayIndex) { if (card.id == cardId) index = arrayIndex; }); if (index == -1) { console.warn('Card ID not found, this is strange.', cardId); return; } var newCards; if (index == 0) newCards = currentCards.slice(1);else if (index == currentCards.length - 1) newCards = currentCards.slice(0, -1);else newCards = currentCards.slice(0, index).concat(currentCards.slice(index + 1)); this.setCards(newCards); }; Store.prototype.createCardId = function createCardId(cardDefinition) { var randomize = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; var id = LangUtils.computeStringSlug(cardDefinition['title']); if (randomize) { id += '-' + Math.round(Math.random() * 100 + 10); } var alreadyExists = false; this._cards.map((function (card) { if (card.id == id) alreadyExists = true; }).bind(this)); if (alreadyExists) { id = this.createCardId(cardDefinition, true); } return id; }; Store.prototype.addCard = function addCard(cardDefinition) { //console.log(cardDefinition); cardDefinition['id'] = this.createCardId(cardDefinition); this.setCards(this._cards.concat([cardDefinition])); }; return Store; })(Observable); exports['default'] = Store; module.exports = exports['default']; },{}],6:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _require = require('react'); var Component = _require.Component; var PropTypes = _require.PropTypes; var _require2 = require('material-ui'); var FlatButton = _require2.FlatButton; var _require3 = require('material-ui/styles'); var muiThemeable = _require3.muiThemeable; exports['default'] = function (PydioComponent, displayName) { var gridDimension = arguments.length <= 2 || arguments[2] === undefined ? { gridWidth: 4, gridHeight: 12 } : arguments[2]; var builderFields = arguments.length <= 3 || arguments[3] === undefined ? undefined : arguments[3]; var originalDisplayName = PydioComponent.displayName || PydioComponent.name; PydioComponent = muiThemeable()(PydioComponent); var GridItem = (function (_Component) { _inherits(GridItem, _Component); function GridItem(props, context) { _classCallCheck(this, GridItem); _Component.call(this, props, context); this.state = { focus: false, showCloseAction: false }; } GridItem.prototype.focusItem = function focusItem() { this.setState({ focus: true }); }; GridItem.prototype.blurItem = function blurItem() { this.setState({ focus: false }); }; GridItem.prototype.mergeStyleWithFocus = function mergeStyleWithFocus() { return _extends({}, this.props.style, { zIndex: this.state.focus ? 1 : null }); }; GridItem.prototype.toggleEditMode = function toggleEditMode() { var value = arguments.length <= 0 || arguments[0] === undefined ? undefined : arguments[0]; if (value === undefined) { this.setState({ showCloseAction: !(this.state && this.state.showCloseAction) }); } else { this.setState({ showCloseAction: value }); } }; GridItem.prototype.getCloseButton = function getCloseButton() { var closeAction = this.props.onCloseAction || function () {}; var overlayStyle = { position: 'absolute', backgroundColor: 'rgba(0,0,0,0.53)', zIndex: 10, top: 0, left: 0, bottom: 0, right: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }; return React.createElement( 'div', { style: overlayStyle }, React.createElement(FlatButton, { label: this.props.pydio.MessageHash['ajxp_admin.home.48'], className: 'card-close-button', onTouchTap: closeAction, style: { color: 'white' } }) ); }; GridItem.prototype.render = function render() { var props = _extends({}, this.props, { style: this.mergeStyleWithFocus(), closeButton: this.state.showCloseAction ? this.getCloseButton() : null, onFocusItem: this.focusItem.bind(this), onBlurItem: this.blurItem.bind(this) }); return React.createElement(PydioComponent, props); }; return GridItem; })(Component); GridItem.propTypes = { onCloseAction: PropTypes.func }; GridItem.displayName = originalDisplayName; GridItem.builderDisplayName = displayName; GridItem.getGridLayout = function (x, y) { return { x: x || 0, y: y || 0, w: gridDimension.gridWidth || 4, h: gridDimension.gridHeight || 12, isResizable: false }; }; GridItem.hasBuilderFields = function () { return builderFields !== undefined; }; GridItem.getBuilderFields = function () { return builderFields; }; return GridItem; }; module.exports = exports['default']; },{"material-ui":"material-ui","material-ui/styles":"material-ui/styles","react":"react"}],7:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ /** * Two columns layout used for Workspaces and Plugins editors */ 'use strict'; exports.__esModule = true; var PaperEditorLayout = React.createClass({ displayName: 'PaperEditorLayout', propTypes: { title: React.PropTypes.any, titleActionBar: React.PropTypes.any, leftNav: React.PropTypes.any, contentFill: React.PropTypes.bool, className: React.PropTypes.string }, toggleMenu: function toggleMenu() { var crtLeftOpen = this.state && this.state.forceLeftOpen; this.setState({ forceLeftOpen: !crtLeftOpen }); }, render: function render() { return React.createElement( 'div', { className: "paper-editor-content layout-fill vertical-layout" + (this.props.className ? ' ' + this.props.className : '') }, React.createElement( 'div', { className: 'paper-editor-title' }, React.createElement( 'h2', null, this.props.title, ' ', React.createElement( 'div', { className: 'left-picker-toggle' }, React.createElement(ReactMUI.IconButton, { iconClassName: 'icon-caret-down', onClick: this.toggleMenu }) ) ), React.createElement( 'div', { className: 'title-bar' }, this.props.titleActionBar ) ), React.createElement( 'div', { className: 'layout-fill main-layout-nav-to-stack' }, React.createElement( 'div', { className: "paper-editor-left" + (this.state && this.state.forceLeftOpen ? ' picker-open' : ''), onClick: this.toggleMenu }, this.props.leftNav ), React.createElement( 'div', { className: "layout-fill paper-editor-right" + (this.props.contentFill ? ' vertical-layout' : ''), style: this.props.contentFill ? {} : { overflowY: 'auto' } }, this.props.children ) ) ); } }); /** * Navigation subheader used by PaperEditorLayout */ var PaperEditorNavHeader = React.createClass({ displayName: 'PaperEditorNavHeader', propTypes: { label: React.PropTypes.string }, render: function render() { return React.createElement( 'div', { className: 'mui-subheader' }, this.props.children, this.props.label ); } }); /** * Navigation entry used by PaperEditorLayout. */ var PaperEditorNavEntry = React.createClass({ displayName: 'PaperEditorNavEntry', propTypes: { keyName: React.PropTypes.string.isRequired, onClick: React.PropTypes.func.isRequired, label: React.PropTypes.string, selectedKey: React.PropTypes.string, isLast: React.PropTypes.bool, // Drop Down Data dropDown: React.PropTypes.bool, dropDownData: React.PropTypes.object, dropDownChange: React.PropTypes.func, dropDownDefaultItems: React.PropTypes.array }, onClick: function onClick() { this.props.onClick(this.props.keyName); }, captureDropDownClick: function captureDropDownClick() { if (this.preventClick) { this.preventClick = false; return; } this.props.onClick(this.props.keyName); }, dropDownChange: function dropDownChange(event, index, item) { this.preventClick = true; this.props.dropDownChange(item); }, render: function render() { if (!this.props.dropDown || !this.props.dropDownData) { return React.createElement( 'div', { className: 'menu-entry' + (this.props.keyName == this.props.selectedKey ? ' menu-entry-selected' : '') + (this.props.isLast ? ' last' : ''), onClick: this.onClick }, this.props.children, this.props.label ); } // dropDown & dropDownData are loaded var menuItemsTpl = [{ text: this.props.label, payload: '-1' }]; if (this.props.dropDownDefaultItems) { menuItemsTpl = menuItemsTpl.concat(this.props.dropDownDefaultItems); } this.props.dropDownData.forEach(function (v, k) { menuItemsTpl.push({ text: v.label, payload: v }); }); return React.createElement( 'div', { onClick: this.captureDropDownClick, className: 'menu-entry-dropdown' + (this.props.keyName == this.props.selectedKey ? ' menu-entry-selected' : '') + (this.props.isLast ? ' last' : '') }, React.createElement(ReactMUI.DropDownMenu, { menuItems: menuItemsTpl, className: 'dropdown-full-width', style: { width: 256 }, autoWidth: false, onChange: this.dropDownChange }) ); } }); exports.PaperEditorLayout = PaperEditorLayout; exports.PaperEditorNavEntry = PaperEditorNavEntry; exports.PaperEditorNavHeader = PaperEditorNavHeader; },{}],8:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ "use strict"; exports.__esModule = true; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var propTypes = { node: React.PropTypes.instanceOf(AjxpNode).isRequired, registry: React.PropTypes.instanceOf(Registry).isRequired, editorData: React.PropTypes.object.isRequired, icon: React.PropTypes.bool }; var defaultProps = { icon: false }; var ReactEditorOpener = (function (_React$Component) { _inherits(ReactEditorOpener, _React$Component); function ReactEditorOpener(props) { _classCallCheck(this, ReactEditorOpener); _React$Component.call(this, props); var node = props.node; var editorData = props.editorData; this.state = { ready: false }; } ReactEditorOpener.prototype.componentDidMount = function componentDidMount() { var _this = this; var _props = this.props; var editorData = _props.editorData; var registry = _props.registry; registry.loadEditorResources(editorData.resourcesManager, function () { return _this.setState({ ready: true }); }); }; ReactEditorOpener.prototype.render = function render() { var editorData = this.props.editorData; var ready = this.state.ready; if (!ready) return null; var EditorClass = null; if (!(EditorClass = FuncUtils.getFunctionByName(editorData.editorClass, window))) { return React.createElement( "div", null, "Cannot find editor component (" + editorData.editorClass + ")!" ); } // Getting HOC of the class return React.createElement(EditorClass.Editor, this.props); }; return ReactEditorOpener; })(React.Component); ReactEditorOpener.propTypes = propTypes; ReactEditorOpener.defaultProps = defaultProps; exports["default"] = ReactEditorOpener; module.exports = exports["default"]; },{}],9:[function(require,module,exports){ (function (global){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; exports['default'] = React.createClass({ displayName: 'ClipboardTextField', propTypes: { floatingLabelText: React.PropTypes.string, inputValue: React.PropTypes.string, inputClassName: React.PropTypes.string, getMessage: React.PropTypes.func, inputCopyMessage: React.PropTypes.string }, getInitialState: function getInitialState() { return { copyMessage: null }; }, componentDidMount: function componentDidMount() { this.attachClipboard(); }, componentDidUpdate: function componentDidUpdate() { this.attachClipboard(); }, attachClipboard: function attachClipboard() { if (this._clip) { this._clip.destroy(); } if (!this.refs['copy-button']) { return; } this._clip = new Clipboard(this.refs['copy-button'], { text: (function (trigger) { return this.props.inputValue; }).bind(this) }); this._clip.on('success', (function () { this.setState({ copyMessage: this.props.getMessage(this.props.inputCopyMessage || '192') }, this.clearCopyMessage); }).bind(this)); this._clip.on('error', (function () { var copyMessage; if (global.navigator.platform.indexOf("Mac") === 0) { copyMessage = this.props.getMessage('144'); } else { copyMessage = this.props.getMessage('143'); } this.refs['input'].focus(); this.setState({ copyMessage: copyMessage }, this.clearCopyMessage); }).bind(this)); }, clearCopyMessage: function clearCopyMessage() { global.setTimeout((function () { this.setState({ copyMessage: '' }); }).bind(this), 3000); }, render: function render() { var select = function select(e) { e.currentTarget.select(); }; var copyMessage = null; if (this.state.copyMessage) { var setHtml = (function () { return { __html: this.state.copyMessage }; }).bind(this); copyMessage = React.createElement('div', { style: { color: 'rgba(0,0,0,0.23)' }, className: 'copy-message', dangerouslySetInnerHTML: setHtml() }); } var buttonStyle = _extends({ position: 'absolute', right: -8, bottom: 13, fontSize: 15, color: this.props.buttonColor || 'rgba(0, 150, 136, 0.52)', height: 26, width: 26, lineHeight: '28px', textAlign: 'center', cursor: 'pointer', borderRadius: '50%' }, this.props.buttonStyle); return React.createElement( 'div', null, React.createElement( 'div', { style: { position: 'relative' } }, React.createElement(MaterialUI.TextField, { fullWidth: true, ref: 'input', floatingLabelText: this.props.floatingLabelText, floatingLabelStyle: { whiteSpace: 'nowrap' }, underlineShow: this.props.underlineShow, defaultValue: this.props.inputValue, className: this.props.inputClassName, multiLine: this.props.multiLine, rows: this.props.rows, rowsMax: this.props.rowsMax, readOnly: true, onClick: select, style: { marginTop: -10, width: '92%', fontSize: 14 } }), React.createElement('span', { ref: 'copy-button', style: buttonStyle, title: this.props.getMessage('191'), className: 'copy-button mdi mdi-content-copy' }) ), copyMessage ); } }); module.exports = exports['default']; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],10:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; exports['default'] = React.createClass({ displayName: 'LabelWithTip', propTypes: { label: React.PropTypes.string, labelElement: React.PropTypes.object, tooltip: React.PropTypes.string, tooltipClassName: React.PropTypes.string, className: React.PropTypes.string, style: React.PropTypes.object }, getInitialState: function getInitialState() { return { show: false }; }, show: function show() { this.setState({ show: true }); }, hide: function hide() { this.setState({ show: false }); }, render: function render() { if (this.props.tooltip) { var tooltipStyle = {}; if (this.props.label || this.props.labelElement) { if (this.state.show) { tooltipStyle = { bottom: -10, top: 'inherit' }; } } else { tooltipStyle = { position: 'relative' }; } var label = undefined; if (this.props.label) { label = React.createElement( 'span', { className: 'ellipsis-label' }, this.props.label ); } else if (this.props.labelElement) { label = this.props.labelElement; } var style = this.props.style || { position: 'relative' }; return React.createElement( 'span', { onMouseEnter: this.show, onMouseLeave: this.hide, style: style, className: this.props.className }, label, this.props.children, React.createElement(ReactMUI.Tooltip, { label: this.props.tooltip, style: tooltipStyle, className: this.props.tooltipClassName, show: this.state.show }) ); } else { if (this.props.label) { return React.createElement( 'span', null, this.props.label ); } else if (this.props.labelElement) { return this.props.labelElement; } else { return React.createElement( 'span', null, this.props.children ); } } } }); module.exports = exports['default']; },{}],11:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ /** * Simple MuiPaper with a figure and a legend */ 'use strict'; exports.__esModule = true; exports['default'] = React.createClass({ displayName: 'SimpleFigureBadge', propTypes: { colorIndicator: React.PropTypes.string, figure: React.PropTypes.number.isRequired, legend: React.PropTypes.string }, getDefaultProps: function getDefaultProps() { return { colorIndicator: '' }; }, render: function render() { return React.createElement( ReactMUI.Paper, { style: { display: 'inline-block', marginLeft: 16 } }, React.createElement( 'div', { className: 'figure-badge', style: this.props.colorIndicator ? { borderLeftColor: this.props.colorIndicator } : {} }, React.createElement( 'div', { className: 'figure' }, this.props.figure ), React.createElement( 'div', { className: 'legend' }, this.props.legend ) ) ); } }); module.exports = exports['default']; },{}],12:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _listSortableList = require('./list/SortableList'); var _listSortableList2 = _interopRequireDefault(_listSortableList); var _listSimpleList = require('./list/SimpleList'); var _listSimpleList2 = _interopRequireDefault(_listSimpleList); var _listNodeListCustomProvider = require('./list/NodeListCustomProvider'); var _listNodeListCustomProvider2 = _interopRequireDefault(_listNodeListCustomProvider); var _listListEntry = require('./list/ListEntry'); var _listListPaginator = require('./list/ListPaginator'); var _listListPaginator2 = _interopRequireDefault(_listListPaginator); var _viewsTreeView = require('./views/TreeView'); var _elementsLabelWithTip = require('./elements/LabelWithTip'); var _elementsLabelWithTip2 = _interopRequireDefault(_elementsLabelWithTip); var _elementsSimpleFigureBadge = require('./elements/SimpleFigureBadge'); var _elementsSimpleFigureBadge2 = _interopRequireDefault(_elementsSimpleFigureBadge); var _viewsSearchBox = require('./views/SearchBox'); var _viewsSearchBox2 = _interopRequireDefault(_viewsSearchBox); var _elementsClipboardTextField = require('./elements/ClipboardTextField'); var _elementsClipboardTextField2 = _interopRequireDefault(_elementsClipboardTextField); var _viewsEmptyStateView = require('./views/EmptyStateView'); var _viewsEmptyStateView2 = _interopRequireDefault(_viewsEmptyStateView); var _viewsModalAppBar = require('./views/ModalAppBar'); var _viewsModalAppBar2 = _interopRequireDefault(_viewsModalAppBar); var _editorReactEditorOpener = require('./editor/ReactEditorOpener'); var _editorReactEditorOpener2 = _interopRequireDefault(_editorReactEditorOpener); var _editorPaperEditor = require('./editor/PaperEditor'); var _dynamicGridDynamicGrid = require('./dynamic-grid/DynamicGrid'); var _dynamicGridDynamicGrid2 = _interopRequireDefault(_dynamicGridDynamicGrid); var _dynamicGridStore = require('./dynamic-grid/Store'); var _dynamicGridStore2 = _interopRequireDefault(_dynamicGridStore); var _dynamicGridGridItemMixin = require('./dynamic-grid/GridItemMixin'); var _dynamicGridGridItemMixin2 = _interopRequireDefault(_dynamicGridGridItemMixin); var _dynamicGridAsGridItem = require('./dynamic-grid/asGridItem'); var _dynamicGridAsGridItem2 = _interopRequireDefault(_dynamicGridAsGridItem); var _utilDND = require('./util/DND'); var _usersAvatarUserAvatar = require('./users/avatar/UserAvatar'); var _usersAvatarUserAvatar2 = _interopRequireDefault(_usersAvatarUserAvatar); var _usersUsersCompleter = require('./users/UsersCompleter'); var _usersUsersCompleter2 = _interopRequireDefault(_usersUsersCompleter); var _usersTeamCreationForm = require('./users/TeamCreationForm'); var _usersTeamCreationForm2 = _interopRequireDefault(_usersTeamCreationForm); var _menuButtonMenu = require('./menu/ButtonMenu'); var _menuButtonMenu2 = _interopRequireDefault(_menuButtonMenu); var _menuContextMenu = require('./menu/ContextMenu'); var _menuContextMenu2 = _interopRequireDefault(_menuContextMenu); var _menuIconButtonMenu = require('./menu/IconButtonMenu'); var _menuIconButtonMenu2 = _interopRequireDefault(_menuIconButtonMenu); var _menuToolbar = require('./menu/Toolbar'); var _menuToolbar2 = _interopRequireDefault(_menuToolbar); var _usersAddressbookAddressBook = require('./users/addressbook/AddressBook'); var _usersAddressbookAddressBook2 = _interopRequireDefault(_usersAddressbookAddressBook); var PydioComponents = { SortableList: _listSortableList2['default'], SimpleList: _listSimpleList2['default'], NodeListCustomProvider: _listNodeListCustomProvider2['default'], ListEntry: _listListEntry.ListEntry, ListPaginator: _listListPaginator2['default'], TreeView: _viewsTreeView.TreeView, DNDTreeView: _viewsTreeView.DNDTreeView, FoldersTree: _viewsTreeView.FoldersTree, ClipboardTextField: _elementsClipboardTextField2['default'], LabelWithTip: _elementsLabelWithTip2['default'], EmptyStateView: _viewsEmptyStateView2['default'], SimpleFigureBadge: _elementsSimpleFigureBadge2['default'], SearchBox: _viewsSearchBox2['default'], ModalAppBar: _viewsModalAppBar2['default'], ReactEditorOpener: _editorReactEditorOpener2['default'], PaperEditorLayout: _editorPaperEditor.PaperEditorLayout, PaperEditorNavEntry: _editorPaperEditor.PaperEditorNavEntry, PaperEditorNavHeader: _editorPaperEditor.PaperEditorNavHeader, DynamicGrid: _dynamicGridDynamicGrid2['default'], DynamicGridItemMixin: _dynamicGridGridItemMixin2['default'], asGridItem: _dynamicGridAsGridItem2['default'], DynamicGridStore: _dynamicGridStore2['default'], DND: { Types: _utilDND.Types, collect: _utilDND.collect, collectDrop: _utilDND.collectDrop, nodeDragSource: _utilDND.nodeDragSource, nodeDropTarget: _utilDND.nodeDropTarget, DNDActionParameter: _utilDND.DNDActionParameter }, DNDActionParameter: _utilDND.DNDActionParameter, UserAvatar: _usersAvatarUserAvatar2['default'], UsersCompleter: _usersUsersCompleter2['default'], TeamCreationForm: _usersTeamCreationForm2['default'], AddressBook: _usersAddressbookAddressBook2['default'], ContextMenu: _menuContextMenu2['default'], Toolbar: _menuToolbar2['default'], ButtonMenu: _menuButtonMenu2['default'], IconButtonMenu: _menuIconButtonMenu2['default'] }; exports['default'] = PydioComponents; module.exports = exports['default']; },{"./dynamic-grid/DynamicGrid":2,"./dynamic-grid/GridItemMixin":4,"./dynamic-grid/Store":5,"./dynamic-grid/asGridItem":6,"./editor/PaperEditor":7,"./editor/ReactEditorOpener":8,"./elements/ClipboardTextField":9,"./elements/LabelWithTip":10,"./elements/SimpleFigureBadge":11,"./list/ListEntry":15,"./list/ListPaginator":17,"./list/NodeListCustomProvider":18,"./list/SimpleList":19,"./list/SortableList":21,"./menu/ButtonMenu":24,"./menu/ContextMenu":25,"./menu/IconButtonMenu":26,"./menu/Toolbar":30,"./users/TeamCreationForm":32,"./users/UsersCompleter":33,"./users/addressbook/AddressBook":34,"./users/avatar/UserAvatar":46,"./util/DND":47,"./views/EmptyStateView":49,"./views/ModalAppBar":50,"./views/SearchBox":51,"./views/TreeView":53}],13:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _ListEntryNodeListenerMixin = require('./ListEntryNodeListenerMixin'); var _ListEntryNodeListenerMixin2 = _interopRequireDefault(_ListEntryNodeListenerMixin); var _InlineEditor = require('./InlineEditor'); var _InlineEditor2 = _interopRequireDefault(_InlineEditor); var _ListEntry = require('./ListEntry'); var _materialUi = require('material-ui'); /** * Callback based material list entry with custom icon render, firstLine, secondLine, etc. */ exports['default'] = _react2['default'].createClass({ displayName: 'ConfigurableListEntry', mixins: [_ListEntryNodeListenerMixin2['default']], propTypes: { node: _react2['default'].PropTypes.instanceOf(AjxpNode), // SEE ALSO ListEntry PROPS renderIcon: _react2['default'].PropTypes.func, renderFirstLine: _react2['default'].PropTypes.func, renderSecondLine: _react2['default'].PropTypes.func, renderThirdLine: _react2['default'].PropTypes.func, renderActions: _react2['default'].PropTypes.func, style: _react2['default'].PropTypes.object }, render: function render() { var _this = this; var icon = undefined, firstLine = undefined, secondLine = undefined, thirdLine = undefined, style = this.props.style || {}; if (this.props.renderIcon) { icon = this.props.renderIcon(this.props.node, this.props); } else { var node = this.props.node; var iconClass = node.getMetadata().get("icon_class") ? node.getMetadata().get("icon_class") : node.isLeaf() ? "icon-file-alt" : "icon-folder-close"; icon = _react2['default'].createElement(_materialUi.FontIcon, { className: iconClass }); } if (this.props.renderFirstLine) { firstLine = this.props.renderFirstLine(this.props.node); } else { firstLine = this.props.node.getLabel(); } if (this.state && this.state.inlineEdition) { firstLine = _react2['default'].createElement( 'span', null, _react2['default'].createElement(_InlineEditor2['default'], { node: this.props.node, onClose: function () { _this.setState({ inlineEdition: false }); }, callback: this.state.inlineEditionCallback }), firstLine ); style.position = 'relative'; } if (this.props.renderSecondLine) { secondLine = this.props.renderSecondLine(this.props.node); } if (this.props.renderThirdLine) { thirdLine = this.props.renderThirdLine(this.props.node); } var actions = this.props.actions; if (this.props.renderActions) { actions = this.props.renderActions(this.props.node); } return _react2['default'].createElement(_ListEntry.DragDropListEntry, _extends({}, this.props, { iconCell: icon, firstLine: firstLine, secondLine: secondLine, thirdLine: thirdLine, actions: actions, style: style })); } }); module.exports = exports['default']; },{"./InlineEditor":14,"./ListEntry":15,"./ListEntryNodeListenerMixin":16,"material-ui":"material-ui","react":"react"}],14:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var React = require('react'); var Pydio = require('pydio'); var AjxpNode = require('pydio/model/node'); var _Pydio$requireLib = Pydio.requireLib('boot'); var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer; var _require = require('material-ui'); var Paper = _require.Paper; var TextField = _require.TextField; var FlatButton = _require.FlatButton; var InlineEditor = React.createClass({ displayName: 'InlineEditor', propTypes: { node: React.PropTypes.instanceOf(AjxpNode), callback: React.PropTypes.func, onClose: React.PropTypes.func, detached: React.PropTypes.bool }, submit: function submit() { if (!this.state || !this.state.value || this.state.value === this.props.node.getLabel()) { this.setState({ errorString: 'Please use a different value for renaming!' }); this.props.getPydio().displayMessage('ERROR', 'Please use a different value for renaming!'); } else { this.props.callback(this.state.value); this.props.onClose(); } }, componentDidMount: function componentDidMount() { this.refs.text.focus(); }, catchClicks: function catchClicks(e) { e.stopPropagation(); }, onKeyDown: function onKeyDown(e) { if (e.key === 'Enter') { this.submit(); } this.setState({ errorString: '' }); e.stopPropagation(); }, render: function render() { var _this = this; return React.createElement( Paper, { className: "inline-editor" + (this.props.detached ? " detached" : ""), style: { padding: 8 }, zDepth: 2 }, React.createElement(TextField, { ref: 'text', defaultValue: this.props.node.getLabel(), onChange: function (e, value) { _this.setState({ value: value }); }, onClick: this['catch'], onDoubleClick: this.catchClicks, tabIndex: '0', onKeyDown: this.onKeyDown, errorText: this.state ? this.state.errorString : null }), React.createElement( 'div', { style: { textAlign: 'right', paddingTop: 8 } }, React.createElement(FlatButton, { label: 'Cancel', onClick: this.props.onClose }), React.createElement(FlatButton, { label: 'Submit', onClick: this.submit }) ) ); } }); exports['default'] = InlineEditor = PydioContextConsumer(InlineEditor); exports['default'] = InlineEditor; module.exports = exports['default']; },{"material-ui":"material-ui","pydio":"pydio","pydio/model/node":"pydio/model/node","react":"react"}],15:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _reactDom = require('react-dom'); var _reactDom2 = _interopRequireDefault(_reactDom); var _utilDND = require('../util/DND'); var _reactDnd = require('react-dnd'); var _materialUi = require('material-ui'); var _materialUiStyles = require('material-ui/styles'); var _color = require('color'); var _color2 = _interopRequireDefault(_color); /** * Material List Entry */ var ListEntry = (function (_React$Component) { _inherits(ListEntry, _React$Component); function ListEntry() { _classCallCheck(this, ListEntry); _React$Component.apply(this, arguments); } ListEntry.prototype.onClick = function onClick(event) { if (this.props.showSelector) { if (this.props.selectorDisabled) return; this.props.onSelect(this.props.node, event); event.stopPropagation(); event.preventDefault(); } else if (this.props.onClick) { this.props.onClick(this.props.node, event); } }; ListEntry.prototype.onDoubleClick = function onDoubleClick(event) { if (this.props.onDoubleClick) { this.props.onDoubleClick(this.props.node, event); } }; ListEntry.prototype.render = function render() { var _this = this; var selector = undefined, icon = undefined, additionalClassName = undefined; var _props = this.props; var node = _props.node; var showSelector = _props.showSelector; var selected = _props.selected; var selectorDisabled = _props.selectorDisabled; var firstLine = _props.firstLine; var secondLine = _props.secondLine; var thirdLine = _props.thirdLine; var style = _props.style; var actions = _props.actions; var iconCell = _props.iconCell; var mainIcon = _props.mainIcon; var className = _props.className; var canDrop = _props.canDrop; var isOver = _props.isOver; var connectDragSource = _props.connectDragSource; var connectDropTarget = _props.connectDropTarget; var mainClasses = ['material-list-entry', 'material-list-entry-' + (thirdLine ? 3 : secondLine ? 2 : 1) + '-lines']; if (className) mainClasses.push(className); if (showSelector) { selector = React.createElement( 'div', { className: 'material-list-selector' }, React.createElement(_materialUi.Checkbox, { checked: selected, ref: 'selector', disabled: selectorDisabled }) ); } if (iconCell) { icon = this.props.iconCell; } else if (this.props.mainIcon) { icon = React.createElement(_materialUi.FontIcon, { className: "mui-font-icon " + this.props.mainIcon, style: { fontSize: 18 /*, color: "#FFFFFF"*/ } }); } if (canDrop && isOver) { mainClasses.push('droppable-active'); } if (node) { mainClasses.push('listentry' + node.getPath().replace(/\//g, '_')); mainClasses.push('ajxp_node_' + (node.isLeaf() ? 'leaf' : 'collection')); if (node.getAjxpMime()) { mainClasses.push('ajxp_mime_' + node.getAjxpMime()); } } var additionalStyle = { /*transition:'background-color 250ms cubic-bezier(0.23, 1, 0.32, 1) 0ms, color 250ms cubic-bezier(0.23, 1, 0.32, 1) 0ms'*/ }; if (this.state && this.state.hover && !this.props.noHover) { additionalStyle = _extends({}, additionalStyle, { backgroundColor: 'rgba(0,0,0,0.05)', borderBottom: '1px solid transparent' }); } if (selected) { var selectionColor = this.props.muiTheme.palette.accent2Color; var selectionColorDark = _color2['default'](selectionColor).dark(); additionalStyle = _extends({}, additionalStyle, { backgroundColor: selectionColor, color: selectionColorDark ? 'white' : 'rgba(0,0,0,.87)' }); mainClasses.push('selected'); mainClasses.push('selected-' + (selectionColorDark ? 'dark' : 'light')); } return React.createElement( ContextMenuWrapper, _extends({}, this.props, { ref: function (instance) { var node = _reactDom2['default'].findDOMNode(instance); if (typeof connectDropTarget === 'function') connectDropTarget(node); if (typeof connectDragSource === 'function') connectDragSource(node); }, onClick: this.onClick.bind(this), onDoubleClick: showSelector ? null : this.onDoubleClick.bind(this), className: mainClasses.join(' '), onMouseOver: function () { _this.setState({ hover: true }); }, onMouseOut: function () { _this.setState({ hover: false }); }, style: _extends({}, style, additionalStyle) }), selector, React.createElement( 'div', { className: "material-list-icon" + (mainIcon || iconCell ? "" : " material-list-icon-none") }, icon ), React.createElement( 'div', { className: 'material-list-text' }, React.createElement( 'div', { key: 'line-1', className: 'material-list-line-1' }, firstLine ), React.createElement( 'div', { key: 'line-2', className: 'material-list-line-2' }, secondLine ), React.createElement( 'div', { key: 'line-3', className: 'material-list-line-3' }, thirdLine ) ), React.createElement( 'div', { className: 'material-list-actions' }, actions ) ); }; return ListEntry; })(React.Component); var ContextMenuWrapper = function ContextMenuWrapper(props) { return React.createElement('div', props); }; ContextMenuWrapper = PydioHOCs.withContextMenu(ContextMenuWrapper); ListEntry.propTypes = { showSelector: React.PropTypes.bool, selected: React.PropTypes.bool, selectorDisabled: React.PropTypes.bool, onSelect: React.PropTypes.func, onClick: React.PropTypes.func, iconCell: React.PropTypes.element, mainIcon: React.PropTypes.string, firstLine: React.PropTypes.node, secondLine: React.PropTypes.node, thirdLine: React.PropTypes.node, actions: React.PropTypes.element, activeDroppable: React.PropTypes.bool, className: React.PropTypes.string, style: React.PropTypes.object, noHover: React.PropTypes.bool }; exports.ListEntry = ListEntry = _materialUiStyles.muiThemeable()(ListEntry); var DragDropListEntry = _reactDnd.flow(_reactDnd.DragSource(_utilDND.Types.NODE_PROVIDER, _utilDND.nodeDragSource, _utilDND.collect), _reactDnd.DropTarget(_utilDND.Types.NODE_PROVIDER, _utilDND.nodeDropTarget, _utilDND.collectDrop))(ListEntry); exports.DragDropListEntry = DragDropListEntry; exports.ListEntry = ListEntry; },{"../util/DND":47,"color":"color","material-ui":"material-ui","material-ui/styles":"material-ui/styles","react-dnd":"react-dnd","react-dom":"react-dom"}],16:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ "use strict"; exports.__esModule = true; exports["default"] = { attach: function attach(node) { this._nodeListener = (function () { if (!this.isMounted()) { this.detach(node); return; } this.forceUpdate(); }).bind(this); this._actionListener = (function (eventMemo) { if (!this.isMounted()) { this.detach(node); return; } if (eventMemo && eventMemo.type === 'prompt-rename' && eventMemo.callback) { this.setState({ inlineEdition: true, inlineEditionCallback: eventMemo.callback }); } return true; }).bind(this); node.observe("node_replaced", this._nodeListener); node.observe("node_action", this._actionListener); }, detach: function detach(node) { if (this._nodeListener) { node.stopObserving("node_replaced", this._nodeListener); node.stopObserving("node_action", this._actionListener); } }, componentDidMount: function componentDidMount() { this.attach(this.props.node); }, componentWillUnmount: function componentWillUnmount() { this.detach(this.props.node); } }; module.exports = exports["default"]; },{}],17:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ "use strict"; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var _utilMessagesConsumerMixin = require('../util/MessagesConsumerMixin'); var _utilMessagesConsumerMixin2 = _interopRequireDefault(_utilMessagesConsumerMixin); /** * Pagination component reading metadata "paginationData" from current node. */ exports["default"] = React.createClass({ displayName: "ListPaginator", mixins: [_utilMessagesConsumerMixin2["default"]], propTypes: { dataModel: React.PropTypes.instanceOf(PydioDataModel).isRequired, node: React.PropTypes.instanceOf(AjxpNode) }, componentDidMount: function componentDidMount() { var _this = this; if (!this.props.node) { (function () { var dm = _this.props.dataModel; _this._dmObserver = (function () { this.setState({ node: dm.getContextNode() }); }).bind(_this); dm.observe("context_changed", _this._dmObserver); _this.setState({ node: dm.getContextNode() }); })(); } }, componentWillUnmount: function componentWillUnmount() { if (this._dmObserver) { this.props.dataModel.stopObserving("context_changed", this._dmObserver); } }, getInitialState: function getInitialState() { return { node: this.props.node }; }, changePage: function changePage(event) { this.state.node.getMetadata().get("paginationData").set("new_page", event.currentTarget.getAttribute('data-page')); this.props.dataModel.requireContextChange(this.state.node); }, onMenuChange: function onMenuChange(event, index, item) { this.state.node.getMetadata().get("paginationData").set("new_page", item.payload); this.props.dataModel.requireContextChange(this.state.node); }, render: function render() { if (!this.state.node || !this.state.node.getMetadata().get("paginationData")) { return null; } var pData = this.state.node.getMetadata().get("paginationData"); var current = parseInt(pData.get("current")); var total = parseInt(pData.get("total")); var pages = [], next, last, previous, first; var pageWord = this.context.getMessage ? this.context.getMessage('331', '') : this.props.getMessage('331', ''); for (var i = 1; i <= total; i++) { pages.push({ payload: i, text: pageWord + ' ' + i + (i == current ? ' / ' + total : '') }); } if (pages.length <= 1) { return null; } var sep = undefined; if (this.props.toolbarDisplay) { if (current > 1) previous = React.createElement( "span", { className: "toolbars-button-menu" }, React.createElement(ReactMUI.IconButton, { onClick: this.changePage, "data-page": current - 1, iconClassName: "icon-caret-left" }) ); if (current < total) next = React.createElement( "span", { className: "toolbars-button-menu" }, React.createElement(ReactMUI.IconButton, { onClick: this.changePage, "data-page": current + 1, iconClassName: "icon-caret-right" }) ); } else { if (current > 1) previous = React.createElement(ReactMUI.FontIcon, { onClick: this.changePage, "data-page": current - 1, className: "icon-angle-left" }); if (current < total) next = React.createElement(ReactMUI.FontIcon, { onClick: this.changePage, "data-page": current + 1, className: "icon-angle-right" }); sep = React.createElement( "span", { className: "mui-toolbar-separator" }, " " ); } return React.createElement( "span", { id: this.props.id, style: this.props.style }, first, previous, React.createElement(ReactMUI.DropDownMenu, { onChange: this.onMenuChange, menuItems: pages, selectedIndex: current - 1 }), next, last, sep ); } }); module.exports = exports["default"]; },{"../util/MessagesConsumerMixin":48}],18:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ "use strict"; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var _SimpleList = require('./SimpleList'); var _SimpleList2 = _interopRequireDefault(_SimpleList); /** * Simple to use list component encapsulated with its own query mechanism * using a set of properties for the remote node provider. */ exports["default"] = React.createClass({ displayName: "NodeListCustomProvider", propTypes: { nodeProviderProperties: React.PropTypes.object, presetDataModel: React.PropTypes.instanceOf(PydioDataModel), autoRefresh: React.PropTypes.number, actionBarGroups: React.PropTypes.array, heightAutoWithMax: React.PropTypes.number, elementHeight: React.PropTypes.number.isRequired, nodeClicked: React.PropTypes.func, reloadOnServerMessage: React.PropTypes.string, entryRenderAsCard: React.PropTypes.func }, reload: function reload() { if (this.refs.list && this.isMounted()) { this.refs.list.reload(); } }, componentWillUnmount: function componentWillUnmount() { if (this._smObs) { this.props.pydio.stopObserving("server_message", this._smObs); this.props.pydio.stopObserving("server_message:" + this.props.reloadOnServerMessage, this.reload); } }, componentWillReceiveProps: function componentWillReceiveProps(nextProps) { if (this.props.nodeProviderProperties && this.props.nodeProviderProperties !== nextProps.nodeProviderProperties) { var _state = this.state; var dataModel = _state.dataModel; var node = _state.node; var provider = new RemoteNodeProvider(nextProps.nodeProviderProperties); dataModel.setAjxpNodeProvider(provider); node.updateProvider(provider); this.setState({ dataModel: dataModel, node: node }); } else if (this.props.presetDataModel !== nextProps.presetDataModel) { this.setState({ dataModel: nextProps.presetDataModel, node: nextProps.presetDataModel.getRootNode() }); } }, getInitialState: function getInitialState() { var dataModel = undefined; if (this.props.presetDataModel) { dataModel = this.props.presetDataModel; } else { dataModel = PydioDataModel.RemoteDataModelFactory(this.props.nodeProviderProperties); } var rootNode = dataModel.getRootNode(); if (this.props.nodeClicked) { // leaf this.openEditor = (function (node) { this.props.nodeClicked(node); return false; }).bind(this); // dir dataModel.observe("selection_changed", (function (event) { var selectedNodes = event.memo.getSelectedNodes(); if (selectedNodes.length) { this.props.nodeClicked(selectedNodes[0]); event.memo.setSelectedNodes([]); } }).bind(this)); } if (this.props.reloadOnServerMessage && this.props.pydio) { this._smObs = (function (event) { if (XMLUtils.XPathSelectSingleNode(event, this.props.reloadOnServerMessage)) this.reload(); }).bind(this); this.props.pydio.observe("server_message", this._smObs); this.props.pydio.observe("server_message:" + this.props.reloadOnServerMessage, this.reload); } return { node: rootNode, dataModel: dataModel }; }, render: function render() { var legend; if (this.props.legend) { legend = React.createElement( "div", { className: "subtitle" }, this.props.legend ); } return React.createElement( "div", { className: this.props.heightAutoWithMax ? "" : "layout-fill vertical-layout" }, React.createElement(_SimpleList2["default"], _extends({}, this.props, { openEditor: this.openEditor, ref: "list", style: Object.assign({ height: '100%' }, this.props.style || {}), node: this.state.node, dataModel: this.state.dataModel, actionBarGroups: this.props.actionBarGroups, skipParentNavigation: true, observeNodeReload: true })) ); } }); module.exports = exports["default"]; },{"./SimpleList":19}],19:[function(require,module,exports){ (function (global){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _reactScrollbar = require('react-scrollbar'); var _reactScrollbar2 = _interopRequireDefault(_reactScrollbar); var _utilMessagesConsumerMixin = require('../util/MessagesConsumerMixin'); var _utilMessagesConsumerMixin2 = _interopRequireDefault(_utilMessagesConsumerMixin); var _ListEntry = require('./ListEntry'); var _TableListEntry = require('./TableListEntry'); var _TableListEntry2 = _interopRequireDefault(_TableListEntry); var _TableListHeader = require('./TableListHeader'); var _TableListHeader2 = _interopRequireDefault(_TableListHeader); var _ConfigurableListEntry = require('./ConfigurableListEntry'); var _ConfigurableListEntry2 = _interopRequireDefault(_ConfigurableListEntry); var _SortColumns = require('./SortColumns'); var _SortColumns2 = _interopRequireDefault(_SortColumns); var _ListPaginator = require('./ListPaginator'); var _ListPaginator2 = _interopRequireDefault(_ListPaginator); var _viewsSimpleReactActionBar = require('../views/SimpleReactActionBar'); var _viewsSimpleReactActionBar2 = _interopRequireDefault(_viewsSimpleReactActionBar); var _InlineEditor = require('./InlineEditor'); var _InlineEditor2 = _interopRequireDefault(_InlineEditor); var _viewsEmptyStateView = require('../views/EmptyStateView'); var _viewsEmptyStateView2 = _interopRequireDefault(_viewsEmptyStateView); var React = require('react'); var Infinite = require('react-infinite'); var DOMUtils = require('pydio/util/dom'); var LangUtils = require('pydio/util/lang'); var PydioDataModel = require('pydio/model/data-model'); var PeriodicalExecuter = require('pydio/util/periodical-executer'); /** * Generic List component, using Infinite for cell virtualization, pagination, various * displays, etc... It provides many hooks for rendering cells on-demand. */ var SimpleList = React.createClass({ displayName: 'SimpleList', mixins: [_utilMessagesConsumerMixin2['default']], propTypes: { infiniteSliceCount: React.PropTypes.number, filterNodes: React.PropTypes.func, customToolbar: React.PropTypes.object, tableKeys: React.PropTypes.object, autoRefresh: React.PropTypes.number, reloadAtCursor: React.PropTypes.bool, clearSelectionOnReload: React.PropTypes.bool, heightAutoWithMax: React.PropTypes.number, containerHeight: React.PropTypes.number, observeNodeReload: React.PropTypes.bool, defaultGroupBy: React.PropTypes.string, defaultGroupByLabel: React.PropTypes.string, defaultSortingInfo: React.PropTypes.object, skipParentNavigation: React.PropTypes.bool, skipInternalDataModel: React.PropTypes.bool, delayInitialLoad: React.PropTypes.number, entryEnableSelector: React.PropTypes.func, renderCustomEntry: React.PropTypes.func, entryRenderIcon: React.PropTypes.func, entryRenderActions: React.PropTypes.func, entryRenderFirstLine: React.PropTypes.func, entryRenderSecondLine: React.PropTypes.func, entryRenderThirdLine: React.PropTypes.func, entryHandleClicks: React.PropTypes.func, hideToolbar: React.PropTypes.bool, computeActionsForNode: React.PropTypes.bool, multipleActions: React.PropTypes.array, openEditor: React.PropTypes.func, openCollection: React.PropTypes.func, elementStyle: React.PropTypes.object, passScrollingStateToChildren: React.PropTypes.bool, elementHeight: React.PropTypes.oneOfType([React.PropTypes.number, React.PropTypes.object]).isRequired }, statics: { HEIGHT_ONE_LINE: 50, HEIGHT_TWO_LINES: 73, CLICK_TYPE_SIMPLE: 'simple', CLICK_TYPE_DOUBLE: 'double', PARENT_FOLDER_ICON: 'mdi mdi-chevron-left' }, getDefaultProps: function getDefaultProps() { return { infiniteSliceCount: 30, clearSelectionOnReload: true }; }, clickRow: function clickRow(gridRow, event) { var node = undefined; if (gridRow.props) { node = gridRow.props.data.node; } else { node = gridRow; } if (this.props.entryHandleClicks) { this.props.entryHandleClicks(node, SimpleList.CLICK_TYPE_SIMPLE, event); return; } if (node.isLeaf() && this.props.openEditor) { if (this.props.openEditor(node) === false) { return; } var uniqueSelection = new Map(); uniqueSelection.set(node, true); this.setState({ selection: uniqueSelection }, this.rebuildLoadedElements); } else if (!node.isLeaf()) { if (this.props.openCollection) { this.props.openCollection(node); } else { this.props.dataModel.setSelectedNodes([node]); } } }, doubleClickRow: function doubleClickRow(gridRow, event) { var node = undefined; if (gridRow.props) { node = gridRow.props.data.node; } else { node = gridRow; } if (this.props.entryHandleClicks) { this.props.entryHandleClicks(node, SimpleList.CLICK_TYPE_DOUBLE, event); } }, onColumnSort: function onColumnSort(column) { var stateSetCallback = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1]; var pagination = this.props.node.getMetadata().get('paginationData'); if (pagination && pagination.get('total') > 1 && pagination.get('remote_order')) { var dir = 'asc'; if (this.props.node.getMetadata().get('paginationData').get('currentOrderDir')) { dir = this.props.node.getMetadata().get('paginationData').get('currentOrderDir') === 'asc' ? 'desc' : 'asc'; } var orderData = new Map(); orderData.set('order_column', column['remoteSortAttribute'] ? column.remoteSortAttribute : column.name); orderData.set('order_direction', dir); this.props.node.getMetadata().set("remote_order", orderData); this.props.dataModel.requireContextChange(this.props.node, true); } else { var att = column['sortAttribute'] ? column['sortAttribute'] : column.name; var sortingInfo = undefined; var _state$sortingInfo = this.state.sortingInfo; var attribute = _state$sortingInfo.attribute; var direction = _state$sortingInfo.direction; if (attribute === att && direction) { if (direction === 'asc') { // Switch direction sortingInfo = { attribute: att, sortType: column.sortType, direction: 'desc' }; } else { // Reset sorting sortingInfo = this.props.defaultSortingInfo || {}; } } else { sortingInfo = { attribute: att, sortType: column.sortType, direction: 'asc' }; } this.setState({ sortingInfo: sortingInfo }, (function () { this.rebuildLoadedElements(); if (stateSetCallback) { stateSetCallback(); } }).bind(this)); } }, computeSelectionFromCurrentPlusTargetNode: function computeSelectionFromCurrentPlusTargetNode(currentSelection, targetNode) { var currentIndexStart = undefined, currentIndexEnd = undefined, nodeBefore = false; if (!this.indexedElements) { return []; } var firstSelected = currentSelection[0]; var lastSelected = currentSelection[currentSelection.length - 1]; var newSelection = []; for (var i = 0; i < this.indexedElements.length; i++) { if (currentIndexStart !== undefined) { newSelection.push(this.indexedElements[i].node); } if (this.indexedElements[i].node === targetNode) { if (currentIndexStart !== undefined && currentIndexEnd === undefined) { currentIndexEnd = i; break; } currentIndexStart = i; nodeBefore = true; newSelection.push(this.indexedElements[i].node); } if (this.indexedElements[i].node === firstSelected && currentIndexStart === undefined) { currentIndexStart = i; newSelection.push(this.indexedElements[i].node); } if (this.indexedElements[i].node === lastSelected && nodeBefore) { currentIndexEnd = i; break; } } return newSelection; }, onKeyDown: function onKeyDown(e) { var currentIndexStart = undefined, currentIndexEnd = undefined; var contextHolder = window.pydio.getContextHolder(); var elementsPerLine = this.props.elementsPerLine || 1; var shiftKey = e.shiftKey; var key = e.key; if (contextHolder.isEmpty() || !this.indexedElements) { return; } var downKeys = ['ArrowDown', 'ArrowRight', 'PageDown', 'End']; var position = shiftKey && downKeys.indexOf(key) > -1 ? 'first' : 'last'; var currentSelection = contextHolder.getSelectedNodes(); var firstSelected = currentSelection[0]; var lastSelected = currentSelection[currentSelection.length - 1]; if (key === 'Enter') { this.doubleClickRow(firstSelected); return; } if (key === 'Delete' && global.pydio.Controller.fireActionByKey('key_delete')) { return; } for (var i = 0; i < this.indexedElements.length; i++) { if (this.indexedElements[i].node === firstSelected) { currentIndexStart = i; } if (this.indexedElements[i].node === lastSelected) { currentIndexEnd = i; break; } } var selectionIndex = undefined; var maxIndex = this.indexedElements.length - 1; var increment = key === 'PageDown' || key === 'PageUp' ? 10 : 1; if (key === 'ArrowDown' || key === 'PageDown') { selectionIndex = Math.min(currentIndexEnd + elementsPerLine * increment, maxIndex); } else if (key === 'ArrowUp' || key === 'PageUp') { selectionIndex = Math.max(currentIndexStart - elementsPerLine * increment, 0); } else if (key === 'Home') { selectionIndex = 0; } else if (key === 'End') { selectionIndex = maxIndex; } if (elementsPerLine > 1) { if (key === 'ArrowRight') { selectionIndex = currentIndexEnd + 1; } else if (key === 'ArrowLeft') { selectionIndex = currentIndexStart - 1; } } if (shiftKey && selectionIndex !== undefined) { var min = Math.min(currentIndexStart, currentIndexEnd, selectionIndex); var max = Math.max(currentIndexStart, currentIndexEnd, selectionIndex); if (min !== max) { var selection = []; for (var i = min; i < max + 1; i++) { if (this.indexedElements[i]) selection.push(this.indexedElements[i].node); } contextHolder.setSelectedNodes(selection); } } else if (this.indexedElements[selectionIndex] && this.indexedElements[selectionIndex].node) { contextHolder.setSelectedNodes([this.indexedElements[selectionIndex].node]); } }, getInitialState: function getInitialState() { this.actionsCache = { multiple: new Map() }; if (!this.props.skipInternalDataModel) { this.dm = new PydioDataModel(); this.dm.setRootNode(this.props.dataModel.getContextNode()); this.dm.setContextNode(this.props.dataModel.getContextNode()); } else { this.dm = this.props.dataModel; } var sortingInfo = this.props.defaultSortingInfo || null; var state = { loaded: this.props.node.isLoaded(), loading: !this.props.node.isLoaded(), showSelector: false, elements: this.props.node.isLoaded() ? this.buildElements(sortingInfo, 0, this.props.infiniteSliceCount) : [], containerHeight: this.props.containerHeight ? this.props.containerHeight : this.props.heightAutoWithMax ? 0 : 500, sortingInfo: sortingInfo }; if (this.props.elementHeight instanceof Object) { state.elementHeight = this.computeElementHeightResponsive(); } state.infiniteLoadBeginBottomOffset = 200; return state; }, componentWillReceiveProps: function componentWillReceiveProps(nextProps) { var _this = this; this.indexedElements = null; var currentLength = Math.max(this.state.elements.length, nextProps.infiniteSliceCount); var sortingInfo = this.state.sortingInfo || nextProps.defaultSortingInfo || null; this.setState({ loaded: nextProps.node.isLoaded(), loading: !nextProps.node.isLoaded(), showSelector: false, elements: nextProps.node.isLoaded() ? this.buildElements(sortingInfo, 0, currentLength, nextProps.node) : [], infiniteLoadBeginBottomOffset: 200, sortingInfo: sortingInfo }, function () { if (nextProps.node.isLoaded()) _this.updateInfiniteContainerHeight(); }); if (!nextProps.autoRefresh && this.refreshInterval) { window.clearInterval(this.refreshInterval); this.refreshInterval = null; } else if (nextProps.autoRefresh && !this.refreshInterval) { this.refreshInterval = window.setInterval(this.reload, nextProps.autoRefresh); } this.patchInfiniteGrid(nextProps.elementsPerLine); if (this.props.node && nextProps.node !== this.props.node) { this.observeNodeChildren(this.props.node, true); } if (this._manualScrollPe) { this._manualScrollPe.stop(); this._manualScrollPe = null; } }, observeNodeChildren: function observeNodeChildren(node) { var stop = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; if (stop && !this._childrenObserver) return; if (!this._childrenObserver) { this._childrenObserver = (function () { this.indexedElements = null; this.rebuildLoadedElements(); }).bind(this); } if (!this._childrenActionsObserver) { this._childrenActionsObserver = (function (eventMemo) { if (eventMemo.type === 'prompt-rename') { this.setState({ inlineEditionForNode: eventMemo.child, inlineEditionCallback: eventMemo.callback }); } }).bind(this); } if (stop) { node.stopObserving("child_added", this._childrenObserver); node.stopObserving("child_removed", this._childrenObserver); node.stopObserving("child_node_action", this._childrenActionsObserver); } else { node.observe("child_added", this._childrenObserver); node.observe("child_removed", this._childrenObserver); node.observe("child_node_action", this._childrenActionsObserver); } }, _loadNodeIfNotLoaded: function _loadNodeIfNotLoaded() { var node = this.props.node; if (!node.isLoaded()) { node.observeOnce("loaded", (function () { if (!this.isMounted()) return; if (this.props.node === node) { this.observeNodeChildren(node); this.setState({ loaded: true, loading: false, elements: this.buildElements(this.state.sortingInfo, 0, this.props.infiniteSliceCount) }); } if (this.props.heightAutoWithMax) { this.updateInfiniteContainerHeight(); } }).bind(this)); node.load(); } else { this.observeNodeChildren(node); } }, _loadingListener: function _loadingListener() { this.observeNodeChildren(this.props.node, true); this.setState({ loaded: false, loading: true }); this.indexedElements = null; }, _loadedListener: function _loadedListener() { var currentLength = Math.max(this.state.elements.length, this.props.infiniteSliceCount); this.setState({ loading: false, elements: this.buildElements(this.state.sortingInfo, 0, currentLength, this.props.node) }); if (this.props.heightAutoWithMax) { this.updateInfiniteContainerHeight(); } this.observeNodeChildren(this.props.node); }, reload: function reload() { if (this.props.reloadAtCursor && this._currentCursor) { this.loadStartingAtCursor(); return; } if (this.props.clearSelectionOnReload) { this.props.dataModel.setSelectedNodes([]); } this._loadingListener(); this.props.node.observeOnce("loaded", this._loadedListener); this.props.node.reload(); }, loadStartingAtCursor: function loadStartingAtCursor() { this._loadingListener(); var node = this.props.node; var cachedChildren = node.getChildren(); var newChildren = []; node.observeOnce("loaded", (function () { var reorderedChildren = new Map(); newChildren.map(function (c) { reorderedChildren.set(c.getPath(), c); }); cachedChildren.forEach(function (c) { reorderedChildren.set(c.getPath(), c); }); node._children = reorderedChildren; this._loadedListener(); }).bind(this)); node.setLoaded(false); node.observe("child_added", function (newChild) { newChildren.push(node._children.get(newChild)); }); this.props.node.load(null, { cursor: this._currentCursor }); }, wireReloadListeners: function wireReloadListeners() { this.wrappedLoading = this._loadingListener; this.wrappedLoaded = this._loadedListener; this.props.node.observe("loading", this.wrappedLoading); this.props.node.observe("loaded", this.wrappedLoaded); }, stopReloadListeners: function stopReloadListeners() { this.props.node.stopObserving("loading", this.wrappedLoading); this.props.node.stopObserving("loaded", this.wrappedLoaded); }, toggleSelector: function toggleSelector() { // Force rebuild elements this.setState({ showSelector: !this.state.showSelector, selection: new Map() }, this.rebuildLoadedElements); }, toggleSelection: function toggleSelection(node) { var selection = this.state.selection || new Map(); if (selection.get(node)) selection['delete'](node);else selection.set(node, true); if (this.refs.all_selector) this.refs.all_selector.setChecked(false); this.setState({ selection: selection }, this.rebuildLoadedElements); }, selectAll: function selectAll() { var _this2 = this; if (this.refs.all_selector && !this.refs.all_selector.isChecked()) { this.setState({ selection: new Map() }, this.rebuildLoadedElements); } else { (function () { var selection = new Map(); _this2.props.node.getChildren().forEach((function (child) { if (this.props.filterNodes && !this.props.filterNodes(child)) { return; } if (child.isLeaf()) { selection.set(child, true); } }).bind(_this2)); if (_this2.refs.all_selector) _this2.refs.all_selector.setChecked(true); _this2.setState({ selection: selection }, _this2.rebuildLoadedElements); })(); } }, applyMultipleAction: function applyMultipleAction(ev) { if (!this.state.selection || !this.state.selection.size) { return; } var actionName = ev.currentTarget.getAttribute('data-action'); var dm = this.dm || new PydioDataModel(); dm.setContextNode(this.props.node); var selNodes = []; this.state.selection.forEach(function (v, node) { selNodes.push(node); }); dm.setSelectedNodes(selNodes); var a = this.props.pydio.Controller.getActionByName(actionName); a.fireContextChange(dm, true, this.props.pydio.user); a.apply([dm]); ev.stopPropagation(); ev.preventDefault(); }, getActionsForNode: function getActionsForNode(dm, node) { if (!this.props.computeActionsForNode) { return []; } var cacheKey = node.isLeaf() ? 'file-' + node.getAjxpMime() : 'folder'; var selectionType = node.isLeaf() ? 'file' : 'dir'; var nodeActions = []; if (this.actionsCache[cacheKey]) { nodeActions = this.actionsCache[cacheKey]; } else { dm.setSelectedNodes([node]); window.pydio.Controller.actions.forEach((function (a) { a.fireContextChange(dm, true, window.pydio.user); if (a.context.selection && a.context.actionBar && a.selectionContext[selectionType] && !a.deny && a.options.icon_class && (!this.props.actionBarGroups || this.props.actionBarGroups.indexOf(a.context.actionBarGroup) !== -1) && (!a.selectionContext.allowedMimes.length || a.selectionContext.allowedMimes.indexOf(node.getAjxpMime()) !== -1)) { nodeActions.push(a); if (node.isLeaf() && a.selectionContext.unique === false) { this.actionsCache.multiple.set(a.options.name, a); } } }).bind(this)); this.actionsCache[cacheKey] = nodeActions; } return nodeActions; }, updateInfiniteContainerHeight: function updateInfiniteContainerHeight() { var retries = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0]; if (this.props.containerHeight) { return this.props.containerHeight; } if (!this.refs.infiniteParent) { return; } var containerHeight = this.refs.infiniteParent.clientHeight; if (this.props.heightAutoWithMax) { var number = this.indexedElements ? this.indexedElements.length : this.props.node.getChildren().size; var elementHeight = this.state.elementHeight ? this.state.elementHeight : this.props.elementHeight; containerHeight = Math.min(number * elementHeight, this.props.heightAutoWithMax); } if (!containerHeight && !retries) { global.setTimeout((function () { this.updateInfiniteContainerHeight(true); }).bind(this), 50); } this.setState({ containerHeight: containerHeight }); }, computeElementHeightResponsive: function computeElementHeightResponsive() { var breaks = this.props.elementHeight; if (!(breaks instanceof Object)) { breaks = { "min-width:480px": this.props.elementHeight, "max-width:480px": Object.keys(this.props.tableKeys).length * 24 + 33 }; } if (window.matchMedia) { for (var k in breaks) { if (breaks.hasOwnProperty(k) && window.matchMedia('(' + k + ')').matches) { return breaks[k]; } } } else { var width = DOMUtils.getViewportWidth(); if (width < 480) return breaks["max-width:480px"];else return breaks["max-width:480px"]; } return 50; }, updateElementHeightResponsive: function updateElementHeightResponsive() { var newH = this.computeElementHeightResponsive(); if (!this.state || !this.state.elementHeight || this.state.elementHeight != newH) { this.setState({ elementHeight: newH }, (function () { if (this.props.heightAutoWithMax) { this.updateInfiniteContainerHeight(); } }).bind(this)); } }, patchInfiniteGrid: function patchInfiniteGrid(els) { if (this.refs.infinite && els > 1) { this.refs.infinite.state.infiniteComputer.__proto__.getDisplayIndexStart = function (windowTop) { return els * Math.floor(windowTop / this.heightData / els); }; this.refs.infinite.state.infiniteComputer.__proto__.getDisplayIndexEnd = function (windowBottom) { return els * Math.ceil(windowBottom / this.heightData / els); }; } }, componentDidMount: function componentDidMount() { var _this3 = this; if (this.props.delayInitialLoad) { setTimeout(function () { _this3._loadNodeIfNotLoaded(); }, this.props.delayInitialLoad); } else { this._loadNodeIfNotLoaded(); } this.patchInfiniteGrid(this.props.elementsPerLine); if (this.refs.infiniteParent) { this.updateInfiniteContainerHeight(); if (!this.props.heightAutoWithMax && !this.props.externalResize) { if (window.addEventListener) { window.addEventListener('resize', this.updateInfiniteContainerHeight); } else { window.attachEvent('onresize', this.updateInfiniteContainerHeight); } } } if (this.props.autoRefresh) { this.refreshInterval = window.setInterval(this.reload, this.props.autoRefresh); } if (this.props.observeNodeReload) { this.wireReloadListeners(); } if (this.props.elementHeight instanceof Object || this.props.tableKeys) { if (window.addEventListener) { window.addEventListener('resize', this.updateElementHeightResponsive); } else { window.attachEvent('onresize', this.updateElementHeightResponsive); } this.updateElementHeightResponsive(); } this.props.dataModel.observe('selection_changed', (function () { var _this4 = this; if (!this.isMounted()) return; var selection = new Map(); var selectedNodes = this.props.dataModel.getSelectedNodes(); selectedNodes.map(function (n) { selection.set(n, true); }); this.setState({ selection: selection }, function () { _this4.rebuildLoadedElements(); if (selectedNodes.length === 1) { _this4.scrollToView(selectedNodes[0]); } }); }).bind(this)); }, componentWillUnmount: function componentWillUnmount() { if (!this.props.heightAutoWithMax) { if (window.removeEventListener) { window.removeEventListener('resize', this.updateInfiniteContainerHeight); } else { window.detachEvent('onresize', this.updateInfiniteContainerHeight); } } if (this.props.elementHeight instanceof Object || this.props.tableKeys) { if (window.removeEventListener) { window.removeEventListener('resize', this.updateElementHeightResponsive); } else { window.detachEvent('resize', this.updateElementHeightResponsive); } } if (this.refreshInterval) { window.clearInterval(this.refreshInterval); } if (this.props.observeNodeReload) { this.stopReloadListeners(); } if (this.props.node) { this.observeNodeChildren(this.props.node, true); } }, componentDidUpdate: function componentDidUpdate(prevProps, prevState) { if (prevProps.node && this.props.node && prevProps.node.getPath() === this.props.node.getPath()) { return; } this._loadNodeIfNotLoaded(); }, onScroll: function onScroll(scrollTop) { if (!this.props.passScrollingStateToChildren) { return; } // Maintains a series of timeouts to set this.state.isScrolling // to be true when the element is scrolling. if (this.state.scrollTimeout) { clearTimeout(this.state.scrollTimeout); } var that = this, scrollTimeout = setTimeout(function () { that.setState({ isScrolling: false, scrollTimeout: undefined }); }, 150); this.setState({ isScrolling: true, scrollTimeout: scrollTimeout }); }, scrollToLast: function scrollToLast() { if (this.indexedElements && this.indexedElements[this.indexedElements.length - 1].node) { this.scrollToView(this.indexedElements[this.indexedElements.length - 1].node); } }, scrollToView: function scrollToView(node) { var _this5 = this; if (!this.indexedElements || !this.refs.infinite || !this.refs.infinite.scrollable) return; var scrollable = this.refs.infinite.scrollable; var visibleFrame = { top: scrollable.scrollTop + this.props.elementHeight / 2, bottom: scrollable.scrollTop + this.state.containerHeight - this.props.elementHeight / 2 }; var realMaxScrollTop = this.indexedElements.length * this.props.elementHeight - this.state.containerHeight; var position = -1; this.indexedElements.forEach(function (e, k) { if (e.node && e.node === node) position = k; }); if (position === -1) return; var elementHeight = this.props.elementHeight; var scrollTarget = position * elementHeight; if (scrollTarget > visibleFrame.top && scrollTarget < visibleFrame.bottom) { // already visible; return; } else if (scrollTarget >= visibleFrame.bottom) { scrollTarget -= this.state.containerHeight - elementHeight * 2; } scrollTarget = Math.min(scrollTarget, realMaxScrollTop); scrollable.scrollTop = scrollTarget; if (this._manualScrollPe) this._manualScrollPe.stop(); if (scrollable.scrollHeight < scrollTarget) { this._manualScrollPe = new PeriodicalExecuter(function () { scrollable.scrollTop = scrollTarget; if (scrollable.scrollHeight >= scrollTarget) { _this5._manualScrollPe.stop(); _this5._manualScrollPe = null; } }, .25); } }, buildElementsFromNodeEntries: function buildElementsFromNodeEntries(nodeEntries, showSelector) { var components = [], index = 0; var nodeEntriesLength = nodeEntries.length; nodeEntries.forEach((function (entry) { var data = undefined; if (entry.parent) { data = { node: entry.node, key: entry.node.getPath(), id: entry.node.getPath(), mainIcon: SimpleList.PARENT_FOLDER_ICON, firstLine: "..", className: "list-parent-node", secondLine: this.context.getMessage('react.1'), onClick: this.clickRow, onDoubleClick: this.doubleClickRow, showSelector: false, selectorDisabled: true, noHover: false }; if (this.props.entryRenderParentIcon && !this.props.tableKeys) { data['iconCell'] = this.props.entryRenderParentIcon(entry.node, entry); } else { data['mainIcon'] = SimpleList.PARENT_FOLDER_ICON; } if (this.props.elementStyle) { data['style'] = this.props.elementStyle; } if (this.props.passScrollingStateToChildren) { data['parentIsScrolling'] = this.state.isScrolling; } components.push(React.createElement(_ListEntry.ListEntry, data)); } else if (entry.groupHeader) { var id = entry.groupHeader, firstLine = entry.groupHeaderLabel; if (this.props.entryRenderGroupHeader) { firstLine = this.props.entryRenderGroupHeader(id, firstLine); } data = { node: null, key: entry.groupHeader, id: id, mainIcon: null, firstLine: firstLine, className: 'list-group-header', onClick: null, showSelector: false, selectorDisabled: true, noHover: true }; if (this.props.passScrollingStateToChildren) { data['parentIsScrolling'] = this.state.isScrolling; } components.push(React.createElement(_ListEntry.ListEntry, data)); } else { data = { node: entry.node, onClick: this.clickRow, onDoubleClick: this.doubleClickRow, onSelect: this.toggleSelection, key: entry.node.getPath(), id: entry.node.getPath(), renderIcon: this.props.entryRenderIcon, renderFirstLine: this.props.entryRenderFirstLine, renderSecondLine: this.props.entryRenderSecondLine, renderThirdLine: this.props.entryRenderThirdLine, renderActions: this.props.entryRenderActions, showSelector: showSelector, selected: this.state && this.state.selection ? this.state.selection.get(entry.node) : false, actions: React.createElement(_viewsSimpleReactActionBar2['default'], { node: entry.node, actions: entry.actions, dataModel: this.dm }), selectorDisabled: !(this.props.entryEnableSelector ? this.props.entryEnableSelector(entry.node) : entry.node.isLeaf()) }; data['isFirst'] = index === 0; data['isLast'] = index === nodeEntriesLength - 1; index++; if (this.props.elementStyle) { data['style'] = this.props.elementStyle; } if (this.props.passScrollingStateToChildren) { data['parentIsScrolling'] = this.state.isScrolling; } if (this.props.renderCustomEntry) { components.push(this.props.renderCustomEntry(data)); } else if (this.props.tableKeys) { if (this.props.defaultGroupBy) { data['tableKeys'] = LangUtils.deepCopy(this.props.tableKeys); delete data['tableKeys'][this.props.defaultGroupBy]; } else { data['tableKeys'] = this.props.tableKeys; } components.push(React.createElement(_TableListEntry2['default'], data)); } else { components.push(React.createElement(_ConfigurableListEntry2['default'], data)); } } }).bind(this)); return components; }, buildElements: function buildElements(sortingInfo, start, end, node, showSelector) { var _this6 = this; var theNode = this.props.node; if (node) theNode = node; var theShowSelector = this.state && this.state.showSelector; if (showSelector !== undefined) theShowSelector = showSelector; if (!this.indexedElements || this.indexedElements.length !== theNode.getChildren().size) { (function () { _this6.indexedElements = []; var groupBy = undefined, groupByLabel = undefined, groups = undefined, groupKeys = undefined, groupLabels = undefined; if (_this6.props.defaultGroupBy) { groupBy = _this6.props.defaultGroupBy; groupByLabel = _this6.props.groupByLabel || false; groups = {}, groupKeys = [], groupLabels = {}; } if (!_this6.props.skipParentNavigation && theNode.getParent() && (_this6.props.dataModel.getContextNode() !== theNode || _this6.props.skipInternalDataModel)) { _this6.indexedElements.push({ node: theNode.getParent(), parent: true, actions: null }); } theNode.getChildren().forEach((function (child) { if (child.getMetadata().has('cursor')) { var childCursor = parseInt(child.getMetadata().get('cursor')); this._currentCursor = Math.max(this._currentCursor ? this._currentCursor : 0, childCursor); } if (this.props.filterNodes && !this.props.filterNodes(child)) { return; } var nodeActions = this.getActionsForNode(this.dm, child); if (groupBy) { var groupValue = child.getMetadata().get(groupBy) || 'N/A'; if (!groups[groupValue]) { groups[groupValue] = []; groupKeys.push(groupValue); } if (groupByLabel && child.getMetadata().has(groupByLabel) && !groupLabels[groupValue]) { groupLabels[groupValue] = child.getMetadata().get(groupByLabel); } groups[groupValue].push({ node: child, parent: false, actions: nodeActions }); } else { this.indexedElements.push({ node: child, parent: false, actions: nodeActions }); } }).bind(_this6)); if (groupBy) { groupKeys = groupKeys.sort(); groupKeys.map((function (k) { var label = k; if (groupLabels[k]) { label = groupLabels[k]; } else if (this.props.renderGroupLabels) { label = this.props.renderGroupLabels(groupBy, k); } this.indexedElements.push({ node: null, groupHeader: k, groupHeaderLabel: label, parent: false, actions: null }); this.indexedElements = this.indexedElements.concat(groups[k]); }).bind(_this6)); } })(); } if (sortingInfo && !this.remoteSortingInfo()) { (function () { var attribute = sortingInfo.attribute; var direction = sortingInfo.direction; var sortType = sortingInfo.sortType; var sortFunction = undefined; if (sortType === 'file-natural') { sortFunction = function (a, b) { if (a.parent) { return -1; } if (b.parent) { return 1; } var nodeA = a.node; var nodeB = b.node; // Recycle always last if (nodeA.isRecycle()) return 1; if (nodeB.isRecycle()) return -1; // Folders first var aLeaf = nodeA.isLeaf(); var bLeaf = nodeB.isLeaf(); var res = aLeaf && !bLeaf ? 1 : !aLeaf && bLeaf ? -1 : 0; if (res !== 0) return res; res = nodeA.getLabel().localeCompare(nodeB.getLabel()); return res; }; } else { sortFunction = function (a, b) { if (a.parent) { return -1; } var aMeta = a.node.getMetadata().get(attribute) || ""; var bMeta = b.node.getMetadata().get(attribute) || ""; var res = undefined; if (sortType === 'number') { aMeta = parseFloat(aMeta); bMeta = parseFloat(bMeta); res = direction === 'asc' ? aMeta - bMeta : bMeta - aMeta; } else if (sortType === 'string') { res = direction === 'asc' ? aMeta.localeCompare(bMeta) : bMeta.localeCompare(aMeta); } if (res === 0) { // Resort by label to make it stable var labComp = a.node.getLabel().localeCompare(b.node.getLabel()); res = direction === 'asc' ? labComp : -labComp; } return res; }; } _this6.indexedElements.sort(sortFunction); })(); } if (this.props.elementPerLine > 1) { end = end * this.props.elementPerLine; start = start * this.props.elementPerLine; } return this.indexedElements.slice(start, end); }, rebuildLoadedElements: function rebuildLoadedElements() { var newElements = this.buildElements(this.state.sortingInfo, 0, Math.max(this.state.elements.length, this.props.infiniteSliceCount)); var infiniteLoadBeginBottomOffset = newElements.length ? 200 : 0; this.setState({ elements: newElements, infiniteLoadBeginBottomOffset: infiniteLoadBeginBottomOffset }); this.updateInfiniteContainerHeight(); }, handleInfiniteLoad: function handleInfiniteLoad() { var elemLength = this.state.elements.length; var newElements = this.buildElements(this.state.sortingInfo, elemLength, elemLength + this.props.infiniteSliceCount); var infiniteLoadBeginBottomOffset = newElements.length ? 200 : 0; this.setState({ isInfiniteLoading: false, elements: this.state.elements.concat(newElements), infiniteLoadBeginBottomOffset: infiniteLoadBeginBottomOffset }); }, /** * Extract remote sorting info from current node metadata */ remoteSortingInfo: function remoteSortingInfo() { var meta = this.props.node.getMetadata().get('paginationData'); if (meta && meta.get('total') > 1 && meta.has('remote_order')) { var col = meta.get('currentOrderCol'); var dir = meta.get('currentOrderDir'); if (col && dir) { return { remote: true, attribute: col, direction: dir }; } } return null; }, renderToolbar: function renderToolbar() { var _this7 = this; var rightButtons = [React.createElement(ReactMUI.FontIcon, { key: 1, tooltip: 'Reload', className: "icon-refresh" + (this.state.loading ? " rotating" : ""), onClick: this.reload })]; var i = 2; if (this.props.sortKeys) { var sortingInfo = undefined, remoteSortingInfo = this.remoteSortingInfo(); if (remoteSortingInfo) { sortingInfo = remoteSortingInfo; } else { sortingInfo = this.state ? this.state.sortingInfo : null; } rightButtons.push(React.createElement(_SortColumns2['default'], { key: i, displayMode: 'menu', tableKeys: this.props.sortKeys, columnClicked: this.onColumnSort, sortingInfo: sortingInfo })); i++; } if (this.props.additionalActions) { rightButtons.push(this.props.additionalActions); } var leftToolbar = undefined, paginator = undefined; if (this.props.node.getMetadata().get("paginationData") && this.props.node.getMetadata().get("paginationData").get('total') > 1) { paginator = React.createElement(_ListPaginator2['default'], { dataModel: this.dm, node: this.props.node }); } if (this.props.listTitle) { leftToolbar = React.createElement( ReactMUI.ToolbarGroup, { key: 0, float: 'left' }, React.createElement( 'div', { className: 'list-title' }, this.props.listTitle ) ); } if (this.props.searchResultData) { leftToolbar = React.createElement( ReactMUI.ToolbarGroup, { key: 0, float: 'left' }, React.createElement( 'h2', { className: 'search-results-title' }, this.context.getMessage('react.3').replace('%s', this.props.searchResultData.term) ) ); rightButtons = React.createElement(ReactMUI.RaisedButton, { key: 1, label: this.context.getMessage('react.4'), primary: true, onClick: this.props.searchResultData.toggleState }); } else if (this.actionsCache.multiple.size || this.props.multipleActions) { var bulkLabel = this.context.getMessage('react.2'); if (this.state.selection && this.state.showSelector) { bulkLabel += " (" + this.state.selection.size + ")"; } leftToolbar = React.createElement( ReactMUI.ToolbarGroup, { key: 0, float: 'left', className: 'hide-on-vertical-layout' }, React.createElement(ReactMUI.Checkbox, { ref: 'all_selector', onClick: this.selectAll }), React.createElement(ReactMUI.FlatButton, { label: bulkLabel, onClick: this.toggleSelector }) ); if (this.state.showSelector) { (function () { rightButtons = []; var index = 0; var actions = _this7.props.multipleActions || _this7.actionsCache.multiple; actions.forEach((function (a) { rightButtons.push(React.createElement(ReactMUI.RaisedButton, { key: index, label: a.options.text, 'data-action': a.options.name, onClick: this.applyMultipleAction, primary: true })); }).bind(_this7)); rightButtons = React.createElement( 'span', null, rightButtons ); })(); } } return React.createElement( ReactMUI.Toolbar, null, leftToolbar, React.createElement( ReactMUI.ToolbarGroup, { key: 1, float: 'right' }, paginator, rightButtons ) ); }, render: function render() { var _this8 = this; var containerClasses = "material-list vertical-layout layout-fill"; if (this.props.className) { containerClasses += " " + this.props.className; } if (this.state.showSelector) { containerClasses += " list-show-selectors"; } if (this.props.tableKeys) { containerClasses += " table-mode"; } var toolbar = undefined; if (this.props.tableKeys) { var tableKeys = undefined; if (this.props.defaultGroupBy) { tableKeys = LangUtils.deepCopy(this.props.tableKeys); delete tableKeys[this.props.defaultGroupBy]; } else { tableKeys = this.props.tableKeys; } var sortingInfo = undefined, remoteSortingInfo = this.remoteSortingInfo(); if (remoteSortingInfo) { sortingInfo = remoteSortingInfo; } else { sortingInfo = this.state ? this.state.sortingInfo : null; } toolbar = React.createElement(_TableListHeader2['default'], { tableKeys: tableKeys, loading: this.state.loading, reload: this.reload, ref: 'loading_indicator', dm: this.props.dataModel, node: this.props.node, additionalActions: this.props.additionalActions, onHeaderClick: this.onColumnSort, sortingInfo: sortingInfo }); } else { toolbar = this.props.customToolbar ? this.props.customToolbar : !this.props.hideToolbar ? this.renderToolbar() : null; } var inlineEditor = undefined; if (this.state.inlineEditionForNode) { inlineEditor = React.createElement(_InlineEditor2['default'], { detached: true, node: this.state.inlineEditionForNode, callback: this.state.inlineEditionCallback, onClose: function () { _this8.setState({ inlineEditionForNode: null }); } }); } var emptyState = undefined; var _props = this.props; var emptyStateProps = _props.emptyStateProps; var node = _props.node; if (emptyStateProps && this.props.node.isLoaded() && !this.props.node.isLoading() && (!this.state.elements.length || this.state.elements.length === 1 && this.state.elements[0].parent)) { var actionProps = {}; if (this.state.elements.length === 1 && this.state.elements[0].parent) { (function () { var parentNode = _this8.state.elements[0].node; actionProps = { actionLabelId: 'react.1', actionIconClassName: SimpleList.PARENT_FOLDER_ICON, actionCallback: function actionCallback(e) { if (_this8.props.entryHandleClicks) { _this8.props.entryHandleClicks(parentNode, SimpleList.CLICK_TYPE_DOUBLE, e); } } }; })(); } emptyState = React.createElement(_viewsEmptyStateView2['default'], _extends({}, emptyStateProps, actionProps)); } else if (emptyStateProps && emptyStateProps.checkEmptyState && emptyStateProps.checkEmptyState(this.props.node)) { emptyState = React.createElement(_viewsEmptyStateView2['default'], emptyStateProps); } var elements = this.buildElementsFromNodeEntries(this.state.elements, this.state.showSelector); return React.createElement( 'div', { className: containerClasses, onContextMenu: this.contextMenuResponder, tabIndex: '0', onKeyDown: this.onKeyDown, style: this.props.style }, toolbar, inlineEditor, React.createElement( 'div', { className: this.props.heightAutoWithMax ? "infinite-parent-smooth-height" : emptyState ? "layout-fill vertical_layout" : "layout-fill", ref: 'infiniteParent' }, !emptyState && !this.props.verticalScroller && React.createElement( Infinite, { elementHeight: this.state.elementHeight ? this.state.elementHeight : this.props.elementHeight, containerHeight: this.state.containerHeight ? this.state.containerHeight : 1, infiniteLoadBeginEdgeOffset: this.state.infiniteLoadBeginBottomOffset, onInfiniteLoad: this.handleInfiniteLoad, handleScroll: this.onScroll, ref: 'infinite' }, elements ), !emptyState && this.props.verticalScroller && React.createElement( _reactScrollbar2['default'], { speed: 0.8, horizontalScroll: false, style: { height: this.state.containerHeight }, verticalScrollbarStyle: { borderRadius: 10, width: 6 }, verticalContainerStyle: { width: 8 } }, React.createElement( 'div', null, elements ) ), emptyState ) ); } }); exports['default'] = SimpleList; module.exports = exports['default']; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../util/MessagesConsumerMixin":48,"../views/EmptyStateView":49,"../views/SimpleReactActionBar":52,"./ConfigurableListEntry":13,"./InlineEditor":14,"./ListEntry":15,"./ListPaginator":17,"./SortColumns":20,"./TableListEntry":22,"./TableListHeader":23,"pydio/model/data-model":"pydio/model/data-model","pydio/util/dom":"pydio/util/dom","pydio/util/lang":"pydio/util/lang","pydio/util/periodical-executer":"pydio/util/periodical-executer","react":"react","react-infinite":"react-infinite","react-scrollbar":1}],20:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _menuIconButtonMenu = require('../menu/IconButtonMenu'); var _menuIconButtonMenu2 = _interopRequireDefault(_menuIconButtonMenu); var React = require('react'); var Pydio = require('pydio'); var _Pydio$requireLib = Pydio.requireLib('boot'); var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer; var _require = require('material-ui-legacy'); var ToolbarGroup = _require.ToolbarGroup; var SortColumns = React.createClass({ displayName: 'SortColumns', propTypes: { tableKeys: React.PropTypes.object.isRequired, columnClicked: React.PropTypes.func, sortingInfo: React.PropTypes.object, displayMode: React.PropTypes.string }, onMenuClicked: function onMenuClicked(object) { this.props.columnClicked(object.payload); }, onHeaderClick: function onHeaderClick(key, callback) { var data = this.props.tableKeys[key]; if (data && data['sortType'] && this.props.columnClicked) { data['name'] = key; this.props.columnClicked(data, callback); } }, getColumnsItems: function getColumnsItems(displayMode) { var _this = this; var controller = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1]; var items = []; var _callback = function _callback() { if (controller) { controller.notify('actions_refreshed'); } }; var _loop = function (key) { if (!_this.props.tableKeys.hasOwnProperty(key)) return 'continue'; var data = _this.props.tableKeys[key]; var style = data['width'] ? { width: data['width'] } : null; var icon = undefined; var className = 'cell header_cell cell-' + key; if (data['sortType']) { className += ' sortable'; if (_this.props.sortingInfo && (_this.props.sortingInfo.attribute === key || _this.props.sortingInfo.attribute === data['sortAttribute'] || _this.props.sortingInfo.attribute === data['remoteSortAttribute'])) { icon = _this.props.sortingInfo.direction === 'asc' ? 'mdi mdi-arrow-up' : 'mdi mdi-arrow-down'; className += ' active-sort-' + _this.props.sortingInfo.direction; } } if (displayMode === 'menu') { data['name'] = key; items.push({ payload: data, text: data['label'], iconClassName: icon }); } else if (displayMode === 'menu_data') { items.push({ name: data['label'], callback: function callback() { _this.onHeaderClick(key, _callback); }, icon_class: icon || '__INSET__' }); } else { items.push(React.createElement( 'span', { key: key, className: className, style: style, onClick: function () { _this.onHeaderClick(key, _callback); } }, data['label'] )); } }; for (var key in this.props.tableKeys) { var _ret = _loop(key); if (_ret === 'continue') continue; } return items; }, buildSortingMenuItems: function buildSortingMenuItems(controller) { return this.getColumnsItems('menu_data', controller); }, componentDidMount: function componentDidMount() { var sortAction = new Action({ name: 'sort_action', icon_class: 'mdi mdi-sort-descending', text_id: 450, title_id: 450, text: this.props.getMessage(450), title: this.props.getMessage(450), hasAccessKey: false, subMenu: true, subMenuUpdateImage: true }, { selection: false, dir: true, actionBar: true, actionBarGroup: 'display_toolbar', contextMenu: false, infoPanel: false }, {}, {}, { dynamicBuilder: this.buildSortingMenuItems }); var buttons = new Map(); buttons.set('sort_action', sortAction); this.props.pydio.getController().updateGuiActions(buttons); }, componentWillUnmount: function componentWillUnmount() { this.props.pydio.getController().deleteFromGuiActions('sort_action'); }, render: function render() { if (this.props.displayMode === 'menu') { return React.createElement(_menuIconButtonMenu2['default'], { buttonTitle: 'Sort by...', buttonClassName: 'mdi mdi-sort-descending', menuItems: this.getColumnsItems('menu', this.props.pydio.getController()), onMenuClicked: this.onMenuClicked }); } else { return React.createElement( ToolbarGroup, { float: 'left' }, this.getColumnsItems('header', this.props.pydio.getController()) ); } } }); exports['default'] = SortColumns = PydioContextConsumer(SortColumns); exports['default'] = SortColumns; module.exports = exports['default']; },{"../menu/IconButtonMenu":26,"material-ui-legacy":"material-ui-legacy","pydio":"pydio","react":"react"}],21:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ "use strict"; exports.__esModule = true; var _utilDND = require('../util/DND'); /***************************/ /* REACT DND SORTABLE LIST /**************************/ /** * Specifies the drag source contract. * Only `beginDrag` function is required. */ var sortableItemSource = { beginDrag: function beginDrag(props) { // Return the data describing the dragged item return { id: props.id }; }, endDrag: function endDrag(props) { props.endSwitching(); } }; var sortableItemTarget = { hover: function hover(props, monitor) { var draggedId = monitor.getItem().id; if (draggedId !== props.id) { props.switchItems(draggedId, props.id); } } }; var sortableItem = React.createClass({ displayName: "sortableItem", propTypes: { connectDragSource: React.PropTypes.func.isRequired, connectDropTarget: React.PropTypes.func.isRequired, isDragging: React.PropTypes.bool.isRequired, id: React.PropTypes.any.isRequired, label: React.PropTypes.string.isRequired, switchItems: React.PropTypes.func.isRequired, removable: React.PropTypes.bool, onRemove: React.PropTypes.func }, removeClicked: function removeClicked() { this.props.onRemove(this.props.id); }, render: function render() { // Your component receives its own props as usual var id = this.props.id; // These two props are injected by React DnD, // as defined by your `collect` function above: var isDragging = this.props.isDragging; var connectDragSource = this.props.connectDragSource; var connectDropTarget = this.props.connectDropTarget; var remove; if (this.props.removable) { remove = React.createElement("span", { className: "button mdi mdi-close", onClick: this.removeClicked }); } return React.createElement( ReactMUI.Paper, { ref: function (instance) { connectDropTarget(ReactDOM.findDOMNode(instance)); connectDragSource(ReactDOM.findDOMNode(instance)); }, zDepth: 1, style: { opacity: isDragging ? 0 : 1 } }, React.createElement( "div", { className: this.props.className }, this.props.label, remove ) ); } }); var NonDraggableListItem = React.createClass({ displayName: "NonDraggableListItem", render: function render() { var remove; if (this.props.removable) { remove = React.createElement("span", { className: "button mdi mdi-close", onClick: this.removeClicked }); } return React.createElement( ReactMUI.Paper, { zDepth: 1 }, React.createElement( "div", { className: this.props.className }, this.props.label, remove ) ); } }); var DraggableListItem; if (window.ReactDND) { DraggableListItem = ReactDND.flow(ReactDND.DragSource(_utilDND.Types.SORTABLE_LIST_ITEM, sortableItemSource, _utilDND.collect), ReactDND.DropTarget(_utilDND.Types.SORTABLE_LIST_ITEM, sortableItemTarget, _utilDND.collectDrop))(sortableItem); } else { DraggableListItem = NonDraggableListItem; } var SortableList = React.createClass({ displayName: "SortableList", propTypes: { values: React.PropTypes.array.isRequired, onOrderUpdated: React.PropTypes.func, removable: React.PropTypes.bool, onRemove: React.PropTypes.func, className: React.PropTypes.string, itemClassName: React.PropTypes.string }, getInitialState: function getInitialState() { return { values: this.props.values }; }, componentWillReceiveProps: function componentWillReceiveProps(props) { this.setState({ values: props.values, switchData: null }); }, findItemIndex: function findItemIndex(itemId, data) { for (var i = 0; i < data.length; i++) { if (data[i]['payload'] == itemId) { return i; } } }, switchItems: function switchItems(oldId, newId) { var oldIndex = this.findItemIndex(oldId, this.state.values); var oldItem = this.state.values[oldIndex]; var newIndex = this.findItemIndex(newId, this.state.values); var newItem = this.state.values[newIndex]; var currentValues = this.state.values.slice(); currentValues[oldIndex] = newItem; currentValues[newIndex] = oldItem; // Check that it did not come back to original state var oldPrevious = this.findItemIndex(oldId, this.props.values); var newPrevious = this.findItemIndex(newId, this.props.values); if (oldPrevious == newIndex && newPrevious == oldIndex) { this.setState({ values: currentValues, switchData: null }); //console.log("no more moves"); } else { this.setState({ values: currentValues, switchData: { oldId: oldId, newId: newId } }); //console.log({oldId:oldIndex, newId:newIndex}); } }, endSwitching: function endSwitching() { if (this.state.switchData) { // Check that it did not come back to original state if (this.props.onOrderUpdated) { this.props.onOrderUpdated(this.state.switchData.oldId, this.state.switchData.newId, this.state.values); } } this.setState({ switchData: null }); }, render: function render() { var switchItems = this.switchItems; return React.createElement( "div", { className: this.props.className }, this.state.values.map((function (item) { return React.createElement(DraggableListItem, { id: item.payload, key: item.payload, label: item.text, switchItems: switchItems, endSwitching: this.endSwitching, removable: this.props.removable, onRemove: this.props.onRemove, className: this.props.itemClassName }); }).bind(this)) ); } }); exports["default"] = SortableList; module.exports = exports["default"]; },{"../util/DND":47}],22:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _ListEntryNodeListenerMixin = require('./ListEntryNodeListenerMixin'); var _ListEntryNodeListenerMixin2 = _interopRequireDefault(_ListEntryNodeListenerMixin); var _ListEntry = require('./ListEntry'); var _InlineEditor = require('./InlineEditor'); var _InlineEditor2 = _interopRequireDefault(_InlineEditor); /** * Specific list entry rendered as a table row. Not a real table, CSS used. */ exports['default'] = React.createClass({ displayName: 'TableListEntry', mixins: [_ListEntryNodeListenerMixin2['default']], propTypes: { node: React.PropTypes.instanceOf(AjxpNode), tableKeys: React.PropTypes.object.isRequired, renderActions: React.PropTypes.func // See also ListEntry nodes }, render: function render() { var _this = this; var actions = this.props.actions; if (this.props.renderActions) { actions = this.props.renderActions(this.props.node); } var cells = []; var firstKey = true; var meta = this.props.node.getMetadata(); for (var key in this.props.tableKeys) { if (!this.props.tableKeys.hasOwnProperty(key)) continue; var data = this.props.tableKeys[key]; var style = data['width'] ? { width: data['width'] } : null; var value = undefined, rawValue = undefined; if (data.renderCell) { data['name'] = key; value = data.renderCell(this.props.node, data); } else if (key === 'ajxp_modiftime' && meta.get('ajxp_relativetime')) { value = meta.get('ajxp_relativetime'); } else { value = meta.get(key); } rawValue = meta.get(key); var inlineEditor = undefined; if (this.state && this.state.inlineEdition && firstKey) { inlineEditor = React.createElement(_InlineEditor2['default'], { node: this.props.node, onClose: function () { _this.setState({ inlineEdition: false }); }, callback: this.state.inlineEditionCallback }); var _style = this.props.style || {}; _style.position = 'relative'; this.props.style = _style; } cells.push(React.createElement( 'span', { key: key, className: 'cell cell-' + key, title: rawValue, style: style, 'data-label': data['label'] }, inlineEditor, value )); firstKey = false; } return React.createElement(_ListEntry.DragDropListEntry, _extends({}, this.props, { iconCell: null, firstLine: cells, actions: actions })); } }); module.exports = exports['default']; },{"./InlineEditor":14,"./ListEntry":15,"./ListEntryNodeListenerMixin":16}],23:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _utilMessagesConsumerMixin = require('../util/MessagesConsumerMixin'); var _utilMessagesConsumerMixin2 = _interopRequireDefault(_utilMessagesConsumerMixin); var _SortColumns = require('./SortColumns'); var _SortColumns2 = _interopRequireDefault(_SortColumns); var _ListPaginator = require('./ListPaginator'); var _ListPaginator2 = _interopRequireDefault(_ListPaginator); /** * Specific header for Table layout, reading metadata from node and using keys */ exports['default'] = React.createClass({ displayName: 'TableListHeader', mixins: [_utilMessagesConsumerMixin2['default']], propTypes: { tableKeys: React.PropTypes.object.isRequired, loading: React.PropTypes.bool, reload: React.PropTypes.func, dm: React.PropTypes.instanceOf(PydioDataModel), node: React.PropTypes.instanceOf(AjxpNode), onHeaderClick: React.PropTypes.func, sortingInfo: React.PropTypes.object }, render: function render() { var headers = undefined, paginator = undefined; if (this.props.node.getMetadata().get("paginationData") && this.props.node.getMetadata().get("paginationData").get('total') > 1) { paginator = React.createElement(_ListPaginator2['default'], { dataModel: this.props.dm, node: this.props.node }); } return React.createElement( ReactMUI.Toolbar, { className: 'toolbarTableHeader' }, React.createElement(_SortColumns2['default'], _extends({ displayMode: 'tableHeader' }, this.props, { columnClicked: this.props.onHeaderClick })), React.createElement( ReactMUI.ToolbarGroup, { float: 'right' }, paginator, React.createElement(ReactMUI.FontIcon, { key: 1, tooltip: this.context.getMessage('149', ''), className: "icon-refresh" + (this.props.loading ? " rotating" : ""), onClick: this.props.reload }), this.props.additionalActions ) ); } }); module.exports = exports['default']; },{"../util/MessagesConsumerMixin":48,"./ListPaginator":17,"./SortColumns":20}],24:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _Utils = require('./Utils'); var _Utils2 = _interopRequireDefault(_Utils); var _MenuItemsConsumer = require('./MenuItemsConsumer'); var _MenuItemsConsumer2 = _interopRequireDefault(_MenuItemsConsumer); var React = require('react'); var ReactDOM = require('react-dom'); var _require = require('material-ui'); var Menu = _require.Menu; var Controller = require('pydio/model/controller'); var ButtonMenu = React.createClass({ displayName: 'ButtonMenu', propTypes: { buttonTitle: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.object]).isRequired, menuItems: React.PropTypes.array.isRequired, className: React.PropTypes.string, raised: React.PropTypes.bool, direction: React.PropTypes.oneOf(['left', 'right']) }, componentDidMount: function componentDidMount() { var _this = this; if (this.props.openOnEvent) { this.props.pydio.observe(this.props.openOnEvent, function () { _this.showMenu(); }); } }, getInitialState: function getInitialState() { return { showMenu: false }; }, showMenu: function showMenu(event) { var anchor = undefined; if (event) { anchor = event.currentTarget; } else { anchor = this._buttonDOM; } this.setState({ showMenu: true, anchor: anchor }); }, menuClicked: function menuClicked(event, index, object) { //object.payload(); this.setState({ showMenu: false }); }, render: function render() { var _this2 = this; var label = React.createElement( 'span', null, this.props.buttonTitle, ' ', React.createElement('span', { className: 'icon-caret-down' }) ); var button = undefined; var props = { primary: this.props.primary, secondary: this.props.secondary, disabled: this.props.disabeld, label: label, onTouchTap: this.showMenu }; var menuItems = this.props.menuItems; var _state = this.state; var showMenu = _state.showMenu; var anchor = _state.anchor; if (menuItems.length) { if (this.props.raised) { button = React.createElement(MaterialUI.RaisedButton, _extends({}, props, { style: this.props.buttonStyle, labelStyle: this.props.buttonLabelStyle, ref: function (b) { _this2._buttonDOM = ReactDOM.findDOMNode(b); } })); } else { button = React.createElement(MaterialUI.FlatButton, _extends({}, props, { style: this.props.buttonStyle, labelStyle: this.props.buttonLabelStyle, ref: function (b) { _this2._buttonDOM = ReactDOM.findDOMNode(b); } })); } } return React.createElement( 'span', { id: this.props.id, className: this.props.className }, button, React.createElement( MaterialUI.Popover, { className: 'menuPopover', open: showMenu, anchorEl: anchor, anchorOrigin: { horizontal: this.props.direction || 'left', vertical: 'bottom' }, targetOrigin: { horizontal: this.props.direction || 'left', vertical: 'top' }, onRequestClose: function () { _this2.setState({ showMenu: false }); }, style: { marginTop: 1 }, useLayerForClickAway: false }, _Utils2['default'].itemsToMenu(menuItems, this.menuClicked) ) ); } }); exports['default'] = _MenuItemsConsumer2['default'](ButtonMenu); module.exports = exports['default']; },{"./MenuItemsConsumer":28,"./Utils":31,"material-ui":"material-ui","pydio/model/controller":"pydio/model/controller","react":"react","react-dom":"react-dom"}],25:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _pydioModelContextMenu = require('pydio/model/context-menu'); var _pydioModelContextMenu2 = _interopRequireDefault(_pydioModelContextMenu); var _Utils = require('./Utils'); var _Utils2 = _interopRequireDefault(_Utils); var _PopupMenu = require('./PopupMenu'); var _PopupMenu2 = _interopRequireDefault(_PopupMenu); var _require = require('react'); var Component = _require.Component; var dims = { MENU_ITEM_HEIGHT: 32, //48 if not display:compact MENU_SEP_HEIGHT: 16, MENU_VERTICAL_PADDING: 8, MENU_WIDTH: 250, OFFSET_VERTICAL: 8, OFFSET_HORIZONTAL: 8 }; var ContextMenu = (function (_Component) { _inherits(ContextMenu, _Component); function ContextMenu() { _classCallCheck(this, ContextMenu); _Component.apply(this, arguments); } ContextMenu.prototype.modelOpen = function modelOpen(node) { var position = _pydioModelContextMenu2['default'].getInstance().getPosition(); var items = undefined; if (node) { var dm = pydio.getContextHolder(); if (dm.getSelectedNodes().indexOf(node) !== -1) { this.openMenu('selectionContext', position); } else { pydio.observeOnce("actions_refreshed", (function (dataModel) { this.openMenu('selectionContext', position); }).bind(this)); dm.setSelectedNodes([node]); } } else { this.openMenu('genericContext', position); } }; ContextMenu.prototype.openMenu = function openMenu(context, position) { var items = this.computeMenuItems(context); this._items = items; var mobile = this.props.pydio.UI.MOBILE_EXTENSIONS; if (!mobile) { position = this.computeVisiblePosition(position, items); this.refs['menu'].showMenu({ top: position.y, left: position.x }, items); } else { this.refs['menu'].showMenu({ bottom: 0, left: 0, right: 0, height: 200, zIndex: 10000, overflowY: 'auto' }, items); } }; ContextMenu.prototype.computeMenuItems = function computeMenuItems(context) { var actions = this.props.pydio.Controller.getContextActions(context, ['inline', 'info_panel', 'info_panel_share']); return _Utils2['default'].pydioActionsToItems(actions); }; ContextMenu.prototype.computeVisiblePosition = function computeVisiblePosition(position, items) { var menuHeight = dims.MENU_VERTICAL_PADDING * 2; items.map(function (it) { if (it.separator) menuHeight += dims.MENU_SEP_HEIGHT;else menuHeight += dims.MENU_ITEM_HEIGHT; }); var menuWidth = dims.MENU_WIDTH; var windowW = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); var windowH = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); if (position.x + menuWidth > windowW) { position.x = Math.max(position.x - menuWidth, 10) - dims.OFFSET_HORIZONTAL; } else { position.x += dims.OFFSET_HORIZONTAL; } if (position.y + menuHeight > windowH) { position.y = Math.max(position.y - menuHeight, 10) - dims.OFFSET_VERTICAL; } else { position.y += dims.OFFSET_VERTICAL; } return position; }; ContextMenu.prototype.componentDidMount = function componentDidMount() { this._modelOpen = this.modelOpen.bind(this); _pydioModelContextMenu2['default'].getInstance().observe("open", this._modelOpen); }; ContextMenu.prototype.componentWillUnmount = function componentWillUnmount() { _pydioModelContextMenu2['default'].getInstance().stopObserving("open", this._modelOpen); }; ContextMenu.prototype.render = function render() { var mobile = this.props.pydio.UI.MOBILE_EXTENSIONS; return React.createElement(_PopupMenu2['default'], { ref: 'menu', menuItems: this._items || [], onMenuClosed: this.props.onMenuClosed, menuProps: mobile ? { width: 600, autoWidth: false, desktop: false } : {}, zDepth: mobile ? 2 : 1 }); }; return ContextMenu; })(Component); exports['default'] = ContextMenu; module.exports = exports['default']; },{"./PopupMenu":29,"./Utils":31,"pydio/model/context-menu":"pydio/model/context-menu","react":"react"}],26:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _Utils = require('./Utils'); var _Utils2 = _interopRequireDefault(_Utils); var _MenuItemsConsumer = require('./MenuItemsConsumer'); var _MenuItemsConsumer2 = _interopRequireDefault(_MenuItemsConsumer); var React = require('react'); var _require = require('material-ui'); var IconButton = _require.IconButton; var Popover = _require.Popover; var IconButtonMenu = (function (_React$Component) { _inherits(IconButtonMenu, _React$Component); function IconButtonMenu(props, context) { _classCallCheck(this, IconButtonMenu); _React$Component.call(this, props, context); this.state = { showMenu: false }; } IconButtonMenu.prototype.showMenu = function showMenu(event) { this.setState({ showMenu: true, anchor: event.currentTarget }); }; IconButtonMenu.prototype.closeMenu = function closeMenu(event, index, menuItem) { this.setState({ showMenu: false }); }; IconButtonMenu.prototype.render = function render() { var _this = this; return React.createElement( 'span', { className: "toolbars-button-menu " + (this.props.className ? this.props.className : '') }, React.createElement(IconButton, { ref: 'menuButton', tooltip: this.props.buttonTitle, iconClassName: this.props.buttonClassName, onTouchTap: this.showMenu.bind(this), iconStyle: this.props.buttonStyle }), React.createElement( Popover, { open: this.state.showMenu, anchorEl: this.state.anchor, anchorOrigin: { horizontal: this.props.popoverDirection || 'right', vertical: this.props.popoverTargetPosition || 'bottom' }, targetOrigin: { horizontal: this.props.popoverDirection || 'right', vertical: 'top' }, onRequestClose: function () { _this.setState({ showMenu: false }); }, useLayerForClickAway: false }, _Utils2['default'].itemsToMenu(this.props.menuItems, this.closeMenu.bind(this), false, this.props.menuProps || undefined) ) ); }; return IconButtonMenu; })(React.Component); IconButtonMenu.propTypes = { buttonTitle: React.PropTypes.string.isRequired, buttonClassName: React.PropTypes.string.isRequired, className: React.PropTypes.string, popoverDirection: React.PropTypes.oneOf(['right', 'left']), popoverPosition: React.PropTypes.oneOf(['top', 'bottom']), menuProps: React.PropTypes.object, menuItems: React.PropTypes.array.isRequired }; exports['default'] = _MenuItemsConsumer2['default'](IconButtonMenu); module.exports = exports['default']; },{"./MenuItemsConsumer":28,"./Utils":31,"material-ui":"material-ui","react":"react"}],27:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var React = require('react'); var _require = require('material-ui'); var IconButton = _require.IconButton; var Popover = _require.Popover; var IconButtonPopover = (function (_React$Component) { _inherits(IconButtonPopover, _React$Component); function IconButtonPopover(props, context) { _classCallCheck(this, IconButtonPopover); _React$Component.call(this, props, context); this.state = { showPopover: false }; } IconButtonPopover.prototype.showPopover = function showPopover(event) { this.setState({ showPopover: true, anchor: event.currentTarget }); }; IconButtonPopover.prototype.render = function render() { var _this = this; return React.createElement( 'span', { className: "toolbars-button-menu " + (this.props.className ? this.props.className : '') }, React.createElement(IconButton, { ref: 'menuButton', tooltip: this.props.buttonTitle, iconClassName: this.props.buttonClassName, onTouchTap: this.showPopover.bind(this), iconStyle: this.props.buttonStyle }), React.createElement( Popover, { open: this.state.showPopover, anchorEl: this.state.anchor, anchorOrigin: { horizontal: this.props.direction || 'right', vertical: 'bottom' }, targetOrigin: { horizontal: this.props.direction || 'right', vertical: 'top' }, onRequestClose: function () { _this.setState({ showPopover: false }); }, useLayerForClickAway: false }, this.props.popoverContent ) ); }; return IconButtonPopover; })(React.Component); IconButtonPopover.propTypes = { buttonTitle: React.PropTypes.string.isRequired, buttonClassName: React.PropTypes.string.isRequired, className: React.PropTypes.string, direction: React.PropTypes.oneOf(['right', 'left']), popoverContent: React.PropTypes.object.isRequired }; exports['default'] = IconButtonPopover; module.exports = exports['default']; },{"material-ui":"material-ui","react":"react"}],28:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _Utils = require('./Utils'); var _Utils2 = _interopRequireDefault(_Utils); var React = require('react'); var Controller = require('pydio/model/controller'); exports['default'] = function (Component) { var Wrapped = (function (_React$Component) { _inherits(Wrapped, _React$Component); function Wrapped(props, context) { _classCallCheck(this, Wrapped); _React$Component.call(this, props, context); this.state = { menuItems: this.props.menuItems || [] }; } Wrapped.prototype.componentDidMount = function componentDidMount() { var _this = this; if (this.props.controller && !this.props.menuItems) { this._observer = function () { var actions = _this.props.controller.getContextActions('genericContext', null, _this.props.toolbars); var menuItems = _Utils2['default'].pydioActionsToItems(actions); _this.setState({ menuItems: menuItems }); }; if (this.props.controller === this.props.pydio.Controller) { this.props.pydio.observe("actions_refreshed", this._observer); } else { this.props.controller.observe("actions_refreshed", this._observer); } this._observer(); } }; Wrapped.prototype.componentWillUnmount = function componentWillUnmount() { if (this._observer) { if (this.props.controller === this.props.pydio.Controller) { this.props.pydio.stopObserving("actions_refreshed", this._observer); } else { this.props.controller.stopObserving("actions_refreshed", this._observer); } } }; Wrapped.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { if (nextProps.menuItems && nextProps.menuItems !== this.props.menuItems) { this.setState({ menuItems: nextProps.menuItems }); } }; Wrapped.prototype.render = function render() { return React.createElement(Component, _extends({}, this.props, { menuItems: this.state.menuItems })); }; return Wrapped; })(React.Component); Wrapped.propTypes = { menuItems: React.PropTypes.array, toolbars: React.PropTypes.array, controller: React.PropTypes.instanceOf(Controller), pydio: React.PropTypes.instanceOf(Pydio) }; return Wrapped; }; module.exports = exports['default']; },{"./Utils":31,"pydio/model/controller":"pydio/model/controller","react":"react"}],29:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _Utils = require('./Utils'); var _Utils2 = _interopRequireDefault(_Utils); var React = require('react'); var ReactDOM = require('react-dom'); var _require = require('material-ui'); var Menu = _require.Menu; var Paper = _require.Paper; exports['default'] = React.createClass({ displayName: 'PopupMenu', propTypes: { menuItems: React.PropTypes.array.isRequired, onExternalClickCheckElements: React.PropTypes.func, className: React.PropTypes.string, style: React.PropTypes.object, onMenuClosed: React.PropTypes.func }, getInitialState: function getInitialState() { return { showMenu: false, menuItems: this.props.menuItems }; }, showMenu: function showMenu() { var style = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0]; var menuItems = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1]; this.setState({ showMenu: true, style: style, menuItems: menuItems ? menuItems : this.state.menuItems }); }, hideMenu: function hideMenu(event) { if (!event) { this.setState({ showMenu: false }); if (this.props.onMenuClosed) this.props.onMenuClosed(); return; } var node = ReactDOM.findDOMNode(this.refs.menuContainer); if (node.contains(event.target) || node === event.target) { return; } this.setState({ showMenu: false }); if (this.props.onMenuClosed) this.props.onMenuClosed(); }, componentDidMount: function componentDidMount() { this._observer = this.hideMenu; }, componentWillUnmount: function componentWillUnmount() { document.removeEventListener('click', this._observer, false); }, componentWillReceiveProps: function componentWillReceiveProps(nextProps) { if (nextProps.menuItems) { this.setState({ menuItems: nextProps.menuItems }); } }, componentDidUpdate: function componentDidUpdate(prevProps, nextProps) { if (this.state.showMenu) { document.addEventListener('click', this._observer, false); } else { document.removeEventListener('click', this._observer, false); } }, menuClicked: function menuClicked(event, index, menuItem) { this.hideMenu(); }, render: function render() { var style = this.state.style || {}; style = _extends({}, style, { zIndex: 1000 }); var menu = _Utils2['default'].itemsToMenu(this.state.menuItems, this.menuClicked, false, _extends({ desktop: true, display: 'right', width: 250 }, this.props.menuProps)); if (this.state.showMenu) { return React.createElement( Paper, { zDepth: this.props.zDepth || 1, ref: 'menuContainer', className: 'menu-positioner', style: style }, menu ); } else { return null; } } }); module.exports = exports['default']; },{"./Utils":31,"material-ui":"material-ui","react":"react","react-dom":"react-dom"}],30:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _Utils = require('./Utils'); var _Utils2 = _interopRequireDefault(_Utils); var _IconButtonMenu = require('./IconButtonMenu'); var _IconButtonMenu2 = _interopRequireDefault(_IconButtonMenu); var _ButtonMenu = require('./ButtonMenu'); var _ButtonMenu2 = _interopRequireDefault(_ButtonMenu); var _IconButtonPopover = require('./IconButtonPopover'); var _IconButtonPopover2 = _interopRequireDefault(_IconButtonPopover); (function (global) { exports['default'] = React.createClass({ displayName: 'Toolbar', propTypes: { toolbars: React.PropTypes.array, groupOtherList: React.PropTypes.array, renderingType: React.PropTypes.string, controller: React.PropTypes.instanceOf(Controller), toolbarStyle: React.PropTypes.object, buttonStyle: React.PropTypes.object }, componentDidMount: function componentDidMount() { this._observer = (function () { if (!this.isMounted()) return; this.setState({ groups: this.props.controller.getToolbarsActions(this.props.toolbars, this.props.groupOtherList) }); }).bind(this); if (this.props.controller === pydio.Controller) { pydio.observe("actions_refreshed", this._observer); } else { this.props.controller.observe("actions_refreshed", this._observer); } }, componentWillUnmount: function componentWillUnmount() { if (this.props.controller === pydio.Controller) { pydio.stopObserving("actions_refreshed", this._observer); } else { this.props.controller.stopObserving("actions_refreshed", this._observer); } }, componentWillReceiveProps: function componentWillReceiveProps(nextProps) { if (nextProps.toolbars !== this.props.toolbars) { this.setState({ groups: this.props.controller.getToolbarsActions(nextProps.toolbars, nextProps.groupOtherList) }); } }, getInitialState: function getInitialState() { return { groups: this.props.controller.getToolbarsActions(this.props.toolbars, this.props.groupOtherList) }; }, getDefaultProps: function getDefaultProps() { return { controller: global.pydio.Controller, renderingType: 'button', groupOtherList: [] }; }, render: function render() { var groups = this.state.groups; var actions = []; var _props = this.props; var toolbars = _props.toolbars; var renderingType = _props.renderingType; var groupOtherList = _props.groupOtherList; var buttonStyle = _props.buttonStyle; var tooltipPosition = _props.tooltipPosition; var controller = _props.controller; var allToolbars = [].concat(toolbars); if (groupOtherList.length) { allToolbars = allToolbars.concat(['MORE_ACTION']); } allToolbars.map(function (barName) { if (!groups.has(barName)) return; groups.get(barName).map(function (action) { if (action.deny) return; var menuItems = undefined, popoverContent = undefined, menuTitle = undefined, menuIcon = undefined; var actionName = action.options.name; menuTitle = action.options.text; menuIcon = action.options.icon_class; if (barName === 'MORE_ACTION') { (function () { var subItems = action.subMenuItems.dynamicItems; var items = []; subItems.map(function (obj) { if (obj.separator) { items.push(obj); } else if (obj.actionId && !obj.actionId.deny) { items.push(obj.actionId.getMenuData()); } }); menuItems = _Utils2['default'].pydioActionsToItems(items); })(); } else if (action.subMenuItems.staticItems) { menuItems = _Utils2['default'].pydioActionsToItems(action.subMenuItems.staticItems); } else if (action.subMenuItems.dynamicBuilder) { menuItems = _Utils2['default'].pydioActionsToItems(action.subMenuItems.dynamicBuilder(controller)); } else if (action.subMenuItems.popoverContent) { popoverContent = action.subMenuItems.popoverContent; } else {} var id = 'action-' + action.options.name; if (renderingType === 'button-icon') { menuTitle = React.createElement( 'span', { className: 'button-icon' }, React.createElement('span', { className: "button-icon-icon " + menuIcon }), React.createElement( 'span', { className: 'button-icon-label' }, menuTitle ) ); } if (menuItems) { if (renderingType === 'button' || renderingType === 'button-icon') { actions.push(React.createElement(_ButtonMenu2['default'], { key: actionName, className: id, buttonTitle: menuTitle, menuItems: menuItems, buttonLabelStyle: buttonStyle })); } else { actions.push(React.createElement(_IconButtonMenu2['default'], { key: actionName, className: id, onMenuClicked: function (object) { object.payload(); }, buttonClassName: menuIcon, buttonTitle: menuTitle, menuItems: menuItems, buttonStyle: buttonStyle })); } } else if (popoverContent) { actions.push(React.createElement(_IconButtonPopover2['default'], { key: actionName, className: id, buttonClassName: menuIcon, buttonTitle: menuTitle, buttonStyle: buttonStyle, popoverContent: popoverContent })); } else { var click = function click(synthEvent) { action.apply(); }; if (renderingType === 'button-icon') { actions.push(React.createElement(ReactMUI.FlatButton, { key: actionName, className: id, onTouchTap: click, label: menuTitle, labelStyle: buttonStyle })); } else if (renderingType === 'button') { actions.push(React.createElement(MaterialUI.FlatButton, { key: actionName, className: id, onTouchTap: click, label: menuTitle, labelStyle: buttonStyle })); } else { actions.push(React.createElement(MaterialUI.IconButton, { key: actionName, iconClassName: menuIcon + ' ' + id, iconStyle: buttonStyle, onTouchTap: click, tooltip: menuTitle, tooltipPosition: tooltipPosition })); } } }); }); var cName = this.props.className ? this.props.className : ''; cName += ' ' + 'toolbar'; if (!actions.length) { cName += ' empty-toolbar'; } return React.createElement( 'div', { className: cName, style: this.props.toolbarStyle, id: this.props.id }, actions ); } }); })(window); module.exports = exports['default']; },{"./ButtonMenu":24,"./IconButtonMenu":26,"./IconButtonPopover":27,"./Utils":31}],31:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _require = require('material-ui'); var Divider = _require.Divider; var Menu = _require.Menu; var MenuItem = _require.MenuItem; var FontIcon = _require.FontIcon; function pydioActionsToItems() { var actions = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; var items = []; var lastIsSeparator = false; actions.map((function (action, index) { if (action.separator) { if (lastIsSeparator) return; items.push(action); lastIsSeparator = true; return; } lastIsSeparator = false; var label = action.raw_name ? action.raw_name : action.name; var iconClass = action.icon_class; var payload = undefined; if (action.subMenu) { var subItems = action.subMenuBeforeShow ? pydioActionsToItems(action.subMenuBeforeShow()) : action.subMenu; items.push({ text: label, iconClassName: iconClass, subItems: subItems }); } else { items.push({ text: label, iconClassName: iconClass, payload: action.callback }); } }).bind(this)); if (lastIsSeparator) { items = items.slice(0, items.length - 1); } if (items.length && items[0] && items[0].separator) { items.shift(); } return items; } function itemsToMenu(items, closeMenuCallback) { var subItemsOnly = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; var menuProps = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3]; menuProps = _extends({ display: 'normal', width: 216, desktop: true, autoWidth: false }, menuProps); var menuItems = items.map(function (item, index) { if (item.separator) return React.createElement(Divider, { key: "divider" + index }); var subItems = undefined, payload = undefined; if (item.subItems) { subItems = itemsToMenu(item.subItems, closeMenuCallback, true); } else if (item.payload) { payload = function () { item.payload(); closeMenuCallback(); }; } var leftIcon = undefined, rightIcon = undefined; var iconClassName = item.iconClassName;var inset = false; if (iconClassName === '__INSET__') { iconClassName = ''; inset = true; } if (menuProps.display === 'normal') { leftIcon = iconClassName ? React.createElement(FontIcon, { className: item.iconClassName + ' menu-icons', style: { fontSize: 16, padding: 5 } }) : null; } else if (menuProps.display === 'right') { rightIcon = iconClassName ? React.createElement(FontIcon, { className: item.iconClassName + ' menu-icons', style: { fontSize: 16, padding: 5 } }) : null; } rightIcon = subItems && subItems.length ? React.createElement(FontIcon, { className: 'mdi mdi-menu-right menu-icons' }) : rightIcon; return React.createElement(MenuItem, { key: item.text, primaryText: item.text, insetChildren: inset, leftIcon: leftIcon, rightIcon: rightIcon, onTouchTap: payload, menuItems: subItems }); }); if (subItemsOnly) { return menuItems; } else { return React.createElement( Menu, menuProps, menuItems ); } } exports['default'] = { pydioActionsToItems: pydioActionsToItems, itemsToMenu: itemsToMenu }; module.exports = exports['default']; },{"material-ui":"material-ui"}],32:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _require = require('react'); var Component = _require.Component; var PropTypes = _require.PropTypes; var _require2 = require('material-ui'); var TextField = _require2.TextField; var FlatButton = _require2.FlatButton; var _require$requireLib = require('pydio').requireLib('boot'); var PydioContextConsumer = _require$requireLib.PydioContextConsumer; /** * Simple form for creating a team */ var TeamCreationForm = (function (_Component) { _inherits(TeamCreationForm, _Component); TeamCreationForm.updateTeamUsers = function updateTeamUsers(team, operation, users, callback) { var teamId = team.id.replace('/AJXP_TEAM/', ''); var clearUserCache = function clearUserCache(uId) { MetaCacheService.getInstance().deleteKey('user_public_data-rich', uId); }; if (operation === 'add') { users.forEach(function (user) { var userId = user.getId ? user.getId() : user.id; PydioUsers.Client.addUserToTeam(teamId, userId, callback); clearUserCache(userId); }); } else if (operation === 'delete') { users.forEach(function (user) { var userId = user.getId ? user.getId() : user.id; PydioUsers.Client.removeUserFromTeam(teamId, userId, callback); clearUserCache(userId); }); } else if (operation === 'create') { PydioUsers.Client.saveSelectionAsTeam(teamId, users, callback); users.forEach(function (user) { clearUserCache(user.getId ? user.getId() : user.id); }); } }; function TeamCreationForm(props, context) { _classCallCheck(this, TeamCreationForm); _Component.call(this, props, context); this.state = { value: '' }; } TeamCreationForm.prototype.onChange = function onChange(e, value) { this.setState({ value: value }); }; TeamCreationForm.prototype.submitCreationForm = function submitCreationForm() { var value = this.state.value; TeamCreationForm.updateTeamUsers({ id: value }, 'create', [], this.props.onTeamCreated); }; TeamCreationForm.prototype.render = function render() { var getMessage = this.props.getMessage; return React.createElement( 'div', { style: { padding: 20 } }, React.createElement( 'div', null, getMessage(591) ), React.createElement(TextField, { floatingLabelText: getMessage(578), value: this.state.value, onChange: this.onChange.bind(this), fullWidth: true }), React.createElement( 'div', null, React.createElement( 'div', { style: { textAlign: 'right', paddingTop: 10 } }, React.createElement(FlatButton, { label: getMessage(49), onTouchTap: this.props.onCancel.bind(this) }), React.createElement(FlatButton, { label: getMessage(579), secondary: true, onTouchTap: this.submitCreationForm.bind(this) }) ) ) ); }; return TeamCreationForm; })(Component); TeamCreationForm.propTypes = { /** * Callback triggered after team creation succeeded */ onTeamCreated: PropTypes.func.isRequired, /** * Request modal close */ onCancel: PropTypes.func.isRequired }; exports['default'] = TeamCreationForm = PydioContextConsumer(TeamCreationForm); exports['default'] = TeamCreationForm; module.exports = exports['default']; },{"material-ui":"material-ui","pydio":"pydio","react":"react"}],33:[function(require,module,exports){ (function (global){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _addressbookAddressBook = require('./addressbook/AddressBook'); var _addressbookAddressBook2 = _interopRequireDefault(_addressbookAddressBook); var _require$requireLib = require('pydio/http/resources-manager').requireLib('boot'); var AsyncComponent = _require$requireLib.AsyncComponent; var _require = require('material-ui'); var TextField = _require.TextField; var AutoComplete = _require.AutoComplete; var RefreshIndicator = _require.RefreshIndicator; var IconButton = _require.IconButton; var Popover = _require.Popover; var React = require('react'); var FuncUtils = require('pydio/util/func'); /** * Ready to use autocomplete field that will load users/groups/roles from * the server (using user_list_authorized_users API). * Used for sharing, addressbooks, send email, etc. * * Can also open a "selector-style" adress book. */ var UsersLoader = React.createClass({ displayName: 'UsersLoader', propTypes: { /** * Method called to render a commponent, taking a UserObject as input */ renderSuggestion: React.PropTypes.func.isRequired, /** * Callback when a value is finally selected */ onValueSelected: React.PropTypes.func.isRequired, /** * Floating Label Text displayed on the field */ fieldLabel: React.PropTypes.string.isRequired, /** * Array of values to ignore */ excludes: React.PropTypes.array.isRequired, /** * Display only users, no groups nor roles */ usersOnly: React.PropTypes.bool, /** * Display users from local directory and/or from remote. */ usersFrom: React.PropTypes.oneOf(['local', 'remote', 'any']), /** * Do not propose a "Create user" option */ existingOnly: React.PropTypes.bool, /** * Allow free typing */ freeValueAllowed: React.PropTypes.bool, /** * Will be passed to the root component */ className: React.PropTypes.string }, getInitialState: function getInitialState() { return { dataSource: [], loading: false, searchText: '', minChars: parseInt(global.pydio.getPluginConfigs("core.conf").get("USERS_LIST_COMPLETE_MIN_CHARS")) }; }, /** * Loads values from server * @param {string} input Currently searched text * @param {Function} callback Called with the values */ suggestionLoader: function suggestionLoader(input, callback) { var excludes = this.props.excludes; var disallowTemporary = this.props.existingOnly && !this.props.freeValueAllowed; this.setState({ loading: this.state.loading + 1 }); PydioUsers.Client.authorizedUsersStartingWith(input, (function (users) { this.setState({ loading: this.state.loading - 1 }); if (disallowTemporary) { users = users.filter(function (user) { return !user.getTemporary(); }); } if (excludes && excludes.length) { users = users.filter(function (user) { return excludes.indexOf(user.getId()) == -1; }); } callback(users); }).bind(this), this.props.usersOnly, this.props.existingOnly); }, /** * Called when the field is updated * @param value */ textFieldUpdate: function textFieldUpdate(value) { this.setState({ searchText: value }); if (this.state.minChars && value && value.length < this.state.minChars) { return; } this.loadBuffered(value, 350); }, getPendingSearchText: function getPendingSearchText() { return this.state.searchText || false; }, /** * Debounced call for rendering search * @param value {string} * @param timeout {int} */ loadBuffered: function loadBuffered(value, timeout) { if (!value && this._emptyValueList) { this.setState({ dataSource: this._emptyValueList }); return; } FuncUtils.bufferCallback('remote_users_search', timeout, (function () { this.setState({ loading: true }); this.suggestionLoader(value, (function (users) { var crtValueFound = false; var values = users.map((function (userObject) { var component = React.createElement( MaterialUI.MenuItem, null, this.props.renderSuggestion(userObject) ); return { userObject: userObject, text: userObject.getExtendedLabel(), value: component }; }).bind(this)); if (!value) { this._emptyValueList = values; } this.setState({ dataSource: values, loading: false }); }).bind(this)); }).bind(this)); }, /** * Called when user selects a value from the list * @param value * @param index */ onCompleterRequest: function onCompleterRequest(value, index) { if (index === -1) { this.state.dataSource.map(function (entry) { if (entry.text === value) { value = entry; } }); if (value && !value.userObject && this.props.freeValueAllowed) { var fake = new PydioUsers.User(value, value, 'user', null, null, true); this.props.onValueSelected(fake); this.setState({ searchText: '', dataSource: [] }); return; } } if (value && value.userObject) { var object = value.userObject; if (object.getTemporary()) { if (this.props.freeValueAllowed) { this.props.onValueSelected(object); } else { this.setState({ createUser: object.getLabel() }); } } else { this.props.onValueSelected(object); } this.setState({ searchText: '', dataSource: [] }); } }, /** * Triggers onValueSelected props callback * @param {Pydio.User} newUser */ onUserCreated: function onUserCreated(newUser) { this.props.onValueSelected(newUser); this.setState({ createUser: null }); }, /** * Close user creation form */ onCreationCancelled: function onCreationCancelled() { this.setState({ createUser: null }); }, /** * Open address book inside a Popover * @param event */ openAddressBook: function openAddressBook(event) { this.setState({ addressBookOpen: true, addressBookAnchor: event.currentTarget }); }, /** * Close address book popover */ closeAddressBook: function closeAddressBook() { this.setState({ addressBookOpen: false }); }, /** * Triggered when user clicks on an entry from adress book. * @param item */ onAddressBookItemSelected: function onAddressBookItemSelected(item) { this.props.onValueSelected(item); }, render: function render() { var _this = this; var _state = this.state; var dataSource = _state.dataSource; var createUser = _state.createUser; var containerStyle = { position: 'relative', overflow: 'visible' }; /* if(createUser){ return (
); } */ return React.createElement( 'div', { style: containerStyle, ref: function (el) { _this._popoverAnchor = el; } }, !createUser && React.createElement(AutoComplete, { filter: MaterialUI.AutoComplete.noFilter, dataSource: dataSource, searchText: this.state.searchText, onUpdateInput: this.textFieldUpdate, className: this.props.className, openOnFocus: true, floatingLabelText: this.props.fieldLabel, underlineShow: !this.props.underlineHide, fullWidth: true, onNewRequest: this.onCompleterRequest, listStyle: { maxHeight: 350, overflowY: 'auto' }, onFocus: function () { _this.loadBuffered(_this.state.searchText, 100); } }), createUser && React.createElement(TextField, { floatingLabelText: this.props.fieldLabel, value: global.pydio.MessageHash[485] + ' (' + this.state.createUser + ')', disabled: true, fullWidth: true, underlineShow: !this.props.underlineHide }), !createUser && React.createElement( 'div', { style: { position: 'absolute', right: 4, bottom: 14, height: 20, width: 20 } }, React.createElement(RefreshIndicator, { size: 20, left: 0, top: 0, status: this.state.loading ? 'loading' : 'hide' }) ), this.props.showAddressBook && !createUser && React.createElement(_addressbookAddressBook2['default'], { mode: 'popover', pydio: this.props.pydio, loaderStyle: { width: 320, height: 420 }, onItemSelected: this.onAddressBookItemSelected, usersFrom: this.props.usersFrom, disableSearch: true }), React.createElement( Popover, { open: createUser, anchorEl: this._popoverAnchor, anchorOrigin: { horizontal: 'left', vertical: 'bottom' }, targetOrigin: { horizontal: 'left', vertical: 'top' }, onRequestClose: this.onCreationCancelled, canAutoPosition: false }, createUser && React.createElement(AsyncComponent, { namespace: "PydioForm", componentName: "UserCreationForm", style: { width: 350, height: 320 }, newUserName: this.state.createUser, onUserCreated: this.onUserCreated, onCancel: this.onCreationCancelled, pydio: this.props.pydio }) ) ); } }); exports['default'] = UsersLoader; module.exports = exports['default']; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./addressbook/AddressBook":34,"material-ui":"material-ui","pydio/http/resources-manager":"pydio/http/resources-manager","pydio/util/func":"pydio/util/func","react":"react"}],34:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _NestedListItem = require('./NestedListItem'); var _NestedListItem2 = _interopRequireDefault(_NestedListItem); var _UsersList = require('./UsersList'); var _UsersList2 = _interopRequireDefault(_UsersList); var _RightPanelCard = require('./RightPanelCard'); var _RightPanelCard2 = _interopRequireDefault(_RightPanelCard); var _SearchPanel = require('./SearchPanel'); var _SearchPanel2 = _interopRequireDefault(_SearchPanel); var _Loaders = require('./Loaders'); var _Loaders2 = _interopRequireDefault(_Loaders); var _TeamCreationForm = require('../TeamCreationForm'); var _TeamCreationForm2 = _interopRequireDefault(_TeamCreationForm); var React = require('react'); var Pydio = require('pydio'); var _Pydio$requireLib = Pydio.requireLib('boot'); var AsyncComponent = _Pydio$requireLib.AsyncComponent; var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer; var _require = require('material-ui'); var Popover = _require.Popover; var IconButton = _require.IconButton; var _require2 = require('material-ui/styles'); var muiThemeable = _require2.muiThemeable; var colors = _require2.colors; /** * High level component to browse users, groups and teams, either in a large format (mode='book') or a more compact * format (mode='selector'|'popover'). * Address book allows to create external users, teams, and also to browse trusted server directories if Federated Sharing * is active. */ var AddressBook = React.createClass({ displayName: 'AddressBook', propTypes: { /** * Main instance of pydio */ pydio: React.PropTypes.instanceOf(Pydio), /** * Display mode, either large (book) or small picker ('selector', 'popover'). */ mode: React.PropTypes.oneOf(['book', 'selector', 'popover']).isRequired, /** * Callback triggered in 'selector' mode whenever an item is clicked. */ onItemSelected: React.PropTypes.func, /** * Display users only, no teams or groups */ usersOnly: React.PropTypes.bool, /** * Choose various user sources, either the local directory or remote ( = trusted ) servers. */ usersFrom: React.PropTypes.oneOf(['local', 'remote', 'any']), /** * Disable the search engine */ disableSearch: React.PropTypes.bool, /** * Theme object passed by muiThemeable() wrapper */ muiTheme: React.PropTypes.object, /** * Will be passed to the Popover object */ popoverStyle: React.PropTypes.object, /** * Used as a button to open the selector in a popover */ popoverButton: React.PropTypes.object, /** * Will be passed to the Popover container object */ popoverContainerStyle: React.PropTypes.object, /** * Will be passed to the Popover Icon Button. */ popoverIconButtonStyle: React.PropTypes.object }, getDefaultProps: function getDefaultProps() { return { mode: 'book', usersOnly: false, usersFrom: 'any', teamsOnly: false, disableSearch: false }; }, getInitialState: function getInitialState() { var _this = this; var _props = this.props; var pydio = _props.pydio; var mode = _props.mode; var usersOnly = _props.usersOnly; var usersFrom = _props.usersFrom; var teamsOnly = _props.teamsOnly; var disableSearch = _props.disableSearch; var getMessage = function getMessage(id) { return _this.props.getMessage(id, ''); }; var confConfigs = pydio.getPluginConfigs('core.conf'); var root = undefined; if (teamsOnly) { root = { id: 'teams', label: getMessage(568), childrenLoader: _Loaders2['default'].loadTeams, _parent: null, _notSelectable: true, actions: { type: 'teams', create: '+ ' + getMessage(569), remove: getMessage(570), multiple: true } }; return { root: root, selectedItem: root, loading: false, rightPaneItem: null }; } root = { id: 'root', label: getMessage(592), type: 'root', collections: [] }; if (usersFrom !== 'remote') { if (confConfigs.get('USER_CREATE_USERS')) { root.collections.push({ id: 'ext', label: getMessage(593), //icon:'mdi mdi-account-network', itemsLoader: _Loaders2['default'].loadExternalUsers, _parent: root, _notSelectable: true, actions: { type: 'users', create: '+ ' + getMessage(484), remove: getMessage(582), multiple: true } }); } if (!usersOnly) { root.collections.push({ id: 'teams', label: getMessage(568), //icon: 'mdi mdi-account-multiple', childrenLoader: _Loaders2['default'].loadTeams, _parent: root, _notSelectable: true, actions: { type: 'teams', create: '+ ' + getMessage(569), remove: getMessage(570), multiple: true } }); } if (confConfigs.get('ALLOW_CROSSUSERS_SHARING')) { var groupOrUsers = confConfigs.get('ADDRESSBOOK_GROUP_OR_USERS'); if (groupOrUsers && groupOrUsers.group_switch_value) groupOrUsers = groupOrUsers.group_switch_value;else groupOrUsers = 'both'; if (groupOrUsers === 'search') { if (!disableSearch) { root.collections.push({ id: 'search', label: getMessage(583), //icon:'mdi mdi-account-search', type: 'search', _parent: root, _notSelectable: true }); } } else { root.collections.push({ id: 'AJXP_GRP_/', label: getMessage(584), //icon:'mdi mdi-account-box', childrenLoader: groupOrUsers === 'both' || groupOrUsers === 'groups' ? _Loaders2['default'].loadGroups : null, itemsLoader: groupOrUsers === 'both' || groupOrUsers === 'users' ? _Loaders2['default'].loadGroupUsers : null, _parent: root, _notSelectable: true }); } } } var ocsRemotes = pydio.getPluginConfigs('core.ocs').get('TRUSTED_SERVERS'); if (ocsRemotes && !usersOnly && usersFrom !== 'local') { var remotes = JSON.parse(ocsRemotes); var remotesNodes = { id: 'remotes', label: getMessage(594), //icon:'mdi mdi-server', collections: [], _parent: root, _notSelectable: true }; for (var k in remotes) { if (!remotes.hasOwnProperty(k)) continue; remotesNodes.collections.push({ id: k, label: remotes[k], icon: 'mdi mdi-server-network', type: 'remote', _parent: remotesNodes, _notSelectable: true }); } if (remotesNodes.collections.length) { root.collections.push(remotesNodes); } } return { root: root, selectedItem: mode === 'selector' ? root : root.collections[0], loading: false, rightPaneItem: null }; }, componentDidMount: function componentDidMount() { this.state.selectedItem && this.onFolderClicked(this.state.selectedItem); }, onFolderClicked: function onFolderClicked(item) { var _this2 = this; var callback = arguments.length <= 1 || arguments[1] === undefined ? undefined : arguments[1]; // Special case for teams if (item.type === 'group' && item.id.indexOf('/AJXP_TEAM/') === 0) { this.onUserListItemClicked(item); return; } this.setState({ loading: true }); _Loaders2['default'].childrenAsPromise(item, false).then(function (children) { _Loaders2['default'].childrenAsPromise(item, true).then(function (children) { _this2.setState({ selectedItem: item, loading: false }, callback); }); }); }, onUserListItemClicked: function onUserListItemClicked(item) { if (this.props.onItemSelected) { var uObject = new PydioUsers.User(item.id, item.label, item.type, item.group, item.avatar, item.temporary, item.external); if (item.trusted_server_id) { uObject.trustedServerId = item.trusted_server_id; uObject.trustedServerLabel = item.trusted_server_label; } this.props.onItemSelected(uObject); } else { this.setState({ rightPaneItem: item }); } }, onCreateAction: function onCreateAction(item) { this.setState({ createDialogItem: item }); }, closeCreateDialogAndReload: function closeCreateDialogAndReload() { this.setState({ createDialogItem: null }); this.reloadCurrentNode(); }, onCardUpdateAction: function onCardUpdateAction(item) { if (item._parent && item._parent === this.state.selectedItem) { this.reloadCurrentNode(); } }, onDeleteAction: function onDeleteAction(parentItem, selection) { if (!confirm(this.props.getMessage(278))) { return; } switch (parentItem.actions.type) { case 'users': selection.forEach((function (user) { if (this.state.rightPaneItem === user) this.setState({ rightPaneItem: null }); PydioUsers.Client.deleteUser(user.id, this.reloadCurrentNode.bind(this)); }).bind(this)); break; case 'teams': selection.forEach((function (team) { if (this.state.rightPaneItem === team) this.setState({ rightPaneItem: null }); PydioUsers.Client.deleteTeam(team.id.replace('/AJXP_TEAM/', ''), this.reloadCurrentNode.bind(this)); }).bind(this)); break; case 'team': _TeamCreationForm2['default'].updateTeamUsers(parentItem, 'delete', selection, this.reloadCurrentNode.bind(this)); break; default: break; } }, openPopover: function openPopover(event) { this.setState({ popoverOpen: true, popoverAnchor: event.currentTarget }); }, closePopover: function closePopover() { this.setState({ popoverOpen: false }); }, reloadCurrentNode: function reloadCurrentNode() { var _this3 = this; this.state.selectedItem.leafLoaded = false; this.state.selectedItem.collectionsLoaded = false; this.onFolderClicked(this.state.selectedItem, function () { if (_this3.state.rightPaneItem) { (function () { var rPaneId = _this3.state.rightPaneItem.id; var foundItem = null; var leafs = _this3.state.selectedItem.leafs || []; var collections = _this3.state.selectedItem.collections || []; [].concat(leafs, collections).forEach(function (leaf) { if (leaf.id === rPaneId) foundItem = leaf; }); _this3.setState({ rightPaneItem: foundItem }); })(); } }); }, reloadCurrentAtPage: function reloadCurrentAtPage(letterOrRange) { this.state.selectedItem.leafLoaded = false; this.state.selectedItem.collectionsLoaded = false; if (letterOrRange === -1) { this.state.selectedItem.currentParams = null; } else if (letterOrRange.indexOf('-') !== -1) { this.state.selectedItem.range = letterOrRange; } else { this.state.selectedItem.range = null; this.state.selectedItem.currentParams = { alpha_pages: 'true', value: letterOrRange }; } this.onFolderClicked(this.state.selectedItem); }, reloadCurrentWithSearch: function reloadCurrentWithSearch(value) { if (!value) { this.reloadCurrentAtPage(-1); return; } this.state.selectedItem.leafLoaded = false; this.state.selectedItem.collectionsLoaded = false; this.state.selectedItem.currentParams = { has_search: true, value: value, existing_only: true }; this.onFolderClicked(this.state.selectedItem); }, render: function render() { var _this4 = this; var _props2 = this.props; var mode = _props2.mode; var muiTheme = _props2.muiTheme; var getMessage = _props2.getMessage; if (mode === 'popover') { var popoverStyle = this.props.popoverStyle || {}; var popoverContainerStyle = this.props.popoverContainerStyle || {}; var iconButtonStyle = this.props.popoverIconButtonStyle || {}; var iconButton = React.createElement(IconButton, { style: _extends({ position: 'absolute', padding: 15, zIndex: 100, right: 0, top: 25, display: this.state.loading ? 'none' : 'initial' }, iconButtonStyle), iconStyle: { fontSize: 19, color: 'rgba(0,0,0,0.6)' }, iconClassName: 'mdi mdi-book-open-variant', onTouchTap: this.openPopover }); if (this.props.popoverButton) { iconButton = React.createElement(this.props.popoverButton.type, _extends({}, this.props.popoverButton.props, { onTouchTap: this.openPopover })); } return React.createElement( 'span', null, iconButton, React.createElement( Popover, { open: this.state.popoverOpen, anchorEl: this.state.popoverAnchor, anchorOrigin: { horizontal: 'right', vertical: 'top' }, targetOrigin: { horizontal: 'left', vertical: 'top' }, onRequestClose: this.closePopover, style: _extends({ marginLeft: 20 }, popoverStyle), zDepth: 2 }, React.createElement( 'div', { style: _extends({ width: 320, height: 420 }, popoverContainerStyle) }, React.createElement(AddressBook, _extends({}, this.props, { mode: 'selector' })) ) ) ); } var _state = this.state; var selectedItem = _state.selectedItem; var root = _state.root; var rightPaneItem = _state.rightPaneItem; var createDialogItem = _state.createDialogItem; var leftColumnStyle = { backgroundColor: colors.grey100, width: 256, overflowY: 'auto', overflowX: 'hidden' }; var centerComponent = undefined, rightPanel = undefined, leftPanel = undefined; if (selectedItem.id === 'search') { centerComponent = React.createElement(_SearchPanel2['default'], { item: selectedItem, title: getMessage(583, ''), searchLabel: getMessage(595, ''), onItemClicked: this.onUserListItemClicked, onFolderClicked: this.onFolderClicked, mode: mode }); } else if (selectedItem.type === 'remote') { centerComponent = React.createElement(_SearchPanel2['default'], { item: selectedItem, params: { trusted_server_id: selectedItem.id }, searchLabel: getMessage(595, ''), title: getMessage(596, '').replace('%s', selectedItem.label), onItemClicked: this.onUserListItemClicked, onFolderClicked: this.onFolderClicked, mode: mode }); } else { var emptyStatePrimary = undefined; var emptyStateSecondary = undefined; var otherProps = {}; if (selectedItem.id === 'teams') { emptyStatePrimary = getMessage(571, ''); emptyStateSecondary = getMessage(572, ''); } else if (selectedItem.id === 'ext') { emptyStatePrimary = getMessage(585, ''); emptyStateSecondary = getMessage(586, ''); } else if (selectedItem.id.indexOf('AJXP_GRP_/') === 0) { otherProps = { showSubheaders: true, paginatorType: !(selectedItem.currentParams && selectedItem.currentParams.has_search) && 'alpha', paginatorCallback: this.reloadCurrentAtPage.bind(this), enableSearch: !this.props.disableSearch, searchLabel: getMessage(595, ''), onSearch: this.reloadCurrentWithSearch.bind(this) }; } centerComponent = React.createElement(_UsersList2['default'], _extends({ item: selectedItem, onItemClicked: this.onUserListItemClicked, onFolderClicked: this.onFolderClicked, onCreateAction: this.onCreateAction, onDeleteAction: this.onDeleteAction, loading: this.state.loading, mode: mode, emptyStatePrimaryText: emptyStatePrimary, emptyStateSecondaryText: emptyStateSecondary, onTouchTap: this.state.rightPaneItem ? function () { _this4.setState({ rightPaneItem: null }); } : null }, otherProps)); } var rightPanelStyle = _extends({}, leftColumnStyle, { transformOrigin: 'right', backgroundColor: 'white' }); if (!rightPaneItem) { rightPanelStyle = _extends({}, rightPanelStyle, { transform: 'translateX(256px)', width: 0 }); } rightPanel = React.createElement(_RightPanelCard2['default'], { pydio: this.props.pydio, onRequestClose: function () { _this4.setState({ rightPaneItem: null }); }, style: rightPanelStyle, onCreateAction: this.onCreateAction, onDeleteAction: this.onDeleteAction, onUpdateAction: this.onCardUpdateAction, item: rightPaneItem }); if (mode === 'book') { leftPanel = React.createElement( MaterialUI.Paper, { zDepth: 0, style: _extends({}, leftColumnStyle, { zIndex: 2 }) }, React.createElement( MaterialUI.List, null, root.collections.map((function (e) { return React.createElement(_NestedListItem2['default'], { key: e.id, selected: selectedItem.id, nestedLevel: 0, entry: e, onTouchTap: this.onFolderClicked }); }).bind(this)) ) ); } var dialogTitle = undefined, dialogContent = undefined; if (createDialogItem) { if (createDialogItem.actions.type === 'users') { dialogTitle = getMessage(484, ''); dialogContent = React.createElement( 'div', { style: { height: 500 } }, React.createElement(AsyncComponent, { namespace: 'PydioForm', componentName: 'UserCreationForm', zDepth: 0, style: { height: 500 }, newUserName: "", onUserCreated: this.closeCreateDialogAndReload, onCancel: function () { _this4.setState({ createDialogItem: null }); }, pydio: this.props.pydio }) ); } else if (createDialogItem.actions.type === 'teams') { dialogTitle = getMessage(569, ''); dialogContent = React.createElement(_TeamCreationForm2['default'], { onTeamCreated: this.closeCreateDialogAndReload, onCancel: function () { _this4.setState({ createDialogItem: null }); } }); } else if (createDialogItem.actions.type === 'team') { var selectUser = function selectUser(item) { _TeamCreationForm2['default'].updateTeamUsers(createDialogItem, 'add', [item], _this4.reloadCurrentNode.bind(_this4)); }; dialogTitle = null; dialogContent = React.createElement(AddressBook, { pydio: this.props.pydio, mode: 'selector', usersOnly: true, disableSearch: true, onItemSelected: selectUser }); } } var style = this.props.style || {}; return React.createElement( 'div', { style: _extends({ display: 'flex', height: mode === 'selector' ? 420 : 450 }, style) }, leftPanel, centerComponent, rightPanel, React.createElement( MaterialUI.Dialog, { contentStyle: { width: 380, minWidth: 380, maxWidth: 380, padding: 0 }, bodyStyle: { padding: 0 }, title: React.createElement( 'div', { style: { padding: 20 } }, dialogTitle ), actions: null, modal: false, open: createDialogItem ? true : false, onRequestClose: function () { _this4.setState({ createDialogItem: null }); } }, dialogContent ) ); } }); exports['default'] = AddressBook = PydioContextConsumer(AddressBook); exports['default'] = AddressBook = muiThemeable()(AddressBook); exports['default'] = AddressBook; module.exports = exports['default']; },{"../TeamCreationForm":32,"./Loaders":36,"./NestedListItem":37,"./RightPanelCard":38,"./SearchPanel":40,"./UsersList":43,"material-ui":"material-ui","material-ui/styles":"material-ui/styles","pydio":"pydio","react":"react"}],35:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _react = require('react'); var _materialUiStyles = require('material-ui/styles'); var _pydio = require('pydio'); var _pydio2 = _interopRequireDefault(_pydio); var _materialUi = require('material-ui'); /** * Alphabet and pages generator to give a first-letter-based pagination */ var _Pydio$requireLib = _pydio2['default'].requireLib('boot'); var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer; var AlphaPaginator = (function (_Component) { _inherits(AlphaPaginator, _Component); function AlphaPaginator() { _classCallCheck(this, AlphaPaginator); _Component.apply(this, arguments); } AlphaPaginator.prototype.render = function render() { var letters = 'abcdefghijklmnopqrstuvwxyz0123456789'.split(''); letters = [-1].concat(letters); var _props = this.props; var item = _props.item; var paginatorCallback = _props.paginatorCallback; var style = _props.style; var getMessage = _props.getMessage; var paginator = undefined; if (item.pagination) { (function () { var _item$pagination = item.pagination; var start = _item$pagination.start; var end = _item$pagination.end; var max = _item$pagination.max; var interval = _item$pagination.interval; var total_pages = Math.ceil(max / interval); var current = Math.ceil(start / interval); var pages = []; for (var i = 0; i < total_pages; i++) { pages.push(i); }paginator = React.createElement( _materialUi.SelectField, { floatingLabelText: getMessage(331), style: { width: 60 }, fullWidth: true, value: current, onChange: function (e, i, v) { paginatorCallback(v * interval + '-' + (v + 1) * interval); } }, pages.map(function (p) { return React.createElement(_materialUi.MenuItem, { value: p, key: p, primaryText: p + 1 }); }) ); })(); } var currentPage = item.currentParams && item.currentParams.alpha_pages && item.currentParams.value || -1; return React.createElement( 'div', { style: _extends({}, style, { display: 'flex', paddingRight: 8, alignItems: 'center' }) }, React.createElement( 'div', { style: { flex: 1 } }, getMessage(249, '') ), paginator, React.createElement( _materialUi.SelectField, { floatingLabelText: getMessage(625), style: { width: 60, marginLeft: 20 }, fullWidth: true, value: currentPage, onChange: function (e, i, v) { paginatorCallback(v); } }, letters.map(function (l) { return React.createElement(_materialUi.MenuItem, { value: l, key: l, primaryText: l === -1 ? getMessage(597, '') : l }); }) ) ); }; return AlphaPaginator; })(_react.Component); AlphaPaginator.propTypes = { /** * Currently selected Item */ item: _react.PropTypes.object, /** * When a letter is clicked, function(letter) */ paginatorCallback: _react.PropTypes.func.isRequired, /** * Main instance of pydio */ pydio: _react.PropTypes.instanceOf(_pydio2['default']), /** * Display mode, either large (book) or small picker ('selector', 'popover'). */ mode: _react.PropTypes.oneOf(['book', 'selector', 'popover']).isRequired }; exports['default'] = AlphaPaginator = PydioContextConsumer(AlphaPaginator); exports['default'] = AlphaPaginator = _materialUiStyles.muiThemeable()(AlphaPaginator); exports['default'] = AlphaPaginator; module.exports = exports['default']; },{"material-ui":"material-ui","material-ui/styles":"material-ui/styles","pydio":"pydio","react":"react"}],36:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } var Loaders = (function () { function Loaders() { _classCallCheck(this, Loaders); } Loaders.childrenAsPromise = function childrenAsPromise(item) { var leaf = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; var childrenLoader = item.childrenLoader; var itemsLoader = item.itemsLoader; var leafLoaded = item.leafLoaded; var collectionsLoaded = item.collectionsLoaded; var leafs = item.leafs; var collections = item.collections; var loader = leaf ? itemsLoader : childrenLoader; var loaded = leaf ? leafLoaded : collectionsLoaded; return new Promise(function (resolve, reject) { if (!loaded && loader) { loader(item, function (newChildren) { if (leaf) { item.leafs = newChildren; item.leafLoaded = true; } else { item.collections = newChildren; item.collectionsLoaded = true; } resolve(newChildren); }); } else { var res = (leaf ? leafs : collections) || []; resolve(res); } }); }; Loaders.listUsers = function listUsers(params, callback) { var parent = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2]; var baseParams = { get_action: 'user_list_authorized_users', format: 'json' }; baseParams = _extends({}, baseParams, params); var cb = callback; if (parent) { if (parent.range) { baseParams['range'] = parent.range; } cb = function (children) { callback(children.map(function (c) { c._parent = parent;return c; })); }; } PydioApi.getClient().request(baseParams, function (transport) { cb(transport.responseJSON); var cRange = transport.responseObject.headers.get('Content-Range'); var aRange = transport.responseObject.headers.get('Accept-Range'); if (cRange && aRange && parent) { var _aRange$split = aRange.split(' '); var type = _aRange$split[0]; var interval = _aRange$split[1]; var _cRange$split = cRange.split('/'); var range = _cRange$split[0]; var max = _cRange$split[1]; var _range$split = range.split('-'); var start = _range$split[0]; var end = _range$split[1]; parent.pagination = { start: parseInt(start), end: parseInt(end), max: parseInt(max), interval: parseInt(interval) }; } }); }; Loaders.loadTeams = function loadTeams(entry, callback) { var wrapped = function wrapped(children) { children.map(function (child) { child.icon = 'mdi mdi-account-multiple'; child.itemsLoader = Loaders.loadTeamUsers; child.actions = { type: 'team', create: '573', remove: '574', multiple: true }; child._notSelectable = true; }); callback(children); }; Loaders.listUsers({ filter_value: 8 }, wrapped, entry); }; Loaders.loadGroups = function loadGroups(entry, callback) { var wrapped = function wrapped(children) { children.map(function (child) { child.icon = 'mdi mdi-account-multiple'; child.childrenLoader = entry.childrenLoader ? Loaders.loadGroups : null; child.itemsLoader = entry.itemsLoader ? Loaders.loadGroupUsers : null; if (entry.currentParams && entry.currentParams.alpha_pages) { child.currentParams = _extends({}, entry.currentParams); } }); callback(children); }; var path = entry.id.replace('AJXP_GRP_', ''); var params = { filter_value: 4, group_path: path }; if (entry.currentParams && !entry.currentParams.alpha_pages) { params = _extends({}, params, entry.currentParams); } Loaders.listUsers(params, wrapped, entry); }; Loaders.loadExternalUsers = function loadExternalUsers(entry, callback) { Loaders.listUsers({ filter_value: 2 }, callback, entry); }; Loaders.loadGroupUsers = function loadGroupUsers(entry, callback) { var path = entry.id.replace('AJXP_GRP_', ''); var params = { filter_value: 1, group_path: path }; if (entry.currentParams) { params = _extends({}, params, entry.currentParams); } Loaders.listUsers(params, callback, entry); }; Loaders.loadTeamUsers = function loadTeamUsers(entry, callback) { Loaders.listUsers({ filter_value: 3, group_path: entry.id }, callback, entry); }; return Loaders; })(); exports['default'] = Loaders; module.exports = exports['default']; },{}],37:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _require = require('react'); var Component = _require.Component; var PropTypes = _require.PropTypes; /** * Left panel of the address book * Display treeview hierarchy of users, teams, groups. */ var NestedListItem = (function (_Component) { _inherits(NestedListItem, _Component); function NestedListItem() { _classCallCheck(this, NestedListItem); _Component.apply(this, arguments); } /** * Triggers this.props.onTouchTap */ NestedListItem.prototype.onTouchTap = function onTouchTap() { this.props.onTouchTap(this.props.entry); }; /** * Recursively build other NestedListItem * @param data */ NestedListItem.prototype.buildNestedItems = function buildNestedItems(data) { return data.map((function (entry) { return React.createElement(NestedListItem, { nestedLevel: this.props.nestedLevel + 1, entry: entry, onTouchTap: this.props.onTouchTap, selected: this.props.selected }); }).bind(this)); }; NestedListItem.prototype.render = function render() { var _props$entry = this.props.entry; var id = _props$entry.id; var label = _props$entry.label; var icon = _props$entry.icon; var selected = _props$entry.selected; var children = this.props.entry.collections || []; var nested = this.buildNestedItems(children); var fontIcon = undefined; if (icon) { fontIcon = React.createElement(MaterialUI.FontIcon, { className: icon }); } return React.createElement(MaterialUI.ListItem, { nestedLevel: this.props.nestedLevel, key: id, primaryText: label, onTouchTap: this.onTouchTap.bind(this), nestedItems: nested, initiallyOpen: true, leftIcon: false && fontIcon, innerDivStyle: { fontWeight: this.props.selected === this.props.entry.id ? 500 : 400 } }); }; return NestedListItem; })(Component); NestedListItem.propTypes = { /** * Keeps track of the current depth level */ nestedLevel: PropTypes.number, /** * Currently selected node id */ selected: PropTypes.string, /** * Callback triggered when an entry is selected */ onTouchTap: PropTypes.func }; exports['default'] = NestedListItem; module.exports = exports['default']; },{"react":"react"}],38:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _TeamCard = require('./TeamCard'); var _TeamCard2 = _interopRequireDefault(_TeamCard); var _UserCard = require('./UserCard'); var _UserCard2 = _interopRequireDefault(_UserCard); var React = require('react'); var _require = require('material-ui'); var Paper = _require.Paper; /** * Container for UserCard or TeamCard */ var RightPanelCard = (function (_React$Component) { _inherits(RightPanelCard, _React$Component); function RightPanelCard() { _classCallCheck(this, RightPanelCard); _React$Component.apply(this, arguments); } RightPanelCard.prototype.render = function render() { var content = undefined; var item = this.props.item || {}; if (item.type === 'user') { content = React.createElement(_UserCard2['default'], this.props); } else if (item.type === 'group' && item.id.indexOf('/AJXP_TEAM/') === 0) { content = React.createElement(_TeamCard2['default'], this.props); } return React.createElement( Paper, { zDepth: 2, style: _extends({ position: 'relative' }, this.props.style) }, content ); }; return RightPanelCard; })(React.Component); RightPanelCard.propTypes = { /** * Pydio instance */ pydio: React.PropTypes.instanceOf(Pydio), /** * Selected item */ item: React.PropTypes.object, /** * Applies to root container */ style: React.PropTypes.object, /** * Forwarded to child */ onRequestClose: React.PropTypes.func, /** * Forwarded to child */ onDeleteAction: React.PropTypes.func, /** * Forwarded to child */ onUpdateAction: React.PropTypes.func }; exports['default'] = RightPanelCard; module.exports = exports['default']; },{"./TeamCard":41,"./UserCard":42,"material-ui":"material-ui","react":"react"}],39:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _require = require('react'); var Component = _require.Component; var PropTypes = _require.PropTypes; /** * Ready to use Form + Result List for search users */ var SearchForm = (function (_Component) { _inherits(SearchForm, _Component); function SearchForm(props, context) { _classCallCheck(this, SearchForm); _Component.call(this, props.context); this.state = { value: '' }; } SearchForm.prototype.search = function search() { this.props.onSearch(this.state.value); }; SearchForm.prototype.onChange = function onChange(event, value) { this.setState({ value: value }); FuncUtils.bufferCallback('search_users_list', 300, this.search.bind(this)); }; SearchForm.prototype.render = function render() { return React.createElement( 'div', { style: _extends({ minWidth: 320 }, this.props.style) }, React.createElement(MaterialUI.TextField, { fullWidth: true, value: this.state.value, onChange: this.onChange.bind(this), hintText: this.props.searchLabel }) ); }; return SearchForm; })(Component); SearchForm.propTypes = { /** * Label displayed in the search field */ searchLabel: PropTypes.string.isRequired, /** * Callback triggered to search */ onSearch: PropTypes.func.isRequired, /** * Will be appended to the root element */ style: PropTypes.object }; exports['default'] = SearchForm; module.exports = exports['default']; },{"react":"react"}],40:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _SearchForm = require('./SearchForm'); var _SearchForm2 = _interopRequireDefault(_SearchForm); var _UsersList = require('./UsersList'); var _UsersList2 = _interopRequireDefault(_UsersList); var _Loaders = require('./Loaders'); var _Loaders2 = _interopRequireDefault(_Loaders); /** * Ready to use Form + Result List for search users */ var _require = require('react'); var Component = _require.Component; var PropTypes = _require.PropTypes; var _require$requireLib = require('pydio').requireLib('boot'); var PydioContextConsumer = _require$requireLib.PydioContextConsumer; var SearchPanel = (function (_Component) { _inherits(SearchPanel, _Component); function SearchPanel(props, context) { _classCallCheck(this, SearchPanel); _Component.call(this, props.context); this.state = { items: [] }; } SearchPanel.prototype.onSearch = function onSearch(value) { var _this = this; if (!value) { this.setState({ items: [] }); return; } var params = { value: value, existing_only: 'true' }; if (this.props.params) { params = _extends({}, params, this.props.params); } _Loaders2['default'].listUsers(params, function (children) { _this.setState({ items: children }); }); }; SearchPanel.prototype.render = function render() { var _this2 = this; var _props = this.props; var mode = _props.mode; var item = _props.item; var getMessage = _props.getMessage; return React.createElement( 'div', { style: { flex: 1, display: 'flex', flexDirection: 'column' } }, React.createElement( 'div', { style: { padding: 10, height: 56, backgroundColor: this.state.select ? activeTbarColor : '#fafafa', display: 'flex', alignItems: 'center', transition: DOMUtils.getBeziersTransition() } }, mode === "selector" && item._parent && React.createElement(MaterialUI.IconButton, { iconClassName: 'mdi mdi-chevron-left', onTouchTap: function () { _this2.props.onFolderClicked(item._parent); } }), mode === 'book' && React.createElement( 'div', { style: { fontSize: 20, color: 'rgba(0,0,0,0.87)', flex: 1 } }, this.props.title ), React.createElement(_SearchForm2['default'], { style: mode === 'book' ? { minWidth: 320 } : { flex: 1 }, searchLabel: this.props.searchLabel, onSearch: this.onSearch.bind(this) }) ), React.createElement(_UsersList2['default'], { mode: this.props.mode, onItemClicked: this.props.onItemClicked, item: { leafs: this.state.items }, noToolbar: true, emptyStatePrimaryText: getMessage(587, ''), emptyStateSecondaryText: getMessage(588, '') }) ); }; return SearchPanel; })(Component); SearchPanel.propTypes = { /** * Optional parameters added to listUsers() request */ params: PropTypes.object, /** * Label displayed in the toolbar */ searchLabel: PropTypes.string, /** * Callback triggered when a search result is clicked */ onItemClicked: PropTypes.func, /** * Currently selected item, required for navigation */ item: PropTypes.object, /** * Callback triggered if the result is a collection */ onFolderClicked: PropTypes.func }; exports['default'] = SearchPanel = PydioContextConsumer(SearchPanel); exports['default'] = SearchPanel; module.exports = exports['default']; },{"./Loaders":36,"./SearchForm":39,"./UsersList":43,"pydio":"pydio","react":"react"}],41:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _UsersList = require('./UsersList'); var _UsersList2 = _interopRequireDefault(_UsersList); var _Loaders = require('./Loaders'); var _Loaders2 = _interopRequireDefault(_Loaders); var _avatarActionsPanel = require('../avatar/ActionsPanel'); var _avatarActionsPanel2 = _interopRequireDefault(_avatarActionsPanel); var React = require('react'); var _require = require('material-ui'); var TextField = _require.TextField; var FlatButton = _require.FlatButton; var CardTitle = _require.CardTitle; var Divider = _require.Divider; var _require$requireLib = require('pydio').requireLib('boot'); var PydioContextConsumer = _require$requireLib.PydioContextConsumer; /** * Display info about a Team inside a popover-able card */ var TeamCard = (function (_React$Component) { _inherits(TeamCard, _React$Component); function TeamCard(props, context) { _classCallCheck(this, TeamCard); _React$Component.call(this, props, context); this.state = { label: this.props.item.label }; } /** * Use loader to get team participants * @param item */ TeamCard.prototype.loadMembers = function loadMembers(item) { var _this = this; this.setState({ loading: true }); _Loaders2['default'].childrenAsPromise(item, false).then(function (children) { _Loaders2['default'].childrenAsPromise(item, true).then(function (children) { _this.setState({ members: item.leafs, loading: false }); }); }); }; TeamCard.prototype.componentWillMount = function componentWillMount() { this.loadMembers(this.props.item); }; TeamCard.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { this.loadMembers(nextProps.item); this.setState({ label: nextProps.item.label }); }; TeamCard.prototype.onLabelChange = function onLabelChange(e, value) { this.setState({ label: value }); }; TeamCard.prototype.updateLabel = function updateLabel() { var _this2 = this; if (this.state.label !== this.props.item.label) { PydioUsers.Client.updateTeamLabel(this.props.item.id.replace('/AJXP_TEAM/', ''), this.state.label, function () { _this2.props.onUpdateAction(_this2.props.item); }); } this.setState({ editMode: false }); }; TeamCard.prototype.render = function render() { var _this3 = this; var _props = this.props; var item = _props.item; var onDeleteAction = _props.onDeleteAction; var onCreateAction = _props.onCreateAction; var getMessage = _props.getMessage; var editProps = { team: item, userEditable: true, onDeleteAction: function onDeleteAction() { _this3.props.onDeleteAction(item._parent, [item]); }, onEditAction: function onEditAction() { _this3.setState({ editMode: !_this3.state.editMode }); }, reloadAction: function reloadAction() { _this3.props.onUpdateAction(item); } }; var title = undefined; if (this.state.editMode) { title = React.createElement( 'div', { style: { display: 'flex', alignItems: 'center', margin: 16 } }, React.createElement(TextField, { style: { flex: 1, fontSize: 24 }, fullWidth: true, disabled: false, underlineShow: false, value: this.state.label, onChange: this.onLabelChange.bind(this) }), React.createElement(FlatButton, { secondary: true, label: getMessage(48), onTouchTap: function () { _this3.updateLabel(); } }) ); } else { title = React.createElement(CardTitle, { title: this.state.label, subtitle: item.leafs && item.leafs.length ? getMessage(576).replace('%s', item.leafs.length) : getMessage(577) }); } return React.createElement( 'div', null, title, React.createElement(_avatarActionsPanel2['default'], _extends({}, this.props, editProps)), React.createElement(Divider, null), React.createElement(_UsersList2['default'], { subHeader: getMessage(575), onItemClicked: function () {}, item: item, mode: 'inner', onDeleteAction: onDeleteAction }) ); }; return TeamCard; })(React.Component); TeamCard.propTypes = { /** * Pydio instance */ pydio: React.PropTypes.instanceOf(Pydio), /** * Team data object */ item: React.PropTypes.object, /** * Applied to root container */ style: React.PropTypes.object, /** * Called to dismiss the popover */ onRequestClose: React.PropTypes.func, /** * Delete current team */ onDeleteAction: React.PropTypes.func, /** * Update current team */ onUpdateAction: React.PropTypes.func }; exports['default'] = TeamCard = PydioContextConsumer(TeamCard); exports['default'] = TeamCard; module.exports = exports['default']; },{"../avatar/ActionsPanel":44,"./Loaders":36,"./UsersList":43,"material-ui":"material-ui","pydio":"pydio","react":"react"}],42:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _avatarUserAvatar = require('../avatar/UserAvatar'); var _avatarUserAvatar2 = _interopRequireDefault(_avatarUserAvatar); var React = require('react'); var _require$requireLib = require('pydio').requireLib('boot'); var AsyncComponent = _require$requireLib.AsyncComponent; /** * Card presentation of a user. Relies on the UserAvatar object, * plus the PydioForm.UserCreationForm when in edit mode. */ var UserCard = (function (_React$Component) { _inherits(UserCard, _React$Component); function UserCard(props, context) { _classCallCheck(this, UserCard); _React$Component.call(this, props, context); this.state = { editForm: false }; } UserCard.prototype.render = function render() { var _this = this; var item = this.props.item; var editableProps = {}, editForm = undefined; if (item._parent && item._parent.id === 'ext') { editableProps = { userEditable: true, onDeleteAction: function onDeleteAction() { _this.props.onDeleteAction(item._parent, [item]); }, onEditAction: function onEditAction() { _this.setState({ editForm: true }); }, reloadAction: function reloadAction() { _this.props.onUpdateAction(item); } }; } if (this.state.editForm) { editForm = React.createElement(AsyncComponent, { namespace: 'PydioForm', componentName: 'UserCreationForm', pydio: this.props.pydio, zDepth: 0, style: { height: 500 }, newUserName: item.id, editMode: true, userData: item, onUserCreated: function () { _this.props.onUpdateAction(item);_this.setState({ editForm: false }); }, onCancel: function () { _this.setState({ editForm: false }); } }); } return React.createElement( 'div', null, React.createElement( _avatarUserAvatar2['default'], _extends({ userId: this.props.item.id, richCard: true, pydio: this.props.pydio, cardSize: this.props.style.width }, editableProps), editForm ) ); }; return UserCard; })(React.Component); UserCard.propTypes = { /** * Pydio instance */ pydio: React.PropTypes.instanceOf(Pydio), /** * Team data object */ item: React.PropTypes.object, /** * Applied to root container */ style: React.PropTypes.object, /** * Called to dismiss the popover */ onRequestClose: React.PropTypes.func, /** * Delete current team */ onDeleteAction: React.PropTypes.func, /** * Update current team */ onUpdateAction: React.PropTypes.func }; exports['default'] = UserCard; module.exports = exports['default']; },{"../avatar/UserAvatar":46,"pydio":"pydio","react":"react"}],43:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _avatarUserAvatar = require('../avatar/UserAvatar'); var _avatarUserAvatar2 = _interopRequireDefault(_avatarUserAvatar); var _viewsEmptyStateView = require('../../views/EmptyStateView'); var _viewsEmptyStateView2 = _interopRequireDefault(_viewsEmptyStateView); var _AlphaPaginator = require('./AlphaPaginator'); var _AlphaPaginator2 = _interopRequireDefault(_AlphaPaginator); var _SearchForm = require('./SearchForm'); var _SearchForm2 = _interopRequireDefault(_SearchForm); var _require = require('material-ui'); var IconButton = _require.IconButton; var Checkbox = _require.Checkbox; var FlatButton = _require.FlatButton; var RaisedButton = _require.RaisedButton; var ListItem = _require.ListItem; var FontIcon = _require.FontIcon; var Avatar = _require.Avatar; var Divider = _require.Divider; var Subheader = _require.Subheader; var List = _require.List; var _require2 = require('material-ui/styles'); var muiThemeable = _require2.muiThemeable; var _require$requireLib = require('pydio').requireLib('boot'); var Loader = _require$requireLib.Loader; var PydioContextConsumer = _require$requireLib.PydioContextConsumer; var UsersList = (function (_React$Component) { _inherits(UsersList, _React$Component); function UsersList(props, context) { _classCallCheck(this, UsersList); _React$Component.call(this, props, context); this.state = { select: false, selection: [] }; } UsersList.prototype.render = function render() { var _this = this; var _props = this.props; var item = _props.item; var mode = _props.mode; var paginatorType = _props.paginatorType; var loading = _props.loading; var enableSearch = _props.enableSearch; var showSubheaders = _props.showSubheaders; var getMessage = _props.getMessage; var folders = item.collections || []; var leafs = item.leafs || []; var foldersSubHeader = folders.length && (leafs.length || showSubheaders) ? [{ subheader: getMessage('532') }] : []; var usersSubHeader = []; if ((showSubheaders || paginatorType) && leafs.length) { usersSubHeader = [{ subheader: paginatorType ? React.createElement(_AlphaPaginator2['default'], _extends({}, this.props, { style: { lineHeight: '20px', padding: '14px 0' } })) : getMessage('249') }]; } var items = [].concat(foldersSubHeader, folders, usersSubHeader, leafs); var total = items.length; var elements = []; var toggleSelect = function toggleSelect() { _this.setState({ select: !_this.state.select, selection: [] }); }; var createAction = function createAction() { _this.props.onCreateAction(item); }; var deleteAction = function deleteAction() { _this.props.onDeleteAction(item, _this.state.selection);_this.setState({ select: false, selection: [] }); }; var activeTbarColor = this.props.muiTheme.palette.accent2Color; var toolbar = React.createElement( 'div', { style: { padding: 10, height: 56, backgroundColor: this.state.select ? activeTbarColor : '#fafafa', display: 'flex', alignItems: 'center', transition: DOMUtils.getBeziersTransition() } }, mode === "selector" && item._parent && React.createElement(IconButton, { iconClassName: 'mdi mdi-chevron-left', onTouchTap: function () { _this.props.onFolderClicked(item._parent); } }), mode === 'book' && total > 0 && item.actions && item.actions.multiple && React.createElement(Checkbox, { style: { width: 'initial', marginLeft: this.state.select ? 7 : 14 }, checked: this.state.select, onCheck: toggleSelect }), React.createElement( 'div', { style: { flex: 1, fontSize: 20, color: this.state.select ? 'white' : 'rgba(0,0,0,0.87)' } }, item.label ), mode === 'book' && item.actions && item.actions.create && !this.state.select && React.createElement(FlatButton, { secondary: true, label: getMessage(item.actions.create), onTouchTap: createAction }), mode === 'book' && item.actions && item.actions.remove && this.state.select && React.createElement(RaisedButton, { secondary: true, label: getMessage(item.actions.remove), disabled: !this.state.selection.length, onTouchTap: deleteAction }), enableSearch && React.createElement(_SearchForm2['default'], { searchLabel: this.props.searchLabel, onSearch: this.props.onSearch, style: { flex: 1, minWidth: 200 } }) ); // PARENT NODE if (item._parent && mode === 'book' && item._parent._parent) { elements.push(React.createElement(ListItem, { key: '__parent__', primaryText: "..", onTouchTap: function (e) { e.stopPropagation();_this.props.onFolderClicked(item._parent); }, leftAvatar: React.createElement(Avatar, { icon: React.createElement(FontIcon, { className: 'mdi mdi-arrow-up' }) }) })); if (total) { elements.push(React.createElement(Divider, { inset: true, key: 'parent-divider' })); } } // ITEMS items.forEach((function (item, index) { var _this2 = this; if (item.subheader) { elements.push(React.createElement( Subheader, null, item.subheader )); return; } var fontIcon = React.createElement(_avatarUserAvatar2['default'], { avatarSize: 36, pydio: this.props.pydio || pydio, userId: item.id, userLabel: item.label, avatar: item.avatar, icon: item.icon, avatarOnly: true, useDefaultAvatar: true }); var rightIconButton = undefined; var touchTap = function touchTap(e) { e.stopPropagation();_this2.props.onItemClicked(item); }; if (folders.indexOf(item) > -1 && this.props.onFolderClicked) { touchTap = function (e) { e.stopPropagation();_this2.props.onFolderClicked(item); }; if (mode === 'selector' && !item._notSelectable) { rightIconButton = React.createElement(IconButton, { iconClassName: "mdi mdi-account-multiple-plus", tooltip: "Select this group", tooltipPosition: 'bottom-left', onTouchTap: function () { _this2.props.onItemClicked(item); } }); } } else if (mode === 'inner' && this.props.onDeleteAction) { rightIconButton = React.createElement(IconButton, { iconClassName: "mdi mdi-delete", tooltip: getMessage(257), tooltipPosition: 'bottom-left', iconStyle: { color: 'rgba(0,0,0,0.13)', hoverColor: 'rgba(0,0,0,0.53)' }, onTouchTap: function () { _this2.props.onDeleteAction(_this2.props.item, [item]); } }); } var select = function select(e, checked) { if (checked) { _this2.setState({ selection: [].concat(_this2.state.selection, [item]) }); } else { var stateSel = _this2.state.selection; var selection = [].concat(stateSel.slice(0, stateSel.indexOf(item)), stateSel.slice(stateSel.indexOf(item) + 1)); _this2.setState({ selection: selection }); } }; elements.push(React.createElement(ListItem, { key: item.id, primaryText: item.label, onTouchTap: touchTap, disabled: mode === 'inner', leftAvatar: !this.state.select && fontIcon, rightIconButton: rightIconButton, leftCheckbox: this.state.select && React.createElement(Checkbox, { checked: this.state.selection.indexOf(item) > -1, onCheck: select }) })); if (mode !== 'inner' && index < total - 1) { elements.push(React.createElement(Divider, { inset: true, key: item.id + '-divider' })); } }).bind(this)); var emptyState = undefined; if (!elements.length) { var emptyStateProps = { style: { backgroundColor: 'rgb(250, 250, 250)' }, iconClassName: 'mdi mdi-account-off', primaryTextId: this.props.emptyStatePrimaryText || getMessage(629), secondaryTextId: mode === 'book' ? this.props.emptyStateSecondaryText || null : null }; if (mode === 'book' && item.actions && item.actions.create) { emptyStateProps = _extends({}, emptyStateProps, { actionLabelId: getMessage(item.actions.create), actionCallback: createAction }); } emptyState = React.createElement(_viewsEmptyStateView2['default'], emptyStateProps); } return React.createElement( 'div', { style: { flex: 1, flexDirection: 'column', display: 'flex' }, onTouchTap: this.props.onTouchTap }, mode !== 'inner' && /*(!emptyState || mode !== 'book') &&*/!this.props.noToolbar && toolbar, !emptyState && !loading && React.createElement( List, { style: { flex: 1, overflowY: mode !== 'inner' ? 'auto' : 'initial' } }, this.props.subHeader && React.createElement( Subheader, null, this.props.subHeader ), elements ), loading && React.createElement(Loader, { style: { flex: 1 } }), !loading && emptyState ); }; return UsersList; })(React.Component); UsersList.propTypes = { item: React.PropTypes.object, onCreateAction: React.PropTypes.func, onDeleteAction: React.PropTypes.func, onItemClicked: React.PropTypes.func, onFolderClicked: React.PropTypes.func, mode: React.PropTypes.oneOf(['book', 'selector', 'inner']) }; exports['default'] = UsersList = PydioContextConsumer(UsersList); exports['default'] = UsersList = muiThemeable()(UsersList); exports['default'] = UsersList; module.exports = exports['default']; },{"../../views/EmptyStateView":49,"../avatar/UserAvatar":46,"./AlphaPaginator":35,"./SearchForm":39,"material-ui":"material-ui","material-ui/styles":"material-ui/styles","pydio":"pydio"}],44:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _addressbookAddressBook = require('../addressbook/AddressBook'); var _addressbookAddressBook2 = _interopRequireDefault(_addressbookAddressBook); var React = require('react'); var _require = require('pydio/http/users-api'); var UsersApi = _require.UsersApi; var ResourcesManager = require('pydio/http/resources-manager'); var _require2 = require('material-ui'); var IconButton = _require2.IconButton; var Popover = _require2.Popover; var _require3 = require('material-ui/styles'); var muiThemeable = _require3.muiThemeable; var _require$requireLib = require('pydio').requireLib('boot'); var PydioContextConsumer = _require$requireLib.PydioContextConsumer; var AsyncComponent = _require$requireLib.AsyncComponent; var ActionsPanel = (function (_React$Component) { _inherits(ActionsPanel, _React$Component); function ActionsPanel(props, context) { _classCallCheck(this, ActionsPanel); _React$Component.call(this, props, context); this.state = { showPicker: false, pickerAnchor: null, showMailer: false, mailerAnchor: null }; } ActionsPanel.prototype.onTeamSelected = function onTeamSelected(item) { this.setState({ showPicker: false }); if (item.getType() === 'group' && item.getId().indexOf('/AJXP_TEAM/') === 0) { UsersApi.addUserToTeam(item.getId().replace('/AJXP_TEAM/', ''), this.props.userId, this.props.reloadAction); } }; ActionsPanel.prototype.onUserSelected = function onUserSelected(item) { this.setState({ showPicker: false }); UsersApi.addUserToTeam(this.props.team.id, item.getId(), this.props.reloadAction); }; ActionsPanel.prototype.openPicker = function openPicker(event) { this.setState({ showPicker: true, pickerAnchor: event.currentTarget }); }; ActionsPanel.prototype.openMailer = function openMailer(event) { var _this = this; var target = event.currentTarget; ResourcesManager.loadClassesAndApply(['PydioMailer'], function () { _this.setState({ mailerLibLoaded: true }, function () { _this.setState({ showMailer: true, mailerAnchor: target }); }); }); }; ActionsPanel.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState) { if (!this.props.lockOnSubPopoverOpen) return; if ((this.state.showPicker || this.state.showMailer) && !(prevState.showPicker || prevState.showMailer)) { this.props.lockOnSubPopoverOpen(true); } else if (!(this.state.showPicker || this.state.showMailer) && (prevState.showPicker || prevState.showMailer)) { this.props.lockOnSubPopoverOpen(false); } }; ActionsPanel.prototype.render = function render() { var _this2 = this; var _props = this.props; var getMessage = _props.getMessage; var muiTheme = _props.muiTheme; var team = _props.team; var user = _props.user; var userEditable = _props.userEditable; var styles = { button: { backgroundColor: muiTheme.palette.accent2Color, borderRadius: '50%', margin: '0 4px', width: 44, height: 44, padding: 10 }, icon: { color: 'white' } }; var mailer = undefined, usermails = {}; var actions = []; if (user && user.hasEmail) { actions.push({ key: 'message', label: getMessage(598), icon: 'email', callback: this.openMailer.bind(this) }); usermails[this.props.user.id] = PydioUsers.User.fromObject(this.props.user); } if (team) { actions.push({ key: 'users', label: getMessage(599), icon: 'account-multiple-plus', callback: this.openPicker.bind(this) }); } else { actions.push({ key: 'teams', label: getMessage(573), icon: 'account-multiple-plus', callback: this.openPicker.bind(this) }); } if (userEditable) { actions.push({ key: 'edit', label: this.props.team ? getMessage(580) : getMessage(600), icon: 'pencil', callback: this.props.onEditAction }); actions.push({ key: 'delete', label: this.props.team ? getMessage(570) : getMessage(582), icon: 'delete', callback: this.props.onDeleteAction }); } return React.createElement( 'div', { style: { textAlign: 'center', marginBottom: 16 } }, actions.map(function (a) { return React.createElement(IconButton, { key: a.key, style: styles.button, iconStyle: styles.icon, tooltip: a.label, iconClassName: "mdi mdi-" + a.icon, onTouchTap: a.callback }); }), React.createElement( Popover, { open: this.state.showPicker, anchorEl: this.state.pickerAnchor, anchorOrigin: { horizontal: 'right', vertical: 'top' }, targetOrigin: { horizontal: 'right', vertical: 'top' }, onRequestClose: function () { _this2.setState({ showPicker: false }); }, useLayerForClickAway: false, style: { zIndex: 2200 } }, React.createElement( 'div', { style: { width: 256, height: 320 } }, React.createElement(_addressbookAddressBook2['default'], { mode: 'selector', pydio: this.props.pydio, loaderStyle: { width: 320, height: 420 }, onItemSelected: this.props.team ? this.onUserSelected.bind(this) : this.onTeamSelected.bind(this), teamsOnly: this.props.team ? false : true, usersOnly: this.props.team ? true : false }) ) ), React.createElement( Popover, { open: this.state.showMailer, anchorEl: this.state.mailerAnchor, anchorOrigin: { horizontal: 'right', vertical: 'top' }, targetOrigin: { horizontal: 'right', vertical: 'top' }, useLayerForClickAway: false, style: { zIndex: 2200 } }, React.createElement( 'div', { style: { width: 256, height: 320 } }, this.state.mailerLibLoaded && React.createElement(AsyncComponent, { namespace: 'PydioMailer', componentName: 'Pane', zDepth: 0, panelTitle: getMessage(598), uniqueUserStyle: true, users: usermails, onDismiss: function () { _this2.setState({ showMailer: false }); }, onFieldFocus: this.props.otherPopoverMouseOver }) ) ) ); }; return ActionsPanel; })(React.Component); ActionsPanel.propTypes = { /** * User data, props must pass at least one of 'user' or 'team' */ user: React.PropTypes.object, /** * Team data, props must pass at least one of 'user' or 'team' */ team: React.PropTypes.object, /** * For users, whether it is editable or not */ userEditable: React.PropTypes.object }; exports['default'] = ActionsPanel = PydioContextConsumer(ActionsPanel); exports['default'] = ActionsPanel = muiThemeable()(ActionsPanel); exports['default'] = ActionsPanel; module.exports = exports['default']; },{"../addressbook/AddressBook":34,"material-ui":"material-ui","material-ui/styles":"material-ui/styles","pydio":"pydio","pydio/http/resources-manager":"pydio/http/resources-manager","pydio/http/users-api":"pydio/http/users-api","react":"react"}],45:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _addressbookUsersList = require('../addressbook/UsersList'); var _addressbookUsersList2 = _interopRequireDefault(_addressbookUsersList); var _require = require('react'); var Component = _require.Component; var PropTypes = _require.PropTypes; var _require2 = require('material-ui'); var Divider = _require2.Divider; var _require3 = require('pydio/http/users-api'); var UsersApi = _require3.UsersApi; var _require$requireLib = require('pydio').requireLib('boot'); var PydioContextConsumer = _require$requireLib.PydioContextConsumer; /** * Display information about user or team relations */ var GraphPanel = (function (_Component) { _inherits(GraphPanel, _Component); function GraphPanel() { _classCallCheck(this, GraphPanel); _Component.apply(this, arguments); } GraphPanel.prototype.render = function render() { var _props = this.props; var graph = _props.graph; var userLabel = _props.userLabel; var pydio = _props.pydio; var getMessage = _props.getMessage; var elements = []; if (graph.teams && graph.teams.length) { var onDeleteAction = (function (parentItem, team) { var _this = this; UsersApi.removeUserFromTeam(team[0].id, this.props.userId, function (response) { if (response.message) pydio.UI.displayMessage('SUCCESS', response.message); _this.props.reloadAction(); }); }).bind(this); elements.push(React.createElement( 'div', { key: 'teams' }, React.createElement(Divider, null), React.createElement(_addressbookUsersList2['default'], { subHeader: getMessage(581).replace('%s', graph.teams.length), onItemClicked: function () {}, item: { leafs: graph.teams }, mode: 'inner', onDeleteAction: onDeleteAction }) )); } if (graph.source && Object.keys(graph.source).length) { elements.push(React.createElement( 'div', { key: 'source' }, elements.length ? React.createElement(Divider, null) : null, React.createElement( 'div', { style: { padding: 16 } }, getMessage(601).replace('%1', userLabel).replace('%2', Object.keys(graph.source).length) ) )); } if (graph.target && Object.keys(graph.target).length) { elements.push(React.createElement( 'div', { key: 'target' }, elements.length ? React.createElement(Divider, null) : null, React.createElement( 'div', { style: { padding: 16 } }, getMessage(602).replace('%1', userLabel).replace('%2', Object.keys(graph.target).length) ) )); } return React.createElement( 'div', null, elements ); }; return GraphPanel; })(Component); exports['default'] = GraphPanel = PydioContextConsumer(GraphPanel); exports['default'] = GraphPanel; module.exports = exports['default']; },{"../addressbook/UsersList":43,"material-ui":"material-ui","pydio":"pydio","pydio/http/users-api":"pydio/http/users-api","react":"react"}],46:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _GraphPanel = require('./GraphPanel'); var _GraphPanel2 = _interopRequireDefault(_GraphPanel); var _ActionsPanel = require('./ActionsPanel'); var _ActionsPanel2 = _interopRequireDefault(_ActionsPanel); var debounce = require('lodash.debounce'); var React = require('react'); var Color = require('color'); var _require = require('material-ui'); var FontIcon = _require.FontIcon; var Popover = _require.Popover; var Paper = _require.Paper; var Avatar = _require.Avatar; var CardTitle = _require.CardTitle; var _require2 = require('material-ui/styles'); var muiThemeable = _require2.muiThemeable; var MetaCacheService = require('pydio/http/meta-cache-service'); var PydioApi = require('pydio/http/api'); /** * Generic component for display a user and her avatar (first letters or photo) */ var UserAvatar = (function (_React$Component) { _inherits(UserAvatar, _React$Component); function UserAvatar(props, context) { _classCallCheck(this, UserAvatar); _React$Component.call(this, props, context); this.state = { user: null, avatar: null, graph: null }; } UserAvatar.prototype.componentDidMount = function componentDidMount() { if (this.props.pydio.user && this.props.pydio.user.id === this.props.userId) { this.loadLocalData(); if (!this._userLoggedObs) { this._userLoggedObs = this.loadLocalData.bind(this); this.props.pydio.observe('user_logged', this._userLoggedObs); } } else if (this.props.userType === 'user') { this.cache = MetaCacheService.getInstance(); this.cache.registerMetaStream('user_public_data', 'EXPIRATION_MANUAL_TRIGGER'); this.cache.registerMetaStream('user_public_data-rich', 'EXPIRATION_MANUAL_TRIGGER'); this.loadPublicData(this.props.userId); } }; UserAvatar.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { if (!this.props.userId || this.props.userId !== nextProps.userId) { this.setState({ label: nextProps.userId }); } if (this.props.pydio && this.props.pydio.user && this.props.pydio.user.id === nextProps.userId) { this.loadLocalData(); if (!this._userLoggedObs) { this._userLoggedObs = this.loadLocalData.bind(this); this.props.pydio.observe('user_logged', this._userLoggedObs); } } else { if (this._userLoggedObs) { this.props.pydio.stopObserving('user_logged', this._userLoggedObs); } this.cache = MetaCacheService.getInstance(); this.cache.registerMetaStream('user_public_data', 'EXPIRATION_MANUAL_TRIGGER'); this.cache.registerMetaStream('user_public_data-rich', 'EXPIRATION_MANUAL_TRIGGER'); this.loadPublicData(nextProps.userId); } }; UserAvatar.prototype.componentWillUnmount = function componentWillUnmount() { if (this._userLoggedObs) { this.props.pydio.stopObserving('user_logged', this._userLoggedObs); } }; UserAvatar.prototype.loadLocalData = function loadLocalData() { var pydio = this.props.pydio; if (!pydio.user) { this.setState({ label: '', avatar: null }); return; } var userName = pydio.user.getPreference('USER_DISPLAY_NAME') || pydio.user.id; var avatarId = pydio.user.getPreference('avatar'); var avatarUrl = PydioApi.getClient().buildUserAvatarUrl(pydio.user.id, avatarId); this.setState({ label: userName, avatar: avatarUrl }); if (!avatarUrl) { this.loadFromExternalProvider(); } }; UserAvatar.prototype.loadPublicData = function loadPublicData(userId) { var namespace = this.props.richCard ? 'user_public_data-rich' : 'user_public_data'; if (this.cache.hasKey(namespace, userId)) { this.setState(this.cache.getByKey(namespace, userId)); return; } PydioApi.getClient().request({ get_action: 'user_public_data', user_id: userId, graph: this.props.richCard ? 'true' : 'false' }, (function (transport) { var data = transport.responseJSON; if (!data || data.error) { this.cache.setKey(namespace, userId, {}); return; } var user = data.user; var graph = data.graph; var avatarUrl = undefined; var avatarId = user.avatar || null; var label = user.label || userId; if (!user.avatar) { this.loadFromExternalProvider(); } else { avatarUrl = PydioApi.getClient().buildUserAvatarUrl(userId, avatarId); } this.cache.setKey(namespace, userId, { user: user, graph: graph, avatar: avatarUrl }); this.setState({ user: user, graph: graph, avatar: avatarUrl }); }).bind(this)); }; UserAvatar.prototype.loadFromExternalProvider = function loadFromExternalProvider() { if (!this.props.pydio.getPluginConfigs("ajxp_plugin[@id='action.avatar']").get("AVATAR_PROVIDER")) { return; } var namespace = this.props.richCard ? 'user_public_data-rich' : 'user_public_data'; PydioApi.getClient().request({ get_action: 'get_avatar_url', userid: this.props.userId }, (function (transport) { this.setState({ avatar: transport.responseText }); }).bind(this)); }; UserAvatar.prototype.render = function render() { var _this = this; var _state = this.state; var user = _state.user; var avatar = _state.avatar; var graph = _state.graph; var _props = this.props; var pydio = _props.pydio; var userId = _props.userId; var userType = _props.userType; var icon = _props.icon; var style = _props.style; var labelStyle = _props.labelStyle; var avatarStyle = _props.avatarStyle; var avatarSize = _props.avatarSize; var className = _props.className; var avatarClassName = _props.avatarClassName; var labelClassName = _props.labelClassName; var displayLabel = _props.displayLabel; var displayAvatar = _props.displayAvatar; var useDefaultAvatar = _props.useDefaultAvatar; var richCard = _props.richCard; var cardSize = _props.cardSize; var muiTheme = _props.muiTheme; var label = this.state.label; var userTypeLabel = undefined; if (user) { label = user.label; } else if (!label) { label = this.props.userLabel || this.props.userId; } var avatarContent = undefined, avatarColor = undefined, avatarIcon = undefined; if (richCard) { displayAvatar = useDefaultAvatar = displayLabel = true; } if (displayAvatar && !avatar && label && (!displayLabel || useDefaultAvatar)) { var avatarsColor = muiTheme.palette.avatarsColor; if (userType === 'group' || userType === 'team' || userId.indexOf('AJXP_GRP_/') === 0 || userId.indexOf('/AJXP_TEAM/') === 0) { avatarsColor = Color(avatarsColor).darken(0.2).toString(); } var iconClassName = undefined; switch (userType) { case 'group': iconClassName = 'mdi mdi-account-multiple'; userTypeLabel = '289'; break; case 'team': iconClassName = 'mdi mdi-account-multiple-outline'; userTypeLabel = '603'; break; case 'remote': iconClassName = 'mdi mdi-account-network'; userTypeLabel = '604'; break; default: iconClassName = 'mdi mdi-account'; userTypeLabel = user ? user.external ? '589' : '590' : '288'; break; } if (icon) iconClassName = icon; if (userTypeLabel) userTypeLabel = pydio.MessageHash[userTypeLabel]; if (richCard) { avatarIcon = React.createElement(FontIcon, { className: iconClassName, style: { color: avatarsColor } }); avatarColor = '#f5f5f5'; } else { avatarColor = avatarsColor; if (iconClassName) { avatarIcon = React.createElement(FontIcon, { className: iconClassName }); } else { avatarContent = label.split(' ').map(function (word) { return word[0]; }).join('').substring(0, 2); if (avatarContent.length < 2) avatarContent = label.substring(0, 2); } } } var reloadAction = undefined, onEditAction = undefined, onMouseOver = undefined, onMouseOut = undefined, popover = undefined; if (richCard) { (function () { displayAvatar = true; style = _extends({}, style, { flexDirection: 'column' }); avatarSize = cardSize ? cardSize : '100%'; avatarStyle = { borderRadius: 0 }; var localReload = function localReload() { MetaCacheService.getInstance().deleteKey('user_public_data-rich', _this.props.userId); _this.loadPublicData(_this.props.userId); }; reloadAction = function () { localReload(); if (_this.props.reloadAction) _this.props.reloadAction(); }; onEditAction = function () { localReload(); if (_this.props.onEditAction) _this.props.onEditAction(); }; })(); } else if (this.props.richOnHover) { (function () { onMouseOut = function () { if (!_this.lockedBySubPopover) { _this.setState({ showPopover: false }); } }; onMouseOut = debounce(onMouseOut, 350); onMouseOver = function (e) { _this.setState({ showPopover: true, popoverAnchor: e.currentTarget }); onMouseOut.cancel(); }; var onMouseOverInner = function onMouseOverInner(e) { _this.setState({ showPopover: true }); onMouseOut.cancel(); }; var lockOnSubPopoverOpen = function lockOnSubPopoverOpen(status) { _this.lockedBySubPopover = status; onMouseOverInner(); }; popover = React.createElement( Popover, { open: _this.state.showPopover, anchorEl: _this.state.popoverAnchor, onRequestClose: function (reason) { if (reason !== 'clickAway' || !_this.lockedBySubPopover) { _this.setState({ showPopover: false }); } }, anchorOrigin: { horizontal: "left", vertical: "center" }, targetOrigin: { horizontal: "right", vertical: "center" }, useLayerForClickAway: false }, React.createElement( Paper, { zDepth: 2, style: { width: 220, height: 320, overflowY: 'auto' }, onMouseOver: onMouseOverInner, onMouseOut: onMouseOut }, React.createElement(UserAvatar, _extends({}, _this.props, { richCard: true, richOnHover: false, cardSize: 220, lockOnSubPopoverOpen: lockOnSubPopoverOpen })) ) ); })(); } var avatarComponent = React.createElement( Avatar, { src: avatar, icon: avatarIcon, size: avatarSize, style: this.props.avatarOnly ? this.props.style : avatarStyle, backgroundColor: avatarColor }, avatarContent ); if (this.props.avatarOnly) { return avatarComponent; } return React.createElement( 'div', { className: className, style: style, onMouseOver: onMouseOver, onMouseOut: onMouseOut }, displayAvatar && (avatar || avatarContent || avatarIcon) && avatarComponent, displayLabel && !richCard && React.createElement( 'div', { className: labelClassName, style: labelStyle }, label ), displayLabel && richCard && React.createElement(CardTitle, { style: { textAlign: 'center' }, title: label, subtitle: userTypeLabel }), richCard && user && React.createElement(_ActionsPanel2['default'], _extends({}, this.state, this.props, { reloadAction: reloadAction, onEditAction: onEditAction })), graph && React.createElement(_GraphPanel2['default'], _extends({ graph: graph }, this.props, { userLabel: label, reloadAction: reloadAction, onEditAction: onEditAction })), this.props.children, popover ); }; return UserAvatar; })(React.Component); UserAvatar.propTypes = { /** * Id of the user to be loaded */ userId: React.PropTypes.string.isRequired, /** * Pydio instance */ pydio: React.PropTypes.instanceOf(Pydio), /** * Label of the user, if we already have it (otherwise will be loaded) */ userLabel: React.PropTypes.string, /** * Type of user */ userType: React.PropTypes.oneOf(['user', 'group', 'remote', 'team']), /** * Icon to be displayed in avatar */ icon: React.PropTypes.string, /** * Display a rich card or a simple avatar+label chip */ richCard: React.PropTypes.bool, /** * If not rich, display a rich card as popover on mouseover */ richOnHover: React.PropTypes.bool, /** * Add edit action to the card */ userEditable: React.PropTypes.bool, /** * Triggered after successful edition */ onEditAction: React.PropTypes.func, /** * Triggered after deletion */ onDeleteAction: React.PropTypes.func, /** * Triggered if a reload is required */ reloadAction: React.PropTypes.func, /** * Display label element or not */ displayLabel: React.PropTypes.bool, /** * Display avatar element or not */ displayAvatar: React.PropTypes.bool, /** * Display only avatar */ avatarOnly: React.PropTypes.bool, /** * Use default avatar */ useDefaultAvatar: React.PropTypes.bool, /** * Avatar size, 40px by default */ avatarSize: React.PropTypes.number, /** * Add class name to root element */ className: React.PropTypes.string, /** * Add class name to label element */ labelClassName: React.PropTypes.string, /** * Add class name to avatar element */ avatarClassName: React.PropTypes.string, /** * Add style to root element */ style: React.PropTypes.object, /** * Add style to label element */ labelStyle: React.PropTypes.object, /** * Add style to avatar element */ avatarStyle: React.PropTypes.object }; UserAvatar.defaultProps = { displayLabel: true, displayAvatar: true, avatarSize: 40, userType: 'user', className: 'user-avatar-widget', avatarClassName: 'user-avatar', labelClassName: 'user-label' }; exports['default'] = UserAvatar = muiThemeable()(UserAvatar); exports['default'] = UserAvatar; module.exports = exports['default']; },{"./ActionsPanel":44,"./GraphPanel":45,"color":"color","lodash.debounce":"lodash.debounce","material-ui":"material-ui","material-ui/styles":"material-ui/styles","pydio/http/api":"pydio/http/api","pydio/http/meta-cache-service":"pydio/http/meta-cache-service","react":"react"}],47:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ "use strict"; exports.__esModule = true; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var FuncUtils = require("pydio/util/func"); var ResourcesManager = require("pydio/http/resources-manager"); /******************************/ /* REACT DND GENERIC COMPONENTS /******************************/ var Types = { NODE_PROVIDER: 'node', SORTABLE_LIST_ITEM: 'sortable-list-item' }; /** * Specifies which props to inject into your component. */ function collect(connect, monitor) { return { connectDragSource: connect.dragSource(), isDragging: monitor.isDragging() }; } function collectDrop(connect, monitor) { return { connectDropTarget: connect.dropTarget(), canDrop: monitor.canDrop(), isOver: monitor.isOver(), isOverCurrent: monitor.isOver({ shallow: true }) }; } var DNDActionParameter = (function () { function DNDActionParameter(source, target, step) { _classCallCheck(this, DNDActionParameter); this._source = source; this._target = target; this._step = step; } DNDActionParameter.prototype.getSource = function getSource() { return this._source; }; DNDActionParameter.prototype.getTarget = function getTarget() { return this._target; }; DNDActionParameter.prototype.getStep = function getStep() { return this._step; }; return DNDActionParameter; })(); DNDActionParameter.STEP_BEGIN_DRAG = 'beginDrag'; DNDActionParameter.STEP_END_DRAG = 'endDrag'; DNDActionParameter.STEP_CAN_DROP = 'canDrop'; DNDActionParameter.STEP_HOVER_DROP = 'hover'; var applyDNDAction = function applyDNDAction(source, target, step) { var Controller = window.pydio.Controller; var dnd = Controller.defaultActions.get("dragndrop"); if (dnd) { var dndAction = Controller.getActionByName(dnd); dndAction.enable(); var params = new DNDActionParameter(source, target, step); var checkModule = dndAction.options.dragndropCheckModule; if (step === DNDActionParameter.STEP_CAN_DROP && checkModule) { if (!FuncUtils.getFunctionByName(checkModule, window)) { ResourcesManager.detectModuleToLoadAndApply(checkModule, function () {}); throw new Error('Cannot find test module, trying to load it'); } FuncUtils.executeFunctionByName(dndAction.options.dragndropCheckModule, window, Controller, params); } else { dndAction.apply(params); } } else { throw new Error('No DND Actions available'); } }; /****************************/ /* REACT DND DRAG/DROP NODES /***************************/ var nodeDragSource = { beginDrag: function beginDrag(props) { // Return the data describing the dragged item return { node: props.node }; }, endDrag: function endDrag(props, monitor, component) { if (!monitor.didDrop()) { return; } var item = monitor.getItem(); var dropResult = monitor.getDropResult(); try { applyDNDAction(item.node, dropResult.node, DNDActionParameter.STEP_END_DRAG); } catch (e) {} } }; var nodeDropTarget = { hover: function hover(props, monitor) {}, canDrop: function canDrop(props, monitor) { var source = monitor.getItem().node; var target = props.node; try { applyDNDAction(source, target, DNDActionParameter.STEP_CAN_DROP); } catch (e) { return false; } return true; }, drop: function drop(props, monitor) { var hasDroppedOnChild = monitor.didDrop(); if (hasDroppedOnChild) { return; } return { node: props.node }; } }; exports.Types = Types; exports.collect = collect; exports.collectDrop = collectDrop; exports.nodeDragSource = nodeDragSource; exports.nodeDropTarget = nodeDropTarget; exports.DNDActionParameter = DNDActionParameter; },{"pydio/http/resources-manager":"pydio/http/resources-manager","pydio/util/func":"pydio/util/func"}],48:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ "use strict"; exports.__esModule = true; exports["default"] = { contextTypes: { messages: React.PropTypes.object, getMessage: React.PropTypes.func } }; module.exports = exports["default"]; },{}],49:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _require = require('react'); var Component = _require.Component; var PropTypes = _require.PropTypes; var _require2 = require('material-ui'); var FlatButton = _require2.FlatButton; var FontIcon = _require2.FontIcon; var _require3 = require('material-ui/styles'); var muiThemeable = _require3.muiThemeable; var Color = require('color'); var Pydio = require('pydio'); var _Pydio$requireLib = Pydio.requireLib('boot'); var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer; var EmptyStateView = (function (_Component) { _inherits(EmptyStateView, _Component); function EmptyStateView(props, context) { _classCallCheck(this, EmptyStateView); _Component.call(this, props, context); } EmptyStateView.prototype.render = function render() { var _props = this.props; var style = _props.style; var iconClassName = _props.iconClassName; var primaryTextId = _props.primaryTextId; var secondaryTextId = _props.secondaryTextId; var actionLabelId = _props.actionLabelId; var actionCallback = _props.actionCallback; var actionStyle = _props.actionStyle; var actionIconClassName = _props.actionIconClassName; var getMessage = _props.getMessage; var mainColor = Color(this.props.muiTheme.palette.primary1Color); var styles = { container: _extends({ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', flex: 1, backgroundColor: mainColor.lightness(97).rgb().toString() }, style), centered: { maxWidth: 280, textAlign: 'center', color: mainColor.fade(0.6).toString() }, icon: { fontSize: 100 }, primaryText: { fontSize: 16, fontWeight: 500 }, secondaryText: { marginTop: 20, fontSize: 13 }, buttonContainer: { marginTop: 100, textAlign: 'center' }, buttonStyle: { color: this.props.muiTheme.palette.accent2Color } }; var buttonIcon = actionIconClassName ? React.createElement(FontIcon, { className: actionIconClassName }) : null; return React.createElement( 'div', { style: styles.container }, React.createElement( 'div', { style: styles.centered }, React.createElement('div', { className: iconClassName, style: styles.icon }), React.createElement( 'div', { style: styles.primaryText }, getMessage(primaryTextId) ), secondaryTextId && React.createElement( 'div', { style: styles.secondaryText }, getMessage(secondaryTextId) ), actionLabelId && actionCallback && React.createElement( 'div', { style: _extends({}, styles.buttonContainer, actionStyle) }, React.createElement(FlatButton, { style: styles.buttonStyle, label: getMessage(actionLabelId), onTouchTap: actionCallback, icon: buttonIcon }) ) ) ); }; return EmptyStateView; })(Component); EmptyStateView.propTypes = { pydio: PropTypes.instanceOf(Pydio).isRequired, iconClassName: PropTypes.string.isRequired, primaryTextId: PropTypes.string.isRequired, secondaryTextId: PropTypes.string, actionLabelId: PropTypes.string, actionCallback: PropTypes.func, actionStyle: PropTypes.object, style: PropTypes.object, getMessage: PropTypes.func }; exports['default'] = EmptyStateView = PydioContextConsumer(EmptyStateView); exports['default'] = EmptyStateView = muiThemeable()(EmptyStateView); exports['default'] = EmptyStateView; module.exports = exports['default']; },{"color":"color","material-ui":"material-ui","material-ui/styles":"material-ui/styles","pydio":"pydio","react":"react"}],50:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _materialUi = require('material-ui'); var ModalAppBar = function ModalAppBar(props) { var style = props.style; var titleStyle = props.titleStyle; var iconStyleRight = props.iconStyleRight; var iconStyleLeft = props.iconStyleLeft; var otherProps = _objectWithoutProperties(props, ['style', 'titleStyle', 'iconStyleRight', 'iconStyleLeft']); var styles = { style: _extends({ flexShrink: 0 }, style), titleStyle: _extends({ lineHeight: '56px', height: 56, marginLeft: -8 }, titleStyle), iconStyleRight: _extends({ marginTop: 4 }, iconStyleRight), iconStyleLeft: _extends({ marginTop: 4 }, iconStyleLeft) }; return _react2['default'].createElement(_materialUi.AppBar, _extends({}, otherProps, styles)); }; exports['default'] = ModalAppBar; module.exports = exports['default']; /*borderRadius: '2px 2px 0 0',*/ },{"material-ui":"material-ui","react":"react"}],51:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ /** * Search input building a set of query parameters and calling * the callbacks to display / hide results */ 'use strict'; exports.__esModule = true; exports['default'] = React.createClass({ displayName: 'SearchBox', propTypes: { // Required parameters: React.PropTypes.object.isRequired, queryParameterName: React.PropTypes.string.isRequired, // Other textLabel: React.PropTypes.string, displayResults: React.PropTypes.func, hideResults: React.PropTypes.func, displayResultsState: React.PropTypes.bool, limit: React.PropTypes.number }, getInitialState: function getInitialState() { return { displayResult: this.props.displayResultsState ? true : false }; }, getDefaultProps: function getDefaultProps() { var dm = new PydioDataModel(); dm.setRootNode(new AjxpNode()); return { dataModel: dm }; }, displayResultsState: function displayResultsState() { this.setState({ displayResult: true }); }, hideResultsState: function hideResultsState() { this.setState({ displayResult: false }); this.props.hideResults(); }, onClickSearch: function onClickSearch() { var value = this.refs.query.getValue(); var dm = this.props.dataModel; var params = this.props.parameters; params[this.props.queryParameterName] = value; params['limit'] = this.props.limit || 100; dm.getRootNode().setChildren([]); PydioApi.getClient().request(params, (function (transport) { var remoteNodeProvider = new RemoteNodeProvider({}); remoteNodeProvider.parseNodes(dm.getRootNode(), transport); dm.getRootNode().setLoaded(true); this.displayResultsState(); this.props.displayResults(value, dm); }).bind(this)); }, keyDown: function keyDown(event) { if (event.key == 'Enter') { this.onClickSearch(); } }, render: function render() { return React.createElement( 'div', { className: this.props.className ? this.props.className : '' }, React.createElement( 'div', { style: { paddingTop: 22, float: 'right', opacity: 0.3 } }, React.createElement(ReactMUI.IconButton, { ref: 'button', onClick: this.onClickSearch, iconClassName: 'icon-search', tooltip: 'Search' }) ), React.createElement( 'div', { className: 'searchbox-input-fill', style: { width: 220, float: 'right' } }, React.createElement(ReactMUI.TextField, { ref: 'query', onKeyDown: this.keyDown, floatingLabelText: this.props.textLabel }) ) ); } }); module.exports = exports['default']; },{}],52:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ /** * Get info from Pydio controller an build an * action bar with active actions. * TBC */ 'use strict'; exports.__esModule = true; exports['default'] = React.createClass({ displayName: 'SimpleReactActionBar', propTypes: { dataModel: React.PropTypes.instanceOf(PydioDataModel).isRequired, node: React.PropTypes.instanceOf(AjxpNode).isRequired, actions: React.PropTypes.array }, clickAction: function clickAction(event) { var actionName = event.currentTarget.getAttribute("data-action"); this.props.dataModel.setSelectedNodes([this.props.node]); var a = window.pydio.Controller.getActionByName(actionName); a.fireContextChange(this.props.dataModel, true, window.pydio.user); //a.fireSelectionChange(this.props.dataModel); a.apply([this.props.dataModel]); event.stopPropagation(); event.preventDefault(); }, render: function render() { var actions = this.props.actions.map((function (a) { return React.createElement('div', { key: a.options.name, className: a.options.icon_class + ' material-list-action-inline' || '', title: a.options.title, 'data-action': a.options.name, onClick: this.clickAction }); }).bind(this)); return React.createElement( 'span', null, actions ); } }); module.exports = exports['default']; },{}],53:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _utilDND = require('../util/DND'); var React = require('react'); var _Pydio$requireLib = Pydio.requireLib('hoc'); var withContextMenu = _Pydio$requireLib.withContextMenu; var ContextMenuWrapper = function ContextMenuWrapper(props) { return React.createElement('div', props); }; ContextMenuWrapper = withContextMenu(ContextMenuWrapper); /** * Tree Node */ var SimpleTreeNode = React.createClass({ displayName: 'SimpleTreeNode', propTypes: { collapse: React.PropTypes.bool, forceExpand: React.PropTypes.bool, childrenOnly: React.PropTypes.bool, depth: React.PropTypes.number, onNodeSelect: React.PropTypes.func, node: React.PropTypes.instanceOf(AjxpNode), dataModel: React.PropTypes.instanceOf(PydioDataModel), forceLabel: React.PropTypes.string, // Optional currently selected detection nodeIsSelected: React.PropTypes.func, // Optional checkboxes checkboxes: React.PropTypes.array, checkboxesValues: React.PropTypes.object, checkboxesComputeStatus: React.PropTypes.func, onCheckboxCheck: React.PropTypes.func }, getDefaultProps: function getDefaultProps() { return { collapse: false, childrenOnly: false, depth: 0, onNodeSelect: function onNodeSelect(node) {} }; }, listenToNode: function listenToNode(node) { this._childrenListener = (function () { if (!this.isMounted()) return; this.setState({ children: this._nodeToChildren(node) }); }).bind(this); this._nodeListener = (function () { if (!this.isMounted()) return; this.forceUpdate(); }).bind(this); node.observe("child_added", this._childrenListener); node.observe("child_removed", this._childrenListener); node.observe("node_replaced", this._nodeListener); }, stopListening: function stopListening(node) { node.stopObserving("child_added", this._childrenListener); node.stopObserving("child_removed", this._childrenListener); node.stopObserving("node_replaced", this._nodeListener); }, componentDidMount: function componentDidMount() { this.listenToNode(this.props.node); }, componentWillUnmount: function componentWillUnmount() { this.stopListening(this.props.node); }, componentWillReceiveProps: function componentWillReceiveProps(nextProps) { var oldNode = this.props.node; var newNode = nextProps.node; if (newNode == oldNode && newNode.getMetadata().get("paginationData")) { var remapedChildren = this.state.children.map(function (c) { c.setParent(newNode);return c; }); var remapedPathes = this.state.children.map(function (c) { return c.getPath(); }); var newChildren = this._nodeToChildren(newNode); newChildren.forEach(function (nc) { if (remapedPathes.indexOf(nc.getPath()) === -1) { remapedChildren.push(nc); } }); this.setState({ children: remapedChildren }); } else { this.setState({ children: this._nodeToChildren(newNode) }); } if (newNode !== oldNode) { this.stopListening(oldNode); this.listenToNode(newNode); } }, getInitialState: function getInitialState() { return { showChildren: !this.props.collapse || this.props.forceExpand, children: this._nodeToChildren(this.props.node) }; }, _nodeToChildren: function _nodeToChildren() { var children = []; this.props.node.getChildren().forEach(function (c) { if (!c.isLeaf() || c.getAjxpMime() === 'ajxp_browsable_archive') children.push(c); }); return children; }, onNodeSelect: function onNodeSelect(ev) { if (this.props.onNodeSelect) { this.props.onNodeSelect(this.props.node); } ev.preventDefault(); ev.stopPropagation(); }, onChildDisplayToggle: function onChildDisplayToggle(ev) { if (this.props.node.getChildren().size) { this.setState({ showChildren: !this.state.showChildren }); } ev.preventDefault(); ev.stopPropagation(); }, nodeIsSelected: function nodeIsSelected(n) { if (this.props.nodeIsSelected) return this.props.nodeIsSelected(n);else return this.props.dataModel.getSelectedNodes().indexOf(n) !== -1; }, render: function render() { var _this = this; var _props = this.props; var node = _props.node; var childrenOnly = _props.childrenOnly; var canDrop = _props.canDrop; var isOverCurrent = _props.isOverCurrent; var checkboxes = _props.checkboxes; var checkboxesComputeStatus = _props.checkboxesComputeStatus; var checkboxesValues = _props.checkboxesValues; var onCheckboxCheck = _props.onCheckboxCheck; var depth = _props.depth; var forceExpand = _props.forceExpand; var selectedItemStyle = _props.selectedItemStyle; var getItemStyle = _props.getItemStyle; var forceLabel = _props.forceLabel; var hasFolderChildrens = this.state.children.length ? true : false; var hasChildren; if (hasFolderChildrens) { hasChildren = React.createElement( 'span', { onClick: this.onChildDisplayToggle }, this.state.showChildren || forceExpand ? React.createElement('span', { className: 'tree-icon icon-angle-down' }) : React.createElement('span', { className: 'tree-icon icon-angle-right' }) ); } else { var cname = "tree-icon icon-angle-right"; if (node.isLoaded()) { cname += " no-folder-children"; } hasChildren = React.createElement('span', { className: cname }); } var isSelected = this.nodeIsSelected(node) ? 'mui-menu-item mui-is-selected' : 'mui-menu-item'; var selfLabel; if (!childrenOnly) { if (canDrop && isOverCurrent) { isSelected += ' droppable-active'; } var boxes; if (checkboxes) { var values = {}, inherited = false, disabled = {}, additionalClassName = ''; if (checkboxesComputeStatus) { var status = checkboxesComputeStatus(node); values = status.VALUES; inherited = status.INHERITED; disabled = status.DISABLED; if (status.CLASSNAME) additionalClassName = ' ' + status.CLASSNAME; } else if (checkboxesValues && checkboxesValues[node.getPath()]) { values = checkboxesValues[node.getPath()]; } var valueClasses = []; boxes = checkboxes.map((function (c) { var selected = values[c] !== undefined ? values[c] : false; var click = (function (event, value) { onCheckboxCheck(node, c, value); }).bind(this); if (selected) valueClasses.push(c); return React.createElement(ReactMUI.Checkbox, { name: c, key: c + "-" + (selected ? "true" : "false"), checked: selected, onCheck: click, disabled: disabled[c], className: "cbox-" + c }); }).bind(this)); isSelected += inherited ? " inherited " : ""; isSelected += valueClasses.length ? " checkbox-values-" + valueClasses.join('-') : " checkbox-values-empty"; boxes = React.createElement( 'div', { className: "tree-checkboxes" + additionalClassName }, boxes ); } var itemStyle = { paddingLeft: depth * 20 }; if (this.nodeIsSelected(node) && selectedItemStyle) { itemStyle = _extends({}, itemStyle, selectedItemStyle); } if (getItemStyle) { itemStyle = _extends({}, itemStyle, getItemStyle(node)); } var icon = 'mdi mdi-folder'; var ajxpMime = node.getAjxpMime(); if (ajxpMime === 'ajxp_browsable_archive') { icon = 'mdi mdi-archive'; } else if (ajxpMime === 'ajxp_recycle') { icon = 'mdi mdi-delete'; } selfLabel = React.createElement( ContextMenuWrapper, { node: node, className: 'tree-item ' + isSelected + (boxes ? ' has-checkboxes' : ''), style: itemStyle }, React.createElement( 'div', { className: 'tree-item-label', onClick: this.onNodeSelect, title: node.getLabel(), 'data-id': node.getPath() }, hasChildren, React.createElement('span', { className: "tree-icon " + icon }), forceLabel ? forceLabel : node.getLabel() ), boxes ); } var children = []; var connector = function connector(instance) { return instance; }; var draggable = false; if (window.ReactDND && this.props.connectDropTarget && this.props.connectDragSource) { (function () { var connectDragSource = _this.props.connectDragSource; var connectDropTarget = _this.props.connectDropTarget; connector = function (instance) { connectDragSource(ReactDOM.findDOMNode(instance)); connectDropTarget(ReactDOM.findDOMNode(instance)); }; draggable = true; })(); } if (this.state.showChildren || forceExpand) { children = this.state.children.map((function (child) { var props = _extends({}, this.props, { forceLabel: null, childrenOnly: false, key: child.getPath(), node: child, depth: depth + 1 }); return React.createElement(draggable ? DragDropTreeNode : SimpleTreeNode, props); }).bind(this)); } return React.createElement( 'li', { ref: connector, className: "treenode" + node.getPath().replace(/\//g, '_') }, selfLabel, React.createElement( 'ul', null, children ) ); } }); var DragDropTreeNode; if (window.ReactDND) { DragDropTreeNode = ReactDND.flow(ReactDND.DragSource(_utilDND.Types.NODE_PROVIDER, _utilDND.nodeDragSource, _utilDND.collect), ReactDND.DropTarget(_utilDND.Types.NODE_PROVIDER, _utilDND.nodeDropTarget, _utilDND.collectDrop))(SimpleTreeNode); } else { DragDropTreeNode = SimpleTreeNode; } /** * Simple openable / loadable tree taking AjxpNode as inputs */ var DNDTreeView = React.createClass({ displayName: 'DNDTreeView', propTypes: { showRoot: React.PropTypes.bool, rootLabel: React.PropTypes.string, onNodeSelect: React.PropTypes.func, node: React.PropTypes.instanceOf(AjxpNode).isRequired, dataModel: React.PropTypes.instanceOf(PydioDataModel).isRequired, selectable: React.PropTypes.bool, selectableMultiple: React.PropTypes.bool, initialSelectionModel: React.PropTypes.array, onSelectionChange: React.PropTypes.func, forceExpand: React.PropTypes.bool, // Optional currently selected detection nodeIsSelected: React.PropTypes.func, // Optional checkboxes checkboxes: React.PropTypes.array, checkboxesValues: React.PropTypes.object, checkboxesComputeStatus: React.PropTypes.func, onCheckboxCheck: React.PropTypes.func }, getDefaultProps: function getDefaultProps() { return { showRoot: true, onNodeSelect: this.onNodeSelect }; }, onNodeSelect: function onNodeSelect(node) { if (this.props.onNodeSelect) { this.props.onNodeSelect(node); } else { this.props.dataModel.setSelectedNodes([node]); } }, render: function render() { return React.createElement( 'ul', { className: this.props.className }, React.createElement(DragDropTreeNode, { childrenOnly: !this.props.showRoot, forceExpand: this.props.forceExpand, node: this.props.node ? this.props.node : this.props.dataModel.getRootNode(), dataModel: this.props.dataModel, onNodeSelect: this.onNodeSelect, nodeIsSelected: this.props.nodeIsSelected, forceLabel: this.props.rootLabel, checkboxes: this.props.checkboxes, checkboxesValues: this.props.checkboxesValues, checkboxesComputeStatus: this.props.checkboxesComputeStatus, onCheckboxCheck: this.props.onCheckboxCheck, selectedItemStyle: this.props.selectedItemStyle, getItemStyle: this.props.getItemStyle }) ); } }); var TreeView = React.createClass({ displayName: 'TreeView', propTypes: { showRoot: React.PropTypes.bool, rootLabel: React.PropTypes.string, onNodeSelect: React.PropTypes.func, node: React.PropTypes.instanceOf(AjxpNode).isRequired, dataModel: React.PropTypes.instanceOf(PydioDataModel).isRequired, selectable: React.PropTypes.bool, selectableMultiple: React.PropTypes.bool, initialSelectionModel: React.PropTypes.array, onSelectionChange: React.PropTypes.func, forceExpand: React.PropTypes.bool, // Optional currently selected detection nodeIsSelected: React.PropTypes.func, // Optional checkboxes checkboxes: React.PropTypes.array, checkboxesValues: React.PropTypes.object, checkboxesComputeStatus: React.PropTypes.func, onCheckboxCheck: React.PropTypes.func }, getDefaultProps: function getDefaultProps() { return { showRoot: true, onNodeSelect: this.onNodeSelect }; }, onNodeSelect: function onNodeSelect(node) { if (this.props.onNodeSelect) { this.props.onNodeSelect(node); } else { this.props.dataModel.setSelectedNodes([node]); } }, render: function render() { return React.createElement( 'ul', { className: this.props.className }, React.createElement(SimpleTreeNode, { childrenOnly: !this.props.showRoot, forceExpand: this.props.forceExpand, node: this.props.node ? this.props.node : this.props.dataModel.getRootNode(), dataModel: this.props.dataModel, onNodeSelect: this.onNodeSelect, nodeIsSelected: this.props.nodeIsSelected, forceLabel: this.props.rootLabel, checkboxes: this.props.checkboxes, checkboxesValues: this.props.checkboxesValues, checkboxesComputeStatus: this.props.checkboxesComputeStatus, onCheckboxCheck: this.props.onCheckboxCheck, selectedItemStyle: this.props.selectedItemStyle, getItemStyle: this.props.getItemStyle }) ); } }); var FoldersTree = React.createClass({ displayName: 'FoldersTree', propTypes: { pydio: React.PropTypes.instanceOf(Pydio).isRequired, dataModel: React.PropTypes.instanceOf(PydioDataModel).isRequired, className: React.PropTypes.string, onNodeSelected: React.PropTypes.func, draggable: React.PropTypes.bool }, nodeObserver: function nodeObserver() { var r = this.props.dataModel.getRootNode(); if (!r.isLoaded()) { r.observeOnce("loaded", (function () { this.forceUpdate(); }).bind(this)); } else { this.forceUpdate(); } }, componentDidMount: function componentDidMount() { var dm = this.props.dataModel; this._dmObs = this.nodeObserver; dm.observe("context_changed", this._dmObs); dm.observe("root_node_changed", this._dmObs); this.nodeObserver(); }, componentWillUnmount: function componentWillUnmount() { if (this._dmObs) { var dm = this.props.dataModel; dm.stopObserving("context_changed", this._dmObs); dm.stopObserving("root_node_changed", this._dmObs); } }, treeNodeSelected: function treeNodeSelected(n) { if (this.props.onNodeSelected) { this.props.onNodeSelected(n); } else { this.props.dataModel.requireContextChange(n); } }, nodeIsSelected: function nodeIsSelected(n) { return n === this.props.dataModel.getContextNode(); }, render: function render() { if (this.props.draggable) { return React.createElement(PydioComponents.DNDTreeView, { onNodeSelect: this.treeNodeSelected, nodeIsSelected: this.nodeIsSelected, dataModel: this.props.dataModel, node: this.props.dataModel.getRootNode(), showRoot: this.props.showRoot ? true : false, selectedItemStyle: this.props.selectedItemStyle, getItemStyle: this.props.getItemStyle, className: "folders-tree" + (this.props.className ? ' ' + this.props.className : '') }); } else { return React.createElement(PydioComponents.TreeView, { onNodeSelect: this.treeNodeSelected, nodeIsSelected: this.nodeIsSelected, dataModel: this.props.dataModel, node: this.props.dataModel.getRootNode(), selectedItemStyle: this.props.selectedItemStyle, getItemStyle: this.props.getItemStyle, showRoot: this.props.showRoot ? true : false, className: "folders-tree" + (this.props.className ? ' ' + this.props.className : '') }); } } }); exports.TreeView = TreeView; exports.DNDTreeView = DNDTreeView; exports.FoldersTree = FoldersTree; },{"../util/DND":47,"react":"react"}]},{},[12])(12) }); //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtc2Nyb2xsYmFyL2Rpc3Qvc2Nyb2xsQXJlYS5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2R5bmFtaWMtZ3JpZC9EeW5hbWljR3JpZC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2R5bmFtaWMtZ3JpZC9HcmlkQnVpbGRlci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2R5bmFtaWMtZ3JpZC9HcmlkSXRlbU1peGluLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvZHluYW1pYy1ncmlkL1N0b3JlLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvZHluYW1pYy1ncmlkL2FzR3JpZEl0ZW0uanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lZGl0b3IvUGFwZXJFZGl0b3IuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lZGl0b3IvUmVhY3RFZGl0b3JPcGVuZXIuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lbGVtZW50cy9DbGlwYm9hcmRUZXh0RmllbGQuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lbGVtZW50cy9MYWJlbFdpdGhUaXAuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lbGVtZW50cy9TaW1wbGVGaWd1cmVCYWRnZS5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2luZGV4LmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvbGlzdC9Db25maWd1cmFibGVMaXN0RW50cnkuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9saXN0L0lubGluZUVkaXRvci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvTGlzdEVudHJ5LmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvbGlzdC9MaXN0RW50cnlOb2RlTGlzdGVuZXJNaXhpbi5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvTGlzdFBhZ2luYXRvci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvTm9kZUxpc3RDdXN0b21Qcm92aWRlci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvU2ltcGxlTGlzdC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvU29ydENvbHVtbnMuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9saXN0L1NvcnRhYmxlTGlzdC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvVGFibGVMaXN0RW50cnkuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9saXN0L1RhYmxlTGlzdEhlYWRlci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvQnV0dG9uTWVudS5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvQ29udGV4dE1lbnUuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9tZW51L0ljb25CdXR0b25NZW51LmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvbWVudS9JY29uQnV0dG9uUG9wb3Zlci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvTWVudUl0ZW1zQ29uc3VtZXIuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9tZW51L1BvcHVwTWVudS5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvVG9vbGJhci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvVXRpbHMuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91c2Vycy9UZWFtQ3JlYXRpb25Gb3JtLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvVXNlcnNDb21wbGV0ZXIuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91c2Vycy9hZGRyZXNzYm9vay9BZGRyZXNzQm9vay5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3VzZXJzL2FkZHJlc3Nib29rL0FscGhhUGFnaW5hdG9yLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYWRkcmVzc2Jvb2svTG9hZGVycy5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3VzZXJzL2FkZHJlc3Nib29rL05lc3RlZExpc3RJdGVtLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYWRkcmVzc2Jvb2svUmlnaHRQYW5lbENhcmQuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91c2Vycy9hZGRyZXNzYm9vay9TZWFyY2hGb3JtLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYWRkcmVzc2Jvb2svU2VhcmNoUGFuZWwuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91c2Vycy9hZGRyZXNzYm9vay9UZWFtQ2FyZC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3VzZXJzL2FkZHJlc3Nib29rL1VzZXJDYXJkLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYWRkcmVzc2Jvb2svVXNlcnNMaXN0LmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYXZhdGFyL0FjdGlvbnNQYW5lbC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3VzZXJzL2F2YXRhci9HcmFwaFBhbmVsLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYXZhdGFyL1VzZXJBdmF0YXIuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91dGlsL0RORC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3V0aWwvTWVzc2FnZXNDb25zdW1lck1peGluLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdmlld3MvRW1wdHlTdGF0ZVZpZXcuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy92aWV3cy9Nb2RhbEFwcEJhci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3ZpZXdzL1NlYXJjaEJveC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3ZpZXdzL1NpbXBsZVJlYWN0QWN0aW9uQmFyLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdmlld3MvVHJlZVZpZXcuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBOzs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3pUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN4TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM5RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQy95Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3JJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN2V0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9MQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFlQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25LQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiIWZ1bmN0aW9uKGUsdCl7XCJvYmplY3RcIj09dHlwZW9mIGV4cG9ydHMmJlwib2JqZWN0XCI9PXR5cGVvZiBtb2R1bGU/bW9kdWxlLmV4cG9ydHM9dChyZXF1aXJlKFwicmVhY3RcIikpOlwiZnVuY3Rpb25cIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUoW1wicmVhY3RcIl0sdCk6XCJvYmplY3RcIj09dHlwZW9mIGV4cG9ydHM/ZXhwb3J0cy5TY3JvbGxBcmVhPXQocmVxdWlyZShcInJlYWN0XCIpKTplLlNjcm9sbEFyZWE9dChlLlJlYWN0KX0odGhpcyxmdW5jdGlvbihlKXtyZXR1cm4gZnVuY3Rpb24oZSl7ZnVuY3Rpb24gdChvKXtpZihuW29dKXJldHVybiBuW29dLmV4cG9ydHM7dmFyIHI9bltvXT17ZXhwb3J0czp7fSxpZDpvLGxvYWRlZDohMX07cmV0dXJuIGVbb10uY2FsbChyLmV4cG9ydHMscixyLmV4cG9ydHMsdCksci5sb2FkZWQ9ITAsci5leHBvcnRzfXZhciBuPXt9O3JldHVybiB0Lm09ZSx0LmM9bix0LnA9XCJcIix0KDApfShbZnVuY3Rpb24oZSx0LG4pe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG8oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fU9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pLG4oMjUpO3ZhciByPW4oMTEpLGk9byhyKTt0LmRlZmF1bHQ9aS5kZWZhdWx0fSxmdW5jdGlvbih0LG4pe3QuZXhwb3J0cz1lfSxmdW5jdGlvbihlLHQsbil7KGZ1bmN0aW9uKHQpeyhmdW5jdGlvbigpe3ZhciBuLG8scjtcInVuZGVmaW5lZFwiIT10eXBlb2YgcGVyZm9ybWFuY2UmJm51bGwhPT1wZXJmb3JtYW5jZSYmcGVyZm9ybWFuY2Uubm93P2UuZXhwb3J0cz1mdW5jdGlvbigpe3JldHVybiBwZXJmb3JtYW5jZS5ub3coKX06XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQmJm51bGwhPT10JiZ0LmhydGltZT8oZS5leHBvcnRzPWZ1bmN0aW9uKCl7cmV0dXJuKG4oKS1yKS8xZTZ9LG89dC5ocnRpbWUsbj1mdW5jdGlvbigpe3ZhciBlO3JldHVybiBlPW8oKSwxZTkqZVswXStlWzFdfSxyPW4oKSk6RGF0ZS5ub3c/KGUuZXhwb3J0cz1mdW5jdGlvbigpe3JldHVybiBEYXRlLm5vdygpLXJ9LHI9RGF0ZS5ub3coKSk6KGUuZXhwb3J0cz1mdW5jdGlvbigpe3JldHVybihuZXcgRGF0ZSkuZ2V0VGltZSgpLXJ9LHI9KG5ldyBEYXRlKS5nZXRUaW1lKCkpfSkuY2FsbCh0aGlzKX0pLmNhbGwodCxuKDE3KSl9LGZ1bmN0aW9uKGUsdCxuKXsoZnVuY3Rpb24odCl7Zm9yKHZhciBvPW4oMikscj1cInVuZGVmaW5lZFwiPT10eXBlb2Ygd2luZG93P3Q6d2luZG93LGk9W1wibW96XCIsXCJ3ZWJraXRcIl0sYT1cIkFuaW1hdGlvbkZyYW1lXCIsbD1yW1wicmVxdWVzdFwiK2FdLHM9cltcImNhbmNlbFwiK2FdfHxyW1wiY2FuY2VsUmVxdWVzdFwiK2FdLHU9MDshbCYmdTxpLmxlbmd0aDt1KyspbD1yW2lbdV0rXCJSZXF1ZXN0XCIrYV0scz1yW2lbdV0rXCJDYW5jZWxcIithXXx8cltpW3VdK1wiQ2FuY2VsUmVxdWVzdFwiK2FdO2lmKCFsfHwhcyl7dmFyIGM9MCxmPTAscD1bXSxkPTFlMy82MDtsPWZ1bmN0aW9uKGUpe2lmKDA9PT1wLmxlbmd0aCl7dmFyIHQ9bygpLG49TWF0aC5tYXgoMCxkLSh0LWMpKTtjPW4rdCxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dmFyIGU9cC5zbGljZSgwKTtwLmxlbmd0aD0wO2Zvcih2YXIgdD0wO3Q8ZS5sZW5ndGg7dCsrKWlmKCFlW3RdLmNhbmNlbGxlZCl0cnl7ZVt0XS5jYWxsYmFjayhjKX1jYXRjaChlKXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dGhyb3cgZX0sMCl9fSxNYXRoLnJvdW5kKG4pKX1yZXR1cm4gcC5wdXNoKHtoYW5kbGU6KytmLGNhbGxiYWNrOmUsY2FuY2VsbGVkOiExfSksZn0scz1mdW5jdGlvbihlKXtmb3IodmFyIHQ9MDt0PHAubGVuZ3RoO3QrKylwW3RdLmhhbmRsZT09PWUmJihwW3RdLmNhbmNlbGxlZD0hMCl9fWUuZXhwb3J0cz1mdW5jdGlvbihlKXtyZXR1cm4gbC5jYWxsKHIsZSl9LGUuZXhwb3J0cy5jYW5jZWw9ZnVuY3Rpb24oKXtzLmFwcGx5KHIsYXJndW1lbnRzKX0sZS5leHBvcnRzLnBvbHlmaWxsPWZ1bmN0aW9uKCl7ci5yZXF1ZXN0QW5pbWF0aW9uRnJhbWU9bCxyLmNhbmNlbEFuaW1hdGlvbkZyYW1lPXN9fSkuY2FsbCh0LGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXN9KCkpfSxmdW5jdGlvbihlLHQpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG4oZSl7dmFyIHQ9e307Zm9yKHZhciBuIGluIGUpT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGUsbikmJih0W25dPTApO3JldHVybiB0fXQuX19lc01vZHVsZT0hMCx0LmRlZmF1bHQ9bixlLmV4cG9ydHM9dC5kZWZhdWx0fSxmdW5jdGlvbihlLHQpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG4oZSx0LG4pe2Zvcih2YXIgbyBpbiB0KWlmKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0LG8pKXtpZigwIT09bltvXSlyZXR1cm4hMTt2YXIgcj1cIm51bWJlclwiPT10eXBlb2YgdFtvXT90W29dOnRbb10udmFsO2lmKGVbb10hPT1yKXJldHVybiExfXJldHVybiEwfXQuX19lc01vZHVsZT0hMCx0LmRlZmF1bHQ9bixlLmV4cG9ydHM9dC5kZWZhdWx0fSxmdW5jdGlvbihlLHQpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG4oZSx0LG4scixpLGEsbCl7dmFyIHM9LWkqKHQtciksdT0tYSpuLGM9cyt1LGY9bitjKmUscD10K2YqZTtyZXR1cm4gTWF0aC5hYnMoZik8bCYmTWF0aC5hYnMocC1yKTxsPyhvWzBdPXIsb1sxXT0wLG8pOihvWzBdPXAsb1sxXT1mLG8pfXQuX19lc01vZHVsZT0hMCx0LmRlZmF1bHQ9bjt2YXIgbz1bMCwwXTtlLmV4cG9ydHM9dC5kZWZhdWx0fSxmdW5jdGlvbihlLHQpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG4oZSl7dmFyIHQ9e307Zm9yKHZhciBuIGluIGUpT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGUsbikmJih0W25dPVwibnVtYmVyXCI9PXR5cGVvZiBlW25dP2Vbbl06ZVtuXS52YWwpO3JldHVybiB0fXQuX19lc01vZHVsZT0hMCx0LmRlZmF1bHQ9bixlLmV4cG9ydHM9dC5kZWZhdWx0fSxmdW5jdGlvbihlLHQsbil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbyhlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2U6e2RlZmF1bHQ6ZX19ZnVuY3Rpb24gcihlKXtyZXR1cm4gcD9mLmRlZmF1bHQuZmluZERPTU5vZGUoZSk6ZX1mdW5jdGlvbiBpKCl7ZHx8cHx8KGQ9ITAsY29uc29sZS5lcnJvcihcIldpdGggUmVhY3QgMC4xNCBhbmQgbGF0ZXIgdmVyc2lvbnMsIHlvdSBubyBsb25nZXIgbmVlZCB0byB3cmFwIDxTY3JvbGxBcmVhPiBjaGlsZCBpbnRvIGEgZnVuY3Rpb24uXCIpKX1mdW5jdGlvbiBhKCl7IWQmJnAmJihkPSEwLGNvbnNvbGUuZXJyb3IoXCJXaXRoIFJlYWN0IDAuMTMsIHlvdSBuZWVkIHRvIHdyYXAgPFNjcm9sbEFyZWE+IGNoaWxkIGludG8gYSBmdW5jdGlvbi5cIikpfWZ1bmN0aW9uIGwoZSl7cmV0dXJuIGU8MD8wOmV9ZnVuY3Rpb24gcyhlKXt2YXIgdD1hcmd1bWVudHMubGVuZ3RoPjEmJnZvaWQgMCE9PWFyZ3VtZW50c1sxXT9hcmd1bWVudHNbMV06ZnVuY3Rpb24oZSl7cmV0dXJuIGV9LG49e307Zm9yKHZhciBvIGluIGUpZS5oYXNPd25Qcm9wZXJ0eShvKSYmKG5bb109dChlW29dKSk7cmV0dXJuIG59ZnVuY3Rpb24gdShlKXt2YXIgdD1lLnZlcnNpb247aWYoXCJzdHJpbmdcIiE9dHlwZW9mIHQpcmV0dXJuITA7dmFyIG49dC5zcGxpdChcIi5cIiksbz1wYXJzZUludChuWzBdLDEwKSxyPXBhcnNlSW50KG5bMV0sMTApO3JldHVybiAwPT09byYmMTM9PT1yfU9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pLHQuZmluZERPTU5vZGU9cix0Lndhcm5BYm91dEZ1bmN0aW9uQ2hpbGQ9aSx0Lndhcm5BYm91dEVsZW1lbnRDaGlsZD1hLHQucG9zaXRpdmVPclplcm89bCx0Lm1vZGlmeU9ialZhbHVlcz1zLHQuaXNSZWFjdDEzPXU7dmFyIGM9bigxKSxmPW8oYykscD11KGYuZGVmYXVsdCksZD0hMX0sZnVuY3Rpb24oZSx0KXtcInVzZSBzdHJpY3RcIjt0Ll9fZXNNb2R1bGU9ITAsdC5kZWZhdWx0PXtub1dvYmJsZTp7c3RpZmZuZXNzOjE3MCxkYW1waW5nOjI2fSxnZW50bGU6e3N0aWZmbmVzczoxMjAsZGFtcGluZzoxNH0sd29iYmx5OntzdGlmZm5lc3M6MTgwLGRhbXBpbmc6MTJ9LHN0aWZmOntzdGlmZm5lc3M6MjEwLGRhbXBpbmc6MjB9fSxlLmV4cG9ydHM9dC5kZWZhdWx0fSxmdW5jdGlvbihlLHQsbil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbyhlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2UuZGVmYXVsdDplfXQuX19lc01vZHVsZT0hMDt2YXIgcj1uKDE4KTt0Lk1vdGlvbj1vKHIpO3ZhciBpPW4oMTkpO3QuU3RhZ2dlcmVkTW90aW9uPW8oaSk7dmFyIGE9bigyMCk7dC5UcmFuc2l0aW9uTW90aW9uPW8oYSk7dmFyIGw9bigyMyk7dC5zcHJpbmc9byhsKTt2YXIgcz1uKDkpO3QucHJlc2V0cz1vKHMpO3ZhciB1PW4oMjIpO3QucmVvcmRlcktleXM9byh1KX0sZnVuY3Rpb24oZSx0LG4pe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG8oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fWZ1bmN0aW9uIHIoZSx0KXtpZighKGUgaW5zdGFuY2VvZiB0KSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpfWZ1bmN0aW9uIGkoZSx0KXtpZighZSl0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoXCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWRcIik7cmV0dXJuIXR8fFwib2JqZWN0XCIhPXR5cGVvZiB0JiZcImZ1bmN0aW9uXCIhPXR5cGVvZiB0P2U6dH1mdW5jdGlvbiBhKGUsdCl7aWYoXCJmdW5jdGlvblwiIT10eXBlb2YgdCYmbnVsbCE9PXQpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgXCIrdHlwZW9mIHQpO2UucHJvdG90eXBlPU9iamVjdC5jcmVhdGUodCYmdC5wcm90b3R5cGUse2NvbnN0cnVjdG9yOnt2YWx1ZTplLGVudW1lcmFibGU6ITEsd3JpdGFibGU6ITAsY29uZmlndXJhYmxlOiEwfX0pLHQmJihPYmplY3Quc2V0UHJvdG90eXBlT2Y/T2JqZWN0LnNldFByb3RvdHlwZU9mKGUsdCk6ZS5fX3Byb3RvX189dCl9T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSk7dmFyIGw9XCJmdW5jdGlvblwiPT10eXBlb2YgU3ltYm9sJiZcInN5bWJvbFwiPT10eXBlb2YgU3ltYm9sLml0ZXJhdG9yP2Z1bmN0aW9uKGUpe3JldHVybiB0eXBlb2YgZX06ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJlwiZnVuY3Rpb25cIj09dHlwZW9mIFN5bWJvbCYmZS5jb25zdHJ1Y3Rvcj09PVN5bWJvbCYmZSE9PVN5bWJvbC5wcm90b3R5cGU/XCJzeW1ib2xcIjp0eXBlb2YgZX0scz1PYmplY3QuYXNzaWdufHxmdW5jdGlvbihlKXtmb3IodmFyIHQ9MTt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKXt2YXIgbj1hcmd1bWVudHNbdF07Zm9yKHZhciBvIGluIG4pT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG4sbykmJihlW29dPW5bb10pfXJldHVybiBlfSx1PWZ1bmN0aW9uKCl7ZnVuY3Rpb24gZShlLHQpe2Zvcih2YXIgbj0wO248dC5sZW5ndGg7bisrKXt2YXIgbz10W25dO28uZW51bWVyYWJsZT1vLmVudW1lcmFibGV8fCExLG8uY29uZmlndXJhYmxlPSEwLFwidmFsdWVcImluIG8mJihvLndyaXRhYmxlPSEwKSxPYmplY3QuZGVmaW5lUHJvcGVydHkoZSxvLmtleSxvKX19cmV0dXJuIGZ1bmN0aW9uKHQsbixvKXtyZXR1cm4gbiYmZSh0LnByb3RvdHlwZSxuKSxvJiZlKHQsbyksdH19KCksYz1uKDEpLGY9byhjKSxwPW4oMTIpLGQ9byhwKSxoPW4oOCkseT1uKDE2KSx2PW8oeSksbT1uKDEwKSxTPXt3aGVlbDpcIndoZWVsXCIsYXBpOlwiYXBpXCIsdG91Y2g6XCJ0b3VjaFwiLHRvdWNoRW5kOlwidG91Y2hFbmRcIixtb3VzZW1vdmU6XCJtb3VzZW1vdmVcIixrZXlQcmVzczpcImtleXByZXNzXCJ9LGc9ZnVuY3Rpb24oZSl7ZnVuY3Rpb24gdChlKXtyKHRoaXMsdCk7dmFyIG49aSh0aGlzLCh0Ll9fcHJvdG9fX3x8T2JqZWN0LmdldFByb3RvdHlwZU9mKHQpKS5jYWxsKHRoaXMsZSkpO3JldHVybiBuLnN0YXRlPXt0b3BQb3NpdGlvbjowLGxlZnRQb3NpdGlvbjowLHJlYWxIZWlnaHQ6MCxjb250YWluZXJIZWlnaHQ6MCxyZWFsV2lkdGg6MCxjb250YWluZXJXaWR0aDowfSxuLnNjcm9sbEFyZWE9e3JlZnJlc2g6ZnVuY3Rpb24oKXtuLnNldFNpemVzVG9TdGF0ZSgpfSxzY3JvbGxUb3A6ZnVuY3Rpb24oKXtuLnNjcm9sbFRvcCgpfSxzY3JvbGxCb3R0b206ZnVuY3Rpb24oKXtuLnNjcm9sbEJvdHRvbSgpfSxzY3JvbGxZVG86ZnVuY3Rpb24oZSl7bi5zY3JvbGxZVG8oZSl9LHNjcm9sbExlZnQ6ZnVuY3Rpb24oKXtuLnNjcm9sbExlZnQoKX0sc2Nyb2xsUmlnaHQ6ZnVuY3Rpb24oKXtuLnNjcm9sbFJpZ2h0KCl9LHNjcm9sbFhUbzpmdW5jdGlvbihlKXtuLnNjcm9sbFhUbyhlKX19LG4uZXZudHNQcmV2aW91c1ZhbHVlcz17Y2xpZW50WDowLGNsaWVudFk6MCxkZWx0YVg6MCxkZWx0YVk6MH0sbi5iaW5kZWRIYW5kbGVXaW5kb3dSZXNpemU9bi5oYW5kbGVXaW5kb3dSZXNpemUuYmluZChuKSxufXJldHVybiBhKHQsZSksdSh0LFt7a2V5OlwiZ2V0Q2hpbGRDb250ZXh0XCIsdmFsdWU6ZnVuY3Rpb24oKXtyZXR1cm57c2Nyb2xsQXJlYTp0aGlzLnNjcm9sbEFyZWF9fX0se2tleTpcImNvbXBvbmVudERpZE1vdW50XCIsdmFsdWU6ZnVuY3Rpb24oKXt0aGlzLnByb3BzLmNvbnRlbnRXaW5kb3cmJnRoaXMucHJvcHMuY29udGVudFdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicmVzaXplXCIsdGhpcy5iaW5kZWRIYW5kbGVXaW5kb3dSZXNpemUpLHRoaXMubGluZUhlaWdodFB4PSgwLHYuZGVmYXVsdCkoKDAsaC5maW5kRE9NTm9kZSkodGhpcy5jb250ZW50KSksdGhpcy5zZXRTaXplc1RvU3RhdGUoKX19LHtrZXk6XCJjb21wb25lbnRXaWxsVW5tb3VudFwiLHZhbHVlOmZ1bmN0aW9uKCl7dGhpcy5wcm9wcy5jb250ZW50V2luZG93JiZ0aGlzLnByb3BzLmNvbnRlbnRXaW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInJlc2l6ZVwiLHRoaXMuYmluZGVkSGFuZGxlV2luZG93UmVzaXplKX19LHtrZXk6XCJjb21wb25lbnREaWRVcGRhdGVcIix2YWx1ZTpmdW5jdGlvbigpe3RoaXMuc2V0U2l6ZXNUb1N0YXRlKCl9fSx7a2V5OlwicmVuZGVyXCIsdmFsdWU6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLHQ9dGhpcy5wcm9wcyxuPXQuY2hpbGRyZW4sbz10LmNsYXNzTmFtZSxyPXQuY29udGVudENsYXNzTmFtZSxpPXQub3duZXJEb2N1bWVudCxhPXRoaXMucHJvcHMuc21vb3RoU2Nyb2xsaW5nJiYodGhpcy5zdGF0ZS5ldmVudFR5cGU9PT1TLndoZWVsfHx0aGlzLnN0YXRlLmV2ZW50VHlwZT09PVMuYXBpfHx0aGlzLnN0YXRlLmV2ZW50VHlwZT09PVMudG91Y2hFbmR8fHRoaXMuc3RhdGUuZXZlbnRUeXBlPT09Uy5rZXlQcmVzcyksbD10aGlzLmNhblNjcm9sbFkoKT9mLmRlZmF1bHQuY3JlYXRlRWxlbWVudChkLmRlZmF1bHQse293bmVyRG9jdW1lbnQ6aSxyZWFsU2l6ZTp0aGlzLnN0YXRlLnJlYWxIZWlnaHQsY29udGFpbmVyU2l6ZTp0aGlzLnN0YXRlLmNvbnRhaW5lckhlaWdodCxwb3NpdGlvbjp0aGlzLnN0YXRlLnRvcFBvc2l0aW9uLG9uTW92ZTp0aGlzLmhhbmRsZVNjcm9sbGJhck1vdmUuYmluZCh0aGlzKSxvblBvc2l0aW9uQ2hhbmdlOnRoaXMuaGFuZGxlU2Nyb2xsYmFyWVBvc2l0aW9uQ2hhbmdlLmJpbmQodGhpcyksY29udGFpbmVyU3R5bGU6dGhpcy5wcm9wcy52ZXJ0aWNhbENvbnRhaW5lclN0eWxlLHNjcm9sbGJhclN0eWxlOnRoaXMucHJvcHMudmVydGljYWxTY3JvbGxiYXJTdHlsZSxzbW9vdGhTY3JvbGxpbmc6YSxtaW5TY3JvbGxTaXplOnRoaXMucHJvcHMubWluU2Nyb2xsU2l6ZSxvbkZvY3VzOnRoaXMuZm9jdXNDb250ZW50LmJpbmQodGhpcyksdHlwZTpcInZlcnRpY2FsXCJ9KTpudWxsLHU9dGhpcy5jYW5TY3JvbGxYKCk/Zi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoZC5kZWZhdWx0LHtvd25lckRvY3VtZW50OmkscmVhbFNpemU6dGhpcy5zdGF0ZS5yZWFsV2lkdGgsY29udGFpbmVyU2l6ZTp0aGlzLnN0YXRlLmNvbnRhaW5lcldpZHRoLHBvc2l0aW9uOnRoaXMuc3RhdGUubGVmdFBvc2l0aW9uLG9uTW92ZTp0aGlzLmhhbmRsZVNjcm9sbGJhck1vdmUuYmluZCh0aGlzKSxvblBvc2l0aW9uQ2hhbmdlOnRoaXMuaGFuZGxlU2Nyb2xsYmFyWFBvc2l0aW9uQ2hhbmdlLmJpbmQodGhpcyksY29udGFpbmVyU3R5bGU6dGhpcy5wcm9wcy5ob3Jpem9udGFsQ29udGFpbmVyU3R5bGUsc2Nyb2xsYmFyU3R5bGU6dGhpcy5wcm9wcy5ob3Jpem9udGFsU2Nyb2xsYmFyU3R5bGUsc21vb3RoU2Nyb2xsaW5nOmEsbWluU2Nyb2xsU2l6ZTp0aGlzLnByb3BzLm1pblNjcm9sbFNpemUsb25Gb2N1czp0aGlzLmZvY3VzQ29udGVudC5iaW5kKHRoaXMpLHR5cGU6XCJob3Jpem9udGFsXCJ9KTpudWxsO1wiZnVuY3Rpb25cIj09dHlwZW9mIG4/KCgwLGgud2FybkFib3V0RnVuY3Rpb25DaGlsZCkoKSxuPW4oKSk6KDAsaC53YXJuQWJvdXRFbGVtZW50Q2hpbGQpKCk7dmFyIGM9XCJzY3JvbGxhcmVhIFwiKyhvfHxcIlwiKSxwPVwic2Nyb2xsYXJlYS1jb250ZW50IFwiKyhyfHxcIlwiKSx5PXttYXJnaW5Ub3A6LXRoaXMuc3RhdGUudG9wUG9zaXRpb24sbWFyZ2luTGVmdDotdGhpcy5zdGF0ZS5sZWZ0UG9zaXRpb259LHY9YT8oMCxoLm1vZGlmeU9ialZhbHVlcykoeSxmdW5jdGlvbihlKXtyZXR1cm4oMCxtLnNwcmluZykoZSl9KTp5O3JldHVybiBmLmRlZmF1bHQuY3JlYXRlRWxlbWVudChtLk1vdGlvbix7c3R5bGU6dn0sZnVuY3Rpb24odCl7cmV0dXJuIGYuZGVmYXVsdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIse3JlZjpmdW5jdGlvbih0KXtyZXR1cm4gZS53cmFwcGVyPXR9LGNsYXNzTmFtZTpjLHN0eWxlOmUucHJvcHMuc3R5bGUsb25XaGVlbDplLmhhbmRsZVdoZWVsLmJpbmQoZSl9LGYuZGVmYXVsdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIse3JlZjpmdW5jdGlvbih0KXtyZXR1cm4gZS5jb250ZW50PXR9LHN0eWxlOnMoe30sZS5wcm9wcy5jb250ZW50U3R5bGUsdCksY2xhc3NOYW1lOnAsb25Ub3VjaFN0YXJ0OmUuaGFuZGxlVG91Y2hTdGFydC5iaW5kKGUpLG9uVG91Y2hNb3ZlOmUuaGFuZGxlVG91Y2hNb3ZlLmJpbmQoZSksb25Ub3VjaEVuZDplLmhhbmRsZVRvdWNoRW5kLmJpbmQoZSksb25LZXlEb3duOmUuaGFuZGxlS2V5RG93bi5iaW5kKGUpLHRhYkluZGV4OmUucHJvcHMuZm9jdXNhYmxlVGFiSW5kZXh9LG4pLGwsdSl9KX19LHtrZXk6XCJzZXRTdGF0ZUZyb21FdmVudFwiLHZhbHVlOmZ1bmN0aW9uKGUsdCl7dGhpcy5wcm9wcy5vblNjcm9sbCYmdGhpcy5wcm9wcy5vblNjcm9sbChlKSx0aGlzLnNldFN0YXRlKHMoe30sZSx7ZXZlbnRUeXBlOnR9KSl9fSx7a2V5OlwiaGFuZGxlVG91Y2hTdGFydFwiLHZhbHVlOmZ1bmN0aW9uKGUpe3ZhciB0PWUudG91Y2hlcztpZigxPT09dC5sZW5ndGgpe3ZhciBuPXRbMF0sbz1uLmNsaWVudFgscj1uLmNsaWVudFk7dGhpcy5ldmVudFByZXZpb3VzVmFsdWVzPXMoe30sdGhpcy5ldmVudFByZXZpb3VzVmFsdWVzLHtjbGllbnRZOnIsY2xpZW50WDpvLHRpbWVzdGFtcDpEYXRlLm5vdygpfSl9fX0se2tleTpcImhhbmRsZVRvdWNoTW92ZVwiLHZhbHVlOmZ1bmN0aW9uKGUpe2UucHJldmVudERlZmF1bHQoKSxlLnN0b3BQcm9wYWdhdGlvbigpO3ZhciB0PWUudG91Y2hlcztpZigxPT09dC5sZW5ndGgpe3ZhciBuPXRbMF0sbz1uLmNsaWVudFgscj1uLmNsaWVudFksaT10aGlzLmV2ZW50UHJldmlvdXNWYWx1ZXMuY2xpZW50WS1yLGE9dGhpcy5ldmVudFByZXZpb3VzVmFsdWVzLmNsaWVudFgtbzt0aGlzLmV2ZW50UHJldmlvdXNWYWx1ZXM9cyh7fSx0aGlzLmV2ZW50UHJldmlvdXNWYWx1ZXMse2RlbHRhWTppLGRlbHRhWDphLGNsaWVudFk6cixjbGllbnRYOm8sdGltZXN0YW1wOkRhdGUubm93KCl9KSx0aGlzLnNldFN0YXRlRnJvbUV2ZW50KHRoaXMuY29tcG9zZU5ld1N0YXRlKC1hLC1pKSl9fX0se2tleTpcImhhbmRsZVRvdWNoRW5kXCIsdmFsdWU6ZnVuY3Rpb24oZSl7dmFyIHQ9dGhpcy5ldmVudFByZXZpb3VzVmFsdWVzLG49dC5kZWx0YVgsbz10LmRlbHRhWSxyPXQudGltZXN0YW1wO1widW5kZWZpbmVkXCI9PXR5cGVvZiBuJiYobj0wKSxcInVuZGVmaW5lZFwiPT10eXBlb2YgbyYmKG89MCksRGF0ZS5ub3coKS1yPDIwMCYmdGhpcy5zZXRTdGF0ZUZyb21FdmVudCh0aGlzLmNvbXBvc2VOZXdTdGF0ZSgxMCotbiwxMCotbyksUy50b3VjaEVuZCksdGhpcy5ldmVudFByZXZpb3VzVmFsdWVzPXMoe30sdGhpcy5ldmVudFByZXZpb3VzVmFsdWVzLHtkZWx0YVk6MCxkZWx0YVg6MH0pfX0se2tleTpcImhhbmRsZVNjcm9sbGJhck1vdmVcIix2YWx1ZTpmdW5jdGlvbihlLHQpe3RoaXMuc2V0U3RhdGVGcm9tRXZlbnQodGhpcy5jb21wb3NlTmV3U3RhdGUodCxlKSl9fSx7a2V5OlwiaGFuZGxlU2Nyb2xsYmFyWFBvc2l0aW9uQ2hhbmdlXCIsdmFsdWU6ZnVuY3Rpb24oZSl7dGhpcy5zY3JvbGxYVG8oZSl9fSx7a2V5OlwiaGFuZGxlU2Nyb2xsYmFyWVBvc2l0aW9uQ2hhbmdlXCIsdmFsdWU6ZnVuY3Rpb24oZSl7dGhpcy5zY3JvbGxZVG8oZSl9fSx7a2V5OlwiaGFuZGxlV2hlZWxcIix2YWx1ZTpmdW5jdGlvbihlKXt2YXIgdD1lLmRlbHRhWSxuPWUuZGVsdGFYO2lmKHRoaXMucHJvcHMuc3dhcFdoZWVsQXhlcyl7dmFyIG89W24sdF07dD1vWzBdLG49b1sxXX0xPT09ZS5kZWx0YU1vZGUmJih0Kj10aGlzLmxpbmVIZWlnaHRQeCxuKj10aGlzLmxpbmVIZWlnaHRQeCksdCo9dGhpcy5wcm9wcy5zcGVlZCxuKj10aGlzLnByb3BzLnNwZWVkO3ZhciByPXRoaXMuY29tcG9zZU5ld1N0YXRlKC1uLC10KTsoci50b3BQb3NpdGlvbiYmdGhpcy5zdGF0ZS50b3BQb3NpdGlvbiE9PXIudG9wUG9zaXRpb258fHIubGVmdFBvc2l0aW9uJiZ0aGlzLnN0YXRlLmxlZnRQb3NpdGlvbiE9PXIubGVmdFBvc2l0aW9ufHx0aGlzLnByb3BzLnN0b3BTY3JvbGxQcm9wYWdhdGlvbikmJihlLnByZXZlbnREZWZhdWx0KCksZS5zdG9wUHJvcGFnYXRpb24oKSksdGhpcy5zZXRTdGF0ZUZyb21FdmVudChyLFMud2hlZWwpLHRoaXMuZm9jdXNDb250ZW50KCl9fSx7a2V5OlwiaGFuZGxlS2V5RG93blwiLHZhbHVlOmZ1bmN0aW9uKGUpe2lmKFwiaW5wdXRcIiE9PWUudGFyZ2V0LnRhZ05hbWUudG9Mb3dlckNhc2UoKSl7dmFyIHQ9MCxuPTAsbz10aGlzLmxpbmVIZWlnaHRQeD90aGlzLmxpbmVIZWlnaHRQeDoxMDtzd2l0Y2goZS5rZXlDb2RlKXtjYXNlIDMzOnQ9dGhpcy5zdGF0ZS5jb250YWluZXJIZWlnaHQtbzticmVhaztjYXNlIDM0OnQ9LXRoaXMuc3RhdGUuY29udGFpbmVySGVpZ2h0K287YnJlYWs7Y2FzZSAzNzpuPW87YnJlYWs7Y2FzZSAzODp0PW87YnJlYWs7Y2FzZSAzOTpuPS1vO2JyZWFrO2Nhc2UgNDA6dD0tb31pZigwIT09dHx8MCE9PW4pe3ZhciByPXRoaXMuY29tcG9zZU5ld1N0YXRlKG4sdCk7ZS5wcmV2ZW50RGVmYXVsdCgpLGUuc3RvcFByb3BhZ2F0aW9uKCksdGhpcy5zZXRTdGF0ZUZyb21FdmVudChyLFMua2V5UHJlc3MpfX19fSx7a2V5OlwiaGFuZGxlV2luZG93UmVzaXplXCIsdmFsdWU6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLmNvbXB1dGVTaXplcygpO2U9dGhpcy5nZXRNb2RpZmllZFBvc2l0aW9uc0lmTmVlZGVkKGUpLHRoaXMuc2V0U3RhdGVGcm9tRXZlbnQoZSl9fSx7a2V5OlwiY29tcG9zZU5ld1N0YXRlXCIsdmFsdWU6ZnVuY3Rpb24oZSx0KXt2YXIgbj10aGlzLmNvbXB1dGVTaXplcygpO3JldHVybiB0aGlzLmNhblNjcm9sbFkobik/bi50b3BQb3NpdGlvbj10aGlzLmNvbXB1dGVUb3BQb3NpdGlvbih0LG4pOm4udG9wUG9zaXRpb249MCx0aGlzLmNhblNjcm9sbFgobikmJihuLmxlZnRQb3NpdGlvbj10aGlzLmNvbXB1dGVMZWZ0UG9zaXRpb24oZSxuKSksbn19LHtrZXk6XCJjb21wdXRlVG9wUG9zaXRpb25cIix2YWx1ZTpmdW5jdGlvbihlLHQpe3ZhciBuPXRoaXMuc3RhdGUudG9wUG9zaXRpb24tZTtyZXR1cm4gdGhpcy5ub3JtYWxpemVUb3BQb3NpdGlvbihuLHQpfX0se2tleTpcImNvbXB1dGVMZWZ0UG9zaXRpb25cIix2YWx1ZTpmdW5jdGlvbihlLHQpe3ZhciBuPXRoaXMuc3RhdGUubGVmdFBvc2l0aW9uLWU7cmV0dXJuIHRoaXMubm9ybWFsaXplTGVmdFBvc2l0aW9uKG4sdCl9fSx7a2V5Olwibm9ybWFsaXplVG9wUG9zaXRpb25cIix2YWx1ZTpmdW5jdGlvbihlLHQpe3JldHVybiBlPnQucmVhbEhlaWdodC10LmNvbnRhaW5lckhlaWdodCYmKGU9dC5yZWFsSGVpZ2h0LXQuY29udGFpbmVySGVpZ2h0KSxlPDAmJihlPTApLGV9fSx7a2V5Olwibm9ybWFsaXplTGVmdFBvc2l0aW9uXCIsdmFsdWU6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gZT50LnJlYWxXaWR0aC10LmNvbnRhaW5lcldpZHRoP2U9dC5yZWFsV2lkdGgtdC5jb250YWluZXJXaWR0aDplPDAmJihlPTApLGV9fSx7a2V5OlwiY29tcHV0ZVNpemVzXCIsdmFsdWU6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLmNvbnRlbnQub2Zmc2V0SGVpZ2h0LHQ9dGhpcy53cmFwcGVyLm9mZnNldEhlaWdodCxuPXRoaXMuY29udGVudC5vZmZzZXRXaWR0aCxvPXRoaXMud3JhcHBlci5vZmZzZXRXaWR0aDtyZXR1cm57cmVhbEhlaWdodDplLGNvbnRhaW5lckhlaWdodDp0LHJlYWxXaWR0aDpuLGNvbnRhaW5lcldpZHRoOm99fX0se2tleTpcInNldFNpemVzVG9TdGF0ZVwiLHZhbHVlOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5jb21wdXRlU2l6ZXMoKTtlLnJlYWxIZWlnaHQ9PT10aGlzLnN0YXRlLnJlYWxIZWlnaHQmJmUucmVhbFdpZHRoPT09dGhpcy5zdGF0ZS5yZWFsV2lkdGh8fHRoaXMuc2V0U3RhdGVGcm9tRXZlbnQodGhpcy5nZXRNb2RpZmllZFBvc2l0aW9uc0lmTmVlZGVkKGUpKX19LHtrZXk6XCJzY3JvbGxUb3BcIix2YWx1ZTpmdW5jdGlvbigpe3RoaXMuc2Nyb2xsWVRvKDApfX0se2tleTpcInNjcm9sbEJvdHRvbVwiLHZhbHVlOmZ1bmN0aW9uKCl7dGhpcy5zY3JvbGxZVG8odGhpcy5zdGF0ZS5yZWFsSGVpZ2h0LXRoaXMuc3RhdGUuY29udGFpbmVySGVpZ2h0KX19LHtrZXk6XCJzY3JvbGxMZWZ0XCIsdmFsdWU6ZnVuY3Rpb24oKXt0aGlzLnNjcm9sbFhUbygwKX19LHtrZXk6XCJzY3JvbGxSaWdodFwiLHZhbHVlOmZ1bmN0aW9uKCl7dGhpcy5zY3JvbGxYVG8odGhpcy5zdGF0ZS5yZWFsV2lkdGgtdGhpcy5zdGF0ZS5jb250YWluZXJXaWR0aCl9fSx7a2V5Olwic2Nyb2xsWVRvXCIsdmFsdWU6ZnVuY3Rpb24oZSl7aWYodGhpcy5jYW5TY3JvbGxZKCkpe3ZhciB0PXRoaXMubm9ybWFsaXplVG9wUG9zaXRpb24oZSx0aGlzLmNvbXB1dGVTaXplcygpKTt0aGlzLnNldFN0YXRlRnJvbUV2ZW50KHt0b3BQb3NpdGlvbjp0fSxTLmFwaSl9fX0se2tleTpcInNjcm9sbFhUb1wiLHZhbHVlOmZ1bmN0aW9uKGUpe2lmKHRoaXMuY2FuU2Nyb2xsWCgpKXt2YXIgdD10aGlzLm5vcm1hbGl6ZUxlZnRQb3NpdGlvbihlLHRoaXMuY29tcHV0ZVNpemVzKCkpO3RoaXMuc2V0U3RhdGVGcm9tRXZlbnQoe2xlZnRQb3NpdGlvbjp0fSxTLmFwaSl9fX0se2tleTpcImNhblNjcm9sbFlcIix2YWx1ZTpmdW5jdGlvbigpe3ZhciBlPWFyZ3VtZW50cy5sZW5ndGg+MCYmdm9pZCAwIT09YXJndW1lbnRzWzBdP2FyZ3VtZW50c1swXTp0aGlzLnN0YXRlLHQ9ZS5yZWFsSGVpZ2h0PmUuY29udGFpbmVySGVpZ2h0O3JldHVybiB0JiZ0aGlzLnByb3BzLnZlcnRpY2FsfX0se2tleTpcImNhblNjcm9sbFhcIix2YWx1ZTpmdW5jdGlvbigpe3ZhciBlPWFyZ3VtZW50cy5sZW5ndGg+MCYmdm9pZCAwIT09YXJndW1lbnRzWzBdP2FyZ3VtZW50c1swXTp0aGlzLnN0YXRlLHQ9ZS5yZWFsV2lkdGg+ZS5jb250YWluZXJXaWR0aDtyZXR1cm4gdCYmdGhpcy5wcm9wcy5ob3Jpem9udGFsfX0se2tleTpcImdldE1vZGlmaWVkUG9zaXRpb25zSWZOZWVkZWRcIix2YWx1ZTpmdW5jdGlvbihlKXt2YXIgdD1lLnJlYWxIZWlnaHQtZS5jb250YWluZXJIZWlnaHQ7dGhpcy5zdGF0ZS50b3BQb3NpdGlvbj49dCYmKGUudG9wUG9zaXRpb249dGhpcy5jYW5TY3JvbGxZKGUpPygwLGgucG9zaXRpdmVPclplcm8pKHQpOjApO3ZhciBuPWUucmVhbFdpZHRoLWUuY29udGFpbmVyV2lkdGg7cmV0dXJuIHRoaXMuc3RhdGUubGVmdFBvc2l0aW9uPj1uJiYoZS5sZWZ0UG9zaXRpb249dGhpcy5jYW5TY3JvbGxYKGUpPygwLGgucG9zaXRpdmVPclplcm8pKG4pOjApLGV9fSx7a2V5OlwiZm9jdXNDb250ZW50XCIsdmFsdWU6ZnVuY3Rpb24oKXt0aGlzLmNvbnRlbnQmJigwLGguZmluZERPTU5vZGUpKHRoaXMuY29udGVudCkuZm9jdXMoKX19XSksdH0oZi5kZWZhdWx0LkNvbXBvbmVudCk7dC5kZWZhdWx0PWcsZy5jaGlsZENvbnRleHRUeXBlcz17c2Nyb2xsQXJlYTpmLmRlZmF1bHQuUHJvcFR5cGVzLm9iamVjdH0sZy5wcm9wVHlwZXM9e2NsYXNzTmFtZTpmLmRlZmF1bHQuUHJvcFR5cGVzLnN0cmluZyxzdHlsZTpmLmRlZmF1bHQuUHJvcFR5cGVzLm9iamVjdCxzcGVlZDpmLmRlZmF1bHQuUHJvcFR5cGVzLm51bWJlcixjb250ZW50Q2xhc3NOYW1lOmYuZGVmYXVsdC5Qcm9wVHlwZXMuc3RyaW5nLGNvbnRlbnRTdHlsZTpmLmRlZmF1bHQuUHJvcFR5cGVzLm9iamVjdCx2ZXJ0aWNhbDpmLmRlZmF1bHQuUHJvcFR5cGVzLmJvb2wsdmVydGljYWxDb250YWluZXJTdHlsZTpmLmRlZmF1bHQuUHJvcFR5cGVzLm9iamVjdCx2ZXJ0aWNhbFNjcm9sbGJhclN0eWxlOmYuZGVmYXVsdC5Qcm9wVHlwZXMub2JqZWN0LGhvcml6b250YWw6Zi5kZWZhdWx0LlByb3BUeXBlcy5ib29sLGhvcml6b250YWxDb250YWluZXJTdHlsZTpmLmRlZmF1bHQuUHJvcFR5cGVzLm9iamVjdCxob3Jpem9udGFsU2Nyb2xsYmFyU3R5bGU6Zi5kZWZhdWx0LlByb3BUeXBlcy5vYmplY3Qsb25TY3JvbGw6Zi5kZWZhdWx0LlByb3BUeXBlcy5mdW5jLGNvbnRlbnRXaW5kb3c6Zi5kZWZhdWx0LlByb3BUeXBlcy5hbnksb3duZXJEb2N1bWVudDpmLmRlZmF1bHQuUHJvcFR5cGVzLmFueSxzbW9vdGhTY3JvbGxpbmc6Zi5kZWZhdWx0LlByb3BUeXBlcy5ib29sLG1pblNjcm9sbFNpemU6Zi5kZWZhdWx0LlByb3BUeXBlcy5udW1iZXIsc3dhcFdoZWVsQXhlczpmLmRlZmF1bHQuUHJvcFR5cGVzLmJvb2wsc3RvcFNjcm9sbFByb3BhZ2F0aW9uOmYuZGVmYXVsdC5Qcm9wVHlwZXMuYm9vbCxmb2N1c2FibGVUYWJJbmRleDpmLmRlZmF1bHQuUHJvcFR5cGVzLm51bWJlcn0sZy5kZWZhdWx0UHJvcHM9e3NwZWVkOjEsdmVydGljYWw6ITAsaG9yaXpvbnRhbDohMCxzbW9vdGhTY3JvbGxpbmc6ITEsc3dhcFdoZWVsQXhlczohMSxjb250ZW50V2luZG93Olwib2JqZWN0XCI9PT0oXCJ1bmRlZmluZWRcIj09dHlwZW9mIHdpbmRvdz9cInVuZGVmaW5lZFwiOmwod2luZG93KSk/d2luZG93OnZvaWQgMCxvd25lckRvY3VtZW50Olwib2JqZWN0XCI9PT0oXCJ1bmRlZmluZWRcIj09dHlwZW9mIGRvY3VtZW50P1widW5kZWZpbmVkXCI6bChkb2N1bWVudCkpP2RvY3VtZW50OnZvaWQgMCxmb2N1c2FibGVUYWJJbmRleDoxfX0sZnVuY3Rpb24oZSx0LG4pe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG8oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fWZ1bmN0aW9uIHIoZSx0KXtpZighKGUgaW5zdGFuY2VvZiB0KSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpfWZ1bmN0aW9uIGkoZSx0KXtpZighZSl0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoXCJ0aGlzIGhhc24ndCBiZWVuIGluaXRpYWxpc2VkIC0gc3VwZXIoKSBoYXNuJ3QgYmVlbiBjYWxsZWRcIik7cmV0dXJuIXR8fFwib2JqZWN0XCIhPXR5cGVvZiB0JiZcImZ1bmN0aW9uXCIhPXR5cGVvZiB0P2U6dH1mdW5jdGlvbiBhKGUsdCl7aWYoXCJmdW5jdGlvblwiIT10eXBlb2YgdCYmbnVsbCE9PXQpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgXCIrdHlwZW9mIHQpO2UucHJvdG90eXBlPU9iamVjdC5jcmVhdGUodCYmdC5wcm90b3R5cGUse2NvbnN0cnVjdG9yOnt2YWx1ZTplLGVudW1lcmFibGU6ITEsd3JpdGFibGU6ITAsY29uZmlndXJhYmxlOiEwfX0pLHQmJihPYmplY3Quc2V0UHJvdG90eXBlT2Y/T2JqZWN0LnNldFByb3RvdHlwZU9mKGUsdCk6ZS5fX3Byb3RvX189dCl9T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSk7dmFyIGw9T2JqZWN0LmFzc2lnbnx8ZnVuY3Rpb24oZSl7Zm9yKHZhciB0PTE7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyl7dmFyIG49YXJndW1lbnRzW3RdO2Zvcih2YXIgbyBpbiBuKU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChuLG8pJiYoZVtvXT1uW29dKX1yZXR1cm4gZX0scz1mdW5jdGlvbigpe2Z1bmN0aW9uIGUoZSx0KXtmb3IodmFyIG49MDtuPHQubGVuZ3RoO24rKyl7dmFyIG89dFtuXTtvLmVudW1lcmFibGU9by5lbnVtZXJhYmxlfHwhMSxvLmNvbmZpZ3VyYWJsZT0hMCxcInZhbHVlXCJpbiBvJiYoby53cml0YWJsZT0hMCksT2JqZWN0LmRlZmluZVByb3BlcnR5KGUsby5rZXksbyl9fXJldHVybiBmdW5jdGlvbih0LG4sbyl7cmV0dXJuIG4mJmUodC5wcm90b3R5cGUsbiksbyYmZSh0LG8pLHR9fSgpLHU9bigxKSxjPW8odSksZj1uKDEwKSxwPW4oOCksZD1mdW5jdGlvbihlKXtmdW5jdGlvbiB0KGUpe3IodGhpcyx0KTt2YXIgbj1pKHRoaXMsKHQuX19wcm90b19ffHxPYmplY3QuZ2V0UHJvdG90eXBlT2YodCkpLmNhbGwodGhpcyxlKSksbz1uLmNhbGN1bGF0ZVN0YXRlKGUpO3JldHVybiBuLnN0YXRlPXtwb3NpdGlvbjpvLnBvc2l0aW9uLHNjcm9sbFNpemU6by5zY3JvbGxTaXplLGlzRHJhZ2dpbmc6ITEsbGFzdENsaWVudFBvc2l0aW9uOjB9LFwidmVydGljYWxcIj09PWUudHlwZT9uLmJpbmRlZEhhbmRsZU1vdXNlTW92ZT1uLmhhbmRsZU1vdXNlTW92ZUZvclZlcnRpY2FsLmJpbmQobik6bi5iaW5kZWRIYW5kbGVNb3VzZU1vdmU9bi5oYW5kbGVNb3VzZU1vdmVGb3JIb3Jpem9udGFsLmJpbmQobiksbi5iaW5kZWRIYW5kbGVNb3VzZVVwPW4uaGFuZGxlTW91c2VVcC5iaW5kKG4pLG59cmV0dXJuIGEodCxlKSxzKHQsW3trZXk6XCJjb21wb25lbnREaWRNb3VudFwiLHZhbHVlOmZ1bmN0aW9uKCl7dGhpcy5wcm9wcy5vd25lckRvY3VtZW50JiYodGhpcy5wcm9wcy5vd25lckRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIix0aGlzLmJpbmRlZEhhbmRsZU1vdXNlTW92ZSksdGhpcy5wcm9wcy5vd25lckRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsdGhpcy5iaW5kZWRIYW5kbGVNb3VzZVVwKSl9fSx7a2V5OlwiY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1wiLHZhbHVlOmZ1bmN0aW9uKGUpe3RoaXMuc2V0U3RhdGUodGhpcy5jYWxjdWxhdGVTdGF0ZShlKSl9fSx7a2V5OlwiY29tcG9uZW50V2lsbFVubW91bnRcIix2YWx1ZTpmdW5jdGlvbigpe3RoaXMucHJvcHMub3duZXJEb2N1bWVudCYmKHRoaXMucHJvcHMub3duZXJEb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsdGhpcy5iaW5kZWRIYW5kbGVNb3VzZU1vdmUpLHRoaXMucHJvcHMub3duZXJEb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLHRoaXMuYmluZGVkSGFuZGxlTW91c2VVcCkpfX0se2tleTpcImNhbGN1bGF0ZUZyYWN0aW9uYWxQb3NpdGlvblwiLHZhbHVlOmZ1bmN0aW9uKGUsdCxuKXt2YXIgbz1lLXQ7cmV0dXJuIDEtKG8tbikvb319LHtrZXk6XCJjYWxjdWxhdGVTdGF0ZVwiLHZhbHVlOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMuY2FsY3VsYXRlRnJhY3Rpb25hbFBvc2l0aW9uKGUucmVhbFNpemUsZS5jb250YWluZXJTaXplLGUucG9zaXRpb24pLG49ZS5jb250YWluZXJTaXplKmUuY29udGFpbmVyU2l6ZS9lLnJlYWxTaXplLG89bjxlLm1pblNjcm9sbFNpemU/ZS5taW5TY3JvbGxTaXplOm4scj0oZS5jb250YWluZXJTaXplLW8pKnQ7cmV0dXJue3Njcm9sbFNpemU6byxwb3NpdGlvbjpNYXRoLnJvdW5kKHIpfX19LHtrZXk6XCJyZW5kZXJcIix2YWx1ZTpmdW5jdGlvbigpe3ZhciBlPXRoaXMsdD10aGlzLnByb3BzLG49dC5zbW9vdGhTY3JvbGxpbmcsbz10LmlzRHJhZ2dpbmcscj10LnR5cGUsaT10LnNjcm9sbGJhclN0eWxlLGE9dC5jb250YWluZXJTdHlsZSxzPVwiaG9yaXpvbnRhbFwiPT09cix1PVwidmVydGljYWxcIj09PXIsZD10aGlzLmNyZWF0ZVNjcm9sbFN0eWxlcygpLGg9bj8oMCxwLm1vZGlmeU9ialZhbHVlcykoZCxmdW5jdGlvbihlKXtyZXR1cm4oMCxmLnNwcmluZykoZSl9KTpkLHk9XCJzY3JvbGxiYXItY29udGFpbmVyIFwiKyhvP1wiYWN0aXZlXCI6XCJcIikrXCIgXCIrKHM/XCJob3Jpem9udGFsXCI6XCJcIikrXCIgXCIrKHU/XCJ2ZXJ0aWNhbFwiOlwiXCIpO3JldHVybiBjLmRlZmF1bHQuY3JlYXRlRWxlbWVudChmLk1vdGlvbix7c3R5bGU6aH0sZnVuY3Rpb24odCl7cmV0dXJuIGMuZGVmYXVsdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIse2NsYXNzTmFtZTp5LHN0eWxlOmEsb25Nb3VzZURvd246ZS5oYW5kbGVTY3JvbGxCYXJDb250YWluZXJDbGljay5iaW5kKGUpLHJlZjpmdW5jdGlvbih0KXtyZXR1cm4gZS5zY3JvbGxiYXJDb250YWluZXI9dH19LGMuZGVmYXVsdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIse2NsYXNzTmFtZTpcInNjcm9sbGJhclwiLHN0eWxlOmwoe30saSx0KSxvbk1vdXNlRG93bjplLmhhbmRsZU1vdXNlRG93bi5iaW5kKGUpfSkpfSl9fSx7a2V5OlwiaGFuZGxlU2Nyb2xsQmFyQ29udGFpbmVyQ2xpY2tcIix2YWx1ZTpmdW5jdGlvbihlKXtlLnByZXZlbnREZWZhdWx0KCk7dmFyIHQ9dGhpcy5jb21wdXRlTXVsdGlwbGllcigpLG49dGhpcy5pc1ZlcnRpY2FsKCk/ZS5jbGllbnRZOmUuY2xpZW50WCxvPXRoaXMuc2Nyb2xsYmFyQ29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLHI9by50b3AsaT1vLmxlZnQsYT10aGlzLmlzVmVydGljYWwoKT9yOmksbD1uLWEscz10aGlzLnByb3BzLmNvbnRhaW5lclNpemUqdGhpcy5wcm9wcy5jb250YWluZXJTaXplL3RoaXMucHJvcHMucmVhbFNpemU7dGhpcy5zZXRTdGF0ZSh7aXNEcmFnZ2luZzohMCxsYXN0Q2xpZW50UG9zaXRpb246bn0pLHRoaXMucHJvcHMub25Qb3NpdGlvbkNoYW5nZSgobC1zLzIpL3QpfX0se2tleTpcImhhbmRsZU1vdXNlTW92ZUZvckhvcml6b250YWxcIix2YWx1ZTpmdW5jdGlvbihlKXt2YXIgdD10aGlzLmNvbXB1dGVNdWx0aXBsaWVyKCk7aWYodGhpcy5zdGF0ZS5pc0RyYWdnaW5nKXtlLnByZXZlbnREZWZhdWx0KCk7dmFyIG49dGhpcy5zdGF0ZS5sYXN0Q2xpZW50UG9zaXRpb24tZS5jbGllbnRYO3RoaXMuc2V0U3RhdGUoe2xhc3RDbGllbnRQb3NpdGlvbjplLmNsaWVudFh9KSx0aGlzLnByb3BzLm9uTW92ZSgwLG4vdCl9fX0se2tleTpcImhhbmRsZU1vdXNlTW92ZUZvclZlcnRpY2FsXCIsdmFsdWU6ZnVuY3Rpb24oZSl7dmFyIHQ9dGhpcy5jb21wdXRlTXVsdGlwbGllcigpO2lmKHRoaXMuc3RhdGUuaXNEcmFnZ2luZyl7ZS5wcmV2ZW50RGVmYXVsdCgpO3ZhciBuPXRoaXMuc3RhdGUubGFzdENsaWVudFBvc2l0aW9uLWUuY2xpZW50WTt0aGlzLnNldFN0YXRlKHtsYXN0Q2xpZW50UG9zaXRpb246ZS5jbGllbnRZfSksdGhpcy5wcm9wcy5vbk1vdmUobi90LDApfX19LHtrZXk6XCJoYW5kbGVNb3VzZURvd25cIix2YWx1ZTpmdW5jdGlvbihlKXtlLnByZXZlbnREZWZhdWx0KCksZS5zdG9wUHJvcGFnYXRpb24oKTt2YXIgdD10aGlzLmlzVmVydGljYWwoKT9lLmNsaWVudFk6ZS5jbGllbnRYO3RoaXMuc2V0U3RhdGUoe2lzRHJhZ2dpbmc6ITAsbGFzdENsaWVudFBvc2l0aW9uOnR9KSx0aGlzLnByb3BzLm9uRm9jdXMoKX19LHtrZXk6XCJoYW5kbGVNb3VzZVVwXCIsdmFsdWU6ZnVuY3Rpb24oZSl7ZS5wcmV2ZW50RGVmYXVsdCgpLHRoaXMuc2V0U3RhdGUoe2lzRHJhZ2dpbmc6ITF9KX19LHtrZXk6XCJjcmVhdGVTY3JvbGxTdHlsZXNcIix2YWx1ZTpmdW5jdGlvbigpe3JldHVyblwidmVydGljYWxcIj09PXRoaXMucHJvcHMudHlwZT97aGVpZ2h0OnRoaXMuc3RhdGUuc2Nyb2xsU2l6ZSxtYXJnaW5Ub3A6dGhpcy5zdGF0ZS5wb3NpdGlvbn06e3dpZHRoOnRoaXMuc3RhdGUuc2Nyb2xsU2l6ZSxtYXJnaW5MZWZ0OnRoaXMuc3RhdGUucG9zaXRpb259fX0se2tleTpcImNvbXB1dGVNdWx0aXBsaWVyXCIsdmFsdWU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wcm9wcy5jb250YWluZXJTaXplL3RoaXMucHJvcHMucmVhbFNpemV9fSx7a2V5OlwiaXNWZXJ0aWNhbFwiLHZhbHVlOmZ1bmN0aW9uKCl7cmV0dXJuXCJ2ZXJ0aWNhbFwiPT09dGhpcy5wcm9wcy50eXBlfX1dKSx0fShjLmRlZmF1bHQuQ29tcG9uZW50KTtkLnByb3BUeXBlcz17b25Nb3ZlOmMuZGVmYXVsdC5Qcm9wVHlwZXMuZnVuYyxvblBvc2l0aW9uQ2hhbmdlOmMuZGVmYXVsdC5Qcm9wVHlwZXMuZnVuYyxvbkZvY3VzOmMuZGVmYXVsdC5Qcm9wVHlwZXMuZnVuYyxyZWFsU2l6ZTpjLmRlZmF1bHQuUHJvcFR5cGVzLm51bWJlcixjb250YWluZXJTaXplOmMuZGVmYXVsdC5Qcm9wVHlwZXMubnVtYmVyLHBvc2l0aW9uOmMuZGVmYXVsdC5Qcm9wVHlwZXMubnVtYmVyLGNvbnRhaW5lclN0eWxlOmMuZGVmYXVsdC5Qcm9wVHlwZXMub2JqZWN0LHNjcm9sbGJhclN0eWxlOmMuZGVmYXVsdC5Qcm9wVHlwZXMub2JqZWN0LHR5cGU6Yy5kZWZhdWx0LlByb3BUeXBlcy5vbmVPZihbXCJ2ZXJ0aWNhbFwiLFwiaG9yaXpvbnRhbFwiXSksb3duZXJEb2N1bWVudDpjLmRlZmF1bHQuUHJvcFR5cGVzLmFueSxzbW9vdGhTY3JvbGxpbmc6Yy5kZWZhdWx0LlByb3BUeXBlcy5ib29sLG1pblNjcm9sbFNpemU6Yy5kZWZhdWx0LlByb3BUeXBlcy5udW1iZXJ9LGQuZGVmYXVsdFByb3BzPXt0eXBlOlwidmVydGljYWxcIixzbW9vdGhTY3JvbGxpbmc6ITF9LHQuZGVmYXVsdD1kfSxmdW5jdGlvbihlLHQpe3ZhciBuPWZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gbj13aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSwobj9uKGUpOmUuY3VycmVudFN0eWxlKVt0LnJlcGxhY2UoLy0oXFx3KS9naSxmdW5jdGlvbihlLHQpe3JldHVybiB0LnRvVXBwZXJDYXNlKCl9KV19O2UuZXhwb3J0cz1ufSxmdW5jdGlvbihlLHQsbil7dD1lLmV4cG9ydHM9bigxNSkoKSx0LnB1c2goW2UuaWQsXCIuc2Nyb2xsYXJlYS1jb250ZW50e21hcmdpbjowO3BhZGRpbmc6MDtvdmVyZmxvdzpoaWRkZW47cG9zaXRpb246cmVsYXRpdmV9LnNjcm9sbGFyZWEtY29udGVudDpmb2N1c3tvdXRsaW5lOjB9LnNjcm9sbGFyZWF7cG9zaXRpb246cmVsYXRpdmU7b3ZlcmZsb3c6aGlkZGVufS5zY3JvbGxhcmVhIC5zY3JvbGxiYXItY29udGFpbmVye3Bvc2l0aW9uOmFic29sdXRlO2JhY2tncm91bmQ6bm9uZTtvcGFjaXR5Oi4xO3otaW5kZXg6OTk5OTstd2Via2l0LXRyYW5zaXRpb246YWxsIC40czt0cmFuc2l0aW9uOmFsbCAuNHN9LnNjcm9sbGFyZWEgLnNjcm9sbGJhci1jb250YWluZXIuaG9yaXpvbnRhbHt3aWR0aDoxMDAlO2hlaWdodDoxMHB4O2xlZnQ6MDtib3R0b206MH0uc2Nyb2xsYXJlYSAuc2Nyb2xsYmFyLWNvbnRhaW5lci5ob3Jpem9udGFsIC5zY3JvbGxiYXJ7d2lkdGg6MjBweDtoZWlnaHQ6OHB4O2JhY2tncm91bmQ6IzAwMDttYXJnaW4tdG9wOjFweH0uc2Nyb2xsYXJlYSAuc2Nyb2xsYmFyLWNvbnRhaW5lci52ZXJ0aWNhbHt3aWR0aDoxMHB4O2hlaWdodDoxMDAlO3JpZ2h0OjA7dG9wOjB9LnNjcm9sbGFyZWEgLnNjcm9sbGJhci1jb250YWluZXIudmVydGljYWwgLnNjcm9sbGJhcnt3aWR0aDo4cHg7aGVpZ2h0OjIwcHg7YmFja2dyb3VuZDojMDAwO21hcmdpbi1sZWZ0OjFweH0uc2Nyb2xsYXJlYSAuc2Nyb2xsYmFyLWNvbnRhaW5lci5hY3RpdmUsLnNjcm9sbGFyZWEgLnNjcm9sbGJhci1jb250YWluZXI6aG92ZXJ7YmFja2dyb3VuZDpncmF5O29wYWNpdHk6LjYhaW1wb3J0YW50fS5zY3JvbGxhcmVhOmhvdmVyIC5zY3JvbGxiYXItY29udGFpbmVye29wYWNpdHk6LjN9XCIsXCJcIl0pfSxmdW5jdGlvbihlLHQpe2UuZXhwb3J0cz1mdW5jdGlvbigpe3ZhciBlPVtdO3JldHVybiBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7Zm9yKHZhciBlPVtdLHQ9MDt0PHRoaXMubGVuZ3RoO3QrKyl7dmFyIG49dGhpc1t0XTtuWzJdP2UucHVzaChcIkBtZWRpYSBcIituWzJdK1wie1wiK25bMV0rXCJ9XCIpOmUucHVzaChuWzFdKX1yZXR1cm4gZS5qb2luKFwiXCIpfSxlLmk9ZnVuY3Rpb24odCxuKXtcInN0cmluZ1wiPT10eXBlb2YgdCYmKHQ9W1tudWxsLHQsXCJcIl1dKTtmb3IodmFyIG89e30scj0wO3I8dGhpcy5sZW5ndGg7cisrKXt2YXIgaT10aGlzW3JdWzBdO1wibnVtYmVyXCI9PXR5cGVvZiBpJiYob1tpXT0hMCl9Zm9yKHI9MDtyPHQubGVuZ3RoO3IrKyl7dmFyIGE9dFtyXTtcIm51bWJlclwiPT10eXBlb2YgYVswXSYmb1thWzBdXXx8KG4mJiFhWzJdP2FbMl09bjpuJiYoYVsyXT1cIihcIithWzJdK1wiKSBhbmQgKFwiK24rXCIpXCIpLGUucHVzaChhKSl9fSxlfX0sZnVuY3Rpb24oZSx0LG4pe2Z1bmN0aW9uIG8oZSl7dmFyIHQ9cihlLFwibGluZS1oZWlnaHRcIiksbj1wYXJzZUZsb2F0KHQsMTApO2lmKHQ9PT1uK1wiXCIpe3ZhciBvPWUuc3R5bGUubGluZUhlaWdodDtlLnN0eWxlLmxpbmVIZWlnaHQ9dCtcImVtXCIsdD1yKGUsXCJsaW5lLWhlaWdodFwiKSxuPXBhcnNlRmxvYXQodCwxMCksbz9lLnN0eWxlLmxpbmVIZWlnaHQ9bzpkZWxldGUgZS5zdHlsZS5saW5lSGVpZ2h0fWlmKHQuaW5kZXhPZihcInB0XCIpIT09LTE/KG4qPTQsbi89Myk6dC5pbmRleE9mKFwibW1cIikhPT0tMT8obio9OTYsbi89MjUuNCk6dC5pbmRleE9mKFwiY21cIikhPT0tMT8obio9OTYsbi89Mi41NCk6dC5pbmRleE9mKFwiaW5cIikhPT0tMT9uKj05Njp0LmluZGV4T2YoXCJwY1wiKSE9PS0xJiYobio9MTYpLG49TWF0aC5yb3VuZChuKSxcIm5vcm1hbFwiPT09dCl7dmFyIGk9ZS5ub2RlTmFtZSxhPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaSk7YS5pbm5lckhUTUw9XCImbmJzcDtcIjt2YXIgbD1yKGUsXCJmb250LXNpemVcIik7YS5zdHlsZS5mb250U2l6ZT1sO3ZhciBzPWRvY3VtZW50LmJvZHk7cy5hcHBlbmRDaGlsZChhKTt2YXIgdT1hLm9mZnNldEhlaWdodDtuPXUscy5yZW1vdmVDaGlsZChhKX1yZXR1cm4gbn12YXIgcj1uKDEzKTtlLmV4cG9ydHM9b30sZnVuY3Rpb24oZSx0KXtmdW5jdGlvbiBuKCl7dGhyb3cgbmV3IEVycm9yKFwic2V0VGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZFwiKX1mdW5jdGlvbiBvKCl7dGhyb3cgbmV3IEVycm9yKFwiY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkXCIpfWZ1bmN0aW9uIHIoZSl7aWYoYz09PXNldFRpbWVvdXQpcmV0dXJuIHNldFRpbWVvdXQoZSwwKTtpZigoYz09PW58fCFjKSYmc2V0VGltZW91dClyZXR1cm4gYz1zZXRUaW1lb3V0LHNldFRpbWVvdXQoZSwwKTt0cnl7cmV0dXJuIGMoZSwwKX1jYXRjaCh0KXt0cnl7cmV0dXJuIGMuY2FsbChudWxsLGUsMCl9Y2F0Y2godCl7cmV0dXJuIGMuY2FsbCh0aGlzLGUsMCl9fX1mdW5jdGlvbiBpKGUpe2lmKGY9PT1jbGVhclRpbWVvdXQpcmV0dXJuIGNsZWFyVGltZW91dChlKTtpZigoZj09PW98fCFmKSYmY2xlYXJUaW1lb3V0KXJldHVybiBmPWNsZWFyVGltZW91dCxjbGVhclRpbWVvdXQoZSk7dHJ5e3JldHVybiBmKGUpfWNhdGNoKHQpe3RyeXtyZXR1cm4gZi5jYWxsKG51bGwsZSl9Y2F0Y2godCl7cmV0dXJuIGYuY2FsbCh0aGlzLGUpfX19ZnVuY3Rpb24gYSgpe3kmJmQmJih5PSExLGQubGVuZ3RoP2g9ZC5jb25jYXQoaCk6dj0tMSxoLmxlbmd0aCYmbCgpKX1mdW5jdGlvbiBsKCl7aWYoIXkpe3ZhciBlPXIoYSk7eT0hMDtmb3IodmFyIHQ9aC5sZW5ndGg7dDspe2ZvcihkPWgsaD1bXTsrK3Y8dDspZCYmZFt2XS5ydW4oKTt2PS0xLHQ9aC5sZW5ndGh9ZD1udWxsLHk9ITEsaShlKX19ZnVuY3Rpb24gcyhlLHQpe3RoaXMuZnVuPWUsdGhpcy5hcnJheT10fWZ1bmN0aW9uIHUoKXt9dmFyIGMsZixwPWUuZXhwb3J0cz17fTshZnVuY3Rpb24oKXt0cnl7Yz1cImZ1bmN0aW9uXCI9PXR5cGVvZiBzZXRUaW1lb3V0P3NldFRpbWVvdXQ6bn1jYXRjaChlKXtjPW59dHJ5e2Y9XCJmdW5jdGlvblwiPT10eXBlb2YgY2xlYXJUaW1lb3V0P2NsZWFyVGltZW91dDpvfWNhdGNoKGUpe2Y9b319KCk7dmFyIGQsaD1bXSx5PSExLHY9LTE7cC5uZXh0VGljaz1mdW5jdGlvbihlKXt2YXIgdD1uZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aC0xKTtpZihhcmd1bWVudHMubGVuZ3RoPjEpZm9yKHZhciBuPTE7bjxhcmd1bWVudHMubGVuZ3RoO24rKyl0W24tMV09YXJndW1lbnRzW25dO2gucHVzaChuZXcgcyhlLHQpKSwxIT09aC5sZW5ndGh8fHl8fHIobCl9LHMucHJvdG90eXBlLnJ1bj1mdW5jdGlvbigpe3RoaXMuZnVuLmFwcGx5KG51bGwsdGhpcy5hcnJheSl9LHAudGl0bGU9XCJicm93c2VyXCIscC5icm93c2VyPSEwLHAuZW52PXt9LHAuYXJndj1bXSxwLnZlcnNpb249XCJcIixwLnZlcnNpb25zPXt9LHAub249dSxwLmFkZExpc3RlbmVyPXUscC5vbmNlPXUscC5vZmY9dSxwLnJlbW92ZUxpc3RlbmVyPXUscC5yZW1vdmVBbGxMaXN0ZW5lcnM9dSxwLmVtaXQ9dSxwLmJpbmRpbmc9ZnVuY3Rpb24oZSl7dGhyb3cgbmV3IEVycm9yKFwicHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWRcIil9LHAuY3dkPWZ1bmN0aW9uKCl7cmV0dXJuXCIvXCJ9LHAuY2hkaXI9ZnVuY3Rpb24oZSl7dGhyb3cgbmV3IEVycm9yKFwicHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkXCIpfSxwLnVtYXNrPWZ1bmN0aW9uKCl7cmV0dXJuIDB9fSxmdW5jdGlvbihlLHQsbil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbyhlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2U6e2RlZmF1bHQ6ZX19dC5fX2VzTW9kdWxlPSEwO3ZhciByPU9iamVjdC5hc3NpZ258fGZ1bmN0aW9uKGUpe2Zvcih2YXIgdD0xO3Q8YXJndW1lbnRzLmxlbmd0aDt0Kyspe3ZhciBuPWFyZ3VtZW50c1t0XTtmb3IodmFyIG8gaW4gbilPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobixvKSYmKGVbb109bltvXSl9cmV0dXJuIGV9LGk9big0KSxhPW8oaSksbD1uKDcpLHM9byhsKSx1PW4oNiksYz1vKHUpLGY9bigyKSxwPW8oZiksZD1uKDMpLGg9byhkKSx5PW4oNSksdj1vKHkpLG09bigxKSxTPW8obSksZz0xZTMvNjAsYj1TLmRlZmF1bHQuY3JlYXRlQ2xhc3Moe2Rpc3BsYXlOYW1lOlwiTW90aW9uXCIscHJvcFR5cGVzOntkZWZhdWx0U3R5bGU6bS5Qcm9wVHlwZXMub2JqZWN0T2YobS5Qcm9wVHlwZXMubnVtYmVyKSxzdHlsZTptLlByb3BUeXBlcy5vYmplY3RPZihtLlByb3BUeXBlcy5vbmVPZlR5cGUoW20uUHJvcFR5cGVzLm51bWJlcixtLlByb3BUeXBlcy5vYmplY3RdKSkuaXNSZXF1aXJlZCxjaGlsZHJlbjptLlByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsb25SZXN0Om0uUHJvcFR5cGVzLmZ1bmN9LGdldEluaXRpYWxTdGF0ZTpmdW5jdGlvbigpe3ZhciBlPXRoaXMucHJvcHMsdD1lLmRlZmF1bHRTdHlsZSxuPWUuc3R5bGUsbz10fHxzLmRlZmF1bHQobikscj1hLmRlZmF1bHQobyk7cmV0dXJue2N1cnJlbnRTdHlsZTpvLGN1cnJlbnRWZWxvY2l0eTpyLGxhc3RJZGVhbFN0eWxlOm8sbGFzdElkZWFsVmVsb2NpdHk6cn19LHdhc0FuaW1hdGluZzohMSxhbmltYXRpb25JRDpudWxsLHByZXZUaW1lOjAsYWNjdW11bGF0ZWRUaW1lOjAsdW5yZWFkUHJvcFN0eWxlOm51bGwsY2xlYXJVbnJlYWRQcm9wU3R5bGU6ZnVuY3Rpb24oZSl7dmFyIHQ9ITEsbj10aGlzLnN0YXRlLG89bi5jdXJyZW50U3R5bGUsaT1uLmN1cnJlbnRWZWxvY2l0eSxhPW4ubGFzdElkZWFsU3R5bGUsbD1uLmxhc3RJZGVhbFZlbG9jaXR5O2Zvcih2YXIgcyBpbiBlKWlmKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChlLHMpKXt2YXIgdT1lW3NdO1wibnVtYmVyXCI9PXR5cGVvZiB1JiYodHx8KHQ9ITAsbz1yKHt9LG8pLGk9cih7fSxpKSxhPXIoe30sYSksbD1yKHt9LGwpKSxvW3NdPXUsaVtzXT0wLGFbc109dSxsW3NdPTApfXQmJnRoaXMuc2V0U3RhdGUoe2N1cnJlbnRTdHlsZTpvLGN1cnJlbnRWZWxvY2l0eTppLGxhc3RJZGVhbFN0eWxlOmEsbGFzdElkZWFsVmVsb2NpdHk6bH0pfSxzdGFydEFuaW1hdGlvbklmTmVjZXNzYXJ5OmZ1bmN0aW9uKCl7dmFyIGU9dGhpczt0aGlzLmFuaW1hdGlvbklEPWguZGVmYXVsdChmdW5jdGlvbih0KXt2YXIgbj1lLnByb3BzLnN0eWxlO2lmKHYuZGVmYXVsdChlLnN0YXRlLmN1cnJlbnRTdHlsZSxuLGUuc3RhdGUuY3VycmVudFZlbG9jaXR5KSlyZXR1cm4gZS53YXNBbmltYXRpbmcmJmUucHJvcHMub25SZXN0JiZlLnByb3BzLm9uUmVzdCgpLGUuYW5pbWF0aW9uSUQ9bnVsbCxlLndhc0FuaW1hdGluZz0hMSx2b2lkKGUuYWNjdW11bGF0ZWRUaW1lPTApO2Uud2FzQW5pbWF0aW5nPSEwO3ZhciBvPXR8fHAuZGVmYXVsdCgpLHI9by1lLnByZXZUaW1lO2lmKGUucHJldlRpbWU9byxlLmFjY3VtdWxhdGVkVGltZT1lLmFjY3VtdWxhdGVkVGltZStyLGUuYWNjdW11bGF0ZWRUaW1lPjEwKmcmJihlLmFjY3VtdWxhdGVkVGltZT0wKSwwPT09ZS5hY2N1bXVsYXRlZFRpbWUpcmV0dXJuIGUuYW5pbWF0aW9uSUQ9bnVsbCx2b2lkIGUuc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpO3ZhciBpPShlLmFjY3VtdWxhdGVkVGltZS1NYXRoLmZsb29yKGUuYWNjdW11bGF0ZWRUaW1lL2cpKmcpL2csYT1NYXRoLmZsb29yKGUuYWNjdW11bGF0ZWRUaW1lL2cpLGw9e30scz17fSx1PXt9LGY9e307Zm9yKHZhciBkIGluIG4paWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG4sZCkpe3ZhciBoPW5bZF07aWYoXCJudW1iZXJcIj09dHlwZW9mIGgpdVtkXT1oLGZbZF09MCxsW2RdPWgsc1tkXT0wO2Vsc2V7Zm9yKHZhciB5PWUuc3RhdGUubGFzdElkZWFsU3R5bGVbZF0sbT1lLnN0YXRlLmxhc3RJZGVhbFZlbG9jaXR5W2RdLFM9MDtTPGE7UysrKXt2YXIgYj1jLmRlZmF1bHQoZy8xZTMseSxtLGgudmFsLGguc3RpZmZuZXNzLGguZGFtcGluZyxoLnByZWNpc2lvbik7eT1iWzBdLG09YlsxXX12YXIgUD1jLmRlZmF1bHQoZy8xZTMseSxtLGgudmFsLGguc3RpZmZuZXNzLGguZGFtcGluZyxoLnByZWNpc2lvbiksVD1QWzBdLHc9UFsxXTt1W2RdPXkrKFQteSkqaSxmW2RdPW0rKHctbSkqaSxsW2RdPXksc1tkXT1tfX1lLmFuaW1hdGlvbklEPW51bGwsZS5hY2N1bXVsYXRlZFRpbWUtPWEqZyxlLnNldFN0YXRlKHtjdXJyZW50U3R5bGU6dSxjdXJyZW50VmVsb2NpdHk6ZixsYXN0SWRlYWxTdHlsZTpsLGxhc3RJZGVhbFZlbG9jaXR5OnN9KSxlLnVucmVhZFByb3BTdHlsZT1udWxsLGUuc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpfSl9LGNvbXBvbmVudERpZE1vdW50OmZ1bmN0aW9uKCl7dGhpcy5wcmV2VGltZT1wLmRlZmF1bHQoKSx0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKX0sY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wczpmdW5jdGlvbihlKXtudWxsIT10aGlzLnVucmVhZFByb3BTdHlsZSYmdGhpcy5jbGVhclVucmVhZFByb3BTdHlsZSh0aGlzLnVucmVhZFByb3BTdHlsZSksdGhpcy51bnJlYWRQcm9wU3R5bGU9ZS5zdHlsZSxudWxsPT10aGlzLmFuaW1hdGlvbklEJiYodGhpcy5wcmV2VGltZT1wLmRlZmF1bHQoKSx0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKSl9LGNvbXBvbmVudFdpbGxVbm1vdW50OmZ1bmN0aW9uKCl7bnVsbCE9dGhpcy5hbmltYXRpb25JRCYmKGguZGVmYXVsdC5jYW5jZWwodGhpcy5hbmltYXRpb25JRCksdGhpcy5hbmltYXRpb25JRD1udWxsKX0scmVuZGVyOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5wcm9wcy5jaGlsZHJlbih0aGlzLnN0YXRlLmN1cnJlbnRTdHlsZSk7cmV0dXJuIGUmJlMuZGVmYXVsdC5DaGlsZHJlbi5vbmx5KGUpfX0pO3QuZGVmYXVsdD1iLGUuZXhwb3J0cz10LmRlZmF1bHR9LGZ1bmN0aW9uKGUsdCxuKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBvKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX1mdW5jdGlvbiByKGUsdCxuKXtmb3IodmFyIG89MDtvPGUubGVuZ3RoO28rKylpZighbS5kZWZhdWx0KGVbb10sdFtvXSxuW29dKSlyZXR1cm4hMTtyZXR1cm4hMH10Ll9fZXNNb2R1bGU9ITA7dmFyIGk9T2JqZWN0LmFzc2lnbnx8ZnVuY3Rpb24oZSl7Zm9yKHZhciB0PTE7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyl7dmFyIG49YXJndW1lbnRzW3RdO2Zvcih2YXIgbyBpbiBuKU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChuLG8pJiYoZVtvXT1uW29dKX1yZXR1cm4gZX0sYT1uKDQpLGw9byhhKSxzPW4oNyksdT1vKHMpLGM9big2KSxmPW8oYykscD1uKDIpLGQ9byhwKSxoPW4oMykseT1vKGgpLHY9big1KSxtPW8odiksUz1uKDEpLGc9byhTKSxiPTFlMy82MCxQPWcuZGVmYXVsdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6XCJTdGFnZ2VyZWRNb3Rpb25cIixwcm9wVHlwZXM6e2RlZmF1bHRTdHlsZXM6Uy5Qcm9wVHlwZXMuYXJyYXlPZihTLlByb3BUeXBlcy5vYmplY3RPZihTLlByb3BUeXBlcy5udW1iZXIpKSxzdHlsZXM6Uy5Qcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLGNoaWxkcmVuOlMuUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZH0sZ2V0SW5pdGlhbFN0YXRlOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5wcm9wcyx0PWUuZGVmYXVsdFN0eWxlcyxuPWUuc3R5bGVzLG89dHx8bigpLm1hcCh1LmRlZmF1bHQpLHI9by5tYXAoZnVuY3Rpb24oZSl7cmV0dXJuIGwuZGVmYXVsdChlKX0pO3JldHVybntjdXJyZW50U3R5bGVzOm8sY3VycmVudFZlbG9jaXRpZXM6cixsYXN0SWRlYWxTdHlsZXM6byxsYXN0SWRlYWxWZWxvY2l0aWVzOnJ9fSxhbmltYXRpb25JRDpudWxsLHByZXZUaW1lOjAsYWNjdW11bGF0ZWRUaW1lOjAsdW5yZWFkUHJvcFN0eWxlczpudWxsLGNsZWFyVW5yZWFkUHJvcFN0eWxlOmZ1bmN0aW9uKGUpe2Zvcih2YXIgdD10aGlzLnN0YXRlLG49dC5jdXJyZW50U3R5bGVzLG89dC5jdXJyZW50VmVsb2NpdGllcyxyPXQubGFzdElkZWFsU3R5bGVzLGE9dC5sYXN0SWRlYWxWZWxvY2l0aWVzLGw9ITEscz0wO3M8ZS5sZW5ndGg7cysrKXt2YXIgdT1lW3NdLGM9ITE7Zm9yKHZhciBmIGluIHUpaWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHUsZikpe3ZhciBwPXVbZl07XCJudW1iZXJcIj09dHlwZW9mIHAmJihjfHwoYz0hMCxsPSEwLG5bc109aSh7fSxuW3NdKSxvW3NdPWkoe30sb1tzXSkscltzXT1pKHt9LHJbc10pLGFbc109aSh7fSxhW3NdKSksbltzXVtmXT1wLG9bc11bZl09MCxyW3NdW2ZdPXAsYVtzXVtmXT0wKX19bCYmdGhpcy5zZXRTdGF0ZSh7Y3VycmVudFN0eWxlczpuLGN1cnJlbnRWZWxvY2l0aWVzOm8sbGFzdElkZWFsU3R5bGVzOnIsbGFzdElkZWFsVmVsb2NpdGllczphfSl9LHN0YXJ0QW5pbWF0aW9uSWZOZWNlc3Nhcnk6ZnVuY3Rpb24oKXt2YXIgZT10aGlzO3RoaXMuYW5pbWF0aW9uSUQ9eS5kZWZhdWx0KGZ1bmN0aW9uKHQpe3ZhciBuPWUucHJvcHMuc3R5bGVzKGUuc3RhdGUubGFzdElkZWFsU3R5bGVzKTtpZihyKGUuc3RhdGUuY3VycmVudFN0eWxlcyxuLGUuc3RhdGUuY3VycmVudFZlbG9jaXRpZXMpKXJldHVybiBlLmFuaW1hdGlvbklEPW51bGwsdm9pZChlLmFjY3VtdWxhdGVkVGltZT0wKTt2YXIgbz10fHxkLmRlZmF1bHQoKSxpPW8tZS5wcmV2VGltZTtpZihlLnByZXZUaW1lPW8sZS5hY2N1bXVsYXRlZFRpbWU9ZS5hY2N1bXVsYXRlZFRpbWUraSxlLmFjY3VtdWxhdGVkVGltZT4xMCpiJiYoZS5hY2N1bXVsYXRlZFRpbWU9MCksMD09PWUuYWNjdW11bGF0ZWRUaW1lKXJldHVybiBlLmFuaW1hdGlvbklEPW51bGwsdm9pZCBlLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKTtmb3IodmFyIGE9KGUuYWNjdW11bGF0ZWRUaW1lLU1hdGguZmxvb3IoZS5hY2N1bXVsYXRlZFRpbWUvYikqYikvYixsPU1hdGguZmxvb3IoZS5hY2N1bXVsYXRlZFRpbWUvYikscz1bXSx1PVtdLGM9W10scD1bXSxoPTA7aDxuLmxlbmd0aDtoKyspe3ZhciB5PW5baF0sdj17fSxtPXt9LFM9e30sZz17fTtmb3IodmFyIFAgaW4geSlpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeSxQKSl7dmFyIFQ9eVtQXTtpZihcIm51bWJlclwiPT10eXBlb2YgVCl2W1BdPVQsbVtQXT0wLFNbUF09VCxnW1BdPTA7ZWxzZXtmb3IodmFyIHc9ZS5zdGF0ZS5sYXN0SWRlYWxTdHlsZXNbaF1bUF0saz1lLnN0YXRlLmxhc3RJZGVhbFZlbG9jaXRpZXNbaF1bUF0sTT0wO008bDtNKyspe3ZhciBPPWYuZGVmYXVsdChiLzFlMyx3LGssVC52YWwsVC5zdGlmZm5lc3MsVC5kYW1waW5nLFQucHJlY2lzaW9uKTt3PU9bMF0saz1PWzFdfXZhciBJPWYuZGVmYXVsdChiLzFlMyx3LGssVC52YWwsVC5zdGlmZm5lc3MsVC5kYW1waW5nLFQucHJlY2lzaW9uKSxEPUlbMF0seD1JWzFdO3ZbUF09dysoRC13KSphLG1bUF09aysoeC1rKSphLFNbUF09dyxnW1BdPWt9fWNbaF09dixwW2hdPW0sc1toXT1TLHVbaF09Z31lLmFuaW1hdGlvbklEPW51bGwsZS5hY2N1bXVsYXRlZFRpbWUtPWwqYixlLnNldFN0YXRlKHtjdXJyZW50U3R5bGVzOmMsY3VycmVudFZlbG9jaXRpZXM6cCxsYXN0SWRlYWxTdHlsZXM6cyxsYXN0SWRlYWxWZWxvY2l0aWVzOnV9KSxlLnVucmVhZFByb3BTdHlsZXM9bnVsbCxlLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKX0pfSxjb21wb25lbnREaWRNb3VudDpmdW5jdGlvbigpe3RoaXMucHJldlRpbWU9ZC5kZWZhdWx0KCksdGhpcy5zdGFydEFuaW1hdGlvbklmTmVjZXNzYXJ5KCl9LGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHM6ZnVuY3Rpb24oZSl7bnVsbCE9dGhpcy51bnJlYWRQcm9wU3R5bGVzJiZ0aGlzLmNsZWFyVW5yZWFkUHJvcFN0eWxlKHRoaXMudW5yZWFkUHJvcFN0eWxlcyksdGhpcy51bnJlYWRQcm9wU3R5bGVzPWUuc3R5bGVzKHRoaXMuc3RhdGUubGFzdElkZWFsU3R5bGVzKSxudWxsPT10aGlzLmFuaW1hdGlvbklEJiYodGhpcy5wcmV2VGltZT1kLmRlZmF1bHQoKSx0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKSl9LGNvbXBvbmVudFdpbGxVbm1vdW50OmZ1bmN0aW9uKCl7bnVsbCE9dGhpcy5hbmltYXRpb25JRCYmKHkuZGVmYXVsdC5jYW5jZWwodGhpcy5hbmltYXRpb25JRCksdGhpcy5hbmltYXRpb25JRD1udWxsKX0scmVuZGVyOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5wcm9wcy5jaGlsZHJlbih0aGlzLnN0YXRlLmN1cnJlbnRTdHlsZXMpO3JldHVybiBlJiZnLmRlZmF1bHQuQ2hpbGRyZW4ub25seShlKX19KTt0LmRlZmF1bHQ9UCxlLmV4cG9ydHM9dC5kZWZhdWx0fSxmdW5jdGlvbihlLHQsbil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbyhlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2U6e2RlZmF1bHQ6ZX19ZnVuY3Rpb24gcihlLHQsbil7dmFyIG89dDtyZXR1cm4gbnVsbD09bz9lLm1hcChmdW5jdGlvbihlLHQpe3JldHVybntrZXk6ZS5rZXksZGF0YTplLmRhdGEsc3R5bGU6blt0XX19KTplLm1hcChmdW5jdGlvbihlLHQpe2Zvcih2YXIgcj0wO3I8by5sZW5ndGg7cisrKWlmKG9bcl0ua2V5PT09ZS5rZXkpcmV0dXJue2tleTpvW3JdLmtleSxkYXRhOm9bcl0uZGF0YSxzdHlsZTpuW3RdfTtyZXR1cm57a2V5OmUua2V5LGRhdGE6ZS5kYXRhLHN0eWxlOm5bdF19fSl9ZnVuY3Rpb24gaShlLHQsbixvKXtpZihvLmxlbmd0aCE9PXQubGVuZ3RoKXJldHVybiExO2Zvcih2YXIgcj0wO3I8by5sZW5ndGg7cisrKWlmKG9bcl0ua2V5IT09dFtyXS5rZXkpcmV0dXJuITE7Zm9yKHZhciByPTA7cjxvLmxlbmd0aDtyKyspaWYoIVAuZGVmYXVsdChlW3JdLHRbcl0uc3R5bGUsbltyXSkpcmV0dXJuITE7cmV0dXJuITB9ZnVuY3Rpb24gYShlLHQsbixvLHIsaSxhLGwpe2Zvcih2YXIgcz15LmRlZmF1bHQobixvLGZ1bmN0aW9uKGUsbil7dmFyIG89dChuKTtyZXR1cm4gbnVsbD09bz9udWxsOlAuZGVmYXVsdChyW2VdLG8saVtlXSk/bnVsbDp7a2V5Om4ua2V5LGRhdGE6bi5kYXRhLHN0eWxlOm99fSksYz1bXSxmPVtdLHA9W10sZD1bXSxoPTA7aDxzLmxlbmd0aDtoKyspe2Zvcih2YXIgdj1zW2hdLG09bnVsbCxTPTA7UzxuLmxlbmd0aDtTKyspaWYobltTXS5rZXk9PT12LmtleSl7bT1TO2JyZWFrfWlmKG51bGw9PW0pe3ZhciBnPWUodik7Y1toXT1nLHBbaF09Zzt2YXIgYj11LmRlZmF1bHQodi5zdHlsZSk7ZltoXT1iLGRbaF09Yn1lbHNlIGNbaF09clttXSxwW2hdPWFbbV0sZltoXT1pW21dLGRbaF09bFttXX1yZXR1cm5bcyxjLGYscCxkXX10Ll9fZXNNb2R1bGU9ITA7dmFyIGw9T2JqZWN0LmFzc2lnbnx8ZnVuY3Rpb24oZSl7Zm9yKHZhciB0PTE7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyl7dmFyIG49YXJndW1lbnRzW3RdO2Zvcih2YXIgbyBpbiBuKU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChuLG8pJiYoZVtvXT1uW29dKX1yZXR1cm4gZX0scz1uKDQpLHU9byhzKSxjPW4oNyksZj1vKGMpLHA9big2KSxkPW8ocCksaD1uKDIxKSx5PW8oaCksdj1uKDIpLG09byh2KSxTPW4oMyksZz1vKFMpLGI9big1KSxQPW8oYiksVD1uKDEpLHc9byhUKSxrPTFlMy82MCxNPXcuZGVmYXVsdC5jcmVhdGVDbGFzcyh7XG5kaXNwbGF5TmFtZTpcIlRyYW5zaXRpb25Nb3Rpb25cIixwcm9wVHlwZXM6e2RlZmF1bHRTdHlsZXM6VC5Qcm9wVHlwZXMuYXJyYXlPZihULlByb3BUeXBlcy5zaGFwZSh7a2V5OlQuUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLGRhdGE6VC5Qcm9wVHlwZXMuYW55LHN0eWxlOlQuUHJvcFR5cGVzLm9iamVjdE9mKFQuUHJvcFR5cGVzLm51bWJlcikuaXNSZXF1aXJlZH0pKSxzdHlsZXM6VC5Qcm9wVHlwZXMub25lT2ZUeXBlKFtULlByb3BUeXBlcy5mdW5jLFQuUHJvcFR5cGVzLmFycmF5T2YoVC5Qcm9wVHlwZXMuc2hhcGUoe2tleTpULlByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxkYXRhOlQuUHJvcFR5cGVzLmFueSxzdHlsZTpULlByb3BUeXBlcy5vYmplY3RPZihULlByb3BUeXBlcy5vbmVPZlR5cGUoW1QuUHJvcFR5cGVzLm51bWJlcixULlByb3BUeXBlcy5vYmplY3RdKSkuaXNSZXF1aXJlZH0pKV0pLmlzUmVxdWlyZWQsY2hpbGRyZW46VC5Qcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLHdpbGxMZWF2ZTpULlByb3BUeXBlcy5mdW5jLHdpbGxFbnRlcjpULlByb3BUeXBlcy5mdW5jfSxnZXREZWZhdWx0UHJvcHM6ZnVuY3Rpb24oKXtyZXR1cm57d2lsbEVudGVyOmZ1bmN0aW9uKGUpe3JldHVybiBmLmRlZmF1bHQoZS5zdHlsZSl9LHdpbGxMZWF2ZTpmdW5jdGlvbigpe3JldHVybiBudWxsfX19LGdldEluaXRpYWxTdGF0ZTpmdW5jdGlvbigpe3ZhciBlPXRoaXMucHJvcHMsdD1lLmRlZmF1bHRTdHlsZXMsbj1lLnN0eWxlcyxvPWUud2lsbEVudGVyLHI9ZS53aWxsTGVhdmUsaT1cImZ1bmN0aW9uXCI9PXR5cGVvZiBuP24odCk6bixsPXZvaWQgMDtsPW51bGw9PXQ/aTp0Lm1hcChmdW5jdGlvbihlKXtmb3IodmFyIHQ9MDt0PGkubGVuZ3RoO3QrKylpZihpW3RdLmtleT09PWUua2V5KXJldHVybiBpW3RdO3JldHVybiBlfSk7dmFyIHM9bnVsbD09dD9pLm1hcChmdW5jdGlvbihlKXtyZXR1cm4gZi5kZWZhdWx0KGUuc3R5bGUpfSk6dC5tYXAoZnVuY3Rpb24oZSl7cmV0dXJuIGYuZGVmYXVsdChlLnN0eWxlKX0pLGM9bnVsbD09dD9pLm1hcChmdW5jdGlvbihlKXtyZXR1cm4gdS5kZWZhdWx0KGUuc3R5bGUpfSk6dC5tYXAoZnVuY3Rpb24oZSl7cmV0dXJuIHUuZGVmYXVsdChlLnN0eWxlKX0pLHA9YShvLHIsbCxpLHMsYyxzLGMpLGQ9cFswXSxoPXBbMV0seT1wWzJdLHY9cFszXSxtPXBbNF07cmV0dXJue2N1cnJlbnRTdHlsZXM6aCxjdXJyZW50VmVsb2NpdGllczp5LGxhc3RJZGVhbFN0eWxlczp2LGxhc3RJZGVhbFZlbG9jaXRpZXM6bSxtZXJnZWRQcm9wc1N0eWxlczpkfX0sdW5tb3VudGluZzohMSxhbmltYXRpb25JRDpudWxsLHByZXZUaW1lOjAsYWNjdW11bGF0ZWRUaW1lOjAsdW5yZWFkUHJvcFN0eWxlczpudWxsLGNsZWFyVW5yZWFkUHJvcFN0eWxlOmZ1bmN0aW9uKGUpe2Zvcih2YXIgdD1hKHRoaXMucHJvcHMud2lsbEVudGVyLHRoaXMucHJvcHMud2lsbExlYXZlLHRoaXMuc3RhdGUubWVyZ2VkUHJvcHNTdHlsZXMsZSx0aGlzLnN0YXRlLmN1cnJlbnRTdHlsZXMsdGhpcy5zdGF0ZS5jdXJyZW50VmVsb2NpdGllcyx0aGlzLnN0YXRlLmxhc3RJZGVhbFN0eWxlcyx0aGlzLnN0YXRlLmxhc3RJZGVhbFZlbG9jaXRpZXMpLG49dFswXSxvPXRbMV0scj10WzJdLGk9dFszXSxzPXRbNF0sdT0wO3U8ZS5sZW5ndGg7dSsrKXt2YXIgYz1lW3VdLnN0eWxlLGY9ITE7Zm9yKHZhciBwIGluIGMpaWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGMscCkpe3ZhciBkPWNbcF07XCJudW1iZXJcIj09dHlwZW9mIGQmJihmfHwoZj0hMCxvW3VdPWwoe30sb1t1XSksclt1XT1sKHt9LHJbdV0pLGlbdV09bCh7fSxpW3VdKSxzW3VdPWwoe30sc1t1XSksblt1XT17a2V5Om5bdV0ua2V5LGRhdGE6blt1XS5kYXRhLHN0eWxlOmwoe30sblt1XS5zdHlsZSl9KSxvW3VdW3BdPWQsclt1XVtwXT0wLGlbdV1bcF09ZCxzW3VdW3BdPTAsblt1XS5zdHlsZVtwXT1kKX19dGhpcy5zZXRTdGF0ZSh7Y3VycmVudFN0eWxlczpvLGN1cnJlbnRWZWxvY2l0aWVzOnIsbWVyZ2VkUHJvcHNTdHlsZXM6bixsYXN0SWRlYWxTdHlsZXM6aSxsYXN0SWRlYWxWZWxvY2l0aWVzOnN9KX0sc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeTpmdW5jdGlvbigpe3ZhciBlPXRoaXM7dGhpcy51bm1vdW50aW5nfHwodGhpcy5hbmltYXRpb25JRD1nLmRlZmF1bHQoZnVuY3Rpb24odCl7dmFyIG49ZS5wcm9wcy5zdHlsZXMsbz1cImZ1bmN0aW9uXCI9PXR5cGVvZiBuP24ocihlLnN0YXRlLm1lcmdlZFByb3BzU3R5bGVzLGUudW5yZWFkUHJvcFN0eWxlcyxlLnN0YXRlLmxhc3RJZGVhbFN0eWxlcykpOm47aWYoaShlLnN0YXRlLmN1cnJlbnRTdHlsZXMsbyxlLnN0YXRlLmN1cnJlbnRWZWxvY2l0aWVzLGUuc3RhdGUubWVyZ2VkUHJvcHNTdHlsZXMpKXJldHVybiBlLmFuaW1hdGlvbklEPW51bGwsdm9pZChlLmFjY3VtdWxhdGVkVGltZT0wKTt2YXIgbD10fHxtLmRlZmF1bHQoKSxzPWwtZS5wcmV2VGltZTtpZihlLnByZXZUaW1lPWwsZS5hY2N1bXVsYXRlZFRpbWU9ZS5hY2N1bXVsYXRlZFRpbWUrcyxlLmFjY3VtdWxhdGVkVGltZT4xMCprJiYoZS5hY2N1bXVsYXRlZFRpbWU9MCksMD09PWUuYWNjdW11bGF0ZWRUaW1lKXJldHVybiBlLmFuaW1hdGlvbklEPW51bGwsdm9pZCBlLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKTtmb3IodmFyIHU9KGUuYWNjdW11bGF0ZWRUaW1lLU1hdGguZmxvb3IoZS5hY2N1bXVsYXRlZFRpbWUvaykqaykvayxjPU1hdGguZmxvb3IoZS5hY2N1bXVsYXRlZFRpbWUvayksZj1hKGUucHJvcHMud2lsbEVudGVyLGUucHJvcHMud2lsbExlYXZlLGUuc3RhdGUubWVyZ2VkUHJvcHNTdHlsZXMsbyxlLnN0YXRlLmN1cnJlbnRTdHlsZXMsZS5zdGF0ZS5jdXJyZW50VmVsb2NpdGllcyxlLnN0YXRlLmxhc3RJZGVhbFN0eWxlcyxlLnN0YXRlLmxhc3RJZGVhbFZlbG9jaXRpZXMpLHA9ZlswXSxoPWZbMV0seT1mWzJdLHY9ZlszXSxTPWZbNF0sZz0wO2c8cC5sZW5ndGg7ZysrKXt2YXIgYj1wW2ddLnN0eWxlLFA9e30sVD17fSx3PXt9LE09e307Zm9yKHZhciBPIGluIGIpaWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsTykpe3ZhciBJPWJbT107aWYoXCJudW1iZXJcIj09dHlwZW9mIEkpUFtPXT1JLFRbT109MCx3W09dPUksTVtPXT0wO2Vsc2V7Zm9yKHZhciBEPXZbZ11bT10seD1TW2ddW09dLGo9MDtqPGM7aisrKXt2YXIgej1kLmRlZmF1bHQoay8xZTMsRCx4LEkudmFsLEkuc3RpZmZuZXNzLEkuZGFtcGluZyxJLnByZWNpc2lvbik7RD16WzBdLHg9elsxXX12YXIgQz1kLmRlZmF1bHQoay8xZTMsRCx4LEkudmFsLEkuc3RpZmZuZXNzLEkuZGFtcGluZyxJLnByZWNpc2lvbiksXz1DWzBdLEU9Q1sxXTtQW09dPUQrKF8tRCkqdSxUW09dPXgrKEUteCkqdSx3W09dPUQsTVtPXT14fX12W2ddPXcsU1tnXT1NLGhbZ109UCx5W2ddPVR9ZS5hbmltYXRpb25JRD1udWxsLGUuYWNjdW11bGF0ZWRUaW1lLT1jKmssZS5zZXRTdGF0ZSh7Y3VycmVudFN0eWxlczpoLGN1cnJlbnRWZWxvY2l0aWVzOnksbGFzdElkZWFsU3R5bGVzOnYsbGFzdElkZWFsVmVsb2NpdGllczpTLG1lcmdlZFByb3BzU3R5bGVzOnB9KSxlLnVucmVhZFByb3BTdHlsZXM9bnVsbCxlLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKX0pKX0sY29tcG9uZW50RGlkTW91bnQ6ZnVuY3Rpb24oKXt0aGlzLnByZXZUaW1lPW0uZGVmYXVsdCgpLHRoaXMuc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpfSxjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOmZ1bmN0aW9uKGUpe3RoaXMudW5yZWFkUHJvcFN0eWxlcyYmdGhpcy5jbGVhclVucmVhZFByb3BTdHlsZSh0aGlzLnVucmVhZFByb3BTdHlsZXMpO3ZhciB0PWUuc3R5bGVzO1wiZnVuY3Rpb25cIj09dHlwZW9mIHQ/dGhpcy51bnJlYWRQcm9wU3R5bGVzPXQocih0aGlzLnN0YXRlLm1lcmdlZFByb3BzU3R5bGVzLHRoaXMudW5yZWFkUHJvcFN0eWxlcyx0aGlzLnN0YXRlLmxhc3RJZGVhbFN0eWxlcykpOnRoaXMudW5yZWFkUHJvcFN0eWxlcz10LG51bGw9PXRoaXMuYW5pbWF0aW9uSUQmJih0aGlzLnByZXZUaW1lPW0uZGVmYXVsdCgpLHRoaXMuc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpKX0sY29tcG9uZW50V2lsbFVubW91bnQ6ZnVuY3Rpb24oKXt0aGlzLnVubW91bnRpbmc9ITAsbnVsbCE9dGhpcy5hbmltYXRpb25JRCYmKGcuZGVmYXVsdC5jYW5jZWwodGhpcy5hbmltYXRpb25JRCksdGhpcy5hbmltYXRpb25JRD1udWxsKX0scmVuZGVyOmZ1bmN0aW9uKCl7dmFyIGU9cih0aGlzLnN0YXRlLm1lcmdlZFByb3BzU3R5bGVzLHRoaXMudW5yZWFkUHJvcFN0eWxlcyx0aGlzLnN0YXRlLmN1cnJlbnRTdHlsZXMpLHQ9dGhpcy5wcm9wcy5jaGlsZHJlbihlKTtyZXR1cm4gdCYmdy5kZWZhdWx0LkNoaWxkcmVuLm9ubHkodCl9fSk7dC5kZWZhdWx0PU0sZS5leHBvcnRzPXQuZGVmYXVsdH0sZnVuY3Rpb24oZSx0KXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBuKGUsdCxuKXtmb3IodmFyIG89e30scj0wO3I8ZS5sZW5ndGg7cisrKW9bZVtyXS5rZXldPXI7Zm9yKHZhciBpPXt9LHI9MDtyPHQubGVuZ3RoO3IrKylpW3Rbcl0ua2V5XT1yO2Zvcih2YXIgYT1bXSxyPTA7cjx0Lmxlbmd0aDtyKyspYVtyXT10W3JdO2Zvcih2YXIgcj0wO3I8ZS5sZW5ndGg7cisrKWlmKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoaSxlW3JdLmtleSkpe3ZhciBsPW4ocixlW3JdKTtudWxsIT1sJiZhLnB1c2gobCl9cmV0dXJuIGEuc29ydChmdW5jdGlvbihlLG4pe3ZhciByPWlbZS5rZXldLGE9aVtuLmtleV0sbD1vW2Uua2V5XSxzPW9bbi5rZXldO2lmKG51bGwhPXImJm51bGwhPWEpcmV0dXJuIGlbZS5rZXldLWlbbi5rZXldO2lmKG51bGwhPWwmJm51bGwhPXMpcmV0dXJuIG9bZS5rZXldLW9bbi5rZXldO2lmKG51bGwhPXIpe2Zvcih2YXIgdT0wO3U8dC5sZW5ndGg7dSsrKXt2YXIgYz10W3VdLmtleTtpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobyxjKSl7aWYocjxpW2NdJiZzPm9bY10pcmV0dXJuLTE7aWYocj5pW2NdJiZzPG9bY10pcmV0dXJuIDF9fXJldHVybiAxfWZvcih2YXIgdT0wO3U8dC5sZW5ndGg7dSsrKXt2YXIgYz10W3VdLmtleTtpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobyxjKSl7aWYoYTxpW2NdJiZsPm9bY10pcmV0dXJuIDE7aWYoYT5pW2NdJiZsPG9bY10pcmV0dXJuLTF9fXJldHVybi0xfSl9dC5fX2VzTW9kdWxlPSEwLHQuZGVmYXVsdD1uLGUuZXhwb3J0cz10LmRlZmF1bHR9LGZ1bmN0aW9uKGUsdCxuKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBvKCl7fXQuX19lc01vZHVsZT0hMCx0LmRlZmF1bHQ9bztlLmV4cG9ydHM9dC5kZWZhdWx0fSxmdW5jdGlvbihlLHQsbil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbyhlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2U6e2RlZmF1bHQ6ZX19ZnVuY3Rpb24gcihlLHQpe3JldHVybiBpKHt9LHMsdCx7dmFsOmV9KX10Ll9fZXNNb2R1bGU9ITA7dmFyIGk9T2JqZWN0LmFzc2lnbnx8ZnVuY3Rpb24oZSl7Zm9yKHZhciB0PTE7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyl7dmFyIG49YXJndW1lbnRzW3RdO2Zvcih2YXIgbyBpbiBuKU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChuLG8pJiYoZVtvXT1uW29dKX1yZXR1cm4gZX07dC5kZWZhdWx0PXI7dmFyIGE9big5KSxsPW8oYSkscz1pKHt9LGwuZGVmYXVsdC5ub1dvYmJsZSx7cHJlY2lzaW9uOi4wMX0pO2UuZXhwb3J0cz10LmRlZmF1bHR9LGZ1bmN0aW9uKGUsdCxuKXtmdW5jdGlvbiBvKGUsdCl7Zm9yKHZhciBuPTA7bjxlLmxlbmd0aDtuKyspe3ZhciBvPWVbbl0scj1kW28uaWRdO2lmKHIpe3IucmVmcysrO2Zvcih2YXIgaT0wO2k8ci5wYXJ0cy5sZW5ndGg7aSsrKXIucGFydHNbaV0oby5wYXJ0c1tpXSk7Zm9yKDtpPG8ucGFydHMubGVuZ3RoO2krKylyLnBhcnRzLnB1c2godShvLnBhcnRzW2ldLHQpKX1lbHNle2Zvcih2YXIgYT1bXSxpPTA7aTxvLnBhcnRzLmxlbmd0aDtpKyspYS5wdXNoKHUoby5wYXJ0c1tpXSx0KSk7ZFtvLmlkXT17aWQ6by5pZCxyZWZzOjEscGFydHM6YX19fX1mdW5jdGlvbiByKGUpe2Zvcih2YXIgdD1bXSxuPXt9LG89MDtvPGUubGVuZ3RoO28rKyl7dmFyIHI9ZVtvXSxpPXJbMF0sYT1yWzFdLGw9clsyXSxzPXJbM10sdT17Y3NzOmEsbWVkaWE6bCxzb3VyY2VNYXA6c307bltpXT9uW2ldLnBhcnRzLnB1c2godSk6dC5wdXNoKG5baV09e2lkOmkscGFydHM6W3VdfSl9cmV0dXJuIHR9ZnVuY3Rpb24gaShlLHQpe3ZhciBuPXYoKSxvPWdbZy5sZW5ndGgtMV07aWYoXCJ0b3BcIj09PWUuaW5zZXJ0QXQpbz9vLm5leHRTaWJsaW5nP24uaW5zZXJ0QmVmb3JlKHQsby5uZXh0U2libGluZyk6bi5hcHBlbmRDaGlsZCh0KTpuLmluc2VydEJlZm9yZSh0LG4uZmlyc3RDaGlsZCksZy5wdXNoKHQpO2Vsc2V7aWYoXCJib3R0b21cIiE9PWUuaW5zZXJ0QXQpdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB2YWx1ZSBmb3IgcGFyYW1ldGVyICdpbnNlcnRBdCcuIE11c3QgYmUgJ3RvcCcgb3IgJ2JvdHRvbScuXCIpO24uYXBwZW5kQ2hpbGQodCl9fWZ1bmN0aW9uIGEoZSl7ZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGUpO3ZhciB0PWcuaW5kZXhPZihlKTt0Pj0wJiZnLnNwbGljZSh0LDEpfWZ1bmN0aW9uIGwoZSl7dmFyIHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO3JldHVybiB0LnR5cGU9XCJ0ZXh0L2Nzc1wiLGkoZSx0KSx0fWZ1bmN0aW9uIHMoZSl7dmFyIHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImxpbmtcIik7cmV0dXJuIHQucmVsPVwic3R5bGVzaGVldFwiLGkoZSx0KSx0fWZ1bmN0aW9uIHUoZSx0KXt2YXIgbixvLHI7aWYodC5zaW5nbGV0b24pe3ZhciBpPVMrKztuPW18fChtPWwodCkpLG89Yy5iaW5kKG51bGwsbixpLCExKSxyPWMuYmluZChudWxsLG4saSwhMCl9ZWxzZSBlLnNvdXJjZU1hcCYmXCJmdW5jdGlvblwiPT10eXBlb2YgVVJMJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBVUkwuY3JlYXRlT2JqZWN0VVJMJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBVUkwucmV2b2tlT2JqZWN0VVJMJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBCbG9iJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBidG9hPyhuPXModCksbz1wLmJpbmQobnVsbCxuKSxyPWZ1bmN0aW9uKCl7YShuKSxuLmhyZWYmJlVSTC5yZXZva2VPYmplY3RVUkwobi5ocmVmKX0pOihuPWwodCksbz1mLmJpbmQobnVsbCxuKSxyPWZ1bmN0aW9uKCl7YShuKX0pO3JldHVybiBvKGUpLGZ1bmN0aW9uKHQpe2lmKHQpe2lmKHQuY3NzPT09ZS5jc3MmJnQubWVkaWE9PT1lLm1lZGlhJiZ0LnNvdXJjZU1hcD09PWUuc291cmNlTWFwKXJldHVybjtvKGU9dCl9ZWxzZSByKCl9fWZ1bmN0aW9uIGMoZSx0LG4sbyl7dmFyIHI9bj9cIlwiOm8uY3NzO2lmKGUuc3R5bGVTaGVldCllLnN0eWxlU2hlZXQuY3NzVGV4dD1iKHQscik7ZWxzZXt2YXIgaT1kb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShyKSxhPWUuY2hpbGROb2RlczthW3RdJiZlLnJlbW92ZUNoaWxkKGFbdF0pLGEubGVuZ3RoP2UuaW5zZXJ0QmVmb3JlKGksYVt0XSk6ZS5hcHBlbmRDaGlsZChpKX19ZnVuY3Rpb24gZihlLHQpe3ZhciBuPXQuY3NzLG89dC5tZWRpYTtpZihvJiZlLnNldEF0dHJpYnV0ZShcIm1lZGlhXCIsbyksZS5zdHlsZVNoZWV0KWUuc3R5bGVTaGVldC5jc3NUZXh0PW47ZWxzZXtmb3IoO2UuZmlyc3RDaGlsZDspZS5yZW1vdmVDaGlsZChlLmZpcnN0Q2hpbGQpO2UuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobikpfX1mdW5jdGlvbiBwKGUsdCl7dmFyIG49dC5jc3Msbz10LnNvdXJjZU1hcDtvJiYobis9XCJcXG4vKiMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247YmFzZTY0LFwiK2J0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KG8pKSkpK1wiICovXCIpO3ZhciByPW5ldyBCbG9iKFtuXSx7dHlwZTpcInRleHQvY3NzXCJ9KSxpPWUuaHJlZjtlLmhyZWY9VVJMLmNyZWF0ZU9iamVjdFVSTChyKSxpJiZVUkwucmV2b2tlT2JqZWN0VVJMKGkpfXZhciBkPXt9LGg9ZnVuY3Rpb24oZSl7dmFyIHQ7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuXCJ1bmRlZmluZWRcIj09dHlwZW9mIHQmJih0PWUuYXBwbHkodGhpcyxhcmd1bWVudHMpKSx0fX0seT1oKGZ1bmN0aW9uKCl7cmV0dXJuL21zaWUgWzYtOV1cXGIvLnRlc3Qod2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKSl9KSx2PWgoZnVuY3Rpb24oKXtyZXR1cm4gZG9jdW1lbnQuaGVhZHx8ZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJoZWFkXCIpWzBdfSksbT1udWxsLFM9MCxnPVtdO2UuZXhwb3J0cz1mdW5jdGlvbihlLHQpe3Q9dHx8e30sXCJ1bmRlZmluZWRcIj09dHlwZW9mIHQuc2luZ2xldG9uJiYodC5zaW5nbGV0b249eSgpKSxcInVuZGVmaW5lZFwiPT10eXBlb2YgdC5pbnNlcnRBdCYmKHQuaW5zZXJ0QXQ9XCJib3R0b21cIik7dmFyIG49cihlKTtyZXR1cm4gbyhuLHQpLGZ1bmN0aW9uKGUpe2Zvcih2YXIgaT1bXSxhPTA7YTxuLmxlbmd0aDthKyspe3ZhciBsPW5bYV0scz1kW2wuaWRdO3MucmVmcy0tLGkucHVzaChzKX1pZihlKXt2YXIgdT1yKGUpO28odSx0KX1mb3IodmFyIGE9MDthPGkubGVuZ3RoO2ErKyl7dmFyIHM9aVthXTtpZigwPT09cy5yZWZzKXtmb3IodmFyIGM9MDtjPHMucGFydHMubGVuZ3RoO2MrKylzLnBhcnRzW2NdKCk7ZGVsZXRlIGRbcy5pZF19fX19O3ZhciBiPWZ1bmN0aW9uKCl7dmFyIGU9W107cmV0dXJuIGZ1bmN0aW9uKHQsbil7cmV0dXJuIGVbdF09bixlLmZpbHRlcihCb29sZWFuKS5qb2luKFwiXFxuXCIpfX0oKX0sZnVuY3Rpb24oZSx0LG4pe3ZhciBvPW4oMTQpO1wic3RyaW5nXCI9PXR5cGVvZiBvJiYobz1bW2UuaWQsbyxcIlwiXV0pO24oMjQpKG8se30pO28ubG9jYWxzJiYoZS5leHBvcnRzPW8ubG9jYWxzKX1dKX0pOyIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfU3RvcmUgPSByZXF1aXJlKCcuL1N0b3JlJyk7XG5cbnZhciBfU3RvcmUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU3RvcmUpO1xuXG52YXIgX0dyaWRCdWlsZGVyID0gcmVxdWlyZSgnLi9HcmlkQnVpbGRlcicpO1xuXG52YXIgX0dyaWRCdWlsZGVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0dyaWRCdWlsZGVyKTtcblxuLyoqXG4gKiBBdXRvbWF0aWMgbGF5b3V0IGZvciBwcmVzZW50aW5nIGRyYWdnYWJsZSBjYXJkcyB0byB1c2Vycy4gVXNlZCBmb3IgdXNlciBhbmQgYWRtaW4gZGFzaGJvYXJkLlxuICovXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIFB5ZGlvID0gcmVxdWlyZSgncHlkaW8nKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgncmVhY3QtZ3JpZC1sYXlvdXQnKTtcblxudmFyIFJlc3BvbnNpdmUgPSBfcmVxdWlyZS5SZXNwb25zaXZlO1xudmFyIFdpZHRoUHJvdmlkZXIgPSBfcmVxdWlyZS5XaWR0aFByb3ZpZGVyO1xuXG52YXIgX1B5ZGlvJHJlcXVpcmVMaWIgPSBQeWRpby5yZXF1aXJlTGliKCdib290Jyk7XG5cbnZhciBQeWRpb0NvbnRleHRDb25zdW1lciA9IF9QeWRpbyRyZXF1aXJlTGliLlB5ZGlvQ29udGV4dENvbnN1bWVyO1xudmFyIENhcmRzR3JpZCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ0NhcmRzR3JpZCcsXG5cbiAgICAvKipcbiAgICAgKiBTYXZlIGxheW91dHMgaW4gdGhlIHVzZXJzIHByZWZlcmVuY2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gYWxsTGF5b3V0cyBSZXNwb25zaXZlIGxheW91dHMgcGFzc2VkIGZvciBzYXZpbmdcbiAgICAgKi9cbiAgICBzYXZlRnVsbExheW91dHM6IGZ1bmN0aW9uIHNhdmVGdWxsTGF5b3V0cyhhbGxMYXlvdXRzKSB7XG4gICAgICAgIHZhciBzYXZlZFByZWYgPSB0aGlzLnByb3BzLnN0b3JlLmdldFVzZXJQcmVmZXJlbmNlKCdMYXlvdXQnKTtcbiAgICAgICAgLy8gQ29tcGFyZSBKU09OIHZlcnNpb25zIHRvIGF2b2lkIHNhdmluZyB1bm5lY2Vzc2FyeSBjaGFuZ2VzXG4gICAgICAgIGlmIChzYXZlZFByZWYgJiYgdGhpcy5wcmV2aW91c0xheW91dCAmJiB0aGlzLnByZXZpb3VzTGF5b3V0ID09IEpTT04uc3RyaW5naWZ5KGFsbExheW91dHMpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wcmV2aW91c0xheW91dCA9IEpTT04uc3RyaW5naWZ5KGFsbExheW91dHMpO1xuICAgICAgICB0aGlzLnByb3BzLnN0b3JlLnNhdmVVc2VyUHJlZmVyZW5jZSgnTGF5b3V0JywgYWxsTGF5b3V0cyk7XG4gICAgfSxcblxuICAgIG9uTGF5b3V0Q2hhbmdlOiBmdW5jdGlvbiBvbkxheW91dENoYW5nZShjdXJyZW50TGF5b3V0LCBhbGxMYXlvdXRzKSB7XG4gICAgICAgIGlmICh0aGlzLl9ibG9ja0xheW91dFNhdmUpIHJldHVybjtcbiAgICAgICAgdGhpcy5zYXZlRnVsbExheW91dHMoYWxsTGF5b3V0cyk7XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50OiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5zdG9yZS5zdG9wT2JzZXJ2aW5nKFwiY2FyZHNcIiwgdGhpcy5fc3RvcmVPYnNlcnZlcik7XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHM6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzICYmIG5leHRQcm9wcy5lZGl0TW9kZSAhPT0gdGhpcy5wcm9wcy5lZGl0TW9kZSkge1xuICAgICAgICAgICAgT2JqZWN0LmtleXModGhpcy5yZWZzKS5mb3JFYWNoKChmdW5jdGlvbiAoaykge1xuICAgICAgICAgICAgICAgIHRoaXMucmVmc1trXS50b2dnbGVFZGl0TW9kZShuZXh0UHJvcHMuZWRpdE1vZGUpO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgc2hvdWxkQ29tcG9uZW50VXBkYXRlOiBmdW5jdGlvbiBzaG91bGRDb21wb25lbnRVcGRhdGUobmV4dFByb3BzLCBuZXh0U3RhdGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZvcmNlVXBkYXRlIHx8IGZhbHNlO1xuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgdGhpcy5fc3RvcmVPYnNlcnZlciA9IChmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICAgICAgdGhpcy5fZm9yY2VVcGRhdGUgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgY2FyZHM6IHRoaXMucHJvcHMuc3RvcmUuZ2V0Q2FyZHMoKVxuICAgICAgICAgICAgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF90aGlzLl9mb3JjZVVwZGF0ZSA9IGZhbHNlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMucHJvcHMuc3RvcmUub2JzZXJ2ZShcImNhcmRzXCIsIHRoaXMuX3N0b3JlT2JzZXJ2ZXIpO1xuICAgICAgICByZXR1cm4geyBjYXJkczogdGhpcy5wcm9wcy5zdG9yZS5nZXRDYXJkcygpIH07XG4gICAgfSxcblxuICAgIHJlbW92ZUNhcmQ6IGZ1bmN0aW9uIHJlbW92ZUNhcmQoaXRlbUtleSkge1xuICAgICAgICB0aGlzLnByb3BzLnJlbW92ZUNhcmQoaXRlbUtleSk7XG4gICAgfSxcblxuICAgIGJ1aWxkQ2FyZHM6IGZ1bmN0aW9uIGJ1aWxkQ2FyZHMoY2FyZHMpIHtcblxuICAgICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgICB2YXIgbGF5b3V0cyA9IHsgbGc6IFtdLCBtZDogW10sIHNtOiBbXSwgeHM6IFtdLCB4eHM6IFtdIH07XG4gICAgICAgIHZhciBpdGVtcyA9IFtdO1xuICAgICAgICB2YXIgYWRkaXRpb25hbE5hbWVzcGFjZXMgPSBbXTtcbiAgICAgICAgdmFyIHJhbmQgPSBNYXRoLnJhbmRvbSgpO1xuICAgICAgICB2YXIgc2F2ZWRMYXlvdXRzID0gdGhpcy5wcm9wcy5zdG9yZS5nZXRVc2VyUHJlZmVyZW5jZSgnTGF5b3V0Jyk7XG4gICAgICAgIHZhciBidWlsZExheW91dCA9IGZ1bmN0aW9uIGJ1aWxkTGF5b3V0KGNsYXNzT2JqZWN0LCBpdGVtS2V5LCBpdGVtLCB4LCB5KSB7XG4gICAgICAgICAgICB2YXIgbGF5b3V0ID0gY2xhc3NPYmplY3QuZ2V0R3JpZExheW91dCh4LCB5KTtcbiAgICAgICAgICAgIGxheW91dFsnaGFuZGxlJ10gPSAnaDQnO1xuICAgICAgICAgICAgaWYgKGl0ZW1bJ2dyaWRIYW5kbGUnXSkge1xuICAgICAgICAgICAgICAgIGxheW91dFsnaGFuZGxlJ10gPSBpdGVtWydncmlkSGFuZGxlJ107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsYXlvdXRbJ2knXSA9IGl0ZW1LZXk7XG4gICAgICAgICAgICByZXR1cm4gbGF5b3V0O1xuICAgICAgICB9O1xuICAgICAgICBjYXJkcy5tYXAoKGZ1bmN0aW9uIChpdGVtKSB7XG5cbiAgICAgICAgICAgIHZhciBwYXJ0cyA9IGl0ZW0uY29tcG9uZW50Q2xhc3Muc3BsaXQoXCIuXCIpO1xuICAgICAgICAgICAgdmFyIGNsYXNzTlMgPSBwYXJ0c1swXTtcbiAgICAgICAgICAgIHZhciBjbGFzc05hbWUgPSBwYXJ0c1sxXTtcbiAgICAgICAgICAgIHZhciBjbGFzc09iamVjdDtcbiAgICAgICAgICAgIGlmIChnbG9iYWxbY2xhc3NOU10gJiYgZ2xvYmFsW2NsYXNzTlNdW2NsYXNzTmFtZV0pIHtcbiAgICAgICAgICAgICAgICBjbGFzc09iamVjdCA9IGdsb2JhbFtjbGFzc05TXVtjbGFzc05hbWVdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoIWdsb2JhbFtjbGFzc05TXSkge1xuICAgICAgICAgICAgICAgICAgICBhZGRpdGlvbmFsTmFtZXNwYWNlcy5wdXNoKGNsYXNzTlMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgcHJvcHMgPSBfZXh0ZW5kcyh7fSwgaXRlbS5wcm9wcyk7XG4gICAgICAgICAgICB2YXIgaXRlbUtleSA9IHByb3BzWydrZXknXSA9IGl0ZW1bJ2lkJ10gfHwgJ2l0ZW1fJyArIGluZGV4O1xuICAgICAgICAgICAgcHJvcHMucmVmID0gaXRlbUtleTtcbiAgICAgICAgICAgIHByb3BzLnB5ZGlvID0gdGhpcy5wcm9wcy5weWRpbztcbiAgICAgICAgICAgIHByb3BzLm9uQ2xvc2VBY3Rpb24gPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlQ2FyZChpdGVtS2V5KTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgICAgICBwcm9wcy5wcmVmZXJlbmNlc1Byb3ZpZGVyID0gdGhpcy5wcm9wcy5zdG9yZTtcbiAgICAgICAgICAgIHZhciBkZWZhdWx0WCA9IDAsXG4gICAgICAgICAgICAgICAgZGVmYXVsdFkgPSAwO1xuICAgICAgICAgICAgaWYgKGl0ZW0uZGVmYXVsdFBvc2l0aW9uKSB7XG4gICAgICAgICAgICAgICAgZGVmYXVsdFggPSBpdGVtLmRlZmF1bHRQb3NpdGlvbi54O1xuICAgICAgICAgICAgICAgIGRlZmF1bHRZID0gaXRlbS5kZWZhdWx0UG9zaXRpb24ueTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBkZWZhdWx0TGF5b3V0ID0gYnVpbGRMYXlvdXQoY2xhc3NPYmplY3QsIGl0ZW1LZXksIGl0ZW0sIGRlZmF1bHRYLCBkZWZhdWx0WSk7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGJyZWFrcG9pbnQgaW4gbGF5b3V0cykge1xuICAgICAgICAgICAgICAgIGlmICghbGF5b3V0cy5oYXNPd25Qcm9wZXJ0eShicmVha3BvaW50KSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgdmFyIGJyZWFrTGF5b3V0ID0gbGF5b3V0c1ticmVha3BvaW50XTtcbiAgICAgICAgICAgICAgICAvLyBGaW5kIGNvcnJlc3BvbmRpbmcgZWxlbWVudCBpbiBwcmVmZXJlbmNlXG4gICAgICAgICAgICAgICAgdmFyIGV4aXN0aW5nO1xuICAgICAgICAgICAgICAgIGlmIChzYXZlZExheW91dHMgJiYgc2F2ZWRMYXlvdXRzW2JyZWFrcG9pbnRdKSB7XG4gICAgICAgICAgICAgICAgICAgIHNhdmVkTGF5b3V0c1ticmVha3BvaW50XS5tYXAoZnVuY3Rpb24gKGdyaWREYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ3JpZERhdGFbJ2knXSA9PSBpdGVtS2V5ICYmIGdyaWREYXRhWydoJ10gPT0gZGVmYXVsdExheW91dFsnaCddKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcgPSBncmlkRGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICAgICAgICAgICAgICBicmVha0xheW91dC5wdXNoKGV4aXN0aW5nKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGl0ZW0uZGVmYXVsdExheW91dHMgJiYgaXRlbS5kZWZhdWx0TGF5b3V0c1ticmVha3BvaW50XSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgY3J0TGF5b3V0ID0gYnVpbGRMYXlvdXQoY2xhc3NPYmplY3QsIGl0ZW1LZXksIGl0ZW0sIGl0ZW0uZGVmYXVsdExheW91dHNbYnJlYWtwb2ludF0ueCwgaXRlbS5kZWZhdWx0TGF5b3V0c1ticmVha3BvaW50XS55KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtMYXlvdXQucHVzaChjcnRMYXlvdXQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrTGF5b3V0LnB1c2goZGVmYXVsdExheW91dCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgICAgIGl0ZW1zLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChjbGFzc09iamVjdCwgcHJvcHMpKTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgaWYgKGFkZGl0aW9uYWxOYW1lc3BhY2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5fYmxvY2tMYXlvdXRTYXZlID0gdHJ1ZTtcbiAgICAgICAgICAgIFJlc291cmNlc01hbmFnZXIubG9hZENsYXNzZXNBbmRBcHBseShhZGRpdGlvbmFsTmFtZXNwYWNlcywgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgYWRkaXRpb25hbE5hbWVzcGFjZXNMb2FkZWQ6IGFkZGl0aW9uYWxOYW1lc3BhY2VzIH0sIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2Jsb2NrTGF5b3V0U2F2ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgY2FyZHM6IGl0ZW1zLCBsYXlvdXRzOiBsYXlvdXRzIH07XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX2J1aWxkQ2FyZHMgPSB0aGlzLmJ1aWxkQ2FyZHModGhpcy5zdGF0ZS5jYXJkcyk7XG5cbiAgICAgICAgdmFyIGNhcmRzID0gX2J1aWxkQ2FyZHMuY2FyZHM7XG4gICAgICAgIHZhciBsYXlvdXRzID0gX2J1aWxkQ2FyZHMubGF5b3V0cztcblxuICAgICAgICB2YXIgUmVzcG9uc2l2ZUdyaWRMYXlvdXQgPSBXaWR0aFByb3ZpZGVyKFJlc3BvbnNpdmUpO1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgIFJlc3BvbnNpdmVHcmlkTGF5b3V0LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogJ2Rhc2hib2FyZC1sYXlvdXQnLFxuICAgICAgICAgICAgICAgIGNvbHM6IHRoaXMucHJvcHMuY29scyB8fCB7IGxnOiAxMCwgbWQ6IDgsIHNtOiA4LCB4czogNCwgeHhzOiAyIH0sXG4gICAgICAgICAgICAgICAgbGF5b3V0czogbGF5b3V0cyxcbiAgICAgICAgICAgICAgICByb3dIZWlnaHQ6IDUsXG4gICAgICAgICAgICAgICAgb25MYXlvdXRDaGFuZ2U6IHRoaXMub25MYXlvdXRDaGFuZ2UsXG4gICAgICAgICAgICAgICAgaXNEcmFnZ2FibGU6ICF0aGlzLnByb3BzLmRpc2FibGVEcmFnLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB0aGlzLnByb3BzLnN0eWxlLFxuICAgICAgICAgICAgICAgIGF1dG9TaXplOiBmYWxzZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNhcmRzXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcblxudmFyIER5bmFtaWNHcmlkID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnRHluYW1pY0dyaWQnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHN0b3JlTmFtZXNwYWNlOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgICAgIGJ1aWxkZXJOYW1lc3BhY2VzOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXksXG4gICAgICAgIGRlZmF1bHRDYXJkczogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuICAgICAgICBweWRpbzogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW8pLFxuICAgICAgICBkaXNhYmxlRHJhZzogUmVhY3QuUHJvcFR5cGVzLmJvb2xcbiAgICB9LFxuXG4gICAgcmVtb3ZlQ2FyZDogZnVuY3Rpb24gcmVtb3ZlQ2FyZChjYXJkSWQpIHtcblxuICAgICAgICB0aGlzLnN0YXRlLnN0b3JlLnJlbW92ZUNhcmQoY2FyZElkKTtcbiAgICB9LFxuXG4gICAgYWRkQ2FyZDogZnVuY3Rpb24gYWRkQ2FyZChjYXJkRGVmaW5pdGlvbikge1xuXG4gICAgICAgIHRoaXMuc3RhdGUuc3RvcmUuYWRkQ2FyZChjYXJkRGVmaW5pdGlvbik7XG4gICAgfSxcblxuICAgIHJlc2V0Q2FyZHNBbmRMYXlvdXQ6IGZ1bmN0aW9uIHJlc2V0Q2FyZHNBbmRMYXlvdXQoKSB7XG4gICAgICAgIHRoaXMuc3RhdGUuc3RvcmUuc2F2ZVVzZXJQcmVmZXJlbmNlKCdMYXlvdXQnLCBudWxsKTtcbiAgICAgICAgdGhpcy5zdGF0ZS5zdG9yZS5zZXRDYXJkcyh0aGlzLnByb3BzLmRlZmF1bHRDYXJkcyk7XG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICB2YXIgc3RvcmUgPSBuZXcgX1N0b3JlMlsnZGVmYXVsdCddKHRoaXMucHJvcHMuc3RvcmVOYW1lc3BhY2UsIHRoaXMucHJvcHMuZGVmYXVsdENhcmRzLCB0aGlzLnByb3BzLnB5ZGlvKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGVkaXRNb2RlOiBmYWxzZSxcbiAgICAgICAgICAgIHN0b3JlOiBzdG9yZVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICB0b2dnbGVFZGl0TW9kZTogZnVuY3Rpb24gdG9nZ2xlRWRpdE1vZGUoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlZGl0TW9kZTogIXRoaXMuc3RhdGUuZWRpdE1vZGUgfSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICB2YXIgbW9uaXRvcldpZGdldEVkaXRpbmcgPSAoZnVuY3Rpb24gKHN0YXR1cykge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHdpZGdldEVkaXRpbmc6IHN0YXR1cyB9KTtcbiAgICAgICAgfSkuYmluZCh0aGlzKTtcblxuICAgICAgICB2YXIgYnVpbGRlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuYnVpbGRlck5hbWVzcGFjZXMgJiYgdGhpcy5zdGF0ZS5lZGl0TW9kZSkge1xuICAgICAgICAgICAgYnVpbGRlciA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoX0dyaWRCdWlsZGVyMlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAnYWRtaW4taGVscGVyLXBhbmVsJyxcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2VzOiB0aGlzLnByb3BzLmJ1aWxkZXJOYW1lc3BhY2VzLFxuICAgICAgICAgICAgICAgIG9uQ3JlYXRlQ2FyZDogdGhpcy5hZGRDYXJkLFxuICAgICAgICAgICAgICAgIG9uUmVzZXRMYXlvdXQ6IHRoaXMucmVzZXRDYXJkc0FuZExheW91dCxcbiAgICAgICAgICAgICAgICBvbkVkaXRTdGF0dXNDaGFuZ2U6IG1vbml0b3JXaWRnZXRFZGl0aW5nLFxuICAgICAgICAgICAgICAgIGdldE1lc3NhZ2U6IGZ1bmN0aW9uIChpZCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbnMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyAnYWp4cF9hZG1pbicgOiBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIucHJvcHMuZ2V0TWVzc2FnZShpZCwgbnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcm9wU3R5bGUgPSB0aGlzLnByb3BzLnN0eWxlIHx8IHt9O1xuICAgICAgICB2YXIgcmdsU3R5bGUgPSB0aGlzLnByb3BzLnJnbFN0eWxlIHx8IHt9O1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgeyBzdHlsZTogX2V4dGVuZHMoe30sIHRoaXMucHJvcHMuc3R5bGUsIHsgd2lkdGg6ICcxMDAlJywgZmxleDogJzEnIH0pLCBjbGFzc05hbWU6IHRoaXMuc3RhdGUuZWRpdE1vZGUgPyBcImJ1aWxkZXItb3BlblwiIDogXCJcIiB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IHBvc2l0aW9uOiAnYWJzb2x1dGUnLCBib3R0b206IDMwLCByaWdodDogMTgsIHpJbmRleDogMTEgfSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWF0ZXJpYWxVSS5GbG9hdGluZ0FjdGlvbkJ1dHRvbiwge1xuICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJ2hvbWUuNDknKSxcbiAgICAgICAgICAgICAgICAgICAgb25DbGljazogdGhpcy50b2dnbGVFZGl0TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogdGhpcy5zdGF0ZS5lZGl0TW9kZSA/IFwiaWNvbi1va1wiIDogXCJtZGkgbWRpLXBlbmNpbFwiLFxuICAgICAgICAgICAgICAgICAgICBtaW5pOiB0aGlzLnN0YXRlLmVkaXRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZDogdGhpcy5zdGF0ZS5lZGl0TW9kZSAmJiB0aGlzLnN0YXRlLndpZGdldEVkaXRpbmdcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIGJ1aWxkZXIsXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnaG9tZS1kYXNoYm9hcmQnLCBzdHlsZTogeyBoZWlnaHQ6ICcxMDAlJyB9IH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChDYXJkc0dyaWQsIHtcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZURyYWc6IHRoaXMucHJvcHMuZGlzYWJsZURyYWcsXG4gICAgICAgICAgICAgICAgICAgIGNvbHM6IHRoaXMucHJvcHMuY29scyxcbiAgICAgICAgICAgICAgICAgICAgc3RvcmU6IHRoaXMuc3RhdGUuc3RvcmUsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiByZ2xTdHlsZSxcbiAgICAgICAgICAgICAgICAgICAgcHlkaW86IHRoaXMucHJvcHMucHlkaW8sXG4gICAgICAgICAgICAgICAgICAgIGVkaXRNb2RlOiB0aGlzLnN0YXRlLmVkaXRNb2RlLFxuICAgICAgICAgICAgICAgICAgICByZW1vdmVDYXJkOiB0aGlzLnJlbW92ZUNhcmRcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cblxufSk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IER5bmFtaWNHcmlkID0gUHlkaW9Db250ZXh0Q29uc3VtZXIoRHluYW1pY0dyaWQpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gRHluYW1pY0dyaWQ7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIFB5ZGlvID0gcmVxdWlyZSgncHlkaW8nKTtcblxudmFyIF9QeWRpbyRyZXF1aXJlTGliID0gUHlkaW8ucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgUHlkaW9Db250ZXh0Q29uc3VtZXIgPSBfUHlkaW8kcmVxdWlyZUxpYi5QeWRpb0NvbnRleHRDb25zdW1lcjtcbnZhciBBc3luY0NvbXBvbmVudCA9IF9QeWRpbyRyZXF1aXJlTGliLkFzeW5jQ29tcG9uZW50O1xuXG52YXIgR3JpZEJ1aWxkZXIgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdHcmlkQnVpbGRlcicsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgbmFtZXNwYWNlczogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuICAgICAgICBvbkNyZWF0ZUNhcmQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvbkVkaXRTdGF0dXNDaGFuZ2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2VsZWN0ZWRJbmRleDogMCxcbiAgICAgICAgICAgIGF2YWlsYWJsZVdpZGdldHM6IHRoaXMubGlzdEF2YWlsYWJsZVdpZGdldHMoKVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBsaXN0QXZhaWxhYmxlV2lkZ2V0czogZnVuY3Rpb24gbGlzdEF2YWlsYWJsZVdpZGdldHMoKSB7XG4gICAgICAgIHZhciBzZWNvbmRQYXNzID0gYXJndW1lbnRzLmxlbmd0aCA8PSAwIHx8IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiBhcmd1bWVudHNbMF07XG5cbiAgICAgICAgdmFyIHdpZGdldHMgPSBbXTtcbiAgICAgICAgdmFyIGFkZGl0aW9uYWxOYW1lc3BhY2VzID0gW107XG4gICAgICAgIHRoaXMucHJvcHMubmFtZXNwYWNlcy5tYXAoZnVuY3Rpb24gKG5zKSB7XG4gICAgICAgICAgICBpZiAoIWdsb2JhbFtuc10pIHtcbiAgICAgICAgICAgICAgICBhZGRpdGlvbmFsTmFtZXNwYWNlcy5wdXNoKG5zKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKHZhciBrIGluIGdsb2JhbFtuc10pIHtcbiAgICAgICAgICAgICAgICBpZiAoZ2xvYmFsW25zXS5oYXNPd25Qcm9wZXJ0eShrKSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgd2lkZ2V0Q2xhc3MgPSBnbG9iYWxbbnNdW2tdO1xuICAgICAgICAgICAgICAgICAgICBpZiAod2lkZ2V0Q2xhc3MuaGFzQnVpbGRlckZpZWxkcyAmJiB3aWRnZXRDbGFzcy5oYXNCdWlsZGVyRmllbGRzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZGdldHMucHVzaCh7IHJlYWN0Q2xhc3M6IHdpZGdldENsYXNzLCBmdWxsTmFtZTogbnMgKyAnLicgKyB3aWRnZXRDbGFzcy5kaXNwbGF5TmFtZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChhZGRpdGlvbmFsTmFtZXNwYWNlcy5sZW5ndGggJiYgIXNlY29uZFBhc3MpIHtcbiAgICAgICAgICAgIFJlc291cmNlc01hbmFnZXIubG9hZENsYXNzZXNBbmRBcHBseShhZGRpdGlvbmFsTmFtZXNwYWNlcywgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgICAgYXZhaWxhYmxlV2lkZ2V0czogdGhpcy5saXN0QXZhaWxhYmxlV2lkZ2V0cyh0cnVlKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHdpZGdldHM7XG4gICAgfSxcblxuICAgIG9uRHJvcERvd25DaGFuZ2U6IGZ1bmN0aW9uIG9uRHJvcERvd25DaGFuZ2UoZXZlbnQsIGluZGV4LCBpdGVtKSB7XG4gICAgICAgIHZhciBkZWZhdWx0VmFsdWVzID0ge307XG4gICAgICAgIGlmIChpbmRleCAhPSAwKSB7XG4gICAgICAgICAgICBpdGVtLnBheWxvYWRbJ3JlYWN0Q2xhc3MnXS5nZXRCdWlsZGVyRmllbGRzKCkubWFwKGZ1bmN0aW9uIChmKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZbJ2RlZmF1bHQnXSkgZGVmYXVsdFZhbHVlc1tmLm5hbWVdID0gZlsnZGVmYXVsdCddO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25FZGl0U3RhdHVzQ2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uRWRpdFN0YXR1c0NoYW5nZShpbmRleCAhPSAwKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNlbGVjdGVkSW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgc2VsZWN0ZWRXaWRnZXQ6IGl0ZW0ucGF5bG9hZCxcbiAgICAgICAgICAgIGN1cnJlbnRGb3JtVmFsdWVzOiBkZWZhdWx0VmFsdWVzXG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBjYW5jZWw6IGZ1bmN0aW9uIGNhbmNlbCgpIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25FZGl0U3RhdHVzQ2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uRWRpdFN0YXR1c0NoYW5nZShmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkSW5kZXg6IDAgfSk7XG4gICAgfSxcblxuICAgIG9uRm9ybVZhbHVlQ2hhbmdlOiBmdW5jdGlvbiBvbkZvcm1WYWx1ZUNoYW5nZShuZXdWYWx1ZXMpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGN1cnJlbnRGb3JtVmFsdWVzOiBuZXdWYWx1ZXMgfSk7XG4gICAgfSxcblxuICAgIG9uRm9ybVN1Ym1pdDogZnVuY3Rpb24gb25Gb3JtU3VibWl0KCkge1xuICAgICAgICB2YXIgdmFsdWVzID0gdGhpcy5zdGF0ZS5jdXJyZW50Rm9ybVZhbHVlcztcbiAgICAgICAgdmFyIHNlbGVjdGVkV2lkZ2V0ID0gdGhpcy5zdGF0ZS5zZWxlY3RlZFdpZGdldDtcbiAgICAgICAgdmFyIHRpdGxlID0gdmFsdWVzLnRpdGxlID8gdmFsdWVzLnRpdGxlIDogdmFsdWVzLmxlZ2VuZDtcbiAgICAgICAgaWYgKCF0aXRsZSkgdGl0bGUgPSB0aGlzLnN0YXRlLnNlbGVjdGVkV2lkZ2V0WydyZWFjdENsYXNzJ10uYnVpbGRlckRpc3BsYXlOYW1lO1xuICAgICAgICB0aGlzLnByb3BzLm9uQ3JlYXRlQ2FyZCh7XG4gICAgICAgICAgICBjb21wb25lbnRDbGFzczogc2VsZWN0ZWRXaWRnZXQuZnVsbE5hbWUsXG4gICAgICAgICAgICB0aXRsZTogdGl0bGUsXG4gICAgICAgICAgICBwcm9wczogdmFsdWVzXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNhbmNlbCgpO1xuICAgIH0sXG5cbiAgICByZXNldExheW91dDogZnVuY3Rpb24gcmVzZXRMYXlvdXQoKSB7XG4gICAgICAgIGlmICh3aW5kb3cuY29uZmlybSh0aGlzLnByb3BzLmdldE1lc3NhZ2UoJ2hvbWUuNTEnKSkpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMub25SZXNldExheW91dCgpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgZ2V0TWVzc2FnZSA9IHRoaXMucHJvcHMuZ2V0TWVzc2FnZTtcblxuICAgICAgICB2YXIgc2VsZWN0b3JJdGVtcyA9IFt7IHBheWxvYWQ6IDAsIHRleHQ6IGdldE1lc3NhZ2UoJ2hvbWUuNTAnKSB9XS5jb25jYXQodGhpcy5zdGF0ZS5hdmFpbGFibGVXaWRnZXRzLm1hcChmdW5jdGlvbiAodywgaW5kZXgpIHtcbiAgICAgICAgICAgIHJldHVybiB7IHBheWxvYWQ6IHcsIHRleHQ6IHdbJ3JlYWN0Q2xhc3MnXS5idWlsZGVyRGlzcGxheU5hbWUgfTtcbiAgICAgICAgfSkpO1xuXG4gICAgICAgIHZhciBzZWxlY3RvciA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoUmVhY3RNVUkuRHJvcERvd25NZW51LCB7XG4gICAgICAgICAgICBtZW51SXRlbXM6IHNlbGVjdG9ySXRlbXMsXG4gICAgICAgICAgICBvbkNoYW5nZTogdGhpcy5vbkRyb3BEb3duQ2hhbmdlLFxuICAgICAgICAgICAgc2VsZWN0ZWRJbmRleDogdGhpcy5zdGF0ZS5zZWxlY3RlZEluZGV4LFxuICAgICAgICAgICAgYXV0b1dpZHRoOiBmYWxzZSxcbiAgICAgICAgICAgIGNsYXNzTmFtZTogJ3dpZGdldC10eXBlLXNlbGVjdG9yJ1xuICAgICAgICB9KTtcblxuICAgICAgICB2YXIgZm9ybSwgYWRkO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3RlZEluZGV4ICE9IDApIHtcbiAgICAgICAgICAgIHZhciBmaWVsZHMgPSB0aGlzLnN0YXRlLnNlbGVjdGVkV2lkZ2V0WydyZWFjdENsYXNzJ10uZ2V0QnVpbGRlckZpZWxkcygpO1xuICAgICAgICAgICAgdmFyIGRlZmF1bHRWYWx1ZXMgPSB7fTtcbiAgICAgICAgICAgIGZpZWxkcy5tYXAoZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICBpZiAoZlsnZGVmYXVsdCddKSBkZWZhdWx0VmFsdWVzW2YubmFtZV0gPSBmWydkZWZhdWx0J107XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLmN1cnJlbnRGb3JtVmFsdWVzKSB7XG4gICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlcyA9IExhbmdVdGlscy5tZXJnZU9iamVjdHNSZWN1cnNpdmUoZGVmYXVsdFZhbHVlcywgdGhpcy5zdGF0ZS5jdXJyZW50Rm9ybVZhbHVlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3JtID0gUmVhY3QuY3JlYXRlRWxlbWVudChBc3luY0NvbXBvbmVudCwge1xuICAgICAgICAgICAgICAgIG5hbWVzcGFjZTogJ1B5ZGlvRm9ybScsXG4gICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogJ0Zvcm1QYW5lbCcsXG4gICAgICAgICAgICAgICAgcGFyYW1ldGVyczogZmllbGRzLFxuICAgICAgICAgICAgICAgIGRlcHRoOiAtMSxcbiAgICAgICAgICAgICAgICB2YWx1ZXM6IGRlZmF1bHRWYWx1ZXMsXG4gICAgICAgICAgICAgICAgb25DaGFuZ2U6IHRoaXMub25Gb3JtVmFsdWVDaGFuZ2VcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgYWRkID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IHRleHRBbGlnbjogJ2NlbnRlcicsIHBhZGRpbmdCb3R0b206IDEwMCB9IH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5SYWlzZWRCdXR0b24sIHsgbGFiZWw6IGdldE1lc3NhZ2UoJ2hvbWUuNTInKSwgb25DbGljazogdGhpcy5vbkZvcm1TdWJtaXQgfSksXG4gICAgICAgICAgICAgICAgJ8KgJyxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLlJhaXNlZEJ1dHRvbiwgeyBsYWJlbDogZ2V0TWVzc2FnZSgnNTQnLCAnJyksIG9uQ2xpY2s6IHRoaXMuY2FuY2VsIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICBSZWFjdE1VSS5QYXBlcixcbiAgICAgICAgICAgIF9leHRlbmRzKHt9LCB0aGlzLnByb3BzLCB7XG4gICAgICAgICAgICAgICAgekRlcHRoOiAzIH0pLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnaDMnLFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgZ2V0TWVzc2FnZSgnaG9tZS41MycpXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2xlZ2VuZCcgfSxcbiAgICAgICAgICAgICAgICBnZXRNZXNzYWdlKCdob21lLjU0JyksXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudCgnYnInLCBudWxsKSxcbiAgICAgICAgICAgICAgICBnZXRNZXNzYWdlKCdob21lLjU1JylcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBzZWxlY3RvcixcbiAgICAgICAgICAgIGZvcm0sXG4gICAgICAgICAgICBhZGQsXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgcG9zaXRpb246ICdhYnNvbHV0ZScsIGJvdHRvbTogMzAsIGxlZnQ6IDEwIH0gfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLkZsYXRCdXR0b24sIHsgZGlzYWJsZWQ6IHRoaXMuc3RhdGUuc2VsZWN0ZWRJbmRleCAhPSAwLCBsYWJlbDogZ2V0TWVzc2FnZSgnaG9tZS41NicpLCBzZWNvbmRhcnk6IHRydWUsIG9uQ2xpY2s6IHRoaXMucmVzZXRMYXlvdXQgfSlcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG5cbn0pO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBHcmlkQnVpbGRlciA9IFB5ZGlvQ29udGV4dENvbnN1bWVyKEdyaWRCdWlsZGVyKTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEdyaWRCdWlsZGVyO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0ge1xuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHNob3dDbG9zZUFjdGlvbjogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIG9uQ2xvc2VBY3Rpb246IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgfSxcblxuICAgIGZvY3VzSXRlbTogZnVuY3Rpb24gZm9jdXNJdGVtKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZm9jdXM6IHRydWUgfSk7XG4gICAgfSxcblxuICAgIGJsdXJJdGVtOiBmdW5jdGlvbiBibHVySXRlbSgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGZvY3VzOiBmYWxzZSB9KTtcbiAgICB9LFxuXG4gICAgbWVyZ2VTdHlsZVdpdGhGb2N1czogZnVuY3Rpb24gbWVyZ2VTdHlsZVdpdGhGb2N1cygpIHtcbiAgICAgICAgcmV0dXJuIF9leHRlbmRzKHt9LCB0aGlzLnByb3BzLnN0eWxlLCB7IHpJbmRleDogdGhpcy5zdGF0ZS5mb2N1cyA/IDEgOiBudWxsIH0pO1xuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU2F0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFNhdGUoKSB7XG4gICAgICAgIHJldHVybiB7IGZvY3VzOiBmYWxzZSwgc2hvd0Nsb3NlQWN0aW9uOiBmYWxzZSB9O1xuICAgIH0sXG5cbiAgICB0b2dnbGVFZGl0TW9kZTogZnVuY3Rpb24gdG9nZ2xlRWRpdE1vZGUoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMCB8fCBhcmd1bWVudHNbMF0gPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGFyZ3VtZW50c1swXTtcblxuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dDbG9zZUFjdGlvbjogISh0aGlzLnN0YXRlICYmIHRoaXMuc3RhdGUuc2hvd0Nsb3NlQWN0aW9uKSB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93Q2xvc2VBY3Rpb246IHZhbHVlIH0pO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGdldENsb3NlQnV0dG9uOiBmdW5jdGlvbiBnZXRDbG9zZUJ1dHRvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgJiYgdGhpcy5zdGF0ZS5zaG93Q2xvc2VBY3Rpb24pIHtcbiAgICAgICAgICAgIHZhciBjbG9zZUFjdGlvbiA9IHRoaXMucHJvcHMub25DbG9zZUFjdGlvbiB8fCBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgICAgIHZhciBvdmVybGF5U3R5bGUgPSB7XG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAncmdiYSgwLDAsMCwwLjUzKScsXG4gICAgICAgICAgICAgICAgekluZGV4OiAxMCxcbiAgICAgICAgICAgICAgICB0b3A6IDAsXG4gICAgICAgICAgICAgICAgbGVmdDogMCxcbiAgICAgICAgICAgICAgICBib3R0b206IDAsXG4gICAgICAgICAgICAgICAgcmlnaHQ6IDAsXG4gICAgICAgICAgICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgICAgICAgICAgIGFsaWduSXRlbXM6ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgIGp1c3RpZnlDb250ZW50OiAnY2VudGVyJ1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IG92ZXJsYXlTdHlsZSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWF0ZXJpYWxVSS5GbGF0QnV0dG9uLCB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBweWRpby5NZXNzYWdlSGFzaFsnYWp4cF9hZG1pbi5ob21lLjQ4J10sXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogJ2NhcmQtY2xvc2UtYnV0dG9uJyxcbiAgICAgICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogY2xvc2VBY3Rpb24sXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7IGNvbG9yOiAnd2hpdGUnIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHN0YXRpY3M6IHtcbiAgICAgICAgZ2V0R3JpZExheW91dDogZnVuY3Rpb24gZ2V0R3JpZExheW91dCh4LCB5KSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHg6IHggfHwgMCxcbiAgICAgICAgICAgICAgICB5OiB5IHx8IDAsXG4gICAgICAgICAgICAgICAgdzogdGhpcy5ncmlkV2lkdGggfHwgNCxcbiAgICAgICAgICAgICAgICBoOiB0aGlzLmdyaWRIZWlnaHQgfHwgMTIsXG4gICAgICAgICAgICAgICAgaXNSZXNpemFibGU6IGZhbHNlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgICBoYXNCdWlsZGVyRmllbGRzOiBmdW5jdGlvbiBoYXNCdWlsZGVyRmllbGRzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRlckZpZWxkcyA/IHRydWUgOiBmYWxzZTtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0QnVpbGRlckZpZWxkczogZnVuY3Rpb24gZ2V0QnVpbGRlckZpZWxkcygpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmJ1aWxkZXJGaWVsZHM7XG4gICAgICAgIH1cbiAgICB9XG5cbn07XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIFN0b3JlID0gKGZ1bmN0aW9uIChfT2JzZXJ2YWJsZSkge1xuICAgIF9pbmhlcml0cyhTdG9yZSwgX09ic2VydmFibGUpO1xuXG4gICAgLyoqXG4gICAgICogSW5pdCBhIGNhcmQgc3RvcmVcbiAgICAgKiBAcGFyYW0gcHJlZk5hbWVzcGFjZSBOYW1lc3BhY2UgZm9yIGdldHRpbmcvc2V0dGluZyB1c2VyIHByZWZlcmVuY2VzXG4gICAgICogQHBhcmFtIGRlZmF1bHRDYXJkcyBBcnJheSBvZiBjYXJkcyB0byBiZSBkaXNwbGF5ZWQgYnkgZGVmYXVsdFxuICAgICAqL1xuXG4gICAgZnVuY3Rpb24gU3RvcmUocHJlZk5hbWVzcGFjZSwgZGVmYXVsdENhcmRzLCBweWRpb09iamVjdCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgU3RvcmUpO1xuXG4gICAgICAgIF9PYnNlcnZhYmxlLmNhbGwodGhpcyk7XG4gICAgICAgIHRoaXMuX25hbWVzcGFjZSA9IHByZWZOYW1lc3BhY2U7XG4gICAgICAgIHRoaXMuX3B5ZGlvID0gcHlkaW9PYmplY3Q7XG4gICAgICAgIHRoaXMuX2NhcmRzID0gdGhpcy5nZXRVc2VyUHJlZmVyZW5jZShcIkNhcmRzXCIpO1xuICAgICAgICBpZiAoIXRoaXMuX2NhcmRzKSB7XG4gICAgICAgICAgICB0aGlzLl9jYXJkcyA9IGRlZmF1bHRDYXJkcztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIFN0b3JlLnByb3RvdHlwZS5nZXRVc2VyUHJlZmVyZW5jZSA9IGZ1bmN0aW9uIGdldFVzZXJQcmVmZXJlbmNlKHByZWZOYW1lKSB7XG4gICAgICAgIHZhciBwcmVmS2V5ID0gdGhpcy5fbmFtZXNwYWNlICsgcHJlZk5hbWU7XG4gICAgICAgIHZhciBndWlQcmVmcyA9IHRoaXMuX3B5ZGlvLnVzZXIuZ2V0UHJlZmVyZW5jZSgnZ3VpX3ByZWZlcmVuY2VzJywgdHJ1ZSk7XG4gICAgICAgIGlmIChndWlQcmVmcyAmJiBndWlQcmVmc1twcmVmS2V5XSkge1xuICAgICAgICAgICAgcmV0dXJuIGd1aVByZWZzW3ByZWZLZXldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RvcmUucHJvdG90eXBlLnNhdmVVc2VyUHJlZmVyZW5jZSA9IGZ1bmN0aW9uIHNhdmVVc2VyUHJlZmVyZW5jZShwcmVmTmFtZSwgcHJlZlZhbHVlKSB7XG4gICAgICAgIHZhciBwcmVmS2V5ID0gdGhpcy5fbmFtZXNwYWNlICsgcHJlZk5hbWU7XG4gICAgICAgIHZhciBndWlQcmVmcyA9IHRoaXMuX3B5ZGlvLnVzZXIuZ2V0UHJlZmVyZW5jZSgnZ3VpX3ByZWZlcmVuY2VzJywgdHJ1ZSk7XG4gICAgICAgIGlmICghZ3VpUHJlZnMpIGd1aVByZWZzID0ge307XG4gICAgICAgIGd1aVByZWZzW3ByZWZLZXldID0gcHJlZlZhbHVlO1xuICAgICAgICB0aGlzLl9weWRpby51c2VyLnNldFByZWZlcmVuY2UoJ2d1aV9wcmVmZXJlbmNlcycsIGd1aVByZWZzLCB0cnVlKTtcbiAgICAgICAgdGhpcy5fcHlkaW8udXNlci5zYXZlUHJlZmVyZW5jZSgnZ3VpX3ByZWZlcmVuY2VzJyk7XG4gICAgfTtcblxuICAgIFN0b3JlLnByb3RvdHlwZS5zYXZlQ2FyZHMgPSBmdW5jdGlvbiBzYXZlQ2FyZHMoY2FyZHMpIHtcbiAgICAgICAgdGhpcy5zYXZlVXNlclByZWZlcmVuY2UoJ0NhcmRzJywgY2FyZHMpO1xuICAgIH07XG5cbiAgICBTdG9yZS5wcm90b3R5cGUucmVzZXRDYXJkcyA9IGZ1bmN0aW9uIHJlc2V0Q2FyZHMoKSB7XG4gICAgICAgIHRoaXMuc2F2ZVVzZXJQcmVmZXJlbmNlKCdDYXJkcycsIG51bGwpO1xuICAgIH07XG5cbiAgICBTdG9yZS5wcm90b3R5cGUuc2V0Q2FyZHMgPSBmdW5jdGlvbiBzZXRDYXJkcyhuZXdDYXJkcykge1xuICAgICAgICB0aGlzLl9jYXJkcyA9IG5ld0NhcmRzO1xuICAgICAgICB0aGlzLm5vdGlmeShcImNhcmRzXCIsIHRoaXMuX2NhcmRzKTtcbiAgICAgICAgdGhpcy5zYXZlQ2FyZHMobmV3Q2FyZHMpO1xuICAgIH07XG5cbiAgICBTdG9yZS5wcm90b3R5cGUuZ2V0Q2FyZHMgPSBmdW5jdGlvbiBnZXRDYXJkcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcmRzO1xuICAgIH07XG5cbiAgICBTdG9yZS5wcm90b3R5cGUucmVtb3ZlQ2FyZCA9IGZ1bmN0aW9uIHJlbW92ZUNhcmQoY2FyZElkKSB7XG4gICAgICAgIHZhciBpbmRleCA9IC0xO1xuICAgICAgICB2YXIgY3VycmVudENhcmRzID0gdGhpcy5nZXRDYXJkcygpO1xuICAgICAgICBjdXJyZW50Q2FyZHMubWFwKGZ1bmN0aW9uIChjYXJkLCBhcnJheUluZGV4KSB7XG4gICAgICAgICAgICBpZiAoY2FyZC5pZCA9PSBjYXJkSWQpIGluZGV4ID0gYXJyYXlJbmRleDtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChpbmRleCA9PSAtMSkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdDYXJkIElEIG5vdCBmb3VuZCwgdGhpcyBpcyBzdHJhbmdlLicsIGNhcmRJZCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG5ld0NhcmRzO1xuICAgICAgICBpZiAoaW5kZXggPT0gMCkgbmV3Q2FyZHMgPSBjdXJyZW50Q2FyZHMuc2xpY2UoMSk7ZWxzZSBpZiAoaW5kZXggPT0gY3VycmVudENhcmRzLmxlbmd0aCAtIDEpIG5ld0NhcmRzID0gY3VycmVudENhcmRzLnNsaWNlKDAsIC0xKTtlbHNlIG5ld0NhcmRzID0gY3VycmVudENhcmRzLnNsaWNlKDAsIGluZGV4KS5jb25jYXQoY3VycmVudENhcmRzLnNsaWNlKGluZGV4ICsgMSkpO1xuICAgICAgICB0aGlzLnNldENhcmRzKG5ld0NhcmRzKTtcbiAgICB9O1xuXG4gICAgU3RvcmUucHJvdG90eXBlLmNyZWF0ZUNhcmRJZCA9IGZ1bmN0aW9uIGNyZWF0ZUNhcmRJZChjYXJkRGVmaW5pdGlvbikge1xuICAgICAgICB2YXIgcmFuZG9taXplID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiBhcmd1bWVudHNbMV07XG5cbiAgICAgICAgdmFyIGlkID0gTGFuZ1V0aWxzLmNvbXB1dGVTdHJpbmdTbHVnKGNhcmREZWZpbml0aW9uWyd0aXRsZSddKTtcbiAgICAgICAgaWYgKHJhbmRvbWl6ZSkge1xuICAgICAgICAgICAgaWQgKz0gJy0nICsgTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogMTAwICsgMTApO1xuICAgICAgICB9XG4gICAgICAgIHZhciBhbHJlYWR5RXhpc3RzID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX2NhcmRzLm1hcCgoZnVuY3Rpb24gKGNhcmQpIHtcbiAgICAgICAgICAgIGlmIChjYXJkLmlkID09IGlkKSBhbHJlYWR5RXhpc3RzID0gdHJ1ZTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgIGlmIChhbHJlYWR5RXhpc3RzKSB7XG4gICAgICAgICAgICBpZCA9IHRoaXMuY3JlYXRlQ2FyZElkKGNhcmREZWZpbml0aW9uLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaWQ7XG4gICAgfTtcblxuICAgIFN0b3JlLnByb3RvdHlwZS5hZGRDYXJkID0gZnVuY3Rpb24gYWRkQ2FyZChjYXJkRGVmaW5pdGlvbikge1xuICAgICAgICAvL2NvbnNvbGUubG9nKGNhcmREZWZpbml0aW9uKTtcblxuICAgICAgICBjYXJkRGVmaW5pdGlvblsnaWQnXSA9IHRoaXMuY3JlYXRlQ2FyZElkKGNhcmREZWZpbml0aW9uKTtcbiAgICAgICAgdGhpcy5zZXRDYXJkcyh0aGlzLl9jYXJkcy5jb25jYXQoW2NhcmREZWZpbml0aW9uXSkpO1xuICAgIH07XG5cbiAgICByZXR1cm4gU3RvcmU7XG59KShPYnNlcnZhYmxlKTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gU3RvcmU7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIENvbXBvbmVudCA9IF9yZXF1aXJlLkNvbXBvbmVudDtcbnZhciBQcm9wVHlwZXMgPSBfcmVxdWlyZS5Qcm9wVHlwZXM7XG5cbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgRmxhdEJ1dHRvbiA9IF9yZXF1aXJlMi5GbGF0QnV0dG9uO1xuXG52YXIgX3JlcXVpcmUzID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWkvc3R5bGVzJyk7XG5cbnZhciBtdWlUaGVtZWFibGUgPSBfcmVxdWlyZTMubXVpVGhlbWVhYmxlO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBmdW5jdGlvbiAoUHlkaW9Db21wb25lbnQsIGRpc3BsYXlOYW1lKSB7XG4gICAgdmFyIGdyaWREaW1lbnNpb24gPSBhcmd1bWVudHMubGVuZ3RoIDw9IDIgfHwgYXJndW1lbnRzWzJdID09PSB1bmRlZmluZWQgPyB7IGdyaWRXaWR0aDogNCwgZ3JpZEhlaWdodDogMTIgfSA6IGFyZ3VtZW50c1syXTtcbiAgICB2YXIgYnVpbGRlckZpZWxkcyA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMyB8fCBhcmd1bWVudHNbM10gPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGFyZ3VtZW50c1szXTtcblxuICAgIHZhciBvcmlnaW5hbERpc3BsYXlOYW1lID0gUHlkaW9Db21wb25lbnQuZGlzcGxheU5hbWUgfHwgUHlkaW9Db21wb25lbnQubmFtZTtcbiAgICBQeWRpb0NvbXBvbmVudCA9IG11aVRoZW1lYWJsZSgpKFB5ZGlvQ29tcG9uZW50KTtcblxuICAgIHZhciBHcmlkSXRlbSA9IChmdW5jdGlvbiAoX0NvbXBvbmVudCkge1xuICAgICAgICBfaW5oZXJpdHMoR3JpZEl0ZW0sIF9Db21wb25lbnQpO1xuXG4gICAgICAgIGZ1bmN0aW9uIEdyaWRJdGVtKHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgR3JpZEl0ZW0pO1xuXG4gICAgICAgICAgICBfQ29tcG9uZW50LmNhbGwodGhpcywgcHJvcHMsIGNvbnRleHQpO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IHsgZm9jdXM6IGZhbHNlLCBzaG93Q2xvc2VBY3Rpb246IGZhbHNlIH07XG4gICAgICAgIH1cblxuICAgICAgICBHcmlkSXRlbS5wcm90b3R5cGUuZm9jdXNJdGVtID0gZnVuY3Rpb24gZm9jdXNJdGVtKCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGZvY3VzOiB0cnVlIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIEdyaWRJdGVtLnByb3RvdHlwZS5ibHVySXRlbSA9IGZ1bmN0aW9uIGJsdXJJdGVtKCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGZvY3VzOiBmYWxzZSB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICBHcmlkSXRlbS5wcm90b3R5cGUubWVyZ2VTdHlsZVdpdGhGb2N1cyA9IGZ1bmN0aW9uIG1lcmdlU3R5bGVXaXRoRm9jdXMoKSB7XG4gICAgICAgICAgICByZXR1cm4gX2V4dGVuZHMoe30sIHRoaXMucHJvcHMuc3R5bGUsIHsgekluZGV4OiB0aGlzLnN0YXRlLmZvY3VzID8gMSA6IG51bGwgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgR3JpZEl0ZW0ucHJvdG90eXBlLnRvZ2dsZUVkaXRNb2RlID0gZnVuY3Rpb24gdG9nZ2xlRWRpdE1vZGUoKSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDAgfHwgYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBhcmd1bWVudHNbMF07XG5cbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dDbG9zZUFjdGlvbjogISh0aGlzLnN0YXRlICYmIHRoaXMuc3RhdGUuc2hvd0Nsb3NlQWN0aW9uKSB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dDbG9zZUFjdGlvbjogdmFsdWUgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgR3JpZEl0ZW0ucHJvdG90eXBlLmdldENsb3NlQnV0dG9uID0gZnVuY3Rpb24gZ2V0Q2xvc2VCdXR0b24oKSB7XG4gICAgICAgICAgICB2YXIgY2xvc2VBY3Rpb24gPSB0aGlzLnByb3BzLm9uQ2xvc2VBY3Rpb24gfHwgZnVuY3Rpb24gKCkge307XG4gICAgICAgICAgICB2YXIgb3ZlcmxheVN0eWxlID0ge1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMCwwLDAsMC41MyknLFxuICAgICAgICAgICAgICAgIHpJbmRleDogMTAsXG4gICAgICAgICAgICAgICAgdG9wOiAwLFxuICAgICAgICAgICAgICAgIGxlZnQ6IDAsXG4gICAgICAgICAgICAgICAgYm90dG9tOiAwLFxuICAgICAgICAgICAgICAgIHJpZ2h0OiAwLFxuICAgICAgICAgICAgICAgIGRpc3BsYXk6ICdmbGV4JyxcbiAgICAgICAgICAgICAgICBhbGlnbkl0ZW1zOiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICBqdXN0aWZ5Q29udGVudDogJ2NlbnRlcidcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IHN0eWxlOiBvdmVybGF5U3R5bGUgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEZsYXRCdXR0b24sIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHRoaXMucHJvcHMucHlkaW8uTWVzc2FnZUhhc2hbJ2FqeHBfYWRtaW4uaG9tZS40OCddLFxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICdjYXJkLWNsb3NlLWJ1dHRvbicsXG4gICAgICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IGNsb3NlQWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogeyBjb2xvcjogJ3doaXRlJyB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH07XG5cbiAgICAgICAgR3JpZEl0ZW0ucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgICAgIHZhciBwcm9wcyA9IF9leHRlbmRzKHt9LCB0aGlzLnByb3BzLCB7XG4gICAgICAgICAgICAgICAgc3R5bGU6IHRoaXMubWVyZ2VTdHlsZVdpdGhGb2N1cygpLFxuICAgICAgICAgICAgICAgIGNsb3NlQnV0dG9uOiB0aGlzLnN0YXRlLnNob3dDbG9zZUFjdGlvbiA/IHRoaXMuZ2V0Q2xvc2VCdXR0b24oKSA6IG51bGwsXG4gICAgICAgICAgICAgICAgb25Gb2N1c0l0ZW06IHRoaXMuZm9jdXNJdGVtLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgb25CbHVySXRlbTogdGhpcy5ibHVySXRlbS5iaW5kKHRoaXMpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFB5ZGlvQ29tcG9uZW50LCBwcm9wcyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIEdyaWRJdGVtO1xuICAgIH0pKENvbXBvbmVudCk7XG5cbiAgICBHcmlkSXRlbS5wcm9wVHlwZXMgPSB7XG4gICAgICAgIG9uQ2xvc2VBY3Rpb246IFByb3BUeXBlcy5mdW5jXG4gICAgfTtcblxuICAgIEdyaWRJdGVtLmRpc3BsYXlOYW1lID0gb3JpZ2luYWxEaXNwbGF5TmFtZTtcbiAgICBHcmlkSXRlbS5idWlsZGVyRGlzcGxheU5hbWUgPSBkaXNwbGF5TmFtZTtcblxuICAgIEdyaWRJdGVtLmdldEdyaWRMYXlvdXQgPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogeCB8fCAwLFxuICAgICAgICAgICAgeTogeSB8fCAwLFxuICAgICAgICAgICAgdzogZ3JpZERpbWVuc2lvbi5ncmlkV2lkdGggfHwgNCxcbiAgICAgICAgICAgIGg6IGdyaWREaW1lbnNpb24uZ3JpZEhlaWdodCB8fCAxMixcbiAgICAgICAgICAgIGlzUmVzaXphYmxlOiBmYWxzZVxuICAgICAgICB9O1xuICAgIH07XG5cbiAgICBHcmlkSXRlbS5oYXNCdWlsZGVyRmllbGRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gYnVpbGRlckZpZWxkcyAhPT0gdW5kZWZpbmVkO1xuICAgIH07XG4gICAgR3JpZEl0ZW0uZ2V0QnVpbGRlckZpZWxkcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGJ1aWxkZXJGaWVsZHM7XG4gICAgfTtcblxuICAgIHJldHVybiBHcmlkSXRlbTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4vKipcbiAqIFR3byBjb2x1bW5zIGxheW91dCB1c2VkIGZvciBXb3Jrc3BhY2VzIGFuZCBQbHVnaW5zIGVkaXRvcnNcbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xudmFyIFBhcGVyRWRpdG9yTGF5b3V0ID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnUGFwZXJFZGl0b3JMYXlvdXQnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHRpdGxlOiBSZWFjdC5Qcm9wVHlwZXMuYW55LFxuICAgICAgICB0aXRsZUFjdGlvbkJhcjogUmVhY3QuUHJvcFR5cGVzLmFueSxcbiAgICAgICAgbGVmdE5hdjogUmVhY3QuUHJvcFR5cGVzLmFueSxcbiAgICAgICAgY29udGVudEZpbGw6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmdcbiAgICB9LFxuXG4gICAgdG9nZ2xlTWVudTogZnVuY3Rpb24gdG9nZ2xlTWVudSgpIHtcbiAgICAgICAgdmFyIGNydExlZnRPcGVuID0gdGhpcy5zdGF0ZSAmJiB0aGlzLnN0YXRlLmZvcmNlTGVmdE9wZW47XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBmb3JjZUxlZnRPcGVuOiAhY3J0TGVmdE9wZW4gfSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgeyBjbGFzc05hbWU6IFwicGFwZXItZWRpdG9yLWNvbnRlbnQgbGF5b3V0LWZpbGwgdmVydGljYWwtbGF5b3V0XCIgKyAodGhpcy5wcm9wcy5jbGFzc05hbWUgPyAnICcgKyB0aGlzLnByb3BzLmNsYXNzTmFtZSA6ICcnKSB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3BhcGVyLWVkaXRvci10aXRsZScgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnaDInLFxuICAgICAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnRpdGxlLFxuICAgICAgICAgICAgICAgICAgICAnICcsXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnbGVmdC1waWNrZXItdG9nZ2xlJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5JY29uQnV0dG9uLCB7IGljb25DbGFzc05hbWU6ICdpY29uLWNhcmV0LWRvd24nLCBvbkNsaWNrOiB0aGlzLnRvZ2dsZU1lbnUgfSlcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAndGl0bGUtYmFyJyB9LFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnRpdGxlQWN0aW9uQmFyXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdsYXlvdXQtZmlsbCBtYWluLWxheW91dC1uYXYtdG8tc3RhY2snIH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiBcInBhcGVyLWVkaXRvci1sZWZ0XCIgKyAodGhpcy5zdGF0ZSAmJiB0aGlzLnN0YXRlLmZvcmNlTGVmdE9wZW4gPyAnIHBpY2tlci1vcGVuJyA6ICcnKSwgb25DbGljazogdGhpcy50b2dnbGVNZW51IH0sXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMubGVmdE5hdlxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiBcImxheW91dC1maWxsIHBhcGVyLWVkaXRvci1yaWdodFwiICsgKHRoaXMucHJvcHMuY29udGVudEZpbGwgPyAnIHZlcnRpY2FsLWxheW91dCcgOiAnJyksIHN0eWxlOiB0aGlzLnByb3BzLmNvbnRlbnRGaWxsID8ge30gOiB7IG92ZXJmbG93WTogJ2F1dG8nIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5jaGlsZHJlblxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcbi8qKlxuICogTmF2aWdhdGlvbiBzdWJoZWFkZXIgdXNlZCBieSBQYXBlckVkaXRvckxheW91dFxuICovXG52YXIgUGFwZXJFZGl0b3JOYXZIZWFkZXIgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdQYXBlckVkaXRvck5hdkhlYWRlcicsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgbGFiZWw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmdcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnbXVpLXN1YmhlYWRlcicgfSxcbiAgICAgICAgICAgIHRoaXMucHJvcHMuY2hpbGRyZW4sXG4gICAgICAgICAgICB0aGlzLnByb3BzLmxhYmVsXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcbi8qKlxuICogTmF2aWdhdGlvbiBlbnRyeSB1c2VkIGJ5IFBhcGVyRWRpdG9yTGF5b3V0LlxuICovXG52YXIgUGFwZXJFZGl0b3JOYXZFbnRyeSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ1BhcGVyRWRpdG9yTmF2RW50cnknLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIGtleU5hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICAgICAgb25DbGljazogUmVhY3QuUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICAgICAgbGFiZWw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIHNlbGVjdGVkS2V5OiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICBpc0xhc3Q6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICAvLyBEcm9wIERvd24gRGF0YVxuICAgICAgICBkcm9wRG93bjogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIGRyb3BEb3duRGF0YTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgZHJvcERvd25DaGFuZ2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBkcm9wRG93bkRlZmF1bHRJdGVtczogUmVhY3QuUHJvcFR5cGVzLmFycmF5XG4gICAgfSxcblxuICAgIG9uQ2xpY2s6IGZ1bmN0aW9uIG9uQ2xpY2soKSB7XG4gICAgICAgIHRoaXMucHJvcHMub25DbGljayh0aGlzLnByb3BzLmtleU5hbWUpO1xuICAgIH0sXG5cbiAgICBjYXB0dXJlRHJvcERvd25DbGljazogZnVuY3Rpb24gY2FwdHVyZURyb3BEb3duQ2xpY2soKSB7XG4gICAgICAgIGlmICh0aGlzLnByZXZlbnRDbGljaykge1xuICAgICAgICAgICAgdGhpcy5wcmV2ZW50Q2xpY2sgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnByb3BzLm9uQ2xpY2sodGhpcy5wcm9wcy5rZXlOYW1lKTtcbiAgICB9LFxuXG4gICAgZHJvcERvd25DaGFuZ2U6IGZ1bmN0aW9uIGRyb3BEb3duQ2hhbmdlKGV2ZW50LCBpbmRleCwgaXRlbSkge1xuICAgICAgICB0aGlzLnByZXZlbnRDbGljayA9IHRydWU7XG4gICAgICAgIHRoaXMucHJvcHMuZHJvcERvd25DaGFuZ2UoaXRlbSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuXG4gICAgICAgIGlmICghdGhpcy5wcm9wcy5kcm9wRG93biB8fCAhdGhpcy5wcm9wcy5kcm9wRG93bkRhdGEpIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAnbWVudS1lbnRyeScgKyAodGhpcy5wcm9wcy5rZXlOYW1lID09IHRoaXMucHJvcHMuc2VsZWN0ZWRLZXkgPyAnIG1lbnUtZW50cnktc2VsZWN0ZWQnIDogJycpICsgKHRoaXMucHJvcHMuaXNMYXN0ID8gJyBsYXN0JyA6ICcnKSxcbiAgICAgICAgICAgICAgICAgICAgb25DbGljazogdGhpcy5vbkNsaWNrIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5jaGlsZHJlbixcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmxhYmVsXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZHJvcERvd24gJiBkcm9wRG93bkRhdGEgYXJlIGxvYWRlZFxuICAgICAgICB2YXIgbWVudUl0ZW1zVHBsID0gW3sgdGV4dDogdGhpcy5wcm9wcy5sYWJlbCwgcGF5bG9hZDogJy0xJyB9XTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuZHJvcERvd25EZWZhdWx0SXRlbXMpIHtcbiAgICAgICAgICAgIG1lbnVJdGVtc1RwbCA9IG1lbnVJdGVtc1RwbC5jb25jYXQodGhpcy5wcm9wcy5kcm9wRG93bkRlZmF1bHRJdGVtcyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wcm9wcy5kcm9wRG93bkRhdGEuZm9yRWFjaChmdW5jdGlvbiAodiwgaykge1xuICAgICAgICAgICAgbWVudUl0ZW1zVHBsLnB1c2goeyB0ZXh0OiB2LmxhYmVsLCBwYXlsb2FkOiB2IH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgb25DbGljazogdGhpcy5jYXB0dXJlRHJvcERvd25DbGljaywgY2xhc3NOYW1lOiAnbWVudS1lbnRyeS1kcm9wZG93bicgKyAodGhpcy5wcm9wcy5rZXlOYW1lID09IHRoaXMucHJvcHMuc2VsZWN0ZWRLZXkgPyAnIG1lbnUtZW50cnktc2VsZWN0ZWQnIDogJycpICsgKHRoaXMucHJvcHMuaXNMYXN0ID8gJyBsYXN0JyA6ICcnKSB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5Ecm9wRG93bk1lbnUsIHtcbiAgICAgICAgICAgICAgICBtZW51SXRlbXM6IG1lbnVJdGVtc1RwbCxcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICdkcm9wZG93bi1mdWxsLXdpZHRoJyxcbiAgICAgICAgICAgICAgICBzdHlsZTogeyB3aWR0aDogMjU2IH0sXG4gICAgICAgICAgICAgICAgYXV0b1dpZHRoOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBvbkNoYW5nZTogdGhpcy5kcm9wRG93bkNoYW5nZVxuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxuZXhwb3J0cy5QYXBlckVkaXRvckxheW91dCA9IFBhcGVyRWRpdG9yTGF5b3V0O1xuZXhwb3J0cy5QYXBlckVkaXRvck5hdkVudHJ5ID0gUGFwZXJFZGl0b3JOYXZFbnRyeTtcbmV4cG9ydHMuUGFwZXJFZGl0b3JOYXZIZWFkZXIgPSBQYXBlckVkaXRvck5hdkhlYWRlcjtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgcHJvcFR5cGVzID0ge1xuICAgIG5vZGU6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKEFqeHBOb2RlKS5pc1JlcXVpcmVkLFxuICAgIHJlZ2lzdHJ5OiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihSZWdpc3RyeSkuaXNSZXF1aXJlZCxcbiAgICBlZGl0b3JEYXRhOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgaWNvbjogUmVhY3QuUHJvcFR5cGVzLmJvb2xcbn07XG5cbnZhciBkZWZhdWx0UHJvcHMgPSB7XG4gICAgaWNvbjogZmFsc2Vcbn07XG5cbnZhciBSZWFjdEVkaXRvck9wZW5lciA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhSZWFjdEVkaXRvck9wZW5lciwgX1JlYWN0JENvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBSZWFjdEVkaXRvck9wZW5lcihwcm9wcykge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUmVhY3RFZGl0b3JPcGVuZXIpO1xuXG4gICAgICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcyk7XG5cbiAgICAgICAgdmFyIG5vZGUgPSBwcm9wcy5ub2RlO1xuICAgICAgICB2YXIgZWRpdG9yRGF0YSA9IHByb3BzLmVkaXRvckRhdGE7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIHJlYWR5OiBmYWxzZVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIFJlYWN0RWRpdG9yT3BlbmVyLnByb3RvdHlwZS5jb21wb25lbnREaWRNb3VudCA9IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgZWRpdG9yRGF0YSA9IF9wcm9wcy5lZGl0b3JEYXRhO1xuICAgICAgICB2YXIgcmVnaXN0cnkgPSBfcHJvcHMucmVnaXN0cnk7XG5cbiAgICAgICAgcmVnaXN0cnkubG9hZEVkaXRvclJlc291cmNlcyhlZGl0b3JEYXRhLnJlc291cmNlc01hbmFnZXIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5zZXRTdGF0ZSh7IHJlYWR5OiB0cnVlIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgUmVhY3RFZGl0b3JPcGVuZXIucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIGVkaXRvckRhdGEgPSB0aGlzLnByb3BzLmVkaXRvckRhdGE7XG4gICAgICAgIHZhciByZWFkeSA9IHRoaXMuc3RhdGUucmVhZHk7XG5cbiAgICAgICAgaWYgKCFyZWFkeSkgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgdmFyIEVkaXRvckNsYXNzID0gbnVsbDtcbiAgICAgICAgaWYgKCEoRWRpdG9yQ2xhc3MgPSBGdW5jVXRpbHMuZ2V0RnVuY3Rpb25CeU5hbWUoZWRpdG9yRGF0YS5lZGl0b3JDbGFzcywgd2luZG93KSkpIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFwiZGl2XCIsXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICBcIkNhbm5vdCBmaW5kIGVkaXRvciBjb21wb25lbnQgKFwiICsgZWRpdG9yRGF0YS5lZGl0b3JDbGFzcyArIFwiKSFcIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdldHRpbmcgSE9DIG9mIHRoZSBjbGFzc1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChFZGl0b3JDbGFzcy5FZGl0b3IsIHRoaXMucHJvcHMpO1xuICAgIH07XG5cbiAgICByZXR1cm4gUmVhY3RFZGl0b3JPcGVuZXI7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5SZWFjdEVkaXRvck9wZW5lci5wcm9wVHlwZXMgPSBwcm9wVHlwZXM7XG5SZWFjdEVkaXRvck9wZW5lci5kZWZhdWx0UHJvcHMgPSBkZWZhdWx0UHJvcHM7XG5cbmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gUmVhY3RFZGl0b3JPcGVuZXI7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ0NsaXBib2FyZFRleHRGaWVsZCcsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgZmxvYXRpbmdMYWJlbFRleHQ6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG5cbiAgICAgICAgaW5wdXRWYWx1ZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgaW5wdXRDbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIGdldE1lc3NhZ2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBpbnB1dENvcHlNZXNzYWdlOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nXG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICByZXR1cm4geyBjb3B5TWVzc2FnZTogbnVsbCB9O1xuICAgIH0sXG5cbiAgICBjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHRoaXMuYXR0YWNoQ2xpcGJvYXJkKCk7XG4gICAgfSxcbiAgICBjb21wb25lbnREaWRVcGRhdGU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZFVwZGF0ZSgpIHtcbiAgICAgICAgdGhpcy5hdHRhY2hDbGlwYm9hcmQoKTtcbiAgICB9LFxuXG4gICAgYXR0YWNoQ2xpcGJvYXJkOiBmdW5jdGlvbiBhdHRhY2hDbGlwYm9hcmQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9jbGlwKSB7XG4gICAgICAgICAgICB0aGlzLl9jbGlwLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMucmVmc1snY29weS1idXR0b24nXSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2NsaXAgPSBuZXcgQ2xpcGJvYXJkKHRoaXMucmVmc1snY29weS1idXR0b24nXSwge1xuICAgICAgICAgICAgdGV4dDogKGZ1bmN0aW9uICh0cmlnZ2VyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJvcHMuaW5wdXRWYWx1ZTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcylcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2NsaXAub24oJ3N1Y2Nlc3MnLCAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNvcHlNZXNzYWdlOiB0aGlzLnByb3BzLmdldE1lc3NhZ2UodGhpcy5wcm9wcy5pbnB1dENvcHlNZXNzYWdlIHx8ICcxOTInKSB9LCB0aGlzLmNsZWFyQ29weU1lc3NhZ2UpO1xuICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5fY2xpcC5vbignZXJyb3InLCAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGNvcHlNZXNzYWdlO1xuICAgICAgICAgICAgaWYgKGdsb2JhbC5uYXZpZ2F0b3IucGxhdGZvcm0uaW5kZXhPZihcIk1hY1wiKSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGNvcHlNZXNzYWdlID0gdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcxNDQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29weU1lc3NhZ2UgPSB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzE0MycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5yZWZzWydpbnB1dCddLmZvY3VzKCk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgY29weU1lc3NhZ2U6IGNvcHlNZXNzYWdlIH0sIHRoaXMuY2xlYXJDb3B5TWVzc2FnZSk7XG4gICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgIH0sXG5cbiAgICBjbGVhckNvcHlNZXNzYWdlOiBmdW5jdGlvbiBjbGVhckNvcHlNZXNzYWdlKCkge1xuICAgICAgICBnbG9iYWwuc2V0VGltZW91dCgoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNvcHlNZXNzYWdlOiAnJyB9KTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSwgMzAwMCk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuXG4gICAgICAgIHZhciBzZWxlY3QgPSBmdW5jdGlvbiBzZWxlY3QoZSkge1xuICAgICAgICAgICAgZS5jdXJyZW50VGFyZ2V0LnNlbGVjdCgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHZhciBjb3B5TWVzc2FnZSA9IG51bGw7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmNvcHlNZXNzYWdlKSB7XG4gICAgICAgICAgICB2YXIgc2V0SHRtbCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgX19odG1sOiB0aGlzLnN0YXRlLmNvcHlNZXNzYWdlIH07XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgY29weU1lc3NhZ2UgPSBSZWFjdC5jcmVhdGVFbGVtZW50KCdkaXYnLCB7IHN0eWxlOiB7IGNvbG9yOiAncmdiYSgwLDAsMCwwLjIzKScgfSwgY2xhc3NOYW1lOiAnY29weS1tZXNzYWdlJywgZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUw6IHNldEh0bWwoKSB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBidXR0b25TdHlsZSA9IF9leHRlbmRzKHtcbiAgICAgICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICAgICAgcmlnaHQ6IC04LFxuICAgICAgICAgICAgYm90dG9tOiAxMyxcbiAgICAgICAgICAgIGZvbnRTaXplOiAxNSxcbiAgICAgICAgICAgIGNvbG9yOiB0aGlzLnByb3BzLmJ1dHRvbkNvbG9yIHx8ICdyZ2JhKDAsIDE1MCwgMTM2LCAwLjUyKScsXG4gICAgICAgICAgICBoZWlnaHQ6IDI2LFxuICAgICAgICAgICAgd2lkdGg6IDI2LFxuICAgICAgICAgICAgbGluZUhlaWdodDogJzI4cHgnLFxuICAgICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgIGN1cnNvcjogJ3BvaW50ZXInLFxuICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNTAlJ1xuICAgICAgICB9LCB0aGlzLnByb3BzLmJ1dHRvblN0eWxlKTtcblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBwb3NpdGlvbjogJ3JlbGF0aXZlJyB9IH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChNYXRlcmlhbFVJLlRleHRGaWVsZCwge1xuICAgICAgICAgICAgICAgICAgICBmdWxsV2lkdGg6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHJlZjogJ2lucHV0JyxcbiAgICAgICAgICAgICAgICAgICAgZmxvYXRpbmdMYWJlbFRleHQ6IHRoaXMucHJvcHMuZmxvYXRpbmdMYWJlbFRleHQsXG4gICAgICAgICAgICAgICAgICAgIGZsb2F0aW5nTGFiZWxTdHlsZTogeyB3aGl0ZVNwYWNlOiAnbm93cmFwJyB9LFxuICAgICAgICAgICAgICAgICAgICB1bmRlcmxpbmVTaG93OiB0aGlzLnByb3BzLnVuZGVybGluZVNob3csXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZTogdGhpcy5wcm9wcy5pbnB1dFZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IHRoaXMucHJvcHMuaW5wdXRDbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgICAgIG11bHRpTGluZTogdGhpcy5wcm9wcy5tdWx0aUxpbmUsXG4gICAgICAgICAgICAgICAgICAgIHJvd3M6IHRoaXMucHJvcHMucm93cyxcbiAgICAgICAgICAgICAgICAgICAgcm93c01heDogdGhpcy5wcm9wcy5yb3dzTWF4LFxuICAgICAgICAgICAgICAgICAgICByZWFkT25seTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgb25DbGljazogc2VsZWN0LFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogeyBtYXJnaW5Ub3A6IC0xMCwgd2lkdGg6ICc5MiUnLCBmb250U2l6ZTogMTQgfVxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCB7IHJlZjogJ2NvcHktYnV0dG9uJywgc3R5bGU6IGJ1dHRvblN0eWxlLCB0aXRsZTogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcxOTEnKSwgY2xhc3NOYW1lOiAnY29weS1idXR0b24gbWRpIG1kaS1jb250ZW50LWNvcHknIH0pXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgY29weU1lc3NhZ2VcbiAgICAgICAgKTtcbiAgICB9XG5cbn0pO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ0xhYmVsV2l0aFRpcCcsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgbGFiZWw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIGxhYmVsRWxlbWVudDogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgdG9vbHRpcDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgdG9vbHRpcENsYXNzTmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgY2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICBzdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdFxuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHsgc2hvdzogZmFsc2UgfTtcbiAgICB9LFxuXG4gICAgc2hvdzogZnVuY3Rpb24gc2hvdygpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3c6IHRydWUgfSk7XG4gICAgfSxcbiAgICBoaWRlOiBmdW5jdGlvbiBoaWRlKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2hvdzogZmFsc2UgfSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy50b29sdGlwKSB7XG4gICAgICAgICAgICB2YXIgdG9vbHRpcFN0eWxlID0ge307XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5sYWJlbCB8fCB0aGlzLnByb3BzLmxhYmVsRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnNob3cpIHtcbiAgICAgICAgICAgICAgICAgICAgdG9vbHRpcFN0eWxlID0geyBib3R0b206IC0xMCwgdG9wOiAnaW5oZXJpdCcgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRvb2x0aXBTdHlsZSA9IHsgcG9zaXRpb246ICdyZWxhdGl2ZScgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBsYWJlbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgbGFiZWwgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnZWxsaXBzaXMtbGFiZWwnIH0sXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMubGFiZWxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByb3BzLmxhYmVsRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIGxhYmVsID0gdGhpcy5wcm9wcy5sYWJlbEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgc3R5bGUgPSB0aGlzLnByb3BzLnN0eWxlIHx8IHsgcG9zaXRpb246ICdyZWxhdGl2ZScgfTtcblxuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgICAgIHsgb25Nb3VzZUVudGVyOiB0aGlzLnNob3csIG9uTW91c2VMZWF2ZTogdGhpcy5oaWRlLCBzdHlsZTogc3R5bGUsIGNsYXNzTmFtZTogdGhpcy5wcm9wcy5jbGFzc05hbWUgfSxcbiAgICAgICAgICAgICAgICBsYWJlbCxcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmNoaWxkcmVuLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoUmVhY3RNVUkuVG9vbHRpcCwgeyBsYWJlbDogdGhpcy5wcm9wcy50b29sdGlwLCBzdHlsZTogdG9vbHRpcFN0eWxlLCBjbGFzc05hbWU6IHRoaXMucHJvcHMudG9vbHRpcENsYXNzTmFtZSwgc2hvdzogdGhpcy5zdGF0ZS5zaG93IH0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMubGFiZWwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmxhYmVsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy5sYWJlbEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wcm9wcy5sYWJlbEVsZW1lbnQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuY2hpbGRyZW5cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG59KTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4vKipcbiAqIFNpbXBsZSBNdWlQYXBlciB3aXRoIGEgZmlndXJlIGFuZCBhIGxlZ2VuZFxuICovXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzWydkZWZhdWx0J10gPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdTaW1wbGVGaWd1cmVCYWRnZScsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgY29sb3JJbmRpY2F0b3I6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIGZpZ3VyZTogUmVhY3QuUHJvcFR5cGVzLm51bWJlci5pc1JlcXVpcmVkLFxuICAgICAgICBsZWdlbmQ6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmdcbiAgICB9LFxuXG4gICAgZ2V0RGVmYXVsdFByb3BzOiBmdW5jdGlvbiBnZXREZWZhdWx0UHJvcHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb2xvckluZGljYXRvcjogJydcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgUmVhY3RNVUkuUGFwZXIsXG4gICAgICAgICAgICB7IHN0eWxlOiB7IGRpc3BsYXk6ICdpbmxpbmUtYmxvY2snLCBtYXJnaW5MZWZ0OiAxNiB9IH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnZmlndXJlLWJhZGdlJywgc3R5bGU6IHRoaXMucHJvcHMuY29sb3JJbmRpY2F0b3IgPyB7IGJvcmRlckxlZnRDb2xvcjogdGhpcy5wcm9wcy5jb2xvckluZGljYXRvciB9IDoge30gfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdmaWd1cmUnIH0sXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuZmlndXJlXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdsZWdlbmQnIH0sXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMubGVnZW5kXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG52YXIgX2xpc3RTb3J0YWJsZUxpc3QgPSByZXF1aXJlKCcuL2xpc3QvU29ydGFibGVMaXN0Jyk7XG5cbnZhciBfbGlzdFNvcnRhYmxlTGlzdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9saXN0U29ydGFibGVMaXN0KTtcblxudmFyIF9saXN0U2ltcGxlTGlzdCA9IHJlcXVpcmUoJy4vbGlzdC9TaW1wbGVMaXN0Jyk7XG5cbnZhciBfbGlzdFNpbXBsZUxpc3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbGlzdFNpbXBsZUxpc3QpO1xuXG52YXIgX2xpc3ROb2RlTGlzdEN1c3RvbVByb3ZpZGVyID0gcmVxdWlyZSgnLi9saXN0L05vZGVMaXN0Q3VzdG9tUHJvdmlkZXInKTtcblxudmFyIF9saXN0Tm9kZUxpc3RDdXN0b21Qcm92aWRlcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9saXN0Tm9kZUxpc3RDdXN0b21Qcm92aWRlcik7XG5cbnZhciBfbGlzdExpc3RFbnRyeSA9IHJlcXVpcmUoJy4vbGlzdC9MaXN0RW50cnknKTtcblxudmFyIF9saXN0TGlzdFBhZ2luYXRvciA9IHJlcXVpcmUoJy4vbGlzdC9MaXN0UGFnaW5hdG9yJyk7XG5cbnZhciBfbGlzdExpc3RQYWdpbmF0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbGlzdExpc3RQYWdpbmF0b3IpO1xuXG52YXIgX3ZpZXdzVHJlZVZpZXcgPSByZXF1aXJlKCcuL3ZpZXdzL1RyZWVWaWV3Jyk7XG5cbnZhciBfZWxlbWVudHNMYWJlbFdpdGhUaXAgPSByZXF1aXJlKCcuL2VsZW1lbnRzL0xhYmVsV2l0aFRpcCcpO1xuXG52YXIgX2VsZW1lbnRzTGFiZWxXaXRoVGlwMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2VsZW1lbnRzTGFiZWxXaXRoVGlwKTtcblxudmFyIF9lbGVtZW50c1NpbXBsZUZpZ3VyZUJhZGdlID0gcmVxdWlyZSgnLi9lbGVtZW50cy9TaW1wbGVGaWd1cmVCYWRnZScpO1xuXG52YXIgX2VsZW1lbnRzU2ltcGxlRmlndXJlQmFkZ2UyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZWxlbWVudHNTaW1wbGVGaWd1cmVCYWRnZSk7XG5cbnZhciBfdmlld3NTZWFyY2hCb3ggPSByZXF1aXJlKCcuL3ZpZXdzL1NlYXJjaEJveCcpO1xuXG52YXIgX3ZpZXdzU2VhcmNoQm94MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3ZpZXdzU2VhcmNoQm94KTtcblxudmFyIF9lbGVtZW50c0NsaXBib2FyZFRleHRGaWVsZCA9IHJlcXVpcmUoJy4vZWxlbWVudHMvQ2xpcGJvYXJkVGV4dEZpZWxkJyk7XG5cbnZhciBfZWxlbWVudHNDbGlwYm9hcmRUZXh0RmllbGQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZWxlbWVudHNDbGlwYm9hcmRUZXh0RmllbGQpO1xuXG52YXIgX3ZpZXdzRW1wdHlTdGF0ZVZpZXcgPSByZXF1aXJlKCcuL3ZpZXdzL0VtcHR5U3RhdGVWaWV3Jyk7XG5cbnZhciBfdmlld3NFbXB0eVN0YXRlVmlldzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF92aWV3c0VtcHR5U3RhdGVWaWV3KTtcblxudmFyIF92aWV3c01vZGFsQXBwQmFyID0gcmVxdWlyZSgnLi92aWV3cy9Nb2RhbEFwcEJhcicpO1xuXG52YXIgX3ZpZXdzTW9kYWxBcHBCYXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdmlld3NNb2RhbEFwcEJhcik7XG5cbnZhciBfZWRpdG9yUmVhY3RFZGl0b3JPcGVuZXIgPSByZXF1aXJlKCcuL2VkaXRvci9SZWFjdEVkaXRvck9wZW5lcicpO1xuXG52YXIgX2VkaXRvclJlYWN0RWRpdG9yT3BlbmVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2VkaXRvclJlYWN0RWRpdG9yT3BlbmVyKTtcblxudmFyIF9lZGl0b3JQYXBlckVkaXRvciA9IHJlcXVpcmUoJy4vZWRpdG9yL1BhcGVyRWRpdG9yJyk7XG5cbnZhciBfZHluYW1pY0dyaWREeW5hbWljR3JpZCA9IHJlcXVpcmUoJy4vZHluYW1pYy1ncmlkL0R5bmFtaWNHcmlkJyk7XG5cbnZhciBfZHluYW1pY0dyaWREeW5hbWljR3JpZDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9keW5hbWljR3JpZER5bmFtaWNHcmlkKTtcblxudmFyIF9keW5hbWljR3JpZFN0b3JlID0gcmVxdWlyZSgnLi9keW5hbWljLWdyaWQvU3RvcmUnKTtcblxudmFyIF9keW5hbWljR3JpZFN0b3JlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2R5bmFtaWNHcmlkU3RvcmUpO1xuXG52YXIgX2R5bmFtaWNHcmlkR3JpZEl0ZW1NaXhpbiA9IHJlcXVpcmUoJy4vZHluYW1pYy1ncmlkL0dyaWRJdGVtTWl4aW4nKTtcblxudmFyIF9keW5hbWljR3JpZEdyaWRJdGVtTWl4aW4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZHluYW1pY0dyaWRHcmlkSXRlbU1peGluKTtcblxudmFyIF9keW5hbWljR3JpZEFzR3JpZEl0ZW0gPSByZXF1aXJlKCcuL2R5bmFtaWMtZ3JpZC9hc0dyaWRJdGVtJyk7XG5cbnZhciBfZHluYW1pY0dyaWRBc0dyaWRJdGVtMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2R5bmFtaWNHcmlkQXNHcmlkSXRlbSk7XG5cbnZhciBfdXRpbERORCA9IHJlcXVpcmUoJy4vdXRpbC9ETkQnKTtcblxudmFyIF91c2Vyc0F2YXRhclVzZXJBdmF0YXIgPSByZXF1aXJlKCcuL3VzZXJzL2F2YXRhci9Vc2VyQXZhdGFyJyk7XG5cbnZhciBfdXNlcnNBdmF0YXJVc2VyQXZhdGFyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3VzZXJzQXZhdGFyVXNlckF2YXRhcik7XG5cbnZhciBfdXNlcnNVc2Vyc0NvbXBsZXRlciA9IHJlcXVpcmUoJy4vdXNlcnMvVXNlcnNDb21wbGV0ZXInKTtcblxudmFyIF91c2Vyc1VzZXJzQ29tcGxldGVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3VzZXJzVXNlcnNDb21wbGV0ZXIpO1xuXG52YXIgX3VzZXJzVGVhbUNyZWF0aW9uRm9ybSA9IHJlcXVpcmUoJy4vdXNlcnMvVGVhbUNyZWF0aW9uRm9ybScpO1xuXG52YXIgX3VzZXJzVGVhbUNyZWF0aW9uRm9ybTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF91c2Vyc1RlYW1DcmVhdGlvbkZvcm0pO1xuXG52YXIgX21lbnVCdXR0b25NZW51ID0gcmVxdWlyZSgnLi9tZW51L0J1dHRvbk1lbnUnKTtcblxudmFyIF9tZW51QnV0dG9uTWVudTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9tZW51QnV0dG9uTWVudSk7XG5cbnZhciBfbWVudUNvbnRleHRNZW51ID0gcmVxdWlyZSgnLi9tZW51L0NvbnRleHRNZW51Jyk7XG5cbnZhciBfbWVudUNvbnRleHRNZW51MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21lbnVDb250ZXh0TWVudSk7XG5cbnZhciBfbWVudUljb25CdXR0b25NZW51ID0gcmVxdWlyZSgnLi9tZW51L0ljb25CdXR0b25NZW51Jyk7XG5cbnZhciBfbWVudUljb25CdXR0b25NZW51MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21lbnVJY29uQnV0dG9uTWVudSk7XG5cbnZhciBfbWVudVRvb2xiYXIgPSByZXF1aXJlKCcuL21lbnUvVG9vbGJhcicpO1xuXG52YXIgX21lbnVUb29sYmFyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21lbnVUb29sYmFyKTtcblxudmFyIF91c2Vyc0FkZHJlc3Nib29rQWRkcmVzc0Jvb2sgPSByZXF1aXJlKCcuL3VzZXJzL2FkZHJlc3Nib29rL0FkZHJlc3NCb29rJyk7XG5cbnZhciBfdXNlcnNBZGRyZXNzYm9va0FkZHJlc3NCb29rMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3VzZXJzQWRkcmVzc2Jvb2tBZGRyZXNzQm9vayk7XG5cbnZhciBQeWRpb0NvbXBvbmVudHMgPSB7XG5cbiAgICBTb3J0YWJsZUxpc3Q6IF9saXN0U29ydGFibGVMaXN0MlsnZGVmYXVsdCddLFxuICAgIFNpbXBsZUxpc3Q6IF9saXN0U2ltcGxlTGlzdDJbJ2RlZmF1bHQnXSxcbiAgICBOb2RlTGlzdEN1c3RvbVByb3ZpZGVyOiBfbGlzdE5vZGVMaXN0Q3VzdG9tUHJvdmlkZXIyWydkZWZhdWx0J10sXG4gICAgTGlzdEVudHJ5OiBfbGlzdExpc3RFbnRyeS5MaXN0RW50cnksXG4gICAgTGlzdFBhZ2luYXRvcjogX2xpc3RMaXN0UGFnaW5hdG9yMlsnZGVmYXVsdCddLFxuXG4gICAgVHJlZVZpZXc6IF92aWV3c1RyZWVWaWV3LlRyZWVWaWV3LFxuICAgIERORFRyZWVWaWV3OiBfdmlld3NUcmVlVmlldy5ETkRUcmVlVmlldyxcbiAgICBGb2xkZXJzVHJlZTogX3ZpZXdzVHJlZVZpZXcuRm9sZGVyc1RyZWUsXG4gICAgQ2xpcGJvYXJkVGV4dEZpZWxkOiBfZWxlbWVudHNDbGlwYm9hcmRUZXh0RmllbGQyWydkZWZhdWx0J10sXG4gICAgTGFiZWxXaXRoVGlwOiBfZWxlbWVudHNMYWJlbFdpdGhUaXAyWydkZWZhdWx0J10sXG4gICAgRW1wdHlTdGF0ZVZpZXc6IF92aWV3c0VtcHR5U3RhdGVWaWV3MlsnZGVmYXVsdCddLFxuICAgIFNpbXBsZUZpZ3VyZUJhZGdlOiBfZWxlbWVudHNTaW1wbGVGaWd1cmVCYWRnZTJbJ2RlZmF1bHQnXSxcbiAgICBTZWFyY2hCb3g6IF92aWV3c1NlYXJjaEJveDJbJ2RlZmF1bHQnXSxcbiAgICBNb2RhbEFwcEJhcjogX3ZpZXdzTW9kYWxBcHBCYXIyWydkZWZhdWx0J10sXG5cbiAgICBSZWFjdEVkaXRvck9wZW5lcjogX2VkaXRvclJlYWN0RWRpdG9yT3BlbmVyMlsnZGVmYXVsdCddLFxuICAgIFBhcGVyRWRpdG9yTGF5b3V0OiBfZWRpdG9yUGFwZXJFZGl0b3IuUGFwZXJFZGl0b3JMYXlvdXQsXG4gICAgUGFwZXJFZGl0b3JOYXZFbnRyeTogX2VkaXRvclBhcGVyRWRpdG9yLlBhcGVyRWRpdG9yTmF2RW50cnksXG4gICAgUGFwZXJFZGl0b3JOYXZIZWFkZXI6IF9lZGl0b3JQYXBlckVkaXRvci5QYXBlckVkaXRvck5hdkhlYWRlcixcblxuICAgIER5bmFtaWNHcmlkOiBfZHluYW1pY0dyaWREeW5hbWljR3JpZDJbJ2RlZmF1bHQnXSxcbiAgICBEeW5hbWljR3JpZEl0ZW1NaXhpbjogX2R5bmFtaWNHcmlkR3JpZEl0ZW1NaXhpbjJbJ2RlZmF1bHQnXSxcbiAgICBhc0dyaWRJdGVtOiBfZHluYW1pY0dyaWRBc0dyaWRJdGVtMlsnZGVmYXVsdCddLFxuICAgIER5bmFtaWNHcmlkU3RvcmU6IF9keW5hbWljR3JpZFN0b3JlMlsnZGVmYXVsdCddLFxuXG4gICAgRE5EOiB7XG4gICAgICAgIFR5cGVzOiBfdXRpbERORC5UeXBlcywgY29sbGVjdDogX3V0aWxETkQuY29sbGVjdCwgY29sbGVjdERyb3A6IF91dGlsRE5ELmNvbGxlY3REcm9wLCBub2RlRHJhZ1NvdXJjZTogX3V0aWxETkQubm9kZURyYWdTb3VyY2UsIG5vZGVEcm9wVGFyZ2V0OiBfdXRpbERORC5ub2RlRHJvcFRhcmdldCwgRE5EQWN0aW9uUGFyYW1ldGVyOiBfdXRpbERORC5ETkRBY3Rpb25QYXJhbWV0ZXJcbiAgICB9LFxuICAgIEROREFjdGlvblBhcmFtZXRlcjogX3V0aWxETkQuRE5EQWN0aW9uUGFyYW1ldGVyLFxuXG4gICAgVXNlckF2YXRhcjogX3VzZXJzQXZhdGFyVXNlckF2YXRhcjJbJ2RlZmF1bHQnXSxcbiAgICBVc2Vyc0NvbXBsZXRlcjogX3VzZXJzVXNlcnNDb21wbGV0ZXIyWydkZWZhdWx0J10sXG4gICAgVGVhbUNyZWF0aW9uRm9ybTogX3VzZXJzVGVhbUNyZWF0aW9uRm9ybTJbJ2RlZmF1bHQnXSxcbiAgICBBZGRyZXNzQm9vazogX3VzZXJzQWRkcmVzc2Jvb2tBZGRyZXNzQm9vazJbJ2RlZmF1bHQnXSxcblxuICAgIENvbnRleHRNZW51OiBfbWVudUNvbnRleHRNZW51MlsnZGVmYXVsdCddLFxuICAgIFRvb2xiYXI6IF9tZW51VG9vbGJhcjJbJ2RlZmF1bHQnXSxcbiAgICBCdXR0b25NZW51OiBfbWVudUJ1dHRvbk1lbnUyWydkZWZhdWx0J10sXG4gICAgSWNvbkJ1dHRvbk1lbnU6IF9tZW51SWNvbkJ1dHRvbk1lbnUyWydkZWZhdWx0J11cbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFB5ZGlvQ29tcG9uZW50cztcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpO1xuXG52YXIgX0xpc3RFbnRyeU5vZGVMaXN0ZW5lck1peGluID0gcmVxdWlyZSgnLi9MaXN0RW50cnlOb2RlTGlzdGVuZXJNaXhpbicpO1xuXG52YXIgX0xpc3RFbnRyeU5vZGVMaXN0ZW5lck1peGluMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0xpc3RFbnRyeU5vZGVMaXN0ZW5lck1peGluKTtcblxudmFyIF9JbmxpbmVFZGl0b3IgPSByZXF1aXJlKCcuL0lubGluZUVkaXRvcicpO1xuXG52YXIgX0lubGluZUVkaXRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9JbmxpbmVFZGl0b3IpO1xuXG52YXIgX0xpc3RFbnRyeSA9IHJlcXVpcmUoJy4vTGlzdEVudHJ5Jyk7XG5cbnZhciBfbWF0ZXJpYWxVaSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbi8qKlxuICogQ2FsbGJhY2sgYmFzZWQgbWF0ZXJpYWwgbGlzdCBlbnRyeSB3aXRoIGN1c3RvbSBpY29uIHJlbmRlciwgZmlyc3RMaW5lLCBzZWNvbmRMaW5lLCBldGMuXG4gKi9cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IF9yZWFjdDJbJ2RlZmF1bHQnXS5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdDb25maWd1cmFibGVMaXN0RW50cnknLFxuXG4gICAgbWl4aW5zOiBbX0xpc3RFbnRyeU5vZGVMaXN0ZW5lck1peGluMlsnZGVmYXVsdCddXSxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBub2RlOiBfcmVhY3QyWydkZWZhdWx0J10uUHJvcFR5cGVzLmluc3RhbmNlT2YoQWp4cE5vZGUpLFxuICAgICAgICAvLyBTRUUgQUxTTyBMaXN0RW50cnkgUFJPUFNcbiAgICAgICAgcmVuZGVySWNvbjogX3JlYWN0MlsnZGVmYXVsdCddLlByb3BUeXBlcy5mdW5jLFxuICAgICAgICByZW5kZXJGaXJzdExpbmU6IF9yZWFjdDJbJ2RlZmF1bHQnXS5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgcmVuZGVyU2Vjb25kTGluZTogX3JlYWN0MlsnZGVmYXVsdCddLlByb3BUeXBlcy5mdW5jLFxuICAgICAgICByZW5kZXJUaGlyZExpbmU6IF9yZWFjdDJbJ2RlZmF1bHQnXS5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgcmVuZGVyQWN0aW9uczogX3JlYWN0MlsnZGVmYXVsdCddLlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBzdHlsZTogX3JlYWN0MlsnZGVmYXVsdCddLlByb3BUeXBlcy5vYmplY3RcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIGljb24gPSB1bmRlZmluZWQsXG4gICAgICAgICAgICBmaXJzdExpbmUgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICBzZWNvbmRMaW5lID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgdGhpcmRMaW5lID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgc3R5bGUgPSB0aGlzLnByb3BzLnN0eWxlIHx8IHt9O1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5yZW5kZXJJY29uKSB7XG4gICAgICAgICAgICBpY29uID0gdGhpcy5wcm9wcy5yZW5kZXJJY29uKHRoaXMucHJvcHMubm9kZSwgdGhpcy5wcm9wcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgbm9kZSA9IHRoaXMucHJvcHMubm9kZTtcbiAgICAgICAgICAgIHZhciBpY29uQ2xhc3MgPSBub2RlLmdldE1ldGFkYXRhKCkuZ2V0KFwiaWNvbl9jbGFzc1wiKSA/IG5vZGUuZ2V0TWV0YWRhdGEoKS5nZXQoXCJpY29uX2NsYXNzXCIpIDogbm9kZS5pc0xlYWYoKSA/IFwiaWNvbi1maWxlLWFsdFwiIDogXCJpY29uLWZvbGRlci1jbG9zZVwiO1xuICAgICAgICAgICAgaWNvbiA9IF9yZWFjdDJbJ2RlZmF1bHQnXS5jcmVhdGVFbGVtZW50KF9tYXRlcmlhbFVpLkZvbnRJY29uLCB7IGNsYXNzTmFtZTogaWNvbkNsYXNzIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucHJvcHMucmVuZGVyRmlyc3RMaW5lKSB7XG4gICAgICAgICAgICBmaXJzdExpbmUgPSB0aGlzLnByb3BzLnJlbmRlckZpcnN0TGluZSh0aGlzLnByb3BzLm5vZGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmlyc3RMaW5lID0gdGhpcy5wcm9wcy5ub2RlLmdldExhYmVsKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgJiYgdGhpcy5zdGF0ZS5pbmxpbmVFZGl0aW9uKSB7XG4gICAgICAgICAgICBmaXJzdExpbmUgPSBfcmVhY3QyWydkZWZhdWx0J10uY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICBfcmVhY3QyWydkZWZhdWx0J10uY3JlYXRlRWxlbWVudChfSW5saW5lRWRpdG9yMlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGU6IHRoaXMucHJvcHMubm9kZSxcbiAgICAgICAgICAgICAgICAgICAgb25DbG9zZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBpbmxpbmVFZGl0aW9uOiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMuc3RhdGUuaW5saW5lRWRpdGlvbkNhbGxiYWNrXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgZmlyc3RMaW5lXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnJlbmRlclNlY29uZExpbmUpIHtcbiAgICAgICAgICAgIHNlY29uZExpbmUgPSB0aGlzLnByb3BzLnJlbmRlclNlY29uZExpbmUodGhpcy5wcm9wcy5ub2RlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wcm9wcy5yZW5kZXJUaGlyZExpbmUpIHtcbiAgICAgICAgICAgIHRoaXJkTGluZSA9IHRoaXMucHJvcHMucmVuZGVyVGhpcmRMaW5lKHRoaXMucHJvcHMubm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGFjdGlvbnMgPSB0aGlzLnByb3BzLmFjdGlvbnM7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnJlbmRlckFjdGlvbnMpIHtcbiAgICAgICAgICAgIGFjdGlvbnMgPSB0aGlzLnByb3BzLnJlbmRlckFjdGlvbnModGhpcy5wcm9wcy5ub2RlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBfcmVhY3QyWydkZWZhdWx0J10uY3JlYXRlRWxlbWVudChfTGlzdEVudHJ5LkRyYWdEcm9wTGlzdEVudHJ5LCBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcywge1xuICAgICAgICAgICAgaWNvbkNlbGw6IGljb24sXG4gICAgICAgICAgICBmaXJzdExpbmU6IGZpcnN0TGluZSxcbiAgICAgICAgICAgIHNlY29uZExpbmU6IHNlY29uZExpbmUsXG4gICAgICAgICAgICB0aGlyZExpbmU6IHRoaXJkTGluZSxcbiAgICAgICAgICAgIGFjdGlvbnM6IGFjdGlvbnMsXG4gICAgICAgICAgICBzdHlsZTogc3R5bGVcbiAgICAgICAgfSkpO1xuICAgIH1cblxufSk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcbnZhciBQeWRpbyA9IHJlcXVpcmUoJ3B5ZGlvJyk7XG52YXIgQWp4cE5vZGUgPSByZXF1aXJlKCdweWRpby9tb2RlbC9ub2RlJyk7XG5cbnZhciBfUHlkaW8kcmVxdWlyZUxpYiA9IFB5ZGlvLnJlcXVpcmVMaWIoJ2Jvb3QnKTtcblxudmFyIFB5ZGlvQ29udGV4dENvbnN1bWVyID0gX1B5ZGlvJHJlcXVpcmVMaWIuUHlkaW9Db250ZXh0Q29uc3VtZXI7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBQYXBlciA9IF9yZXF1aXJlLlBhcGVyO1xudmFyIFRleHRGaWVsZCA9IF9yZXF1aXJlLlRleHRGaWVsZDtcbnZhciBGbGF0QnV0dG9uID0gX3JlcXVpcmUuRmxhdEJ1dHRvbjtcblxudmFyIElubGluZUVkaXRvciA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ0lubGluZUVkaXRvcicsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgbm9kZTogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoQWp4cE5vZGUpLFxuICAgICAgICBjYWxsYmFjazogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIG9uQ2xvc2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBkZXRhY2hlZDogUmVhY3QuUHJvcFR5cGVzLmJvb2xcbiAgICB9LFxuXG4gICAgc3VibWl0OiBmdW5jdGlvbiBzdWJtaXQoKSB7XG4gICAgICAgIGlmICghdGhpcy5zdGF0ZSB8fCAhdGhpcy5zdGF0ZS52YWx1ZSB8fCB0aGlzLnN0YXRlLnZhbHVlID09PSB0aGlzLnByb3BzLm5vZGUuZ2V0TGFiZWwoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVycm9yU3RyaW5nOiAnUGxlYXNlIHVzZSBhIGRpZmZlcmVudCB2YWx1ZSBmb3IgcmVuYW1pbmchJyB9KTtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuZ2V0UHlkaW8oKS5kaXNwbGF5TWVzc2FnZSgnRVJST1InLCAnUGxlYXNlIHVzZSBhIGRpZmZlcmVudCB2YWx1ZSBmb3IgcmVuYW1pbmchJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLmNhbGxiYWNrKHRoaXMuc3RhdGUudmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkNsb3NlKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB0aGlzLnJlZnMudGV4dC5mb2N1cygpO1xuICAgIH0sXG5cbiAgICBjYXRjaENsaWNrczogZnVuY3Rpb24gY2F0Y2hDbGlja3MoZSkge1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0sXG5cbiAgICBvbktleURvd246IGZ1bmN0aW9uIG9uS2V5RG93bihlKSB7XG4gICAgICAgIGlmIChlLmtleSA9PT0gJ0VudGVyJykge1xuICAgICAgICAgICAgdGhpcy5zdWJtaXQoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3JTdHJpbmc6ICcnIH0pO1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgIFBhcGVyLFxuICAgICAgICAgICAgeyBjbGFzc05hbWU6IFwiaW5saW5lLWVkaXRvclwiICsgKHRoaXMucHJvcHMuZGV0YWNoZWQgPyBcIiBkZXRhY2hlZFwiIDogXCJcIiksIHN0eWxlOiB7IHBhZGRpbmc6IDggfSwgekRlcHRoOiAyIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFRleHRGaWVsZCwge1xuICAgICAgICAgICAgICAgIHJlZjogJ3RleHQnLFxuICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZTogdGhpcy5wcm9wcy5ub2RlLmdldExhYmVsKCksXG4gICAgICAgICAgICAgICAgb25DaGFuZ2U6IGZ1bmN0aW9uIChlLCB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IHZhbHVlOiB2YWx1ZSB9KTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIG9uQ2xpY2s6IHRoaXNbJ2NhdGNoJ10sIG9uRG91YmxlQ2xpY2s6IHRoaXMuY2F0Y2hDbGlja3MsXG4gICAgICAgICAgICAgICAgdGFiSW5kZXg6ICcwJywgb25LZXlEb3duOiB0aGlzLm9uS2V5RG93bixcbiAgICAgICAgICAgICAgICBlcnJvclRleHQ6IHRoaXMuc3RhdGUgPyB0aGlzLnN0YXRlLmVycm9yU3RyaW5nIDogbnVsbFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgdGV4dEFsaWduOiAncmlnaHQnLCBwYWRkaW5nVG9wOiA4IH0gfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEZsYXRCdXR0b24sIHsgbGFiZWw6ICdDYW5jZWwnLCBvbkNsaWNrOiB0aGlzLnByb3BzLm9uQ2xvc2UgfSksXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChGbGF0QnV0dG9uLCB7IGxhYmVsOiAnU3VibWl0Jywgb25DbGljazogdGhpcy5zdWJtaXQgfSlcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG5cbn0pO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBJbmxpbmVFZGl0b3IgPSBQeWRpb0NvbnRleHRDb25zdW1lcihJbmxpbmVFZGl0b3IpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBJbmxpbmVFZGl0b3I7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX3JlYWN0RG9tID0gcmVxdWlyZSgncmVhY3QtZG9tJyk7XG5cbnZhciBfcmVhY3REb20yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3REb20pO1xuXG52YXIgX3V0aWxETkQgPSByZXF1aXJlKCcuLi91dGlsL0RORCcpO1xuXG52YXIgX3JlYWN0RG5kID0gcmVxdWlyZSgncmVhY3QtZG5kJyk7XG5cbnZhciBfbWF0ZXJpYWxVaSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBfbWF0ZXJpYWxVaVN0eWxlcyA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpL3N0eWxlcycpO1xuXG52YXIgX2NvbG9yID0gcmVxdWlyZSgnY29sb3InKTtcblxudmFyIF9jb2xvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9jb2xvcik7XG5cbi8qKlxuICogTWF0ZXJpYWwgTGlzdCBFbnRyeVxuICovXG5cbnZhciBMaXN0RW50cnkgPSAoZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoTGlzdEVudHJ5LCBfUmVhY3QkQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIExpc3RFbnRyeSgpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIExpc3RFbnRyeSk7XG5cbiAgICAgICAgX1JlYWN0JENvbXBvbmVudC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIExpc3RFbnRyeS5wcm90b3R5cGUub25DbGljayA9IGZ1bmN0aW9uIG9uQ2xpY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuc2hvd1NlbGVjdG9yKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5zZWxlY3RvckRpc2FibGVkKSByZXR1cm47XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uU2VsZWN0KHRoaXMucHJvcHMubm9kZSwgZXZlbnQpO1xuICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJvcHMub25DbGljaykge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkNsaWNrKHRoaXMucHJvcHMubm9kZSwgZXZlbnQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIExpc3RFbnRyeS5wcm90b3R5cGUub25Eb3VibGVDbGljayA9IGZ1bmN0aW9uIG9uRG91YmxlQ2xpY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25Eb3VibGVDbGljaykge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkRvdWJsZUNsaWNrKHRoaXMucHJvcHMubm9kZSwgZXZlbnQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIExpc3RFbnRyeS5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciBzZWxlY3RvciA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGljb24gPSB1bmRlZmluZWQsXG4gICAgICAgICAgICBhZGRpdGlvbmFsQ2xhc3NOYW1lID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgbm9kZSA9IF9wcm9wcy5ub2RlO1xuICAgICAgICB2YXIgc2hvd1NlbGVjdG9yID0gX3Byb3BzLnNob3dTZWxlY3RvcjtcbiAgICAgICAgdmFyIHNlbGVjdGVkID0gX3Byb3BzLnNlbGVjdGVkO1xuICAgICAgICB2YXIgc2VsZWN0b3JEaXNhYmxlZCA9IF9wcm9wcy5zZWxlY3RvckRpc2FibGVkO1xuICAgICAgICB2YXIgZmlyc3RMaW5lID0gX3Byb3BzLmZpcnN0TGluZTtcbiAgICAgICAgdmFyIHNlY29uZExpbmUgPSBfcHJvcHMuc2Vjb25kTGluZTtcbiAgICAgICAgdmFyIHRoaXJkTGluZSA9IF9wcm9wcy50aGlyZExpbmU7XG4gICAgICAgIHZhciBzdHlsZSA9IF9wcm9wcy5zdHlsZTtcbiAgICAgICAgdmFyIGFjdGlvbnMgPSBfcHJvcHMuYWN0aW9ucztcbiAgICAgICAgdmFyIGljb25DZWxsID0gX3Byb3BzLmljb25DZWxsO1xuICAgICAgICB2YXIgbWFpbkljb24gPSBfcHJvcHMubWFpbkljb247XG4gICAgICAgIHZhciBjbGFzc05hbWUgPSBfcHJvcHMuY2xhc3NOYW1lO1xuICAgICAgICB2YXIgY2FuRHJvcCA9IF9wcm9wcy5jYW5Ecm9wO1xuICAgICAgICB2YXIgaXNPdmVyID0gX3Byb3BzLmlzT3ZlcjtcbiAgICAgICAgdmFyIGNvbm5lY3REcmFnU291cmNlID0gX3Byb3BzLmNvbm5lY3REcmFnU291cmNlO1xuICAgICAgICB2YXIgY29ubmVjdERyb3BUYXJnZXQgPSBfcHJvcHMuY29ubmVjdERyb3BUYXJnZXQ7XG5cbiAgICAgICAgdmFyIG1haW5DbGFzc2VzID0gWydtYXRlcmlhbC1saXN0LWVudHJ5JywgJ21hdGVyaWFsLWxpc3QtZW50cnktJyArICh0aGlyZExpbmUgPyAzIDogc2Vjb25kTGluZSA/IDIgOiAxKSArICctbGluZXMnXTtcbiAgICAgICAgaWYgKGNsYXNzTmFtZSkgbWFpbkNsYXNzZXMucHVzaChjbGFzc05hbWUpO1xuXG4gICAgICAgIGlmIChzaG93U2VsZWN0b3IpIHtcbiAgICAgICAgICAgIHNlbGVjdG9yID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ21hdGVyaWFsLWxpc3Qtc2VsZWN0b3InIH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChfbWF0ZXJpYWxVaS5DaGVja2JveCwgeyBjaGVja2VkOiBzZWxlY3RlZCwgcmVmOiAnc2VsZWN0b3InLCBkaXNhYmxlZDogc2VsZWN0b3JEaXNhYmxlZCB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpY29uQ2VsbCkge1xuICAgICAgICAgICAgaWNvbiA9IHRoaXMucHJvcHMuaWNvbkNlbGw7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy5tYWluSWNvbikge1xuICAgICAgICAgICAgaWNvbiA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoX21hdGVyaWFsVWkuRm9udEljb24sIHsgY2xhc3NOYW1lOiBcIm11aS1mb250LWljb24gXCIgKyB0aGlzLnByb3BzLm1haW5JY29uLCBzdHlsZTogeyBmb250U2l6ZTogMTggLyosIGNvbG9yOiBcIiNGRkZGRkZcIiovIH0gfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2FuRHJvcCAmJiBpc092ZXIpIHtcbiAgICAgICAgICAgIG1haW5DbGFzc2VzLnB1c2goJ2Ryb3BwYWJsZS1hY3RpdmUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChub2RlKSB7XG4gICAgICAgICAgICBtYWluQ2xhc3Nlcy5wdXNoKCdsaXN0ZW50cnknICsgbm9kZS5nZXRQYXRoKCkucmVwbGFjZSgvXFwvL2csICdfJykpO1xuICAgICAgICAgICAgbWFpbkNsYXNzZXMucHVzaCgnYWp4cF9ub2RlXycgKyAobm9kZS5pc0xlYWYoKSA/ICdsZWFmJyA6ICdjb2xsZWN0aW9uJykpO1xuICAgICAgICAgICAgaWYgKG5vZGUuZ2V0QWp4cE1pbWUoKSkge1xuICAgICAgICAgICAgICAgIG1haW5DbGFzc2VzLnB1c2goJ2FqeHBfbWltZV8nICsgbm9kZS5nZXRBanhwTWltZSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBhZGRpdGlvbmFsU3R5bGUgPSB7XG4gICAgICAgICAgICAvKnRyYW5zaXRpb246J2JhY2tncm91bmQtY29sb3IgMjUwbXMgY3ViaWMtYmV6aWVyKDAuMjMsIDEsIDAuMzIsIDEpIDBtcywgY29sb3IgMjUwbXMgY3ViaWMtYmV6aWVyKDAuMjMsIDEsIDAuMzIsIDEpIDBtcycqL1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSAmJiB0aGlzLnN0YXRlLmhvdmVyICYmICF0aGlzLnByb3BzLm5vSG92ZXIpIHtcbiAgICAgICAgICAgIGFkZGl0aW9uYWxTdHlsZSA9IF9leHRlbmRzKHt9LCBhZGRpdGlvbmFsU3R5bGUsIHtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICdyZ2JhKDAsMCwwLDAuMDUpJyxcbiAgICAgICAgICAgICAgICBib3JkZXJCb3R0b206ICcxcHggc29saWQgdHJhbnNwYXJlbnQnXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VsZWN0ZWQpIHtcbiAgICAgICAgICAgIHZhciBzZWxlY3Rpb25Db2xvciA9IHRoaXMucHJvcHMubXVpVGhlbWUucGFsZXR0ZS5hY2NlbnQyQ29sb3I7XG4gICAgICAgICAgICB2YXIgc2VsZWN0aW9uQ29sb3JEYXJrID0gX2NvbG9yMlsnZGVmYXVsdCddKHNlbGVjdGlvbkNvbG9yKS5kYXJrKCk7XG4gICAgICAgICAgICBhZGRpdGlvbmFsU3R5bGUgPSBfZXh0ZW5kcyh7fSwgYWRkaXRpb25hbFN0eWxlLCB7XG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBzZWxlY3Rpb25Db2xvcixcbiAgICAgICAgICAgICAgICBjb2xvcjogc2VsZWN0aW9uQ29sb3JEYXJrID8gJ3doaXRlJyA6ICdyZ2JhKDAsMCwwLC44NyknXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG1haW5DbGFzc2VzLnB1c2goJ3NlbGVjdGVkJyk7XG4gICAgICAgICAgICBtYWluQ2xhc3Nlcy5wdXNoKCdzZWxlY3RlZC0nICsgKHNlbGVjdGlvbkNvbG9yRGFyayA/ICdkYXJrJyA6ICdsaWdodCcpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgQ29udGV4dE1lbnVXcmFwcGVyLFxuICAgICAgICAgICAgX2V4dGVuZHMoe30sIHRoaXMucHJvcHMsIHtcbiAgICAgICAgICAgICAgICByZWY6IGZ1bmN0aW9uIChpbnN0YW5jZSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZSA9IF9yZWFjdERvbTJbJ2RlZmF1bHQnXS5maW5kRE9NTm9kZShpbnN0YW5jZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29ubmVjdERyb3BUYXJnZXQgPT09ICdmdW5jdGlvbicpIGNvbm5lY3REcm9wVGFyZ2V0KG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNvbm5lY3REcmFnU291cmNlID09PSAnZnVuY3Rpb24nKSBjb25uZWN0RHJhZ1NvdXJjZShub2RlKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIG9uQ2xpY2s6IHRoaXMub25DbGljay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIG9uRG91YmxlQ2xpY2s6IHNob3dTZWxlY3RvciA/IG51bGwgOiB0aGlzLm9uRG91YmxlQ2xpY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IG1haW5DbGFzc2VzLmpvaW4oJyAnKSxcbiAgICAgICAgICAgICAgICBvbk1vdXNlT3ZlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IGhvdmVyOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgb25Nb3VzZU91dDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IGhvdmVyOiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHN0eWxlOiBfZXh0ZW5kcyh7fSwgc3R5bGUsIGFkZGl0aW9uYWxTdHlsZSkgfSksXG4gICAgICAgICAgICBzZWxlY3RvcixcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IFwibWF0ZXJpYWwtbGlzdC1pY29uXCIgKyAobWFpbkljb24gfHwgaWNvbkNlbGwgPyBcIlwiIDogXCIgbWF0ZXJpYWwtbGlzdC1pY29uLW5vbmVcIikgfSxcbiAgICAgICAgICAgICAgICBpY29uXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ21hdGVyaWFsLWxpc3QtdGV4dCcgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBrZXk6ICdsaW5lLTEnLCBjbGFzc05hbWU6ICdtYXRlcmlhbC1saXN0LWxpbmUtMScgfSxcbiAgICAgICAgICAgICAgICAgICAgZmlyc3RMaW5lXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBrZXk6ICdsaW5lLTInLCBjbGFzc05hbWU6ICdtYXRlcmlhbC1saXN0LWxpbmUtMicgfSxcbiAgICAgICAgICAgICAgICAgICAgc2Vjb25kTGluZVxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsga2V5OiAnbGluZS0zJywgY2xhc3NOYW1lOiAnbWF0ZXJpYWwtbGlzdC1saW5lLTMnIH0sXG4gICAgICAgICAgICAgICAgICAgIHRoaXJkTGluZVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnbWF0ZXJpYWwtbGlzdC1hY3Rpb25zJyB9LFxuICAgICAgICAgICAgICAgIGFjdGlvbnNcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIExpc3RFbnRyeTtcbn0pKFJlYWN0LkNvbXBvbmVudCk7XG5cbnZhciBDb250ZXh0TWVudVdyYXBwZXIgPSBmdW5jdGlvbiBDb250ZXh0TWVudVdyYXBwZXIocHJvcHMpIHtcbiAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudCgnZGl2JywgcHJvcHMpO1xufTtcbkNvbnRleHRNZW51V3JhcHBlciA9IFB5ZGlvSE9Dcy53aXRoQ29udGV4dE1lbnUoQ29udGV4dE1lbnVXcmFwcGVyKTtcblxuTGlzdEVudHJ5LnByb3BUeXBlcyA9IHtcbiAgICBzaG93U2VsZWN0b3I6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgIHNlbGVjdGVkOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICBzZWxlY3RvckRpc2FibGVkOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICBvblNlbGVjdDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgb25DbGljazogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgaWNvbkNlbGw6IFJlYWN0LlByb3BUeXBlcy5lbGVtZW50LFxuICAgIG1haW5JY29uOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIGZpcnN0TGluZTogUmVhY3QuUHJvcFR5cGVzLm5vZGUsXG4gICAgc2Vjb25kTGluZTogUmVhY3QuUHJvcFR5cGVzLm5vZGUsXG4gICAgdGhpcmRMaW5lOiBSZWFjdC5Qcm9wVHlwZXMubm9kZSxcbiAgICBhY3Rpb25zOiBSZWFjdC5Qcm9wVHlwZXMuZWxlbWVudCxcbiAgICBhY3RpdmVEcm9wcGFibGU6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgIGNsYXNzTmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICBzdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICBub0hvdmVyOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbFxufTtcblxuZXhwb3J0cy5MaXN0RW50cnkgPSBMaXN0RW50cnkgPSBfbWF0ZXJpYWxVaVN0eWxlcy5tdWlUaGVtZWFibGUoKShMaXN0RW50cnkpO1xuXG52YXIgRHJhZ0Ryb3BMaXN0RW50cnkgPSBfcmVhY3REbmQuZmxvdyhfcmVhY3REbmQuRHJhZ1NvdXJjZShfdXRpbERORC5UeXBlcy5OT0RFX1BST1ZJREVSLCBfdXRpbERORC5ub2RlRHJhZ1NvdXJjZSwgX3V0aWxETkQuY29sbGVjdCksIF9yZWFjdERuZC5Ecm9wVGFyZ2V0KF91dGlsRE5ELlR5cGVzLk5PREVfUFJPVklERVIsIF91dGlsRE5ELm5vZGVEcm9wVGFyZ2V0LCBfdXRpbERORC5jb2xsZWN0RHJvcCkpKExpc3RFbnRyeSk7XG5cbmV4cG9ydHMuRHJhZ0Ryb3BMaXN0RW50cnkgPSBEcmFnRHJvcExpc3RFbnRyeTtcbmV4cG9ydHMuTGlzdEVudHJ5ID0gTGlzdEVudHJ5O1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbmV4cG9ydHNbXCJkZWZhdWx0XCJdID0ge1xuXG4gICAgYXR0YWNoOiBmdW5jdGlvbiBhdHRhY2gobm9kZSkge1xuICAgICAgICB0aGlzLl9ub2RlTGlzdGVuZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmlzTW91bnRlZCgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZXRhY2gobm9kZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5mb3JjZVVwZGF0ZSgpO1xuICAgICAgICB9KS5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLl9hY3Rpb25MaXN0ZW5lciA9IChmdW5jdGlvbiAoZXZlbnRNZW1vKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNNb3VudGVkKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRldGFjaChub2RlKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZXZlbnRNZW1vICYmIGV2ZW50TWVtby50eXBlID09PSAncHJvbXB0LXJlbmFtZScgJiYgZXZlbnRNZW1vLmNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlubGluZUVkaXRpb246IHRydWUsIGlubGluZUVkaXRpb25DYWxsYmFjazogZXZlbnRNZW1vLmNhbGxiYWNrIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgIG5vZGUub2JzZXJ2ZShcIm5vZGVfcmVwbGFjZWRcIiwgdGhpcy5fbm9kZUxpc3RlbmVyKTtcbiAgICAgICAgbm9kZS5vYnNlcnZlKFwibm9kZV9hY3Rpb25cIiwgdGhpcy5fYWN0aW9uTGlzdGVuZXIpO1xuICAgIH0sXG5cbiAgICBkZXRhY2g6IGZ1bmN0aW9uIGRldGFjaChub2RlKSB7XG4gICAgICAgIGlmICh0aGlzLl9ub2RlTGlzdGVuZXIpIHtcbiAgICAgICAgICAgIG5vZGUuc3RvcE9ic2VydmluZyhcIm5vZGVfcmVwbGFjZWRcIiwgdGhpcy5fbm9kZUxpc3RlbmVyKTtcbiAgICAgICAgICAgIG5vZGUuc3RvcE9ic2VydmluZyhcIm5vZGVfYWN0aW9uXCIsIHRoaXMuX2FjdGlvbkxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHRoaXMuYXR0YWNoKHRoaXMucHJvcHMubm9kZSk7XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50OiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgdGhpcy5kZXRhY2godGhpcy5wcm9wcy5ub2RlKTtcbiAgICB9XG5cbn07XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgXCJkZWZhdWx0XCI6IG9iaiB9OyB9XG5cbnZhciBfdXRpbE1lc3NhZ2VzQ29uc3VtZXJNaXhpbiA9IHJlcXVpcmUoJy4uL3V0aWwvTWVzc2FnZXNDb25zdW1lck1peGluJyk7XG5cbnZhciBfdXRpbE1lc3NhZ2VzQ29uc3VtZXJNaXhpbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF91dGlsTWVzc2FnZXNDb25zdW1lck1peGluKTtcblxuLyoqXG4gKiBQYWdpbmF0aW9uIGNvbXBvbmVudCByZWFkaW5nIG1ldGFkYXRhIFwicGFnaW5hdGlvbkRhdGFcIiBmcm9tIGN1cnJlbnQgbm9kZS5cbiAqL1xuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6IFwiTGlzdFBhZ2luYXRvclwiLFxuXG4gICAgbWl4aW5zOiBbX3V0aWxNZXNzYWdlc0NvbnN1bWVyTWl4aW4yW1wiZGVmYXVsdFwiXV0sXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgZGF0YU1vZGVsOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpb0RhdGFNb2RlbCkuaXNSZXF1aXJlZCxcbiAgICAgICAgbm9kZTogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoQWp4cE5vZGUpXG4gICAgfSxcblxuICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICBpZiAoIXRoaXMucHJvcHMubm9kZSkge1xuICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgZG0gPSBfdGhpcy5wcm9wcy5kYXRhTW9kZWw7XG4gICAgICAgICAgICAgICAgX3RoaXMuX2RtT2JzZXJ2ZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgbm9kZTogZG0uZ2V0Q29udGV4dE5vZGUoKSB9KTtcbiAgICAgICAgICAgICAgICB9KS5iaW5kKF90aGlzKTtcbiAgICAgICAgICAgICAgICBkbS5vYnNlcnZlKFwiY29udGV4dF9jaGFuZ2VkXCIsIF90aGlzLl9kbU9ic2VydmVyKTtcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IG5vZGU6IGRtLmdldENvbnRleHROb2RlKCkgfSk7XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50OiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2RtT2JzZXJ2ZXIpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuZGF0YU1vZGVsLnN0b3BPYnNlcnZpbmcoXCJjb250ZXh0X2NoYW5nZWRcIiwgdGhpcy5fZG1PYnNlcnZlcik7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiBnZXRJbml0aWFsU3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB7IG5vZGU6IHRoaXMucHJvcHMubm9kZSB9O1xuICAgIH0sXG5cbiAgICBjaGFuZ2VQYWdlOiBmdW5jdGlvbiBjaGFuZ2VQYWdlKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuc3RhdGUubm9kZS5nZXRNZXRhZGF0YSgpLmdldChcInBhZ2luYXRpb25EYXRhXCIpLnNldChcIm5ld19wYWdlXCIsIGV2ZW50LmN1cnJlbnRUYXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXBhZ2UnKSk7XG4gICAgICAgIHRoaXMucHJvcHMuZGF0YU1vZGVsLnJlcXVpcmVDb250ZXh0Q2hhbmdlKHRoaXMuc3RhdGUubm9kZSk7XG4gICAgfSxcblxuICAgIG9uTWVudUNoYW5nZTogZnVuY3Rpb24gb25NZW51Q2hhbmdlKGV2ZW50LCBpbmRleCwgaXRlbSkge1xuICAgICAgICB0aGlzLnN0YXRlLm5vZGUuZ2V0TWV0YWRhdGEoKS5nZXQoXCJwYWdpbmF0aW9uRGF0YVwiKS5zZXQoXCJuZXdfcGFnZVwiLCBpdGVtLnBheWxvYWQpO1xuICAgICAgICB0aGlzLnByb3BzLmRhdGFNb2RlbC5yZXF1aXJlQ29udGV4dENoYW5nZSh0aGlzLnN0YXRlLm5vZGUpO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlLm5vZGUgfHwgIXRoaXMuc3RhdGUubm9kZS5nZXRNZXRhZGF0YSgpLmdldChcInBhZ2luYXRpb25EYXRhXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcERhdGEgPSB0aGlzLnN0YXRlLm5vZGUuZ2V0TWV0YWRhdGEoKS5nZXQoXCJwYWdpbmF0aW9uRGF0YVwiKTtcbiAgICAgICAgdmFyIGN1cnJlbnQgPSBwYXJzZUludChwRGF0YS5nZXQoXCJjdXJyZW50XCIpKTtcbiAgICAgICAgdmFyIHRvdGFsID0gcGFyc2VJbnQocERhdGEuZ2V0KFwidG90YWxcIikpO1xuICAgICAgICB2YXIgcGFnZXMgPSBbXSxcbiAgICAgICAgICAgIG5leHQsXG4gICAgICAgICAgICBsYXN0LFxuICAgICAgICAgICAgcHJldmlvdXMsXG4gICAgICAgICAgICBmaXJzdDtcbiAgICAgICAgdmFyIHBhZ2VXb3JkID0gdGhpcy5jb250ZXh0LmdldE1lc3NhZ2UgPyB0aGlzLmNvbnRleHQuZ2V0TWVzc2FnZSgnMzMxJywgJycpIDogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCczMzEnLCAnJyk7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDw9IHRvdGFsOyBpKyspIHtcbiAgICAgICAgICAgIHBhZ2VzLnB1c2goeyBwYXlsb2FkOiBpLCB0ZXh0OiBwYWdlV29yZCArICcgJyArIGkgKyAoaSA9PSBjdXJyZW50ID8gJyAvICcgKyB0b3RhbCA6ICcnKSB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFnZXMubGVuZ3RoIDw9IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzZXAgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnRvb2xiYXJEaXNwbGF5KSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudCA+IDEpIHByZXZpb3VzID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBcInNwYW5cIixcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogXCJ0b29sYmFycy1idXR0b24tbWVudVwiIH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5JY29uQnV0dG9uLCB7IG9uQ2xpY2s6IHRoaXMuY2hhbmdlUGFnZSwgXCJkYXRhLXBhZ2VcIjogY3VycmVudCAtIDEsIGljb25DbGFzc05hbWU6IFwiaWNvbi1jYXJldC1sZWZ0XCIgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoY3VycmVudCA8IHRvdGFsKSBuZXh0ID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBcInNwYW5cIixcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogXCJ0b29sYmFycy1idXR0b24tbWVudVwiIH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5JY29uQnV0dG9uLCB7IG9uQ2xpY2s6IHRoaXMuY2hhbmdlUGFnZSwgXCJkYXRhLXBhZ2VcIjogY3VycmVudCArIDEsIGljb25DbGFzc05hbWU6IFwiaWNvbi1jYXJldC1yaWdodFwiIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnQgPiAxKSBwcmV2aW91cyA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoUmVhY3RNVUkuRm9udEljb24sIHsgb25DbGljazogdGhpcy5jaGFuZ2VQYWdlLCBcImRhdGEtcGFnZVwiOiBjdXJyZW50IC0gMSwgY2xhc3NOYW1lOiBcImljb24tYW5nbGUtbGVmdFwiIH0pO1xuICAgICAgICAgICAgaWYgKGN1cnJlbnQgPCB0b3RhbCkgbmV4dCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoUmVhY3RNVUkuRm9udEljb24sIHsgb25DbGljazogdGhpcy5jaGFuZ2VQYWdlLCBcImRhdGEtcGFnZVwiOiBjdXJyZW50ICsgMSwgY2xhc3NOYW1lOiBcImljb24tYW5nbGUtcmlnaHRcIiB9KTtcbiAgICAgICAgICAgIHNlcCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgXCJzcGFuXCIsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IFwibXVpLXRvb2xiYXItc2VwYXJhdG9yXCIgfSxcbiAgICAgICAgICAgICAgICBcIsKgXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICBcInNwYW5cIixcbiAgICAgICAgICAgIHsgaWQ6IHRoaXMucHJvcHMuaWQsIHN0eWxlOiB0aGlzLnByb3BzLnN0eWxlIH0sXG4gICAgICAgICAgICBmaXJzdCxcbiAgICAgICAgICAgIHByZXZpb3VzLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5Ecm9wRG93bk1lbnUsIHsgb25DaGFuZ2U6IHRoaXMub25NZW51Q2hhbmdlLCBtZW51SXRlbXM6IHBhZ2VzLCBzZWxlY3RlZEluZGV4OiBjdXJyZW50IC0gMSB9KSxcbiAgICAgICAgICAgIG5leHQsXG4gICAgICAgICAgICBsYXN0LFxuICAgICAgICAgICAgc2VwXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1tcImRlZmF1bHRcIl07XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cblwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBcImRlZmF1bHRcIjogb2JqIH07IH1cblxudmFyIF9TaW1wbGVMaXN0ID0gcmVxdWlyZSgnLi9TaW1wbGVMaXN0Jyk7XG5cbnZhciBfU2ltcGxlTGlzdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TaW1wbGVMaXN0KTtcblxuLyoqXG4gKiBTaW1wbGUgdG8gdXNlIGxpc3QgY29tcG9uZW50IGVuY2Fwc3VsYXRlZCB3aXRoIGl0cyBvd24gcXVlcnkgbWVjaGFuaXNtXG4gKiB1c2luZyBhIHNldCBvZiBwcm9wZXJ0aWVzIGZvciB0aGUgcmVtb3RlIG5vZGUgcHJvdmlkZXIuXG4gKi9cbmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiBcIk5vZGVMaXN0Q3VzdG9tUHJvdmlkZXJcIixcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBub2RlUHJvdmlkZXJQcm9wZXJ0aWVzOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICBwcmVzZXREYXRhTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFB5ZGlvRGF0YU1vZGVsKSxcbiAgICAgICAgYXV0b1JlZnJlc2g6IFJlYWN0LlByb3BUeXBlcy5udW1iZXIsXG4gICAgICAgIGFjdGlvbkJhckdyb3VwczogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuICAgICAgICBoZWlnaHRBdXRvV2l0aE1heDogUmVhY3QuUHJvcFR5cGVzLm51bWJlcixcbiAgICAgICAgZWxlbWVudEhlaWdodDogUmVhY3QuUHJvcFR5cGVzLm51bWJlci5pc1JlcXVpcmVkLFxuICAgICAgICBub2RlQ2xpY2tlZDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIHJlbG9hZE9uU2VydmVyTWVzc2FnZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgZW50cnlSZW5kZXJBc0NhcmQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgfSxcblxuICAgIHJlbG9hZDogZnVuY3Rpb24gcmVsb2FkKCkge1xuICAgICAgICBpZiAodGhpcy5yZWZzLmxpc3QgJiYgdGhpcy5pc01vdW50ZWQoKSkge1xuICAgICAgICAgICAgdGhpcy5yZWZzLmxpc3QucmVsb2FkKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFVubW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICBpZiAodGhpcy5fc21PYnMpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMucHlkaW8uc3RvcE9ic2VydmluZyhcInNlcnZlcl9tZXNzYWdlXCIsIHRoaXMuX3NtT2JzKTtcbiAgICAgICAgICAgIHRoaXMucHJvcHMucHlkaW8uc3RvcE9ic2VydmluZyhcInNlcnZlcl9tZXNzYWdlOlwiICsgdGhpcy5wcm9wcy5yZWxvYWRPblNlcnZlck1lc3NhZ2UsIHRoaXMucmVsb2FkKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5ub2RlUHJvdmlkZXJQcm9wZXJ0aWVzICYmIHRoaXMucHJvcHMubm9kZVByb3ZpZGVyUHJvcGVydGllcyAhPT0gbmV4dFByb3BzLm5vZGVQcm92aWRlclByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHZhciBfc3RhdGUgPSB0aGlzLnN0YXRlO1xuICAgICAgICAgICAgdmFyIGRhdGFNb2RlbCA9IF9zdGF0ZS5kYXRhTW9kZWw7XG4gICAgICAgICAgICB2YXIgbm9kZSA9IF9zdGF0ZS5ub2RlO1xuXG4gICAgICAgICAgICB2YXIgcHJvdmlkZXIgPSBuZXcgUmVtb3RlTm9kZVByb3ZpZGVyKG5leHRQcm9wcy5ub2RlUHJvdmlkZXJQcm9wZXJ0aWVzKTtcbiAgICAgICAgICAgIGRhdGFNb2RlbC5zZXRBanhwTm9kZVByb3ZpZGVyKHByb3ZpZGVyKTtcbiAgICAgICAgICAgIG5vZGUudXBkYXRlUHJvdmlkZXIocHJvdmlkZXIpO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGRhdGFNb2RlbDogZGF0YU1vZGVsLCBub2RlOiBub2RlIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJvcHMucHJlc2V0RGF0YU1vZGVsICE9PSBuZXh0UHJvcHMucHJlc2V0RGF0YU1vZGVsKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBkYXRhTW9kZWw6IG5leHRQcm9wcy5wcmVzZXREYXRhTW9kZWwsXG4gICAgICAgICAgICAgICAgbm9kZTogbmV4dFByb3BzLnByZXNldERhdGFNb2RlbC5nZXRSb290Tm9kZSgpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcblxuICAgICAgICB2YXIgZGF0YU1vZGVsID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5wcmVzZXREYXRhTW9kZWwpIHtcbiAgICAgICAgICAgIGRhdGFNb2RlbCA9IHRoaXMucHJvcHMucHJlc2V0RGF0YU1vZGVsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0YU1vZGVsID0gUHlkaW9EYXRhTW9kZWwuUmVtb3RlRGF0YU1vZGVsRmFjdG9yeSh0aGlzLnByb3BzLm5vZGVQcm92aWRlclByb3BlcnRpZXMpO1xuICAgICAgICB9XG4gICAgICAgIHZhciByb290Tm9kZSA9IGRhdGFNb2RlbC5nZXRSb290Tm9kZSgpO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5ub2RlQ2xpY2tlZCkge1xuICAgICAgICAgICAgLy8gbGVhZlxuICAgICAgICAgICAgdGhpcy5vcGVuRWRpdG9yID0gKGZ1bmN0aW9uIChub2RlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5ub2RlQ2xpY2tlZChub2RlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgLy8gZGlyXG4gICAgICAgICAgICBkYXRhTW9kZWwub2JzZXJ2ZShcInNlbGVjdGlvbl9jaGFuZ2VkXCIsIChmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWROb2RlcyA9IGV2ZW50Lm1lbW8uZ2V0U2VsZWN0ZWROb2RlcygpO1xuICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZE5vZGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLm5vZGVDbGlja2VkKHNlbGVjdGVkTm9kZXNbMF0pO1xuICAgICAgICAgICAgICAgICAgICBldmVudC5tZW1vLnNldFNlbGVjdGVkTm9kZXMoW10pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnJlbG9hZE9uU2VydmVyTWVzc2FnZSAmJiB0aGlzLnByb3BzLnB5ZGlvKSB7XG4gICAgICAgICAgICB0aGlzLl9zbU9icyA9IChmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoWE1MVXRpbHMuWFBhdGhTZWxlY3RTaW5nbGVOb2RlKGV2ZW50LCB0aGlzLnByb3BzLnJlbG9hZE9uU2VydmVyTWVzc2FnZSkpIHRoaXMucmVsb2FkKCk7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5weWRpby5vYnNlcnZlKFwic2VydmVyX21lc3NhZ2VcIiwgdGhpcy5fc21PYnMpO1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5weWRpby5vYnNlcnZlKFwic2VydmVyX21lc3NhZ2U6XCIgKyB0aGlzLnByb3BzLnJlbG9hZE9uU2VydmVyTWVzc2FnZSwgdGhpcy5yZWxvYWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IG5vZGU6IHJvb3ROb2RlLCBkYXRhTW9kZWw6IGRhdGFNb2RlbCB9O1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIGxlZ2VuZDtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMubGVnZW5kKSB7XG4gICAgICAgICAgICBsZWdlbmQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFwiZGl2XCIsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IFwic3VidGl0bGVcIiB9LFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMubGVnZW5kXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgXCJkaXZcIixcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiB0aGlzLnByb3BzLmhlaWdodEF1dG9XaXRoTWF4ID8gXCJcIiA6IFwibGF5b3V0LWZpbGwgdmVydGljYWwtbGF5b3V0XCIgfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX1NpbXBsZUxpc3QyW1wiZGVmYXVsdFwiXSwgX2V4dGVuZHMoe30sIHRoaXMucHJvcHMsIHtcbiAgICAgICAgICAgICAgICBvcGVuRWRpdG9yOiB0aGlzLm9wZW5FZGl0b3IsXG4gICAgICAgICAgICAgICAgcmVmOiBcImxpc3RcIixcbiAgICAgICAgICAgICAgICBzdHlsZTogT2JqZWN0LmFzc2lnbih7IGhlaWdodDogJzEwMCUnIH0sIHRoaXMucHJvcHMuc3R5bGUgfHwge30pLFxuICAgICAgICAgICAgICAgIG5vZGU6IHRoaXMuc3RhdGUubm9kZSxcbiAgICAgICAgICAgICAgICBkYXRhTW9kZWw6IHRoaXMuc3RhdGUuZGF0YU1vZGVsLFxuICAgICAgICAgICAgICAgIGFjdGlvbkJhckdyb3VwczogdGhpcy5wcm9wcy5hY3Rpb25CYXJHcm91cHMsXG4gICAgICAgICAgICAgICAgc2tpcFBhcmVudE5hdmlnYXRpb246IHRydWUsXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZU5vZGVSZWxvYWQ6IHRydWVcbiAgICAgICAgICAgIH0pKVxuICAgICAgICApO1xuICAgIH1cblxufSk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9yZWFjdFNjcm9sbGJhciA9IHJlcXVpcmUoJ3JlYWN0LXNjcm9sbGJhcicpO1xuXG52YXIgX3JlYWN0U2Nyb2xsYmFyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0U2Nyb2xsYmFyKTtcblxudmFyIF91dGlsTWVzc2FnZXNDb25zdW1lck1peGluID0gcmVxdWlyZSgnLi4vdXRpbC9NZXNzYWdlc0NvbnN1bWVyTWl4aW4nKTtcblxudmFyIF91dGlsTWVzc2FnZXNDb25zdW1lck1peGluMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3V0aWxNZXNzYWdlc0NvbnN1bWVyTWl4aW4pO1xuXG52YXIgX0xpc3RFbnRyeSA9IHJlcXVpcmUoJy4vTGlzdEVudHJ5Jyk7XG5cbnZhciBfVGFibGVMaXN0RW50cnkgPSByZXF1aXJlKCcuL1RhYmxlTGlzdEVudHJ5Jyk7XG5cbnZhciBfVGFibGVMaXN0RW50cnkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVGFibGVMaXN0RW50cnkpO1xuXG52YXIgX1RhYmxlTGlzdEhlYWRlciA9IHJlcXVpcmUoJy4vVGFibGVMaXN0SGVhZGVyJyk7XG5cbnZhciBfVGFibGVMaXN0SGVhZGVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1RhYmxlTGlzdEhlYWRlcik7XG5cbnZhciBfQ29uZmlndXJhYmxlTGlzdEVudHJ5ID0gcmVxdWlyZSgnLi9Db25maWd1cmFibGVMaXN0RW50cnknKTtcblxudmFyIF9Db25maWd1cmFibGVMaXN0RW50cnkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQ29uZmlndXJhYmxlTGlzdEVudHJ5KTtcblxudmFyIF9Tb3J0Q29sdW1ucyA9IHJlcXVpcmUoJy4vU29ydENvbHVtbnMnKTtcblxudmFyIF9Tb3J0Q29sdW1uczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Tb3J0Q29sdW1ucyk7XG5cbnZhciBfTGlzdFBhZ2luYXRvciA9IHJlcXVpcmUoJy4vTGlzdFBhZ2luYXRvcicpO1xuXG52YXIgX0xpc3RQYWdpbmF0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTGlzdFBhZ2luYXRvcik7XG5cbnZhciBfdmlld3NTaW1wbGVSZWFjdEFjdGlvbkJhciA9IHJlcXVpcmUoJy4uL3ZpZXdzL1NpbXBsZVJlYWN0QWN0aW9uQmFyJyk7XG5cbnZhciBfdmlld3NTaW1wbGVSZWFjdEFjdGlvbkJhcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF92aWV3c1NpbXBsZVJlYWN0QWN0aW9uQmFyKTtcblxudmFyIF9JbmxpbmVFZGl0b3IgPSByZXF1aXJlKCcuL0lubGluZUVkaXRvcicpO1xuXG52YXIgX0lubGluZUVkaXRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9JbmxpbmVFZGl0b3IpO1xuXG52YXIgX3ZpZXdzRW1wdHlTdGF0ZVZpZXcgPSByZXF1aXJlKCcuLi92aWV3cy9FbXB0eVN0YXRlVmlldycpO1xuXG52YXIgX3ZpZXdzRW1wdHlTdGF0ZVZpZXcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdmlld3NFbXB0eVN0YXRlVmlldyk7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG52YXIgSW5maW5pdGUgPSByZXF1aXJlKCdyZWFjdC1pbmZpbml0ZScpO1xuXG52YXIgRE9NVXRpbHMgPSByZXF1aXJlKCdweWRpby91dGlsL2RvbScpO1xudmFyIExhbmdVdGlscyA9IHJlcXVpcmUoJ3B5ZGlvL3V0aWwvbGFuZycpO1xudmFyIFB5ZGlvRGF0YU1vZGVsID0gcmVxdWlyZSgncHlkaW8vbW9kZWwvZGF0YS1tb2RlbCcpO1xudmFyIFBlcmlvZGljYWxFeGVjdXRlciA9IHJlcXVpcmUoJ3B5ZGlvL3V0aWwvcGVyaW9kaWNhbC1leGVjdXRlcicpO1xuXG4vKipcbiAqIEdlbmVyaWMgTGlzdCBjb21wb25lbnQsIHVzaW5nIEluZmluaXRlIGZvciBjZWxsIHZpcnR1YWxpemF0aW9uLCBwYWdpbmF0aW9uLCB2YXJpb3VzXG4gKiBkaXNwbGF5cywgZXRjLi4uIEl0IHByb3ZpZGVzIG1hbnkgaG9va3MgZm9yIHJlbmRlcmluZyBjZWxscyBvbi1kZW1hbmQuXG4gKi9cbnZhciBTaW1wbGVMaXN0ID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnU2ltcGxlTGlzdCcsXG5cbiAgICBtaXhpbnM6IFtfdXRpbE1lc3NhZ2VzQ29uc3VtZXJNaXhpbjJbJ2RlZmF1bHQnXV0sXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgaW5maW5pdGVTbGljZUNvdW50OiBSZWFjdC5Qcm9wVHlwZXMubnVtYmVyLFxuICAgICAgICBmaWx0ZXJOb2RlczogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGN1c3RvbVRvb2xiYXI6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgICAgIHRhYmxlS2V5czogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgYXV0b1JlZnJlc2g6IFJlYWN0LlByb3BUeXBlcy5udW1iZXIsXG4gICAgICAgIHJlbG9hZEF0Q3Vyc29yOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgY2xlYXJTZWxlY3Rpb25PblJlbG9hZDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIGhlaWdodEF1dG9XaXRoTWF4OiBSZWFjdC5Qcm9wVHlwZXMubnVtYmVyLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IFJlYWN0LlByb3BUeXBlcy5udW1iZXIsXG4gICAgICAgIG9ic2VydmVOb2RlUmVsb2FkOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgZGVmYXVsdEdyb3VwQnk6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIGRlZmF1bHRHcm91cEJ5TGFiZWw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIGRlZmF1bHRTb3J0aW5nSW5mbzogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcblxuICAgICAgICBza2lwUGFyZW50TmF2aWdhdGlvbjogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIHNraXBJbnRlcm5hbERhdGFNb2RlbDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIGRlbGF5SW5pdGlhbExvYWQ6IFJlYWN0LlByb3BUeXBlcy5udW1iZXIsXG5cbiAgICAgICAgZW50cnlFbmFibGVTZWxlY3RvcjogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIHJlbmRlckN1c3RvbUVudHJ5OiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgZW50cnlSZW5kZXJJY29uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgZW50cnlSZW5kZXJBY3Rpb25zOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgZW50cnlSZW5kZXJGaXJzdExpbmU6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBlbnRyeVJlbmRlclNlY29uZExpbmU6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBlbnRyeVJlbmRlclRoaXJkTGluZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGVudHJ5SGFuZGxlQ2xpY2tzOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgaGlkZVRvb2xiYXI6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBjb21wdXRlQWN0aW9uc0Zvck5vZGU6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBtdWx0aXBsZUFjdGlvbnM6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcblxuICAgICAgICBvcGVuRWRpdG9yOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgb3BlbkNvbGxlY3Rpb246IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuXG4gICAgICAgIGVsZW1lbnRTdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgcGFzc1Njcm9sbGluZ1N0YXRlVG9DaGlsZHJlbjogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIGVsZW1lbnRIZWlnaHQ6IFJlYWN0LlByb3BUeXBlcy5vbmVPZlR5cGUoW1JlYWN0LlByb3BUeXBlcy5udW1iZXIsIFJlYWN0LlByb3BUeXBlcy5vYmplY3RdKS5pc1JlcXVpcmVkXG5cbiAgICB9LFxuXG4gICAgc3RhdGljczoge1xuICAgICAgICBIRUlHSFRfT05FX0xJTkU6IDUwLFxuICAgICAgICBIRUlHSFRfVFdPX0xJTkVTOiA3MyxcbiAgICAgICAgQ0xJQ0tfVFlQRV9TSU1QTEU6ICdzaW1wbGUnLFxuICAgICAgICBDTElDS19UWVBFX0RPVUJMRTogJ2RvdWJsZScsXG4gICAgICAgIFBBUkVOVF9GT0xERVJfSUNPTjogJ21kaSBtZGktY2hldnJvbi1sZWZ0J1xuICAgIH0sXG5cbiAgICBnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uIGdldERlZmF1bHRQcm9wcygpIHtcbiAgICAgICAgcmV0dXJuIHsgaW5maW5pdGVTbGljZUNvdW50OiAzMCwgY2xlYXJTZWxlY3Rpb25PblJlbG9hZDogdHJ1ZSB9O1xuICAgIH0sXG5cbiAgICBjbGlja1JvdzogZnVuY3Rpb24gY2xpY2tSb3coZ3JpZFJvdywgZXZlbnQpIHtcbiAgICAgICAgdmFyIG5vZGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChncmlkUm93LnByb3BzKSB7XG4gICAgICAgICAgICBub2RlID0gZ3JpZFJvdy5wcm9wcy5kYXRhLm5vZGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBub2RlID0gZ3JpZFJvdztcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wcm9wcy5lbnRyeUhhbmRsZUNsaWNrcykge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5lbnRyeUhhbmRsZUNsaWNrcyhub2RlLCBTaW1wbGVMaXN0LkNMSUNLX1RZUEVfU0lNUExFLCBldmVudCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5vZGUuaXNMZWFmKCkgJiYgdGhpcy5wcm9wcy5vcGVuRWRpdG9yKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5vcGVuRWRpdG9yKG5vZGUpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB1bmlxdWVTZWxlY3Rpb24gPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICB1bmlxdWVTZWxlY3Rpb24uc2V0KG5vZGUsIHRydWUpO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGlvbjogdW5pcXVlU2VsZWN0aW9uIH0sIHRoaXMucmVidWlsZExvYWRlZEVsZW1lbnRzKTtcbiAgICAgICAgfSBlbHNlIGlmICghbm9kZS5pc0xlYWYoKSkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMub3BlbkNvbGxlY3Rpb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLm9wZW5Db2xsZWN0aW9uKG5vZGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmRhdGFNb2RlbC5zZXRTZWxlY3RlZE5vZGVzKFtub2RlXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgZG91YmxlQ2xpY2tSb3c6IGZ1bmN0aW9uIGRvdWJsZUNsaWNrUm93KGdyaWRSb3csIGV2ZW50KSB7XG4gICAgICAgIHZhciBub2RlID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoZ3JpZFJvdy5wcm9wcykge1xuICAgICAgICAgICAgbm9kZSA9IGdyaWRSb3cucHJvcHMuZGF0YS5ub2RlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbm9kZSA9IGdyaWRSb3c7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMuZW50cnlIYW5kbGVDbGlja3MpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuZW50cnlIYW5kbGVDbGlja3Mobm9kZSwgU2ltcGxlTGlzdC5DTElDS19UWVBFX0RPVUJMRSwgZXZlbnQpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIG9uQ29sdW1uU29ydDogZnVuY3Rpb24gb25Db2x1bW5Tb3J0KGNvbHVtbikge1xuICAgICAgICB2YXIgc3RhdGVTZXRDYWxsYmFjayA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMSB8fCBhcmd1bWVudHNbMV0gPT09IHVuZGVmaW5lZCA/IG51bGwgOiBhcmd1bWVudHNbMV07XG5cbiAgICAgICAgdmFyIHBhZ2luYXRpb24gPSB0aGlzLnByb3BzLm5vZGUuZ2V0TWV0YWRhdGEoKS5nZXQoJ3BhZ2luYXRpb25EYXRhJyk7XG4gICAgICAgIGlmIChwYWdpbmF0aW9uICYmIHBhZ2luYXRpb24uZ2V0KCd0b3RhbCcpID4gMSAmJiBwYWdpbmF0aW9uLmdldCgncmVtb3RlX29yZGVyJykpIHtcblxuICAgICAgICAgICAgdmFyIGRpciA9ICdhc2MnO1xuICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMubm9kZS5nZXRNZXRhZGF0YSgpLmdldCgncGFnaW5hdGlvbkRhdGEnKS5nZXQoJ2N1cnJlbnRPcmRlckRpcicpKSB7XG4gICAgICAgICAgICAgICAgZGlyID0gdGhpcy5wcm9wcy5ub2RlLmdldE1ldGFkYXRhKCkuZ2V0KCdwYWdpbmF0aW9uRGF0YScpLmdldCgnY3VycmVudE9yZGVyRGlyJykgPT09ICdhc2MnID8gJ2Rlc2MnIDogJ2FzYyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgb3JkZXJEYXRhID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgb3JkZXJEYXRhLnNldCgnb3JkZXJfY29sdW1uJywgY29sdW1uWydyZW1vdGVTb3J0QXR0cmlidXRlJ10gPyBjb2x1bW4ucmVtb3RlU29ydEF0dHJpYnV0ZSA6IGNvbHVtbi5uYW1lKTtcbiAgICAgICAgICAgIG9yZGVyRGF0YS5zZXQoJ29yZGVyX2RpcmVjdGlvbicsIGRpcik7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm5vZGUuZ2V0TWV0YWRhdGEoKS5zZXQoXCJyZW1vdGVfb3JkZXJcIiwgb3JkZXJEYXRhKTtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuZGF0YU1vZGVsLnJlcXVpcmVDb250ZXh0Q2hhbmdlKHRoaXMucHJvcHMubm9kZSwgdHJ1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIHZhciBhdHQgPSBjb2x1bW5bJ3NvcnRBdHRyaWJ1dGUnXSA/IGNvbHVtblsnc29ydEF0dHJpYnV0ZSddIDogY29sdW1uLm5hbWU7XG4gICAgICAgICAgICB2YXIgc29ydGluZ0luZm8gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB2YXIgX3N0YXRlJHNvcnRpbmdJbmZvID0gdGhpcy5zdGF0ZS5zb3J0aW5nSW5mbztcbiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGUgPSBfc3RhdGUkc29ydGluZ0luZm8uYXR0cmlidXRlO1xuICAgICAgICAgICAgdmFyIGRpcmVjdGlvbiA9IF9zdGF0ZSRzb3J0aW5nSW5mby5kaXJlY3Rpb247XG5cbiAgICAgICAgICAgIGlmIChhdHRyaWJ1dGUgPT09IGF0dCAmJiBkaXJlY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBpZiAoZGlyZWN0aW9uID09PSAnYXNjJykge1xuICAgICAgICAgICAgICAgICAgICAvLyBTd2l0Y2ggZGlyZWN0aW9uXG4gICAgICAgICAgICAgICAgICAgIHNvcnRpbmdJbmZvID0geyBhdHRyaWJ1dGU6IGF0dCwgc29ydFR5cGU6IGNvbHVtbi5zb3J0VHlwZSwgZGlyZWN0aW9uOiAnZGVzYycgfTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBSZXNldCBzb3J0aW5nXG4gICAgICAgICAgICAgICAgICAgIHNvcnRpbmdJbmZvID0gdGhpcy5wcm9wcy5kZWZhdWx0U29ydGluZ0luZm8gfHwge307XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzb3J0aW5nSW5mbyA9IHsgYXR0cmlidXRlOiBhdHQsIHNvcnRUeXBlOiBjb2x1bW4uc29ydFR5cGUsIGRpcmVjdGlvbjogJ2FzYycgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzb3J0aW5nSW5mbzogc29ydGluZ0luZm8gfSwgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlYnVpbGRMb2FkZWRFbGVtZW50cygpO1xuICAgICAgICAgICAgICAgIGlmIChzdGF0ZVNldENhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlU2V0Q2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBjb21wdXRlU2VsZWN0aW9uRnJvbUN1cnJlbnRQbHVzVGFyZ2V0Tm9kZTogZnVuY3Rpb24gY29tcHV0ZVNlbGVjdGlvbkZyb21DdXJyZW50UGx1c1RhcmdldE5vZGUoY3VycmVudFNlbGVjdGlvbiwgdGFyZ2V0Tm9kZSkge1xuXG4gICAgICAgIHZhciBjdXJyZW50SW5kZXhTdGFydCA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGN1cnJlbnRJbmRleEVuZCA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG5vZGVCZWZvcmUgPSBmYWxzZTtcbiAgICAgICAgaWYgKCF0aGlzLmluZGV4ZWRFbGVtZW50cykge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIHZhciBmaXJzdFNlbGVjdGVkID0gY3VycmVudFNlbGVjdGlvblswXTtcbiAgICAgICAgdmFyIGxhc3RTZWxlY3RlZCA9IGN1cnJlbnRTZWxlY3Rpb25bY3VycmVudFNlbGVjdGlvbi5sZW5ndGggLSAxXTtcbiAgICAgICAgdmFyIG5ld1NlbGVjdGlvbiA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuaW5kZXhlZEVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudEluZGV4U3RhcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG5ld1NlbGVjdGlvbi5wdXNoKHRoaXMuaW5kZXhlZEVsZW1lbnRzW2ldLm5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaW5kZXhlZEVsZW1lbnRzW2ldLm5vZGUgPT09IHRhcmdldE5vZGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudEluZGV4U3RhcnQgIT09IHVuZGVmaW5lZCAmJiBjdXJyZW50SW5kZXhFbmQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50SW5kZXhFbmQgPSBpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY3VycmVudEluZGV4U3RhcnQgPSBpO1xuICAgICAgICAgICAgICAgIG5vZGVCZWZvcmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIG5ld1NlbGVjdGlvbi5wdXNoKHRoaXMuaW5kZXhlZEVsZW1lbnRzW2ldLm5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaW5kZXhlZEVsZW1lbnRzW2ldLm5vZGUgPT09IGZpcnN0U2VsZWN0ZWQgJiYgY3VycmVudEluZGV4U3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRJbmRleFN0YXJ0ID0gaTtcbiAgICAgICAgICAgICAgICBuZXdTZWxlY3Rpb24ucHVzaCh0aGlzLmluZGV4ZWRFbGVtZW50c1tpXS5ub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmluZGV4ZWRFbGVtZW50c1tpXS5ub2RlID09PSBsYXN0U2VsZWN0ZWQgJiYgbm9kZUJlZm9yZSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRJbmRleEVuZCA9IGk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ld1NlbGVjdGlvbjtcbiAgICB9LFxuXG4gICAgb25LZXlEb3duOiBmdW5jdGlvbiBvbktleURvd24oZSkge1xuICAgICAgICB2YXIgY3VycmVudEluZGV4U3RhcnQgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICBjdXJyZW50SW5kZXhFbmQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHZhciBjb250ZXh0SG9sZGVyID0gd2luZG93LnB5ZGlvLmdldENvbnRleHRIb2xkZXIoKTtcbiAgICAgICAgdmFyIGVsZW1lbnRzUGVyTGluZSA9IHRoaXMucHJvcHMuZWxlbWVudHNQZXJMaW5lIHx8IDE7XG4gICAgICAgIHZhciBzaGlmdEtleSA9IGUuc2hpZnRLZXk7XG4gICAgICAgIHZhciBrZXkgPSBlLmtleTtcblxuICAgICAgICBpZiAoY29udGV4dEhvbGRlci5pc0VtcHR5KCkgfHwgIXRoaXMuaW5kZXhlZEVsZW1lbnRzKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGRvd25LZXlzID0gWydBcnJvd0Rvd24nLCAnQXJyb3dSaWdodCcsICdQYWdlRG93bicsICdFbmQnXTtcblxuICAgICAgICB2YXIgcG9zaXRpb24gPSBzaGlmdEtleSAmJiBkb3duS2V5cy5pbmRleE9mKGtleSkgPiAtMSA/ICdmaXJzdCcgOiAnbGFzdCc7XG4gICAgICAgIHZhciBjdXJyZW50U2VsZWN0aW9uID0gY29udGV4dEhvbGRlci5nZXRTZWxlY3RlZE5vZGVzKCk7XG5cbiAgICAgICAgdmFyIGZpcnN0U2VsZWN0ZWQgPSBjdXJyZW50U2VsZWN0aW9uWzBdO1xuICAgICAgICB2YXIgbGFzdFNlbGVjdGVkID0gY3VycmVudFNlbGVjdGlvbltjdXJyZW50U2VsZWN0aW9uLmxlbmd0aCAtIDFdO1xuXG4gICAgICAgIGlmIChrZXkgPT09ICdFbnRlcicpIHtcbiAgICAgICAgICAgIHRoaXMuZG91YmxlQ2xpY2tSb3coZmlyc3RTZWxlY3RlZCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGtleSA9PT0gJ0RlbGV0ZScgJiYgZ2xvYmFsLnB5ZGlvLkNvbnRyb2xsZXIuZmlyZUFjdGlvbkJ5S2V5KCdrZXlfZGVsZXRlJykpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5pbmRleGVkRWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmluZGV4ZWRFbGVtZW50c1tpXS5ub2RlID09PSBmaXJzdFNlbGVjdGVkKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudEluZGV4U3RhcnQgPSBpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaW5kZXhlZEVsZW1lbnRzW2ldLm5vZGUgPT09IGxhc3RTZWxlY3RlZCkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRJbmRleEVuZCA9IGk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHNlbGVjdGlvbkluZGV4ID0gdW5kZWZpbmVkO1xuICAgICAgICB2YXIgbWF4SW5kZXggPSB0aGlzLmluZGV4ZWRFbGVtZW50cy5sZW5ndGggLSAxO1xuICAgICAgICB2YXIgaW5jcmVtZW50ID0ga2V5ID09PSAnUGFnZURvd24nIHx8IGtleSA9PT0gJ1BhZ2VVcCcgPyAxMCA6IDE7XG4gICAgICAgIGlmIChrZXkgPT09ICdBcnJvd0Rvd24nIHx8IGtleSA9PT0gJ1BhZ2VEb3duJykge1xuICAgICAgICAgICAgc2VsZWN0aW9uSW5kZXggPSBNYXRoLm1pbihjdXJyZW50SW5kZXhFbmQgKyBlbGVtZW50c1BlckxpbmUgKiBpbmNyZW1lbnQsIG1heEluZGV4KTtcbiAgICAgICAgfSBlbHNlIGlmIChrZXkgPT09ICdBcnJvd1VwJyB8fCBrZXkgPT09ICdQYWdlVXAnKSB7XG4gICAgICAgICAgICBzZWxlY3Rpb25JbmRleCA9IE1hdGgubWF4KGN1cnJlbnRJbmRleFN0YXJ0IC0gZWxlbWVudHNQZXJMaW5lICogaW5jcmVtZW50LCAwKTtcbiAgICAgICAgfSBlbHNlIGlmIChrZXkgPT09ICdIb21lJykge1xuICAgICAgICAgICAgc2VsZWN0aW9uSW5kZXggPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGtleSA9PT0gJ0VuZCcpIHtcbiAgICAgICAgICAgIHNlbGVjdGlvbkluZGV4ID0gbWF4SW5kZXg7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVsZW1lbnRzUGVyTGluZSA+IDEpIHtcbiAgICAgICAgICAgIGlmIChrZXkgPT09ICdBcnJvd1JpZ2h0Jykge1xuICAgICAgICAgICAgICAgIHNlbGVjdGlvbkluZGV4ID0gY3VycmVudEluZGV4RW5kICsgMTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSAnQXJyb3dMZWZ0Jykge1xuICAgICAgICAgICAgICAgIHNlbGVjdGlvbkluZGV4ID0gY3VycmVudEluZGV4U3RhcnQgLSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNoaWZ0S2V5ICYmIHNlbGVjdGlvbkluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHZhciBtaW4gPSBNYXRoLm1pbihjdXJyZW50SW5kZXhTdGFydCwgY3VycmVudEluZGV4RW5kLCBzZWxlY3Rpb25JbmRleCk7XG4gICAgICAgICAgICB2YXIgbWF4ID0gTWF0aC5tYXgoY3VycmVudEluZGV4U3RhcnQsIGN1cnJlbnRJbmRleEVuZCwgc2VsZWN0aW9uSW5kZXgpO1xuICAgICAgICAgICAgaWYgKG1pbiAhPT0gbWF4KSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlbGVjdGlvbiA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSBtaW47IGkgPCBtYXggKyAxOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaW5kZXhlZEVsZW1lbnRzW2ldKSBzZWxlY3Rpb24ucHVzaCh0aGlzLmluZGV4ZWRFbGVtZW50c1tpXS5ub2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29udGV4dEhvbGRlci5zZXRTZWxlY3RlZE5vZGVzKHNlbGVjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pbmRleGVkRWxlbWVudHNbc2VsZWN0aW9uSW5kZXhdICYmIHRoaXMuaW5kZXhlZEVsZW1lbnRzW3NlbGVjdGlvbkluZGV4XS5ub2RlKSB7XG4gICAgICAgICAgICBjb250ZXh0SG9sZGVyLnNldFNlbGVjdGVkTm9kZXMoW3RoaXMuaW5kZXhlZEVsZW1lbnRzW3NlbGVjdGlvbkluZGV4XS5ub2RlXSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiBnZXRJbml0aWFsU3RhdGUoKSB7XG4gICAgICAgIHRoaXMuYWN0aW9uc0NhY2hlID0geyBtdWx0aXBsZTogbmV3IE1hcCgpIH07XG4gICAgICAgIGlmICghdGhpcy5wcm9wcy5za2lwSW50ZXJuYWxEYXRhTW9kZWwpIHtcbiAgICAgICAgICAgIHRoaXMuZG0gPSBuZXcgUHlkaW9EYXRhTW9kZWwoKTtcbiAgICAgICAgICAgIHRoaXMuZG0uc2V0Um9vdE5vZGUodGhpcy5wcm9wcy5kYXRhTW9kZWwuZ2V0Q29udGV4dE5vZGUoKSk7XG4gICAgICAgICAgICB0aGlzLmRtLnNldENvbnRleHROb2RlKHRoaXMucHJvcHMuZGF0YU1vZGVsLmdldENvbnRleHROb2RlKCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kbSA9IHRoaXMucHJvcHMuZGF0YU1vZGVsO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzb3J0aW5nSW5mbyA9IHRoaXMucHJvcHMuZGVmYXVsdFNvcnRpbmdJbmZvIHx8IG51bGw7XG4gICAgICAgIHZhciBzdGF0ZSA9IHtcbiAgICAgICAgICAgIGxvYWRlZDogdGhpcy5wcm9wcy5ub2RlLmlzTG9hZGVkKCksXG4gICAgICAgICAgICBsb2FkaW5nOiAhdGhpcy5wcm9wcy5ub2RlLmlzTG9hZGVkKCksXG4gICAgICAgICAgICBzaG93U2VsZWN0b3I6IGZhbHNlLFxuICAgICAgICAgICAgZWxlbWVudHM6IHRoaXMucHJvcHMubm9kZS5pc0xvYWRlZCgpID8gdGhpcy5idWlsZEVsZW1lbnRzKHNvcnRpbmdJbmZvLCAwLCB0aGlzLnByb3BzLmluZmluaXRlU2xpY2VDb3VudCkgOiBbXSxcbiAgICAgICAgICAgIGNvbnRhaW5lckhlaWdodDogdGhpcy5wcm9wcy5jb250YWluZXJIZWlnaHQgPyB0aGlzLnByb3BzLmNvbnRhaW5lckhlaWdodCA6IHRoaXMucHJvcHMuaGVpZ2h0QXV0b1dpdGhNYXggPyAwIDogNTAwLFxuICAgICAgICAgICAgc29ydGluZ0luZm86IHNvcnRpbmdJbmZvXG4gICAgICAgIH07XG4gICAgICAgIGlmICh0aGlzLnByb3BzLmVsZW1lbnRIZWlnaHQgaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICAgICAgICAgIHN0YXRlLmVsZW1lbnRIZWlnaHQgPSB0aGlzLmNvbXB1dGVFbGVtZW50SGVpZ2h0UmVzcG9uc2l2ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRlLmluZmluaXRlTG9hZEJlZ2luQm90dG9tT2Zmc2V0ID0gMjAwO1xuICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHM6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgdGhpcy5pbmRleGVkRWxlbWVudHMgPSBudWxsO1xuICAgICAgICB2YXIgY3VycmVudExlbmd0aCA9IE1hdGgubWF4KHRoaXMuc3RhdGUuZWxlbWVudHMubGVuZ3RoLCBuZXh0UHJvcHMuaW5maW5pdGVTbGljZUNvdW50KTtcbiAgICAgICAgdmFyIHNvcnRpbmdJbmZvID0gdGhpcy5zdGF0ZS5zb3J0aW5nSW5mbyB8fCBuZXh0UHJvcHMuZGVmYXVsdFNvcnRpbmdJbmZvIHx8IG51bGw7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgbG9hZGVkOiBuZXh0UHJvcHMubm9kZS5pc0xvYWRlZCgpLFxuICAgICAgICAgICAgbG9hZGluZzogIW5leHRQcm9wcy5ub2RlLmlzTG9hZGVkKCksXG4gICAgICAgICAgICBzaG93U2VsZWN0b3I6IGZhbHNlLFxuICAgICAgICAgICAgZWxlbWVudHM6IG5leHRQcm9wcy5ub2RlLmlzTG9hZGVkKCkgPyB0aGlzLmJ1aWxkRWxlbWVudHMoc29ydGluZ0luZm8sIDAsIGN1cnJlbnRMZW5ndGgsIG5leHRQcm9wcy5ub2RlKSA6IFtdLFxuICAgICAgICAgICAgaW5maW5pdGVMb2FkQmVnaW5Cb3R0b21PZmZzZXQ6IDIwMCxcbiAgICAgICAgICAgIHNvcnRpbmdJbmZvOiBzb3J0aW5nSW5mb1xuICAgICAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAobmV4dFByb3BzLm5vZGUuaXNMb2FkZWQoKSkgX3RoaXMudXBkYXRlSW5maW5pdGVDb250YWluZXJIZWlnaHQoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghbmV4dFByb3BzLmF1dG9SZWZyZXNoICYmIHRoaXMucmVmcmVzaEludGVydmFsKSB7XG4gICAgICAgICAgICB3aW5kb3cuY2xlYXJJbnRlcnZhbCh0aGlzLnJlZnJlc2hJbnRlcnZhbCk7XG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hJbnRlcnZhbCA9IG51bGw7XG4gICAgICAgIH0gZWxzZSBpZiAobmV4dFByb3BzLmF1dG9SZWZyZXNoICYmICF0aGlzLnJlZnJlc2hJbnRlcnZhbCkge1xuICAgICAgICAgICAgdGhpcy5yZWZyZXNoSW50ZXJ2YWwgPSB3aW5kb3cuc2V0SW50ZXJ2YWwodGhpcy5yZWxvYWQsIG5leHRQcm9wcy5hdXRvUmVmcmVzaCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wYXRjaEluZmluaXRlR3JpZChuZXh0UHJvcHMuZWxlbWVudHNQZXJMaW5lKTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMubm9kZSAmJiBuZXh0UHJvcHMubm9kZSAhPT0gdGhpcy5wcm9wcy5ub2RlKSB7XG4gICAgICAgICAgICB0aGlzLm9ic2VydmVOb2RlQ2hpbGRyZW4odGhpcy5wcm9wcy5ub2RlLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fbWFudWFsU2Nyb2xsUGUpIHtcbiAgICAgICAgICAgIHRoaXMuX21hbnVhbFNjcm9sbFBlLnN0b3AoKTtcbiAgICAgICAgICAgIHRoaXMuX21hbnVhbFNjcm9sbFBlID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBvYnNlcnZlTm9kZUNoaWxkcmVuOiBmdW5jdGlvbiBvYnNlcnZlTm9kZUNoaWxkcmVuKG5vZGUpIHtcbiAgICAgICAgdmFyIHN0b3AgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IGFyZ3VtZW50c1sxXTtcblxuICAgICAgICBpZiAoc3RvcCAmJiAhdGhpcy5fY2hpbGRyZW5PYnNlcnZlcikgcmV0dXJuO1xuXG4gICAgICAgIGlmICghdGhpcy5fY2hpbGRyZW5PYnNlcnZlcikge1xuICAgICAgICAgICAgdGhpcy5fY2hpbGRyZW5PYnNlcnZlciA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbmRleGVkRWxlbWVudHMgPSBudWxsO1xuICAgICAgICAgICAgICAgIHRoaXMucmVidWlsZExvYWRlZEVsZW1lbnRzKCk7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5fY2hpbGRyZW5BY3Rpb25zT2JzZXJ2ZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NoaWxkcmVuQWN0aW9uc09ic2VydmVyID0gKGZ1bmN0aW9uIChldmVudE1lbW8pIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnRNZW1vLnR5cGUgPT09ICdwcm9tcHQtcmVuYW1lJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgaW5saW5lRWRpdGlvbkZvck5vZGU6IGV2ZW50TWVtby5jaGlsZCwgaW5saW5lRWRpdGlvbkNhbGxiYWNrOiBldmVudE1lbW8uY2FsbGJhY2sgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkuYmluZCh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RvcCkge1xuICAgICAgICAgICAgbm9kZS5zdG9wT2JzZXJ2aW5nKFwiY2hpbGRfYWRkZWRcIiwgdGhpcy5fY2hpbGRyZW5PYnNlcnZlcik7XG4gICAgICAgICAgICBub2RlLnN0b3BPYnNlcnZpbmcoXCJjaGlsZF9yZW1vdmVkXCIsIHRoaXMuX2NoaWxkcmVuT2JzZXJ2ZXIpO1xuICAgICAgICAgICAgbm9kZS5zdG9wT2JzZXJ2aW5nKFwiY2hpbGRfbm9kZV9hY3Rpb25cIiwgdGhpcy5fY2hpbGRyZW5BY3Rpb25zT2JzZXJ2ZXIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbm9kZS5vYnNlcnZlKFwiY2hpbGRfYWRkZWRcIiwgdGhpcy5fY2hpbGRyZW5PYnNlcnZlcik7XG4gICAgICAgICAgICBub2RlLm9ic2VydmUoXCJjaGlsZF9yZW1vdmVkXCIsIHRoaXMuX2NoaWxkcmVuT2JzZXJ2ZXIpO1xuICAgICAgICAgICAgbm9kZS5vYnNlcnZlKFwiY2hpbGRfbm9kZV9hY3Rpb25cIiwgdGhpcy5fY2hpbGRyZW5BY3Rpb25zT2JzZXJ2ZXIpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIF9sb2FkTm9kZUlmTm90TG9hZGVkOiBmdW5jdGlvbiBfbG9hZE5vZGVJZk5vdExvYWRlZCgpIHtcbiAgICAgICAgdmFyIG5vZGUgPSB0aGlzLnByb3BzLm5vZGU7XG5cbiAgICAgICAgaWYgKCFub2RlLmlzTG9hZGVkKCkpIHtcbiAgICAgICAgICAgIG5vZGUub2JzZXJ2ZU9uY2UoXCJsb2FkZWRcIiwgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNNb3VudGVkKCkpIHJldHVybjtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5ub2RlID09PSBub2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub2JzZXJ2ZU5vZGVDaGlsZHJlbihub2RlKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2FkZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBsb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzOiB0aGlzLmJ1aWxkRWxlbWVudHModGhpcy5zdGF0ZS5zb3J0aW5nSW5mbywgMCwgdGhpcy5wcm9wcy5pbmZpbml0ZVNsaWNlQ291bnQpXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5oZWlnaHRBdXRvV2l0aE1heCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUluZmluaXRlQ29udGFpbmVySGVpZ2h0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICBub2RlLmxvYWQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMub2JzZXJ2ZU5vZGVDaGlsZHJlbihub2RlKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBfbG9hZGluZ0xpc3RlbmVyOiBmdW5jdGlvbiBfbG9hZGluZ0xpc3RlbmVyKCkge1xuICAgICAgICB0aGlzLm9ic2VydmVOb2RlQ2hpbGRyZW4odGhpcy5wcm9wcy5ub2RlLCB0cnVlKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGxvYWRlZDogZmFsc2UsIGxvYWRpbmc6IHRydWUgfSk7XG4gICAgICAgIHRoaXMuaW5kZXhlZEVsZW1lbnRzID0gbnVsbDtcbiAgICB9LFxuICAgIF9sb2FkZWRMaXN0ZW5lcjogZnVuY3Rpb24gX2xvYWRlZExpc3RlbmVyKCkge1xuICAgICAgICB2YXIgY3VycmVudExlbmd0aCA9IE1hdGgubWF4KHRoaXMuc3RhdGUuZWxlbWVudHMubGVuZ3RoLCB0aGlzLnByb3BzLmluZmluaXRlU2xpY2VDb3VudCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgbG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgICBlbGVtZW50czogdGhpcy5idWlsZEVsZW1lbnRzKHRoaXMuc3RhdGUuc29ydGluZ0luZm8sIDAsIGN1cnJlbnRMZW5ndGgsIHRoaXMucHJvcHMubm9kZSlcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLmhlaWdodEF1dG9XaXRoTWF4KSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUluZmluaXRlQ29udGFpbmVySGVpZ2h0KCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vYnNlcnZlTm9kZUNoaWxkcmVuKHRoaXMucHJvcHMubm9kZSk7XG4gICAgfSxcblxuICAgIHJlbG9hZDogZnVuY3Rpb24gcmVsb2FkKCkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5yZWxvYWRBdEN1cnNvciAmJiB0aGlzLl9jdXJyZW50Q3Vyc29yKSB7XG4gICAgICAgICAgICB0aGlzLmxvYWRTdGFydGluZ0F0Q3Vyc29yKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMuY2xlYXJTZWxlY3Rpb25PblJlbG9hZCkge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5kYXRhTW9kZWwuc2V0U2VsZWN0ZWROb2RlcyhbXSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbG9hZGluZ0xpc3RlbmVyKCk7XG4gICAgICAgIHRoaXMucHJvcHMubm9kZS5vYnNlcnZlT25jZShcImxvYWRlZFwiLCB0aGlzLl9sb2FkZWRMaXN0ZW5lcik7XG4gICAgICAgIHRoaXMucHJvcHMubm9kZS5yZWxvYWQoKTtcbiAgICB9LFxuXG4gICAgbG9hZFN0YXJ0aW5nQXRDdXJzb3I6IGZ1bmN0aW9uIGxvYWRTdGFydGluZ0F0Q3Vyc29yKCkge1xuICAgICAgICB0aGlzLl9sb2FkaW5nTGlzdGVuZXIoKTtcbiAgICAgICAgdmFyIG5vZGUgPSB0aGlzLnByb3BzLm5vZGU7XG4gICAgICAgIHZhciBjYWNoZWRDaGlsZHJlbiA9IG5vZGUuZ2V0Q2hpbGRyZW4oKTtcbiAgICAgICAgdmFyIG5ld0NoaWxkcmVuID0gW107XG4gICAgICAgIG5vZGUub2JzZXJ2ZU9uY2UoXCJsb2FkZWRcIiwgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciByZW9yZGVyZWRDaGlsZHJlbiA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIG5ld0NoaWxkcmVuLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgICAgIHJlb3JkZXJlZENoaWxkcmVuLnNldChjLmdldFBhdGgoKSwgYyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNhY2hlZENoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICByZW9yZGVyZWRDaGlsZHJlbi5zZXQoYy5nZXRQYXRoKCksIGMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBub2RlLl9jaGlsZHJlbiA9IHJlb3JkZXJlZENoaWxkcmVuO1xuICAgICAgICAgICAgdGhpcy5fbG9hZGVkTGlzdGVuZXIoKTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgIG5vZGUuc2V0TG9hZGVkKGZhbHNlKTtcbiAgICAgICAgbm9kZS5vYnNlcnZlKFwiY2hpbGRfYWRkZWRcIiwgZnVuY3Rpb24gKG5ld0NoaWxkKSB7XG4gICAgICAgICAgICBuZXdDaGlsZHJlbi5wdXNoKG5vZGUuX2NoaWxkcmVuLmdldChuZXdDaGlsZCkpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wcm9wcy5ub2RlLmxvYWQobnVsbCwgeyBjdXJzb3I6IHRoaXMuX2N1cnJlbnRDdXJzb3IgfSk7XG4gICAgfSxcblxuICAgIHdpcmVSZWxvYWRMaXN0ZW5lcnM6IGZ1bmN0aW9uIHdpcmVSZWxvYWRMaXN0ZW5lcnMoKSB7XG4gICAgICAgIHRoaXMud3JhcHBlZExvYWRpbmcgPSB0aGlzLl9sb2FkaW5nTGlzdGVuZXI7XG4gICAgICAgIHRoaXMud3JhcHBlZExvYWRlZCA9IHRoaXMuX2xvYWRlZExpc3RlbmVyO1xuICAgICAgICB0aGlzLnByb3BzLm5vZGUub2JzZXJ2ZShcImxvYWRpbmdcIiwgdGhpcy53cmFwcGVkTG9hZGluZyk7XG4gICAgICAgIHRoaXMucHJvcHMubm9kZS5vYnNlcnZlKFwibG9hZGVkXCIsIHRoaXMud3JhcHBlZExvYWRlZCk7XG4gICAgfSxcbiAgICBzdG9wUmVsb2FkTGlzdGVuZXJzOiBmdW5jdGlvbiBzdG9wUmVsb2FkTGlzdGVuZXJzKCkge1xuICAgICAgICB0aGlzLnByb3BzLm5vZGUuc3RvcE9ic2VydmluZyhcImxvYWRpbmdcIiwgdGhpcy53cmFwcGVkTG9hZGluZyk7XG4gICAgICAgIHRoaXMucHJvcHMubm9kZS5zdG9wT2JzZXJ2aW5nKFwibG9hZGVkXCIsIHRoaXMud3JhcHBlZExvYWRlZCk7XG4gICAgfSxcblxuICAgIHRvZ2dsZVNlbGVjdG9yOiBmdW5jdGlvbiB0b2dnbGVTZWxlY3RvcigpIHtcbiAgICAgICAgLy8gRm9yY2UgcmVidWlsZCBlbGVtZW50c1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNob3dTZWxlY3RvcjogIXRoaXMuc3RhdGUuc2hvd1NlbGVjdG9yLFxuICAgICAgICAgICAgc2VsZWN0aW9uOiBuZXcgTWFwKClcbiAgICAgICAgfSwgdGhpcy5yZWJ1aWxkTG9hZGVkRWxlbWVudHMpO1xuICAgIH0sXG5cbiAgICB0b2dnbGVTZWxlY3Rpb246IGZ1bmN0aW9uIHRvZ2dsZVNlbGVjdGlvbihub2RlKSB7XG4gICAgICAgIHZhciBzZWxlY3Rpb24gPSB0aGlzLnN0YXRlLnNlbGVjdGlvbiB8fCBuZXcgTWFwKCk7XG4gICAgICAgIGlmIChzZWxlY3Rpb24uZ2V0KG5vZGUpKSBzZWxlY3Rpb25bJ2RlbGV0ZSddKG5vZGUpO2Vsc2Ugc2VsZWN0aW9uLnNldChub2RlLCB0cnVlKTtcbiAgICAgICAgaWYgKHRoaXMucmVmcy5hbGxfc2VsZWN0b3IpIHRoaXMucmVmcy5hbGxfc2VsZWN0b3Iuc2V0Q2hlY2tlZChmYWxzZSk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2VsZWN0aW9uOiBzZWxlY3Rpb25cbiAgICAgICAgfSwgdGhpcy5yZWJ1aWxkTG9hZGVkRWxlbWVudHMpO1xuICAgIH0sXG5cbiAgICBzZWxlY3RBbGw6IGZ1bmN0aW9uIHNlbGVjdEFsbCgpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgaWYgKHRoaXMucmVmcy5hbGxfc2VsZWN0b3IgJiYgIXRoaXMucmVmcy5hbGxfc2VsZWN0b3IuaXNDaGVja2VkKCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3Rpb246IG5ldyBNYXAoKSB9LCB0aGlzLnJlYnVpbGRMb2FkZWRFbGVtZW50cyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBzZWxlY3Rpb24gPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICAgICAgX3RoaXMyLnByb3BzLm5vZGUuZ2V0Q2hpbGRyZW4oKS5mb3JFYWNoKChmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuZmlsdGVyTm9kZXMgJiYgIXRoaXMucHJvcHMuZmlsdGVyTm9kZXMoY2hpbGQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLmlzTGVhZigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb24uc2V0KGNoaWxkLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pLmJpbmQoX3RoaXMyKSk7XG4gICAgICAgICAgICAgICAgaWYgKF90aGlzMi5yZWZzLmFsbF9zZWxlY3RvcikgX3RoaXMyLnJlZnMuYWxsX3NlbGVjdG9yLnNldENoZWNrZWQodHJ1ZSk7XG4gICAgICAgICAgICAgICAgX3RoaXMyLnNldFN0YXRlKHsgc2VsZWN0aW9uOiBzZWxlY3Rpb24gfSwgX3RoaXMyLnJlYnVpbGRMb2FkZWRFbGVtZW50cyk7XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGFwcGx5TXVsdGlwbGVBY3Rpb246IGZ1bmN0aW9uIGFwcGx5TXVsdGlwbGVBY3Rpb24oZXYpIHtcbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlLnNlbGVjdGlvbiB8fCAhdGhpcy5zdGF0ZS5zZWxlY3Rpb24uc2l6ZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciBhY3Rpb25OYW1lID0gZXYuY3VycmVudFRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtYWN0aW9uJyk7XG4gICAgICAgIHZhciBkbSA9IHRoaXMuZG0gfHwgbmV3IFB5ZGlvRGF0YU1vZGVsKCk7XG4gICAgICAgIGRtLnNldENvbnRleHROb2RlKHRoaXMucHJvcHMubm9kZSk7XG4gICAgICAgIHZhciBzZWxOb2RlcyA9IFtdO1xuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGlvbi5mb3JFYWNoKGZ1bmN0aW9uICh2LCBub2RlKSB7XG4gICAgICAgICAgICBzZWxOb2Rlcy5wdXNoKG5vZGUpO1xuICAgICAgICB9KTtcbiAgICAgICAgZG0uc2V0U2VsZWN0ZWROb2RlcyhzZWxOb2Rlcyk7XG4gICAgICAgIHZhciBhID0gdGhpcy5wcm9wcy5weWRpby5Db250cm9sbGVyLmdldEFjdGlvbkJ5TmFtZShhY3Rpb25OYW1lKTtcbiAgICAgICAgYS5maXJlQ29udGV4dENoYW5nZShkbSwgdHJ1ZSwgdGhpcy5wcm9wcy5weWRpby51c2VyKTtcbiAgICAgICAgYS5hcHBseShbZG1dKTtcblxuICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICB9LFxuXG4gICAgZ2V0QWN0aW9uc0Zvck5vZGU6IGZ1bmN0aW9uIGdldEFjdGlvbnNGb3JOb2RlKGRtLCBub2RlKSB7XG4gICAgICAgIGlmICghdGhpcy5wcm9wcy5jb21wdXRlQWN0aW9uc0Zvck5vZGUpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY2FjaGVLZXkgPSBub2RlLmlzTGVhZigpID8gJ2ZpbGUtJyArIG5vZGUuZ2V0QWp4cE1pbWUoKSA6ICdmb2xkZXInO1xuICAgICAgICB2YXIgc2VsZWN0aW9uVHlwZSA9IG5vZGUuaXNMZWFmKCkgPyAnZmlsZScgOiAnZGlyJztcbiAgICAgICAgdmFyIG5vZGVBY3Rpb25zID0gW107XG4gICAgICAgIGlmICh0aGlzLmFjdGlvbnNDYWNoZVtjYWNoZUtleV0pIHtcbiAgICAgICAgICAgIG5vZGVBY3Rpb25zID0gdGhpcy5hY3Rpb25zQ2FjaGVbY2FjaGVLZXldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZG0uc2V0U2VsZWN0ZWROb2Rlcyhbbm9kZV0pO1xuICAgICAgICAgICAgd2luZG93LnB5ZGlvLkNvbnRyb2xsZXIuYWN0aW9ucy5mb3JFYWNoKChmdW5jdGlvbiAoYSkge1xuICAgICAgICAgICAgICAgIGEuZmlyZUNvbnRleHRDaGFuZ2UoZG0sIHRydWUsIHdpbmRvdy5weWRpby51c2VyKTtcbiAgICAgICAgICAgICAgICBpZiAoYS5jb250ZXh0LnNlbGVjdGlvbiAmJiBhLmNvbnRleHQuYWN0aW9uQmFyICYmIGEuc2VsZWN0aW9uQ29udGV4dFtzZWxlY3Rpb25UeXBlXSAmJiAhYS5kZW55ICYmIGEub3B0aW9ucy5pY29uX2NsYXNzICYmICghdGhpcy5wcm9wcy5hY3Rpb25CYXJHcm91cHMgfHwgdGhpcy5wcm9wcy5hY3Rpb25CYXJHcm91cHMuaW5kZXhPZihhLmNvbnRleHQuYWN0aW9uQmFyR3JvdXApICE9PSAtMSkgJiYgKCFhLnNlbGVjdGlvbkNvbnRleHQuYWxsb3dlZE1pbWVzLmxlbmd0aCB8fCBhLnNlbGVjdGlvbkNvbnRleHQuYWxsb3dlZE1pbWVzLmluZGV4T2Yobm9kZS5nZXRBanhwTWltZSgpKSAhPT0gLTEpKSB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGVBY3Rpb25zLnB1c2goYSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlLmlzTGVhZigpICYmIGEuc2VsZWN0aW9uQ29udGV4dC51bmlxdWUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGlvbnNDYWNoZS5tdWx0aXBsZS5zZXQoYS5vcHRpb25zLm5hbWUsIGEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICB0aGlzLmFjdGlvbnNDYWNoZVtjYWNoZUtleV0gPSBub2RlQWN0aW9ucztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbm9kZUFjdGlvbnM7XG4gICAgfSxcblxuICAgIHVwZGF0ZUluZmluaXRlQ29udGFpbmVySGVpZ2h0OiBmdW5jdGlvbiB1cGRhdGVJbmZpbml0ZUNvbnRhaW5lckhlaWdodCgpIHtcbiAgICAgICAgdmFyIHJldHJpZXMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDAgfHwgYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IGFyZ3VtZW50c1swXTtcblxuICAgICAgICBpZiAodGhpcy5wcm9wcy5jb250YWluZXJIZWlnaHQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByb3BzLmNvbnRhaW5lckhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMucmVmcy5pbmZpbml0ZVBhcmVudCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjb250YWluZXJIZWlnaHQgPSB0aGlzLnJlZnMuaW5maW5pdGVQYXJlbnQuY2xpZW50SGVpZ2h0O1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5oZWlnaHRBdXRvV2l0aE1heCkge1xuICAgICAgICAgICAgdmFyIG51bWJlciA9IHRoaXMuaW5kZXhlZEVsZW1lbnRzID8gdGhpcy5pbmRleGVkRWxlbWVudHMubGVuZ3RoIDogdGhpcy5wcm9wcy5ub2RlLmdldENoaWxkcmVuKCkuc2l6ZTtcbiAgICAgICAgICAgIHZhciBlbGVtZW50SGVpZ2h0ID0gdGhpcy5zdGF0ZS5lbGVtZW50SGVpZ2h0ID8gdGhpcy5zdGF0ZS5lbGVtZW50SGVpZ2h0IDogdGhpcy5wcm9wcy5lbGVtZW50SGVpZ2h0O1xuICAgICAgICAgICAgY29udGFpbmVySGVpZ2h0ID0gTWF0aC5taW4obnVtYmVyICogZWxlbWVudEhlaWdodCwgdGhpcy5wcm9wcy5oZWlnaHRBdXRvV2l0aE1heCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjb250YWluZXJIZWlnaHQgJiYgIXJldHJpZXMpIHtcbiAgICAgICAgICAgIGdsb2JhbC5zZXRUaW1lb3V0KChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVJbmZpbml0ZUNvbnRhaW5lckhlaWdodCh0cnVlKTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcyksIDUwKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgY29udGFpbmVySGVpZ2h0OiBjb250YWluZXJIZWlnaHQgfSk7XG4gICAgfSxcblxuICAgIGNvbXB1dGVFbGVtZW50SGVpZ2h0UmVzcG9uc2l2ZTogZnVuY3Rpb24gY29tcHV0ZUVsZW1lbnRIZWlnaHRSZXNwb25zaXZlKCkge1xuICAgICAgICB2YXIgYnJlYWtzID0gdGhpcy5wcm9wcy5lbGVtZW50SGVpZ2h0O1xuICAgICAgICBpZiAoIShicmVha3MgaW5zdGFuY2VvZiBPYmplY3QpKSB7XG4gICAgICAgICAgICBicmVha3MgPSB7XG4gICAgICAgICAgICAgICAgXCJtaW4td2lkdGg6NDgwcHhcIjogdGhpcy5wcm9wcy5lbGVtZW50SGVpZ2h0LFxuICAgICAgICAgICAgICAgIFwibWF4LXdpZHRoOjQ4MHB4XCI6IE9iamVjdC5rZXlzKHRoaXMucHJvcHMudGFibGVLZXlzKS5sZW5ndGggKiAyNCArIDMzXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmICh3aW5kb3cubWF0Y2hNZWRpYSkge1xuICAgICAgICAgICAgZm9yICh2YXIgayBpbiBicmVha3MpIHtcbiAgICAgICAgICAgICAgICBpZiAoYnJlYWtzLmhhc093blByb3BlcnR5KGspICYmIHdpbmRvdy5tYXRjaE1lZGlhKCcoJyArIGsgKyAnKScpLm1hdGNoZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJyZWFrc1trXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgd2lkdGggPSBET01VdGlscy5nZXRWaWV3cG9ydFdpZHRoKCk7XG4gICAgICAgICAgICBpZiAod2lkdGggPCA0ODApIHJldHVybiBicmVha3NbXCJtYXgtd2lkdGg6NDgwcHhcIl07ZWxzZSByZXR1cm4gYnJlYWtzW1wibWF4LXdpZHRoOjQ4MHB4XCJdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiA1MDtcbiAgICB9LFxuXG4gICAgdXBkYXRlRWxlbWVudEhlaWdodFJlc3BvbnNpdmU6IGZ1bmN0aW9uIHVwZGF0ZUVsZW1lbnRIZWlnaHRSZXNwb25zaXZlKCkge1xuICAgICAgICB2YXIgbmV3SCA9IHRoaXMuY29tcHV0ZUVsZW1lbnRIZWlnaHRSZXNwb25zaXZlKCk7XG4gICAgICAgIGlmICghdGhpcy5zdGF0ZSB8fCAhdGhpcy5zdGF0ZS5lbGVtZW50SGVpZ2h0IHx8IHRoaXMuc3RhdGUuZWxlbWVudEhlaWdodCAhPSBuZXdIKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZWxlbWVudEhlaWdodDogbmV3SCB9LCAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmhlaWdodEF1dG9XaXRoTWF4KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSW5maW5pdGVDb250YWluZXJIZWlnaHQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBwYXRjaEluZmluaXRlR3JpZDogZnVuY3Rpb24gcGF0Y2hJbmZpbml0ZUdyaWQoZWxzKSB7XG4gICAgICAgIGlmICh0aGlzLnJlZnMuaW5maW5pdGUgJiYgZWxzID4gMSkge1xuICAgICAgICAgICAgdGhpcy5yZWZzLmluZmluaXRlLnN0YXRlLmluZmluaXRlQ29tcHV0ZXIuX19wcm90b19fLmdldERpc3BsYXlJbmRleFN0YXJ0ID0gZnVuY3Rpb24gKHdpbmRvd1RvcCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBlbHMgKiBNYXRoLmZsb29yKHdpbmRvd1RvcCAvIHRoaXMuaGVpZ2h0RGF0YSAvIGVscyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5yZWZzLmluZmluaXRlLnN0YXRlLmluZmluaXRlQ29tcHV0ZXIuX19wcm90b19fLmdldERpc3BsYXlJbmRleEVuZCA9IGZ1bmN0aW9uICh3aW5kb3dCb3R0b20pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZWxzICogTWF0aC5jZWlsKHdpbmRvd0JvdHRvbSAvIHRoaXMuaGVpZ2h0RGF0YSAvIGVscyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgdmFyIF90aGlzMyA9IHRoaXM7XG5cbiAgICAgICAgaWYgKHRoaXMucHJvcHMuZGVsYXlJbml0aWFsTG9hZCkge1xuICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMzLl9sb2FkTm9kZUlmTm90TG9hZGVkKCk7XG4gICAgICAgICAgICB9LCB0aGlzLnByb3BzLmRlbGF5SW5pdGlhbExvYWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fbG9hZE5vZGVJZk5vdExvYWRlZCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGF0Y2hJbmZpbml0ZUdyaWQodGhpcy5wcm9wcy5lbGVtZW50c1BlckxpbmUpO1xuICAgICAgICBpZiAodGhpcy5yZWZzLmluZmluaXRlUGFyZW50KSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUluZmluaXRlQ29udGFpbmVySGVpZ2h0KCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMucHJvcHMuaGVpZ2h0QXV0b1dpdGhNYXggJiYgIXRoaXMucHJvcHMuZXh0ZXJuYWxSZXNpemUpIHtcbiAgICAgICAgICAgICAgICBpZiAod2luZG93LmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMudXBkYXRlSW5maW5pdGVDb250YWluZXJIZWlnaHQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5hdHRhY2hFdmVudCgnb25yZXNpemUnLCB0aGlzLnVwZGF0ZUluZmluaXRlQ29udGFpbmVySGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMuYXV0b1JlZnJlc2gpIHtcbiAgICAgICAgICAgIHRoaXMucmVmcmVzaEludGVydmFsID0gd2luZG93LnNldEludGVydmFsKHRoaXMucmVsb2FkLCB0aGlzLnByb3BzLmF1dG9SZWZyZXNoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wcm9wcy5vYnNlcnZlTm9kZVJlbG9hZCkge1xuICAgICAgICAgICAgdGhpcy53aXJlUmVsb2FkTGlzdGVuZXJzKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMuZWxlbWVudEhlaWdodCBpbnN0YW5jZW9mIE9iamVjdCB8fCB0aGlzLnByb3BzLnRhYmxlS2V5cykge1xuICAgICAgICAgICAgaWYgKHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMudXBkYXRlRWxlbWVudEhlaWdodFJlc3BvbnNpdmUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuYXR0YWNoRXZlbnQoJ29ucmVzaXplJywgdGhpcy51cGRhdGVFbGVtZW50SGVpZ2h0UmVzcG9uc2l2ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUVsZW1lbnRIZWlnaHRSZXNwb25zaXZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wcm9wcy5kYXRhTW9kZWwub2JzZXJ2ZSgnc2VsZWN0aW9uX2NoYW5nZWQnLCAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIF90aGlzNCA9IHRoaXM7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5pc01vdW50ZWQoKSkgcmV0dXJuO1xuICAgICAgICAgICAgdmFyIHNlbGVjdGlvbiA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIHZhciBzZWxlY3RlZE5vZGVzID0gdGhpcy5wcm9wcy5kYXRhTW9kZWwuZ2V0U2VsZWN0ZWROb2RlcygpO1xuICAgICAgICAgICAgc2VsZWN0ZWROb2Rlcy5tYXAoZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb24uc2V0KG4sIHRydWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0aW9uOiBzZWxlY3Rpb24gfSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF90aGlzNC5yZWJ1aWxkTG9hZGVkRWxlbWVudHMoKTtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWROb2Rlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXM0LnNjcm9sbFRvVmlldyhzZWxlY3RlZE5vZGVzWzBdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50OiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnByb3BzLmhlaWdodEF1dG9XaXRoTWF4KSB7XG4gICAgICAgICAgICBpZiAod2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy51cGRhdGVJbmZpbml0ZUNvbnRhaW5lckhlaWdodCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5kZXRhY2hFdmVudCgnb25yZXNpemUnLCB0aGlzLnVwZGF0ZUluZmluaXRlQ29udGFpbmVySGVpZ2h0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wcm9wcy5lbGVtZW50SGVpZ2h0IGluc3RhbmNlb2YgT2JqZWN0IHx8IHRoaXMucHJvcHMudGFibGVLZXlzKSB7XG4gICAgICAgICAgICBpZiAod2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy51cGRhdGVFbGVtZW50SGVpZ2h0UmVzcG9uc2l2ZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5kZXRhY2hFdmVudCgncmVzaXplJywgdGhpcy51cGRhdGVFbGVtZW50SGVpZ2h0UmVzcG9uc2l2ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucmVmcmVzaEludGVydmFsKSB7XG4gICAgICAgICAgICB3aW5kb3cuY2xlYXJJbnRlcnZhbCh0aGlzLnJlZnJlc2hJbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMub2JzZXJ2ZU5vZGVSZWxvYWQpIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcFJlbG9hZExpc3RlbmVycygpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm5vZGUpIHtcbiAgICAgICAgICAgIHRoaXMub2JzZXJ2ZU5vZGVDaGlsZHJlbih0aGlzLnByb3BzLm5vZGUsIHRydWUpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGNvbXBvbmVudERpZFVwZGF0ZTogZnVuY3Rpb24gY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wcywgcHJldlN0YXRlKSB7XG4gICAgICAgIGlmIChwcmV2UHJvcHMubm9kZSAmJiB0aGlzLnByb3BzLm5vZGUgJiYgcHJldlByb3BzLm5vZGUuZ2V0UGF0aCgpID09PSB0aGlzLnByb3BzLm5vZGUuZ2V0UGF0aCgpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbG9hZE5vZGVJZk5vdExvYWRlZCgpO1xuICAgIH0sXG5cbiAgICBvblNjcm9sbDogZnVuY3Rpb24gb25TY3JvbGwoc2Nyb2xsVG9wKSB7XG5cbiAgICAgICAgaWYgKCF0aGlzLnByb3BzLnBhc3NTY3JvbGxpbmdTdGF0ZVRvQ2hpbGRyZW4pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBNYWludGFpbnMgYSBzZXJpZXMgb2YgdGltZW91dHMgdG8gc2V0IHRoaXMuc3RhdGUuaXNTY3JvbGxpbmdcbiAgICAgICAgLy8gdG8gYmUgdHJ1ZSB3aGVuIHRoZSBlbGVtZW50IGlzIHNjcm9sbGluZy5cblxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5zY3JvbGxUaW1lb3V0KSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5zdGF0ZS5zY3JvbGxUaW1lb3V0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0aGF0ID0gdGhpcyxcbiAgICAgICAgICAgIHNjcm9sbFRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRoYXQuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIGlzU2Nyb2xsaW5nOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzY3JvbGxUaW1lb3V0OiB1bmRlZmluZWRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCAxNTApO1xuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgaXNTY3JvbGxpbmc6IHRydWUsXG4gICAgICAgICAgICBzY3JvbGxUaW1lb3V0OiBzY3JvbGxUaW1lb3V0XG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBzY3JvbGxUb0xhc3Q6IGZ1bmN0aW9uIHNjcm9sbFRvTGFzdCgpIHtcbiAgICAgICAgaWYgKHRoaXMuaW5kZXhlZEVsZW1lbnRzICYmIHRoaXMuaW5kZXhlZEVsZW1lbnRzW3RoaXMuaW5kZXhlZEVsZW1lbnRzLmxlbmd0aCAtIDFdLm5vZGUpIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsVG9WaWV3KHRoaXMuaW5kZXhlZEVsZW1lbnRzW3RoaXMuaW5kZXhlZEVsZW1lbnRzLmxlbmd0aCAtIDFdLm5vZGUpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHNjcm9sbFRvVmlldzogZnVuY3Rpb24gc2Nyb2xsVG9WaWV3KG5vZGUpIHtcbiAgICAgICAgdmFyIF90aGlzNSA9IHRoaXM7XG5cbiAgICAgICAgaWYgKCF0aGlzLmluZGV4ZWRFbGVtZW50cyB8fCAhdGhpcy5yZWZzLmluZmluaXRlIHx8ICF0aGlzLnJlZnMuaW5maW5pdGUuc2Nyb2xsYWJsZSkgcmV0dXJuO1xuICAgICAgICB2YXIgc2Nyb2xsYWJsZSA9IHRoaXMucmVmcy5pbmZpbml0ZS5zY3JvbGxhYmxlO1xuICAgICAgICB2YXIgdmlzaWJsZUZyYW1lID0ge1xuICAgICAgICAgICAgdG9wOiBzY3JvbGxhYmxlLnNjcm9sbFRvcCArIHRoaXMucHJvcHMuZWxlbWVudEhlaWdodCAvIDIsXG4gICAgICAgICAgICBib3R0b206IHNjcm9sbGFibGUuc2Nyb2xsVG9wICsgdGhpcy5zdGF0ZS5jb250YWluZXJIZWlnaHQgLSB0aGlzLnByb3BzLmVsZW1lbnRIZWlnaHQgLyAyXG4gICAgICAgIH07XG4gICAgICAgIHZhciByZWFsTWF4U2Nyb2xsVG9wID0gdGhpcy5pbmRleGVkRWxlbWVudHMubGVuZ3RoICogdGhpcy5wcm9wcy5lbGVtZW50SGVpZ2h0IC0gdGhpcy5zdGF0ZS5jb250YWluZXJIZWlnaHQ7XG5cbiAgICAgICAgdmFyIHBvc2l0aW9uID0gLTE7XG4gICAgICAgIHRoaXMuaW5kZXhlZEVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGUsIGspIHtcbiAgICAgICAgICAgIGlmIChlLm5vZGUgJiYgZS5ub2RlID09PSBub2RlKSBwb3NpdGlvbiA9IGs7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocG9zaXRpb24gPT09IC0xKSByZXR1cm47XG4gICAgICAgIHZhciBlbGVtZW50SGVpZ2h0ID0gdGhpcy5wcm9wcy5lbGVtZW50SGVpZ2h0O1xuICAgICAgICB2YXIgc2Nyb2xsVGFyZ2V0ID0gcG9zaXRpb24gKiBlbGVtZW50SGVpZ2h0O1xuXG4gICAgICAgIGlmIChzY3JvbGxUYXJnZXQgPiB2aXNpYmxlRnJhbWUudG9wICYmIHNjcm9sbFRhcmdldCA8IHZpc2libGVGcmFtZS5ib3R0b20pIHtcbiAgICAgICAgICAgIC8vIGFscmVhZHkgdmlzaWJsZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChzY3JvbGxUYXJnZXQgPj0gdmlzaWJsZUZyYW1lLmJvdHRvbSkge1xuICAgICAgICAgICAgc2Nyb2xsVGFyZ2V0IC09IHRoaXMuc3RhdGUuY29udGFpbmVySGVpZ2h0IC0gZWxlbWVudEhlaWdodCAqIDI7XG4gICAgICAgIH1cbiAgICAgICAgc2Nyb2xsVGFyZ2V0ID0gTWF0aC5taW4oc2Nyb2xsVGFyZ2V0LCByZWFsTWF4U2Nyb2xsVG9wKTtcbiAgICAgICAgc2Nyb2xsYWJsZS5zY3JvbGxUb3AgPSBzY3JvbGxUYXJnZXQ7XG4gICAgICAgIGlmICh0aGlzLl9tYW51YWxTY3JvbGxQZSkgdGhpcy5fbWFudWFsU2Nyb2xsUGUuc3RvcCgpO1xuICAgICAgICBpZiAoc2Nyb2xsYWJsZS5zY3JvbGxIZWlnaHQgPCBzY3JvbGxUYXJnZXQpIHtcbiAgICAgICAgICAgIHRoaXMuX21hbnVhbFNjcm9sbFBlID0gbmV3IFBlcmlvZGljYWxFeGVjdXRlcihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgc2Nyb2xsYWJsZS5zY3JvbGxUb3AgPSBzY3JvbGxUYXJnZXQ7XG4gICAgICAgICAgICAgICAgaWYgKHNjcm9sbGFibGUuc2Nyb2xsSGVpZ2h0ID49IHNjcm9sbFRhcmdldCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpczUuX21hbnVhbFNjcm9sbFBlLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXM1Ll9tYW51YWxTY3JvbGxQZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgLjI1KTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBidWlsZEVsZW1lbnRzRnJvbU5vZGVFbnRyaWVzOiBmdW5jdGlvbiBidWlsZEVsZW1lbnRzRnJvbU5vZGVFbnRyaWVzKG5vZGVFbnRyaWVzLCBzaG93U2VsZWN0b3IpIHtcblxuICAgICAgICB2YXIgY29tcG9uZW50cyA9IFtdLFxuICAgICAgICAgICAgaW5kZXggPSAwO1xuICAgICAgICB2YXIgbm9kZUVudHJpZXNMZW5ndGggPSBub2RlRW50cmllcy5sZW5ndGg7XG4gICAgICAgIG5vZGVFbnRyaWVzLmZvckVhY2goKGZ1bmN0aW9uIChlbnRyeSkge1xuICAgICAgICAgICAgdmFyIGRhdGEgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBpZiAoZW50cnkucGFyZW50KSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZTogZW50cnkubm9kZSxcbiAgICAgICAgICAgICAgICAgICAga2V5OiBlbnRyeS5ub2RlLmdldFBhdGgoKSxcbiAgICAgICAgICAgICAgICAgICAgaWQ6IGVudHJ5Lm5vZGUuZ2V0UGF0aCgpLFxuICAgICAgICAgICAgICAgICAgICBtYWluSWNvbjogU2ltcGxlTGlzdC5QQVJFTlRfRk9MREVSX0lDT04sXG4gICAgICAgICAgICAgICAgICAgIGZpcnN0TGluZTogXCIuLlwiLFxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwibGlzdC1wYXJlbnQtbm9kZVwiLFxuICAgICAgICAgICAgICAgICAgICBzZWNvbmRMaW5lOiB0aGlzLmNvbnRleHQuZ2V0TWVzc2FnZSgncmVhY3QuMScpLFxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiB0aGlzLmNsaWNrUm93LFxuICAgICAgICAgICAgICAgICAgICBvbkRvdWJsZUNsaWNrOiB0aGlzLmRvdWJsZUNsaWNrUm93LFxuICAgICAgICAgICAgICAgICAgICBzaG93U2VsZWN0b3I6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvckRpc2FibGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBub0hvdmVyOiBmYWxzZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuZW50cnlSZW5kZXJQYXJlbnRJY29uICYmICF0aGlzLnByb3BzLnRhYmxlS2V5cykge1xuICAgICAgICAgICAgICAgICAgICBkYXRhWydpY29uQ2VsbCddID0gdGhpcy5wcm9wcy5lbnRyeVJlbmRlclBhcmVudEljb24oZW50cnkubm9kZSwgZW50cnkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGFbJ21haW5JY29uJ10gPSBTaW1wbGVMaXN0LlBBUkVOVF9GT0xERVJfSUNPTjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuZWxlbWVudFN0eWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGFbJ3N0eWxlJ10gPSB0aGlzLnByb3BzLmVsZW1lbnRTdHlsZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMucGFzc1Njcm9sbGluZ1N0YXRlVG9DaGlsZHJlbikge1xuICAgICAgICAgICAgICAgICAgICBkYXRhWydwYXJlbnRJc1Njcm9sbGluZyddID0gdGhpcy5zdGF0ZS5pc1Njcm9sbGluZztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29tcG9uZW50cy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoX0xpc3RFbnRyeS5MaXN0RW50cnksIGRhdGEpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZW50cnkuZ3JvdXBIZWFkZXIpIHtcbiAgICAgICAgICAgICAgICB2YXIgaWQgPSBlbnRyeS5ncm91cEhlYWRlcixcbiAgICAgICAgICAgICAgICAgICAgZmlyc3RMaW5lID0gZW50cnkuZ3JvdXBIZWFkZXJMYWJlbDtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5lbnRyeVJlbmRlckdyb3VwSGVhZGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpcnN0TGluZSA9IHRoaXMucHJvcHMuZW50cnlSZW5kZXJHcm91cEhlYWRlcihpZCwgZmlyc3RMaW5lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZTogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAga2V5OiBlbnRyeS5ncm91cEhlYWRlcixcbiAgICAgICAgICAgICAgICAgICAgaWQ6IGlkLFxuICAgICAgICAgICAgICAgICAgICBtYWluSWNvbjogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgZmlyc3RMaW5lOiBmaXJzdExpbmUsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogJ2xpc3QtZ3JvdXAtaGVhZGVyJyxcbiAgICAgICAgICAgICAgICAgICAgb25DbGljazogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgc2hvd1NlbGVjdG9yOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3JEaXNhYmxlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgbm9Ib3ZlcjogdHJ1ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMucGFzc1Njcm9sbGluZ1N0YXRlVG9DaGlsZHJlbikge1xuICAgICAgICAgICAgICAgICAgICBkYXRhWydwYXJlbnRJc1Njcm9sbGluZyddID0gdGhpcy5zdGF0ZS5pc1Njcm9sbGluZztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29tcG9uZW50cy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoX0xpc3RFbnRyeS5MaXN0RW50cnksIGRhdGEpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZTogZW50cnkubm9kZSxcbiAgICAgICAgICAgICAgICAgICAgb25DbGljazogdGhpcy5jbGlja1JvdyxcbiAgICAgICAgICAgICAgICAgICAgb25Eb3VibGVDbGljazogdGhpcy5kb3VibGVDbGlja1JvdyxcbiAgICAgICAgICAgICAgICAgICAgb25TZWxlY3Q6IHRoaXMudG9nZ2xlU2VsZWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICBrZXk6IGVudHJ5Lm5vZGUuZ2V0UGF0aCgpLFxuICAgICAgICAgICAgICAgICAgICBpZDogZW50cnkubm9kZS5nZXRQYXRoKCksXG4gICAgICAgICAgICAgICAgICAgIHJlbmRlckljb246IHRoaXMucHJvcHMuZW50cnlSZW5kZXJJY29uLFxuICAgICAgICAgICAgICAgICAgICByZW5kZXJGaXJzdExpbmU6IHRoaXMucHJvcHMuZW50cnlSZW5kZXJGaXJzdExpbmUsXG4gICAgICAgICAgICAgICAgICAgIHJlbmRlclNlY29uZExpbmU6IHRoaXMucHJvcHMuZW50cnlSZW5kZXJTZWNvbmRMaW5lLFxuICAgICAgICAgICAgICAgICAgICByZW5kZXJUaGlyZExpbmU6IHRoaXMucHJvcHMuZW50cnlSZW5kZXJUaGlyZExpbmUsXG4gICAgICAgICAgICAgICAgICAgIHJlbmRlckFjdGlvbnM6IHRoaXMucHJvcHMuZW50cnlSZW5kZXJBY3Rpb25zLFxuICAgICAgICAgICAgICAgICAgICBzaG93U2VsZWN0b3I6IHNob3dTZWxlY3RvcixcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHRoaXMuc3RhdGUgJiYgdGhpcy5zdGF0ZS5zZWxlY3Rpb24gPyB0aGlzLnN0YXRlLnNlbGVjdGlvbi5nZXQoZW50cnkubm9kZSkgOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uczogUmVhY3QuY3JlYXRlRWxlbWVudChfdmlld3NTaW1wbGVSZWFjdEFjdGlvbkJhcjJbJ2RlZmF1bHQnXSwgeyBub2RlOiBlbnRyeS5ub2RlLCBhY3Rpb25zOiBlbnRyeS5hY3Rpb25zLCBkYXRhTW9kZWw6IHRoaXMuZG0gfSksXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yRGlzYWJsZWQ6ICEodGhpcy5wcm9wcy5lbnRyeUVuYWJsZVNlbGVjdG9yID8gdGhpcy5wcm9wcy5lbnRyeUVuYWJsZVNlbGVjdG9yKGVudHJ5Lm5vZGUpIDogZW50cnkubm9kZS5pc0xlYWYoKSlcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGRhdGFbJ2lzRmlyc3QnXSA9IGluZGV4ID09PSAwO1xuICAgICAgICAgICAgICAgIGRhdGFbJ2lzTGFzdCddID0gaW5kZXggPT09IG5vZGVFbnRyaWVzTGVuZ3RoIC0gMTtcbiAgICAgICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmVsZW1lbnRTdHlsZSkge1xuICAgICAgICAgICAgICAgICAgICBkYXRhWydzdHlsZSddID0gdGhpcy5wcm9wcy5lbGVtZW50U3R5bGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLnBhc3NTY3JvbGxpbmdTdGF0ZVRvQ2hpbGRyZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YVsncGFyZW50SXNTY3JvbGxpbmcnXSA9IHRoaXMuc3RhdGUuaXNTY3JvbGxpbmc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLnJlbmRlckN1c3RvbUVudHJ5KSB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50cy5wdXNoKHRoaXMucHJvcHMucmVuZGVyQ3VzdG9tRW50cnkoZGF0YSkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy50YWJsZUtleXMpIHtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5kZWZhdWx0R3JvdXBCeSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVsndGFibGVLZXlzJ10gPSBMYW5nVXRpbHMuZGVlcENvcHkodGhpcy5wcm9wcy50YWJsZUtleXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGRhdGFbJ3RhYmxlS2V5cyddW3RoaXMucHJvcHMuZGVmYXVsdEdyb3VwQnldO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVsndGFibGVLZXlzJ10gPSB0aGlzLnByb3BzLnRhYmxlS2V5cztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRzLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChfVGFibGVMaXN0RW50cnkyWydkZWZhdWx0J10sIGRhdGEpKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudHMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KF9Db25maWd1cmFibGVMaXN0RW50cnkyWydkZWZhdWx0J10sIGRhdGEpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pLmJpbmQodGhpcykpO1xuXG4gICAgICAgIHJldHVybiBjb21wb25lbnRzO1xuICAgIH0sXG5cbiAgICBidWlsZEVsZW1lbnRzOiBmdW5jdGlvbiBidWlsZEVsZW1lbnRzKHNvcnRpbmdJbmZvLCBzdGFydCwgZW5kLCBub2RlLCBzaG93U2VsZWN0b3IpIHtcbiAgICAgICAgdmFyIF90aGlzNiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHRoZU5vZGUgPSB0aGlzLnByb3BzLm5vZGU7XG4gICAgICAgIGlmIChub2RlKSB0aGVOb2RlID0gbm9kZTtcbiAgICAgICAgdmFyIHRoZVNob3dTZWxlY3RvciA9IHRoaXMuc3RhdGUgJiYgdGhpcy5zdGF0ZS5zaG93U2VsZWN0b3I7XG4gICAgICAgIGlmIChzaG93U2VsZWN0b3IgIT09IHVuZGVmaW5lZCkgdGhlU2hvd1NlbGVjdG9yID0gc2hvd1NlbGVjdG9yO1xuXG4gICAgICAgIGlmICghdGhpcy5pbmRleGVkRWxlbWVudHMgfHwgdGhpcy5pbmRleGVkRWxlbWVudHMubGVuZ3RoICE9PSB0aGVOb2RlLmdldENoaWxkcmVuKCkuc2l6ZSkge1xuICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBfdGhpczYuaW5kZXhlZEVsZW1lbnRzID0gW107XG4gICAgICAgICAgICAgICAgdmFyIGdyb3VwQnkgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIGdyb3VwQnlMYWJlbCA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICBncm91cEtleXMgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIGdyb3VwTGFiZWxzID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIGlmIChfdGhpczYucHJvcHMuZGVmYXVsdEdyb3VwQnkpIHtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBCeSA9IF90aGlzNi5wcm9wcy5kZWZhdWx0R3JvdXBCeTtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBCeUxhYmVsID0gX3RoaXM2LnByb3BzLmdyb3VwQnlMYWJlbCB8fCBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0ge30sIGdyb3VwS2V5cyA9IFtdLCBncm91cExhYmVscyA9IHt9O1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghX3RoaXM2LnByb3BzLnNraXBQYXJlbnROYXZpZ2F0aW9uICYmIHRoZU5vZGUuZ2V0UGFyZW50KCkgJiYgKF90aGlzNi5wcm9wcy5kYXRhTW9kZWwuZ2V0Q29udGV4dE5vZGUoKSAhPT0gdGhlTm9kZSB8fCBfdGhpczYucHJvcHMuc2tpcEludGVybmFsRGF0YU1vZGVsKSkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpczYuaW5kZXhlZEVsZW1lbnRzLnB1c2goeyBub2RlOiB0aGVOb2RlLmdldFBhcmVudCgpLCBwYXJlbnQ6IHRydWUsIGFjdGlvbnM6IG51bGwgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhlTm9kZS5nZXRDaGlsZHJlbigpLmZvckVhY2goKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQuZ2V0TWV0YWRhdGEoKS5oYXMoJ2N1cnNvcicpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRDdXJzb3IgPSBwYXJzZUludChjaGlsZC5nZXRNZXRhZGF0YSgpLmdldCgnY3Vyc29yJykpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY3VycmVudEN1cnNvciA9IE1hdGgubWF4KHRoaXMuX2N1cnJlbnRDdXJzb3IgPyB0aGlzLl9jdXJyZW50Q3Vyc29yIDogMCwgY2hpbGRDdXJzb3IpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmZpbHRlck5vZGVzICYmICF0aGlzLnByb3BzLmZpbHRlck5vZGVzKGNoaWxkKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHZhciBub2RlQWN0aW9ucyA9IHRoaXMuZ2V0QWN0aW9uc0Zvck5vZGUodGhpcy5kbSwgY2hpbGQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZ3JvdXBCeSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGdyb3VwVmFsdWUgPSBjaGlsZC5nZXRNZXRhZGF0YSgpLmdldChncm91cEJ5KSB8fCAnTi9BJztcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZ3JvdXBzW2dyb3VwVmFsdWVdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBzW2dyb3VwVmFsdWVdID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXlzLnB1c2goZ3JvdXBWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ3JvdXBCeUxhYmVsICYmIGNoaWxkLmdldE1ldGFkYXRhKCkuaGFzKGdyb3VwQnlMYWJlbCkgJiYgIWdyb3VwTGFiZWxzW2dyb3VwVmFsdWVdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBMYWJlbHNbZ3JvdXBWYWx1ZV0gPSBjaGlsZC5nZXRNZXRhZGF0YSgpLmdldChncm91cEJ5TGFiZWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBzW2dyb3VwVmFsdWVdLnB1c2goeyBub2RlOiBjaGlsZCwgcGFyZW50OiBmYWxzZSwgYWN0aW9uczogbm9kZUFjdGlvbnMgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluZGV4ZWRFbGVtZW50cy5wdXNoKHsgbm9kZTogY2hpbGQsIHBhcmVudDogZmFsc2UsIGFjdGlvbnM6IG5vZGVBY3Rpb25zIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSkuYmluZChfdGhpczYpKTtcblxuICAgICAgICAgICAgICAgIGlmIChncm91cEJ5KSB7XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5cyA9IGdyb3VwS2V5cy5zb3J0KCk7XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5cy5tYXAoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbGFiZWwgPSBrO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdyb3VwTGFiZWxzW2tdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSBncm91cExhYmVsc1trXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy5yZW5kZXJHcm91cExhYmVscykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gdGhpcy5wcm9wcy5yZW5kZXJHcm91cExhYmVscyhncm91cEJ5LCBrKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5kZXhlZEVsZW1lbnRzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGU6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBIZWFkZXI6IGssXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBIZWFkZXJMYWJlbDogbGFiZWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb25zOiBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5kZXhlZEVsZW1lbnRzID0gdGhpcy5pbmRleGVkRWxlbWVudHMuY29uY2F0KGdyb3Vwc1trXSk7XG4gICAgICAgICAgICAgICAgICAgIH0pLmJpbmQoX3RoaXM2KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzb3J0aW5nSW5mbyAmJiAhdGhpcy5yZW1vdGVTb3J0aW5nSW5mbygpKSB7XG4gICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBhdHRyaWJ1dGUgPSBzb3J0aW5nSW5mby5hdHRyaWJ1dGU7XG4gICAgICAgICAgICAgICAgdmFyIGRpcmVjdGlvbiA9IHNvcnRpbmdJbmZvLmRpcmVjdGlvbjtcbiAgICAgICAgICAgICAgICB2YXIgc29ydFR5cGUgPSBzb3J0aW5nSW5mby5zb3J0VHlwZTtcblxuICAgICAgICAgICAgICAgIHZhciBzb3J0RnVuY3Rpb24gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgaWYgKHNvcnRUeXBlID09PSAnZmlsZS1uYXR1cmFsJykge1xuICAgICAgICAgICAgICAgICAgICBzb3J0RnVuY3Rpb24gPSBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGEucGFyZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGIucGFyZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZUEgPSBhLm5vZGU7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZUIgPSBiLm5vZGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBSZWN5Y2xlIGFsd2F5cyBsYXN0XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZUEuaXNSZWN5Y2xlKCkpIHJldHVybiAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVCLmlzUmVjeWNsZSgpKSByZXR1cm4gLTE7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGb2xkZXJzIGZpcnN0XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYUxlYWYgPSBub2RlQS5pc0xlYWYoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBiTGVhZiA9IG5vZGVCLmlzTGVhZigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlcyA9IGFMZWFmICYmICFiTGVhZiA/IDEgOiAhYUxlYWYgJiYgYkxlYWYgPyAtMSA6IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzICE9PSAwKSByZXR1cm4gcmVzO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzID0gbm9kZUEuZ2V0TGFiZWwoKS5sb2NhbGVDb21wYXJlKG5vZGVCLmdldExhYmVsKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzb3J0RnVuY3Rpb24gPSBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGEucGFyZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFNZXRhID0gYS5ub2RlLmdldE1ldGFkYXRhKCkuZ2V0KGF0dHJpYnV0ZSkgfHwgXCJcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBiTWV0YSA9IGIubm9kZS5nZXRNZXRhZGF0YSgpLmdldChhdHRyaWJ1dGUpIHx8IFwiXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNvcnRUeXBlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFNZXRhID0gcGFyc2VGbG9hdChhTWV0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYk1ldGEgPSBwYXJzZUZsb2F0KGJNZXRhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXMgPSBkaXJlY3Rpb24gPT09ICdhc2MnID8gYU1ldGEgLSBiTWV0YSA6IGJNZXRhIC0gYU1ldGE7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNvcnRUeXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcyA9IGRpcmVjdGlvbiA9PT0gJ2FzYycgPyBhTWV0YS5sb2NhbGVDb21wYXJlKGJNZXRhKSA6IGJNZXRhLmxvY2FsZUNvbXBhcmUoYU1ldGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcyA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlc29ydCBieSBsYWJlbCB0byBtYWtlIGl0IHN0YWJsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsYWJDb21wID0gYS5ub2RlLmdldExhYmVsKCkubG9jYWxlQ29tcGFyZShiLm5vZGUuZ2V0TGFiZWwoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzID0gZGlyZWN0aW9uID09PSAnYXNjJyA/IGxhYkNvbXAgOiAtbGFiQ29tcDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIF90aGlzNi5pbmRleGVkRWxlbWVudHMuc29ydChzb3J0RnVuY3Rpb24pO1xuICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnByb3BzLmVsZW1lbnRQZXJMaW5lID4gMSkge1xuICAgICAgICAgICAgZW5kID0gZW5kICogdGhpcy5wcm9wcy5lbGVtZW50UGVyTGluZTtcbiAgICAgICAgICAgIHN0YXJ0ID0gc3RhcnQgKiB0aGlzLnByb3BzLmVsZW1lbnRQZXJMaW5lO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmluZGV4ZWRFbGVtZW50cy5zbGljZShzdGFydCwgZW5kKTtcbiAgICB9LFxuXG4gICAgcmVidWlsZExvYWRlZEVsZW1lbnRzOiBmdW5jdGlvbiByZWJ1aWxkTG9hZGVkRWxlbWVudHMoKSB7XG4gICAgICAgIHZhciBuZXdFbGVtZW50cyA9IHRoaXMuYnVpbGRFbGVtZW50cyh0aGlzLnN0YXRlLnNvcnRpbmdJbmZvLCAwLCBNYXRoLm1heCh0aGlzLnN0YXRlLmVsZW1lbnRzLmxlbmd0aCwgdGhpcy5wcm9wcy5pbmZpbml0ZVNsaWNlQ291bnQpKTtcbiAgICAgICAgdmFyIGluZmluaXRlTG9hZEJlZ2luQm90dG9tT2Zmc2V0ID0gbmV3RWxlbWVudHMubGVuZ3RoID8gMjAwIDogMDtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBlbGVtZW50czogbmV3RWxlbWVudHMsXG4gICAgICAgICAgICBpbmZpbml0ZUxvYWRCZWdpbkJvdHRvbU9mZnNldDogaW5maW5pdGVMb2FkQmVnaW5Cb3R0b21PZmZzZXRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudXBkYXRlSW5maW5pdGVDb250YWluZXJIZWlnaHQoKTtcbiAgICB9LFxuXG4gICAgaGFuZGxlSW5maW5pdGVMb2FkOiBmdW5jdGlvbiBoYW5kbGVJbmZpbml0ZUxvYWQoKSB7XG4gICAgICAgIHZhciBlbGVtTGVuZ3RoID0gdGhpcy5zdGF0ZS5lbGVtZW50cy5sZW5ndGg7XG4gICAgICAgIHZhciBuZXdFbGVtZW50cyA9IHRoaXMuYnVpbGRFbGVtZW50cyh0aGlzLnN0YXRlLnNvcnRpbmdJbmZvLCBlbGVtTGVuZ3RoLCBlbGVtTGVuZ3RoICsgdGhpcy5wcm9wcy5pbmZpbml0ZVNsaWNlQ291bnQpO1xuICAgICAgICB2YXIgaW5maW5pdGVMb2FkQmVnaW5Cb3R0b21PZmZzZXQgPSBuZXdFbGVtZW50cy5sZW5ndGggPyAyMDAgOiAwO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGlzSW5maW5pdGVMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgIGVsZW1lbnRzOiB0aGlzLnN0YXRlLmVsZW1lbnRzLmNvbmNhdChuZXdFbGVtZW50cyksXG4gICAgICAgICAgICBpbmZpbml0ZUxvYWRCZWdpbkJvdHRvbU9mZnNldDogaW5maW5pdGVMb2FkQmVnaW5Cb3R0b21PZmZzZXRcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3QgcmVtb3RlIHNvcnRpbmcgaW5mbyBmcm9tIGN1cnJlbnQgbm9kZSBtZXRhZGF0YVxuICAgICAqL1xuICAgIHJlbW90ZVNvcnRpbmdJbmZvOiBmdW5jdGlvbiByZW1vdGVTb3J0aW5nSW5mbygpIHtcbiAgICAgICAgdmFyIG1ldGEgPSB0aGlzLnByb3BzLm5vZGUuZ2V0TWV0YWRhdGEoKS5nZXQoJ3BhZ2luYXRpb25EYXRhJyk7XG4gICAgICAgIGlmIChtZXRhICYmIG1ldGEuZ2V0KCd0b3RhbCcpID4gMSAmJiBtZXRhLmhhcygncmVtb3RlX29yZGVyJykpIHtcbiAgICAgICAgICAgIHZhciBjb2wgPSBtZXRhLmdldCgnY3VycmVudE9yZGVyQ29sJyk7XG4gICAgICAgICAgICB2YXIgZGlyID0gbWV0YS5nZXQoJ2N1cnJlbnRPcmRlckRpcicpO1xuICAgICAgICAgICAgaWYgKGNvbCAmJiBkaXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICByZW1vdGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZTogY29sLFxuICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IGRpclxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSxcblxuICAgIHJlbmRlclRvb2xiYXI6IGZ1bmN0aW9uIHJlbmRlclRvb2xiYXIoKSB7XG4gICAgICAgIHZhciBfdGhpczcgPSB0aGlzO1xuXG4gICAgICAgIHZhciByaWdodEJ1dHRvbnMgPSBbUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5Gb250SWNvbiwge1xuICAgICAgICAgICAga2V5OiAxLFxuICAgICAgICAgICAgdG9vbHRpcDogJ1JlbG9hZCcsXG4gICAgICAgICAgICBjbGFzc05hbWU6IFwiaWNvbi1yZWZyZXNoXCIgKyAodGhpcy5zdGF0ZS5sb2FkaW5nID8gXCIgcm90YXRpbmdcIiA6IFwiXCIpLFxuICAgICAgICAgICAgb25DbGljazogdGhpcy5yZWxvYWRcbiAgICAgICAgfSldO1xuICAgICAgICB2YXIgaSA9IDI7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnNvcnRLZXlzKSB7XG5cbiAgICAgICAgICAgIHZhciBzb3J0aW5nSW5mbyA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICByZW1vdGVTb3J0aW5nSW5mbyA9IHRoaXMucmVtb3RlU29ydGluZ0luZm8oKTtcbiAgICAgICAgICAgIGlmIChyZW1vdGVTb3J0aW5nSW5mbykge1xuICAgICAgICAgICAgICAgIHNvcnRpbmdJbmZvID0gcmVtb3RlU29ydGluZ0luZm87XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNvcnRpbmdJbmZvID0gdGhpcy5zdGF0ZSA/IHRoaXMuc3RhdGUuc29ydGluZ0luZm8gOiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmlnaHRCdXR0b25zLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChfU29ydENvbHVtbnMyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICBrZXk6IGksXG4gICAgICAgICAgICAgICAgZGlzcGxheU1vZGU6ICdtZW51JyxcbiAgICAgICAgICAgICAgICB0YWJsZUtleXM6IHRoaXMucHJvcHMuc29ydEtleXMsXG4gICAgICAgICAgICAgICAgY29sdW1uQ2xpY2tlZDogdGhpcy5vbkNvbHVtblNvcnQsXG4gICAgICAgICAgICAgICAgc29ydGluZ0luZm86IHNvcnRpbmdJbmZvXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBpKys7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMuYWRkaXRpb25hbEFjdGlvbnMpIHtcbiAgICAgICAgICAgIHJpZ2h0QnV0dG9ucy5wdXNoKHRoaXMucHJvcHMuYWRkaXRpb25hbEFjdGlvbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGxlZnRUb29sYmFyID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgcGFnaW5hdG9yID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5ub2RlLmdldE1ldGFkYXRhKCkuZ2V0KFwicGFnaW5hdGlvbkRhdGFcIikgJiYgdGhpcy5wcm9wcy5ub2RlLmdldE1ldGFkYXRhKCkuZ2V0KFwicGFnaW5hdGlvbkRhdGFcIikuZ2V0KCd0b3RhbCcpID4gMSkge1xuICAgICAgICAgICAgcGFnaW5hdG9yID0gUmVhY3QuY3JlYXRlRWxlbWVudChfTGlzdFBhZ2luYXRvcjJbJ2RlZmF1bHQnXSwgeyBkYXRhTW9kZWw6IHRoaXMuZG0sIG5vZGU6IHRoaXMucHJvcHMubm9kZSB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnByb3BzLmxpc3RUaXRsZSkge1xuICAgICAgICAgICAgbGVmdFRvb2xiYXIgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFJlYWN0TVVJLlRvb2xiYXJHcm91cCxcbiAgICAgICAgICAgICAgICB7IGtleTogMCwgZmxvYXQ6ICdsZWZ0JyB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2xpc3QtdGl0bGUnIH0sXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMubGlzdFRpdGxlXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnByb3BzLnNlYXJjaFJlc3VsdERhdGEpIHtcblxuICAgICAgICAgICAgbGVmdFRvb2xiYXIgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFJlYWN0TVVJLlRvb2xiYXJHcm91cCxcbiAgICAgICAgICAgICAgICB7IGtleTogMCwgZmxvYXQ6ICdsZWZ0JyB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdoMicsXG4gICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnc2VhcmNoLXJlc3VsdHMtdGl0bGUnIH0sXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC5nZXRNZXNzYWdlKCdyZWFjdC4zJykucmVwbGFjZSgnJXMnLCB0aGlzLnByb3BzLnNlYXJjaFJlc3VsdERhdGEudGVybSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmlnaHRCdXR0b25zID0gUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5SYWlzZWRCdXR0b24sIHsga2V5OiAxLCBsYWJlbDogdGhpcy5jb250ZXh0LmdldE1lc3NhZ2UoJ3JlYWN0LjQnKSwgcHJpbWFyeTogdHJ1ZSwgb25DbGljazogdGhpcy5wcm9wcy5zZWFyY2hSZXN1bHREYXRhLnRvZ2dsZVN0YXRlIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYWN0aW9uc0NhY2hlLm11bHRpcGxlLnNpemUgfHwgdGhpcy5wcm9wcy5tdWx0aXBsZUFjdGlvbnMpIHtcbiAgICAgICAgICAgIHZhciBidWxrTGFiZWwgPSB0aGlzLmNvbnRleHQuZ2V0TWVzc2FnZSgncmVhY3QuMicpO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2VsZWN0aW9uICYmIHRoaXMuc3RhdGUuc2hvd1NlbGVjdG9yKSB7XG4gICAgICAgICAgICAgICAgYnVsa0xhYmVsICs9IFwiIChcIiArIHRoaXMuc3RhdGUuc2VsZWN0aW9uLnNpemUgKyBcIilcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxlZnRUb29sYmFyID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBSZWFjdE1VSS5Ub29sYmFyR3JvdXAsXG4gICAgICAgICAgICAgICAgeyBrZXk6IDAsIGZsb2F0OiAnbGVmdCcsIGNsYXNzTmFtZTogJ2hpZGUtb24tdmVydGljYWwtbGF5b3V0JyB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoUmVhY3RNVUkuQ2hlY2tib3gsIHsgcmVmOiAnYWxsX3NlbGVjdG9yJywgb25DbGljazogdGhpcy5zZWxlY3RBbGwgfSksXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5GbGF0QnV0dG9uLCB7IGxhYmVsOiBidWxrTGFiZWwsIG9uQ2xpY2s6IHRoaXMudG9nZ2xlU2VsZWN0b3IgfSlcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnNob3dTZWxlY3Rvcikge1xuICAgICAgICAgICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJpZ2h0QnV0dG9ucyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgICAgICAgICAgICAgICB2YXIgYWN0aW9ucyA9IF90aGlzNy5wcm9wcy5tdWx0aXBsZUFjdGlvbnMgfHwgX3RoaXM3LmFjdGlvbnNDYWNoZS5tdWx0aXBsZTtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9ucy5mb3JFYWNoKChmdW5jdGlvbiAoYSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmlnaHRCdXR0b25zLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5SYWlzZWRCdXR0b24sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IGluZGV4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBhLm9wdGlvbnMudGV4dCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGF0YS1hY3Rpb24nOiBhLm9wdGlvbnMubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiB0aGlzLmFwcGx5TXVsdGlwbGVBY3Rpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbWFyeTogdHJ1ZSB9KSk7XG4gICAgICAgICAgICAgICAgICAgIH0pLmJpbmQoX3RoaXM3KSk7XG4gICAgICAgICAgICAgICAgICAgIHJpZ2h0QnV0dG9ucyA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmlnaHRCdXR0b25zXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgUmVhY3RNVUkuVG9vbGJhcixcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICBsZWZ0VG9vbGJhcixcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgUmVhY3RNVUkuVG9vbGJhckdyb3VwLFxuICAgICAgICAgICAgICAgIHsga2V5OiAxLCBmbG9hdDogJ3JpZ2h0JyB9LFxuICAgICAgICAgICAgICAgIHBhZ2luYXRvcixcbiAgICAgICAgICAgICAgICByaWdodEJ1dHRvbnNcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpczggPSB0aGlzO1xuXG4gICAgICAgIHZhciBjb250YWluZXJDbGFzc2VzID0gXCJtYXRlcmlhbC1saXN0IHZlcnRpY2FsLWxheW91dCBsYXlvdXQtZmlsbFwiO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5jbGFzc05hbWUpIHtcbiAgICAgICAgICAgIGNvbnRhaW5lckNsYXNzZXMgKz0gXCIgXCIgKyB0aGlzLnByb3BzLmNsYXNzTmFtZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5zaG93U2VsZWN0b3IpIHtcbiAgICAgICAgICAgIGNvbnRhaW5lckNsYXNzZXMgKz0gXCIgbGlzdC1zaG93LXNlbGVjdG9yc1wiO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnRhYmxlS2V5cykge1xuICAgICAgICAgICAgY29udGFpbmVyQ2xhc3NlcyArPSBcIiB0YWJsZS1tb2RlXCI7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHRvb2xiYXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnRhYmxlS2V5cykge1xuICAgICAgICAgICAgdmFyIHRhYmxlS2V5cyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmRlZmF1bHRHcm91cEJ5KSB7XG4gICAgICAgICAgICAgICAgdGFibGVLZXlzID0gTGFuZ1V0aWxzLmRlZXBDb3B5KHRoaXMucHJvcHMudGFibGVLZXlzKTtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGFibGVLZXlzW3RoaXMucHJvcHMuZGVmYXVsdEdyb3VwQnldO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0YWJsZUtleXMgPSB0aGlzLnByb3BzLnRhYmxlS2V5cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBzb3J0aW5nSW5mbyA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICByZW1vdGVTb3J0aW5nSW5mbyA9IHRoaXMucmVtb3RlU29ydGluZ0luZm8oKTtcbiAgICAgICAgICAgIGlmIChyZW1vdGVTb3J0aW5nSW5mbykge1xuICAgICAgICAgICAgICAgIHNvcnRpbmdJbmZvID0gcmVtb3RlU29ydGluZ0luZm87XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNvcnRpbmdJbmZvID0gdGhpcy5zdGF0ZSA/IHRoaXMuc3RhdGUuc29ydGluZ0luZm8gOiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdG9vbGJhciA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoX1RhYmxlTGlzdEhlYWRlcjJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgIHRhYmxlS2V5czogdGFibGVLZXlzLFxuICAgICAgICAgICAgICAgIGxvYWRpbmc6IHRoaXMuc3RhdGUubG9hZGluZyxcbiAgICAgICAgICAgICAgICByZWxvYWQ6IHRoaXMucmVsb2FkLFxuICAgICAgICAgICAgICAgIHJlZjogJ2xvYWRpbmdfaW5kaWNhdG9yJyxcbiAgICAgICAgICAgICAgICBkbTogdGhpcy5wcm9wcy5kYXRhTW9kZWwsXG4gICAgICAgICAgICAgICAgbm9kZTogdGhpcy5wcm9wcy5ub2RlLFxuICAgICAgICAgICAgICAgIGFkZGl0aW9uYWxBY3Rpb25zOiB0aGlzLnByb3BzLmFkZGl0aW9uYWxBY3Rpb25zLFxuICAgICAgICAgICAgICAgIG9uSGVhZGVyQ2xpY2s6IHRoaXMub25Db2x1bW5Tb3J0LFxuICAgICAgICAgICAgICAgIHNvcnRpbmdJbmZvOiBzb3J0aW5nSW5mb1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0b29sYmFyID0gdGhpcy5wcm9wcy5jdXN0b21Ub29sYmFyID8gdGhpcy5wcm9wcy5jdXN0b21Ub29sYmFyIDogIXRoaXMucHJvcHMuaGlkZVRvb2xiYXIgPyB0aGlzLnJlbmRlclRvb2xiYXIoKSA6IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaW5saW5lRWRpdG9yID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5pbmxpbmVFZGl0aW9uRm9yTm9kZSkge1xuICAgICAgICAgICAgaW5saW5lRWRpdG9yID0gUmVhY3QuY3JlYXRlRWxlbWVudChfSW5saW5lRWRpdG9yMlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICAgICAgZGV0YWNoZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgbm9kZTogdGhpcy5zdGF0ZS5pbmxpbmVFZGl0aW9uRm9yTm9kZSxcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogdGhpcy5zdGF0ZS5pbmxpbmVFZGl0aW9uQ2FsbGJhY2ssXG4gICAgICAgICAgICAgICAgb25DbG9zZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpczguc2V0U3RhdGUoeyBpbmxpbmVFZGl0aW9uRm9yTm9kZTogbnVsbCB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBlbXB0eVN0YXRlID0gdW5kZWZpbmVkO1xuICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcztcbiAgICAgICAgdmFyIGVtcHR5U3RhdGVQcm9wcyA9IF9wcm9wcy5lbXB0eVN0YXRlUHJvcHM7XG4gICAgICAgIHZhciBub2RlID0gX3Byb3BzLm5vZGU7XG5cbiAgICAgICAgaWYgKGVtcHR5U3RhdGVQcm9wcyAmJiB0aGlzLnByb3BzLm5vZGUuaXNMb2FkZWQoKSAmJiAhdGhpcy5wcm9wcy5ub2RlLmlzTG9hZGluZygpICYmICghdGhpcy5zdGF0ZS5lbGVtZW50cy5sZW5ndGggfHwgdGhpcy5zdGF0ZS5lbGVtZW50cy5sZW5ndGggPT09IDEgJiYgdGhpcy5zdGF0ZS5lbGVtZW50c1swXS5wYXJlbnQpKSB7XG5cbiAgICAgICAgICAgIHZhciBhY3Rpb25Qcm9wcyA9IHt9O1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWxlbWVudHMubGVuZ3RoID09PSAxICYmIHRoaXMuc3RhdGUuZWxlbWVudHNbMF0ucGFyZW50KSB7XG4gICAgICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudE5vZGUgPSBfdGhpczguc3RhdGUuZWxlbWVudHNbMF0ubm9kZTtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uUHJvcHMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb25MYWJlbElkOiAncmVhY3QuMScsXG4gICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb25JY29uQ2xhc3NOYW1lOiBTaW1wbGVMaXN0LlBBUkVOVF9GT0xERVJfSUNPTixcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbkNhbGxiYWNrOiBmdW5jdGlvbiBhY3Rpb25DYWxsYmFjayhlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzOC5wcm9wcy5lbnRyeUhhbmRsZUNsaWNrcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpczgucHJvcHMuZW50cnlIYW5kbGVDbGlja3MocGFyZW50Tm9kZSwgU2ltcGxlTGlzdC5DTElDS19UWVBFX0RPVUJMRSwgZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbXB0eVN0YXRlID0gUmVhY3QuY3JlYXRlRWxlbWVudChfdmlld3NFbXB0eVN0YXRlVmlldzJbJ2RlZmF1bHQnXSwgX2V4dGVuZHMoe30sIGVtcHR5U3RhdGVQcm9wcywgYWN0aW9uUHJvcHMpKTtcbiAgICAgICAgfSBlbHNlIGlmIChlbXB0eVN0YXRlUHJvcHMgJiYgZW1wdHlTdGF0ZVByb3BzLmNoZWNrRW1wdHlTdGF0ZSAmJiBlbXB0eVN0YXRlUHJvcHMuY2hlY2tFbXB0eVN0YXRlKHRoaXMucHJvcHMubm9kZSkpIHtcblxuICAgICAgICAgICAgZW1wdHlTdGF0ZSA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoX3ZpZXdzRW1wdHlTdGF0ZVZpZXcyWydkZWZhdWx0J10sIGVtcHR5U3RhdGVQcm9wcyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgZWxlbWVudHMgPSB0aGlzLmJ1aWxkRWxlbWVudHNGcm9tTm9kZUVudHJpZXModGhpcy5zdGF0ZS5lbGVtZW50cywgdGhpcy5zdGF0ZS5zaG93U2VsZWN0b3IpO1xuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IGNsYXNzTmFtZTogY29udGFpbmVyQ2xhc3Nlcywgb25Db250ZXh0TWVudTogdGhpcy5jb250ZXh0TWVudVJlc3BvbmRlciwgdGFiSW5kZXg6ICcwJywgb25LZXlEb3duOiB0aGlzLm9uS2V5RG93biwgc3R5bGU6IHRoaXMucHJvcHMuc3R5bGUgfSxcbiAgICAgICAgICAgIHRvb2xiYXIsXG4gICAgICAgICAgICBpbmxpbmVFZGl0b3IsXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiB0aGlzLnByb3BzLmhlaWdodEF1dG9XaXRoTWF4ID8gXCJpbmZpbml0ZS1wYXJlbnQtc21vb3RoLWhlaWdodFwiIDogZW1wdHlTdGF0ZSA/IFwibGF5b3V0LWZpbGwgdmVydGljYWxfbGF5b3V0XCIgOiBcImxheW91dC1maWxsXCIsIHJlZjogJ2luZmluaXRlUGFyZW50JyB9LFxuICAgICAgICAgICAgICAgICFlbXB0eVN0YXRlICYmICF0aGlzLnByb3BzLnZlcnRpY2FsU2Nyb2xsZXIgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgSW5maW5pdGUsXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRIZWlnaHQ6IHRoaXMuc3RhdGUuZWxlbWVudEhlaWdodCA/IHRoaXMuc3RhdGUuZWxlbWVudEhlaWdodCA6IHRoaXMucHJvcHMuZWxlbWVudEhlaWdodCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lckhlaWdodDogdGhpcy5zdGF0ZS5jb250YWluZXJIZWlnaHQgPyB0aGlzLnN0YXRlLmNvbnRhaW5lckhlaWdodCA6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmZpbml0ZUxvYWRCZWdpbkVkZ2VPZmZzZXQ6IHRoaXMuc3RhdGUuaW5maW5pdGVMb2FkQmVnaW5Cb3R0b21PZmZzZXQsXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkluZmluaXRlTG9hZDogdGhpcy5oYW5kbGVJbmZpbml0ZUxvYWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVTY3JvbGw6IHRoaXMub25TY3JvbGwsXG4gICAgICAgICAgICAgICAgICAgICAgICByZWY6ICdpbmZpbml0ZSdcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudHNcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICFlbXB0eVN0YXRlICYmIHRoaXMucHJvcHMudmVydGljYWxTY3JvbGxlciAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICBfcmVhY3RTY3JvbGxiYXIyWydkZWZhdWx0J10sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNwZWVkOiAwLjgsXG4gICAgICAgICAgICAgICAgICAgICAgICBob3Jpem9udGFsU2Nyb2xsOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7IGhlaWdodDogdGhpcy5zdGF0ZS5jb250YWluZXJIZWlnaHQgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcnRpY2FsU2Nyb2xsYmFyU3R5bGU6IHsgYm9yZGVyUmFkaXVzOiAxMCwgd2lkdGg6IDYgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcnRpY2FsQ29udGFpbmVyU3R5bGU6IHsgd2lkdGg6IDggfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudHNcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgZW1wdHlTdGF0ZVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cblxufSk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFNpbXBsZUxpc3Q7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfbWVudUljb25CdXR0b25NZW51ID0gcmVxdWlyZSgnLi4vbWVudS9JY29uQnV0dG9uTWVudScpO1xuXG52YXIgX21lbnVJY29uQnV0dG9uTWVudTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9tZW51SWNvbkJ1dHRvbk1lbnUpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIFB5ZGlvID0gcmVxdWlyZSgncHlkaW8nKTtcblxudmFyIF9QeWRpbyRyZXF1aXJlTGliID0gUHlkaW8ucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgUHlkaW9Db250ZXh0Q29uc3VtZXIgPSBfUHlkaW8kcmVxdWlyZUxpYi5QeWRpb0NvbnRleHRDb25zdW1lcjtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWktbGVnYWN5Jyk7XG5cbnZhciBUb29sYmFyR3JvdXAgPSBfcmVxdWlyZS5Ub29sYmFyR3JvdXA7XG5cbnZhciBTb3J0Q29sdW1ucyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ1NvcnRDb2x1bW5zJyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICB0YWJsZUtleXM6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgICAgY29sdW1uQ2xpY2tlZDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIHNvcnRpbmdJbmZvOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICBkaXNwbGF5TW9kZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZ1xuICAgIH0sXG5cbiAgICBvbk1lbnVDbGlja2VkOiBmdW5jdGlvbiBvbk1lbnVDbGlja2VkKG9iamVjdCkge1xuICAgICAgICB0aGlzLnByb3BzLmNvbHVtbkNsaWNrZWQob2JqZWN0LnBheWxvYWQpO1xuICAgIH0sXG5cbiAgICBvbkhlYWRlckNsaWNrOiBmdW5jdGlvbiBvbkhlYWRlckNsaWNrKGtleSwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIGRhdGEgPSB0aGlzLnByb3BzLnRhYmxlS2V5c1trZXldO1xuICAgICAgICBpZiAoZGF0YSAmJiBkYXRhWydzb3J0VHlwZSddICYmIHRoaXMucHJvcHMuY29sdW1uQ2xpY2tlZCkge1xuICAgICAgICAgICAgZGF0YVsnbmFtZSddID0ga2V5O1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5jb2x1bW5DbGlja2VkKGRhdGEsIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBnZXRDb2x1bW5zSXRlbXM6IGZ1bmN0aW9uIGdldENvbHVtbnNJdGVtcyhkaXNwbGF5TW9kZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciBjb250cm9sbGVyID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGFyZ3VtZW50c1sxXTtcblxuICAgICAgICB2YXIgaXRlbXMgPSBbXTtcbiAgICAgICAgdmFyIF9jYWxsYmFjayA9IGZ1bmN0aW9uIF9jYWxsYmFjaygpIHtcbiAgICAgICAgICAgIGlmIChjb250cm9sbGVyKSB7XG4gICAgICAgICAgICAgICAgY29udHJvbGxlci5ub3RpZnkoJ2FjdGlvbnNfcmVmcmVzaGVkJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIF9sb29wID0gZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgaWYgKCFfdGhpcy5wcm9wcy50YWJsZUtleXMuaGFzT3duUHJvcGVydHkoa2V5KSkgcmV0dXJuICdjb250aW51ZSc7XG4gICAgICAgICAgICB2YXIgZGF0YSA9IF90aGlzLnByb3BzLnRhYmxlS2V5c1trZXldO1xuICAgICAgICAgICAgdmFyIHN0eWxlID0gZGF0YVsnd2lkdGgnXSA/IHsgd2lkdGg6IGRhdGFbJ3dpZHRoJ10gfSA6IG51bGw7XG4gICAgICAgICAgICB2YXIgaWNvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHZhciBjbGFzc05hbWUgPSAnY2VsbCBoZWFkZXJfY2VsbCBjZWxsLScgKyBrZXk7XG4gICAgICAgICAgICBpZiAoZGF0YVsnc29ydFR5cGUnXSkge1xuICAgICAgICAgICAgICAgIGNsYXNzTmFtZSArPSAnIHNvcnRhYmxlJztcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMucHJvcHMuc29ydGluZ0luZm8gJiYgKF90aGlzLnByb3BzLnNvcnRpbmdJbmZvLmF0dHJpYnV0ZSA9PT0ga2V5IHx8IF90aGlzLnByb3BzLnNvcnRpbmdJbmZvLmF0dHJpYnV0ZSA9PT0gZGF0YVsnc29ydEF0dHJpYnV0ZSddIHx8IF90aGlzLnByb3BzLnNvcnRpbmdJbmZvLmF0dHJpYnV0ZSA9PT0gZGF0YVsncmVtb3RlU29ydEF0dHJpYnV0ZSddKSkge1xuICAgICAgICAgICAgICAgICAgICBpY29uID0gX3RoaXMucHJvcHMuc29ydGluZ0luZm8uZGlyZWN0aW9uID09PSAnYXNjJyA/ICdtZGkgbWRpLWFycm93LXVwJyA6ICdtZGkgbWRpLWFycm93LWRvd24nO1xuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWUgKz0gJyBhY3RpdmUtc29ydC0nICsgX3RoaXMucHJvcHMuc29ydGluZ0luZm8uZGlyZWN0aW9uO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkaXNwbGF5TW9kZSA9PT0gJ21lbnUnKSB7XG4gICAgICAgICAgICAgICAgZGF0YVsnbmFtZSddID0ga2V5O1xuICAgICAgICAgICAgICAgIGl0ZW1zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBwYXlsb2FkOiBkYXRhLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0OiBkYXRhWydsYWJlbCddLFxuICAgICAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lOiBpY29uXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGRpc3BsYXlNb2RlID09PSAnbWVudV9kYXRhJykge1xuICAgICAgICAgICAgICAgIGl0ZW1zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBuYW1lOiBkYXRhWydsYWJlbCddLFxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjazogZnVuY3Rpb24gY2FsbGJhY2soKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5vbkhlYWRlckNsaWNrKGtleSwgX2NhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaWNvbl9jbGFzczogaWNvbiB8fCAnX19JTlNFVF9fJ1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpdGVtcy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAga2V5OiBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBzdHlsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5vbkhlYWRlckNsaWNrKGtleSwgX2NhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgZGF0YVsnbGFiZWwnXVxuICAgICAgICAgICAgICAgICkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGZvciAodmFyIGtleSBpbiB0aGlzLnByb3BzLnRhYmxlS2V5cykge1xuICAgICAgICAgICAgdmFyIF9yZXQgPSBfbG9vcChrZXkpO1xuXG4gICAgICAgICAgICBpZiAoX3JldCA9PT0gJ2NvbnRpbnVlJykgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZW1zO1xuICAgIH0sXG5cbiAgICBidWlsZFNvcnRpbmdNZW51SXRlbXM6IGZ1bmN0aW9uIGJ1aWxkU29ydGluZ01lbnVJdGVtcyhjb250cm9sbGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldENvbHVtbnNJdGVtcygnbWVudV9kYXRhJywgY29udHJvbGxlcik7XG4gICAgfSxcblxuICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcblxuICAgICAgICB2YXIgc29ydEFjdGlvbiA9IG5ldyBBY3Rpb24oe1xuICAgICAgICAgICAgbmFtZTogJ3NvcnRfYWN0aW9uJyxcbiAgICAgICAgICAgIGljb25fY2xhc3M6ICdtZGkgbWRpLXNvcnQtZGVzY2VuZGluZycsXG4gICAgICAgICAgICB0ZXh0X2lkOiA0NTAsXG4gICAgICAgICAgICB0aXRsZV9pZDogNDUwLFxuICAgICAgICAgICAgdGV4dDogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKDQ1MCksXG4gICAgICAgICAgICB0aXRsZTogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKDQ1MCksXG4gICAgICAgICAgICBoYXNBY2Nlc3NLZXk6IGZhbHNlLFxuICAgICAgICAgICAgc3ViTWVudTogdHJ1ZSxcbiAgICAgICAgICAgIHN1Yk1lbnVVcGRhdGVJbWFnZTogdHJ1ZVxuICAgICAgICB9LCB7XG4gICAgICAgICAgICBzZWxlY3Rpb246IGZhbHNlLFxuICAgICAgICAgICAgZGlyOiB0cnVlLFxuICAgICAgICAgICAgYWN0aW9uQmFyOiB0cnVlLFxuICAgICAgICAgICAgYWN0aW9uQmFyR3JvdXA6ICdkaXNwbGF5X3Rvb2xiYXInLFxuICAgICAgICAgICAgY29udGV4dE1lbnU6IGZhbHNlLFxuICAgICAgICAgICAgaW5mb1BhbmVsOiBmYWxzZVxuICAgICAgICB9LCB7fSwge30sIHtcbiAgICAgICAgICAgIGR5bmFtaWNCdWlsZGVyOiB0aGlzLmJ1aWxkU29ydGluZ01lbnVJdGVtc1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGJ1dHRvbnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIGJ1dHRvbnMuc2V0KCdzb3J0X2FjdGlvbicsIHNvcnRBY3Rpb24pO1xuICAgICAgICB0aGlzLnByb3BzLnB5ZGlvLmdldENvbnRyb2xsZXIoKS51cGRhdGVHdWlBY3Rpb25zKGJ1dHRvbnMpO1xuICAgIH0sXG5cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudDogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIHRoaXMucHJvcHMucHlkaW8uZ2V0Q29udHJvbGxlcigpLmRlbGV0ZUZyb21HdWlBY3Rpb25zKCdzb3J0X2FjdGlvbicpO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuZGlzcGxheU1vZGUgPT09ICdtZW51Jykge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX21lbnVJY29uQnV0dG9uTWVudTJbJ2RlZmF1bHQnXSwgeyBidXR0b25UaXRsZTogJ1NvcnQgYnkuLi4nLCBidXR0b25DbGFzc05hbWU6ICdtZGkgbWRpLXNvcnQtZGVzY2VuZGluZycsIG1lbnVJdGVtczogdGhpcy5nZXRDb2x1bW5zSXRlbXMoJ21lbnUnLCB0aGlzLnByb3BzLnB5ZGlvLmdldENvbnRyb2xsZXIoKSksIG9uTWVudUNsaWNrZWQ6IHRoaXMub25NZW51Q2xpY2tlZCB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFRvb2xiYXJHcm91cCxcbiAgICAgICAgICAgICAgICB7IGZsb2F0OiAnbGVmdCcgfSxcbiAgICAgICAgICAgICAgICB0aGlzLmdldENvbHVtbnNJdGVtcygnaGVhZGVyJywgdGhpcy5wcm9wcy5weWRpby5nZXRDb250cm9sbGVyKCkpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxufSk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFNvcnRDb2x1bW5zID0gUHlkaW9Db250ZXh0Q29uc3VtZXIoU29ydENvbHVtbnMpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gU29ydENvbHVtbnM7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfdXRpbERORCA9IHJlcXVpcmUoJy4uL3V0aWwvRE5EJyk7XG5cbi8qKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiBSRUFDVCBETkQgU09SVEFCTEUgTElTVFxuIC8qKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qKlxuICogU3BlY2lmaWVzIHRoZSBkcmFnIHNvdXJjZSBjb250cmFjdC5cbiAqIE9ubHkgYGJlZ2luRHJhZ2AgZnVuY3Rpb24gaXMgcmVxdWlyZWQuXG4gKi9cbnZhciBzb3J0YWJsZUl0ZW1Tb3VyY2UgPSB7XG4gICAgYmVnaW5EcmFnOiBmdW5jdGlvbiBiZWdpbkRyYWcocHJvcHMpIHtcbiAgICAgICAgLy8gUmV0dXJuIHRoZSBkYXRhIGRlc2NyaWJpbmcgdGhlIGRyYWdnZWQgaXRlbVxuICAgICAgICByZXR1cm4geyBpZDogcHJvcHMuaWQgfTtcbiAgICB9LFxuICAgIGVuZERyYWc6IGZ1bmN0aW9uIGVuZERyYWcocHJvcHMpIHtcbiAgICAgICAgcHJvcHMuZW5kU3dpdGNoaW5nKCk7XG4gICAgfVxufTtcblxudmFyIHNvcnRhYmxlSXRlbVRhcmdldCA9IHtcblxuICAgIGhvdmVyOiBmdW5jdGlvbiBob3Zlcihwcm9wcywgbW9uaXRvcikge1xuICAgICAgICB2YXIgZHJhZ2dlZElkID0gbW9uaXRvci5nZXRJdGVtKCkuaWQ7XG4gICAgICAgIGlmIChkcmFnZ2VkSWQgIT09IHByb3BzLmlkKSB7XG4gICAgICAgICAgICBwcm9wcy5zd2l0Y2hJdGVtcyhkcmFnZ2VkSWQsIHByb3BzLmlkKTtcbiAgICAgICAgfVxuICAgIH1cblxufTtcblxudmFyIHNvcnRhYmxlSXRlbSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogXCJzb3J0YWJsZUl0ZW1cIixcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBjb25uZWN0RHJhZ1NvdXJjZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICAgICAgY29ubmVjdERyb3BUYXJnZXQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsXG4gICAgICAgIGlzRHJhZ2dpbmc6IFJlYWN0LlByb3BUeXBlcy5ib29sLmlzUmVxdWlyZWQsXG4gICAgICAgIGlkOiBSZWFjdC5Qcm9wVHlwZXMuYW55LmlzUmVxdWlyZWQsXG4gICAgICAgIGxhYmVsOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgICAgIHN3aXRjaEl0ZW1zOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICAgICAgICByZW1vdmFibGU6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBvblJlbW92ZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmNcbiAgICB9LFxuXG4gICAgcmVtb3ZlQ2xpY2tlZDogZnVuY3Rpb24gcmVtb3ZlQ2xpY2tlZCgpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblJlbW92ZSh0aGlzLnByb3BzLmlkKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIC8vIFlvdXIgY29tcG9uZW50IHJlY2VpdmVzIGl0cyBvd24gcHJvcHMgYXMgdXN1YWxcbiAgICAgICAgdmFyIGlkID0gdGhpcy5wcm9wcy5pZDtcblxuICAgICAgICAvLyBUaGVzZSB0d28gcHJvcHMgYXJlIGluamVjdGVkIGJ5IFJlYWN0IERuRCxcbiAgICAgICAgLy8gYXMgZGVmaW5lZCBieSB5b3VyIGBjb2xsZWN0YCBmdW5jdGlvbiBhYm92ZTpcbiAgICAgICAgdmFyIGlzRHJhZ2dpbmcgPSB0aGlzLnByb3BzLmlzRHJhZ2dpbmc7XG4gICAgICAgIHZhciBjb25uZWN0RHJhZ1NvdXJjZSA9IHRoaXMucHJvcHMuY29ubmVjdERyYWdTb3VyY2U7XG4gICAgICAgIHZhciBjb25uZWN0RHJvcFRhcmdldCA9IHRoaXMucHJvcHMuY29ubmVjdERyb3BUYXJnZXQ7XG5cbiAgICAgICAgdmFyIHJlbW92ZTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMucmVtb3ZhYmxlKSB7XG4gICAgICAgICAgICByZW1vdmUgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFwic3BhblwiLCB7IGNsYXNzTmFtZTogXCJidXR0b24gbWRpIG1kaS1jbG9zZVwiLCBvbkNsaWNrOiB0aGlzLnJlbW92ZUNsaWNrZWQgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICBSZWFjdE1VSS5QYXBlcixcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICByZWY6IGZ1bmN0aW9uIChpbnN0YW5jZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0RHJvcFRhcmdldChSZWFjdERPTS5maW5kRE9NTm9kZShpbnN0YW5jZSkpO1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0RHJhZ1NvdXJjZShSZWFjdERPTS5maW5kRE9NTm9kZShpbnN0YW5jZSkpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgekRlcHRoOiAxLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7IG9wYWNpdHk6IGlzRHJhZ2dpbmcgPyAwIDogMSB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBcImRpdlwiLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiB0aGlzLnByb3BzLmNsYXNzTmFtZSB9LFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMubGFiZWwsXG4gICAgICAgICAgICAgICAgcmVtb3ZlXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5cbnZhciBOb25EcmFnZ2FibGVMaXN0SXRlbSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogXCJOb25EcmFnZ2FibGVMaXN0SXRlbVwiLFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciByZW1vdmU7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnJlbW92YWJsZSkge1xuICAgICAgICAgICAgcmVtb3ZlID0gUmVhY3QuY3JlYXRlRWxlbWVudChcInNwYW5cIiwgeyBjbGFzc05hbWU6IFwiYnV0dG9uIG1kaSBtZGktY2xvc2VcIiwgb25DbGljazogdGhpcy5yZW1vdmVDbGlja2VkIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgUmVhY3RNVUkuUGFwZXIsXG4gICAgICAgICAgICB7IHpEZXB0aDogMSB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBcImRpdlwiLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiB0aGlzLnByb3BzLmNsYXNzTmFtZSB9LFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMubGFiZWwsXG4gICAgICAgICAgICAgICAgcmVtb3ZlXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5cbnZhciBEcmFnZ2FibGVMaXN0SXRlbTtcbmlmICh3aW5kb3cuUmVhY3RETkQpIHtcbiAgICBEcmFnZ2FibGVMaXN0SXRlbSA9IFJlYWN0RE5ELmZsb3coUmVhY3RETkQuRHJhZ1NvdXJjZShfdXRpbERORC5UeXBlcy5TT1JUQUJMRV9MSVNUX0lURU0sIHNvcnRhYmxlSXRlbVNvdXJjZSwgX3V0aWxETkQuY29sbGVjdCksIFJlYWN0RE5ELkRyb3BUYXJnZXQoX3V0aWxETkQuVHlwZXMuU09SVEFCTEVfTElTVF9JVEVNLCBzb3J0YWJsZUl0ZW1UYXJnZXQsIF91dGlsRE5ELmNvbGxlY3REcm9wKSkoc29ydGFibGVJdGVtKTtcbn0gZWxzZSB7XG4gICAgRHJhZ2dhYmxlTGlzdEl0ZW0gPSBOb25EcmFnZ2FibGVMaXN0SXRlbTtcbn1cblxudmFyIFNvcnRhYmxlTGlzdCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogXCJTb3J0YWJsZUxpc3RcIixcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICB2YWx1ZXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheS5pc1JlcXVpcmVkLFxuICAgICAgICBvbk9yZGVyVXBkYXRlZDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIHJlbW92YWJsZTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIG9uUmVtb3ZlOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgY2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICBpdGVtQ2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nXG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICByZXR1cm4geyB2YWx1ZXM6IHRoaXMucHJvcHMudmFsdWVzIH07XG4gICAgfSxcbiAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKHByb3BzKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyB2YWx1ZXM6IHByb3BzLnZhbHVlcywgc3dpdGNoRGF0YTogbnVsbCB9KTtcbiAgICB9LFxuXG4gICAgZmluZEl0ZW1JbmRleDogZnVuY3Rpb24gZmluZEl0ZW1JbmRleChpdGVtSWQsIGRhdGEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoZGF0YVtpXVsncGF5bG9hZCddID09IGl0ZW1JZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSxcblxuICAgIHN3aXRjaEl0ZW1zOiBmdW5jdGlvbiBzd2l0Y2hJdGVtcyhvbGRJZCwgbmV3SWQpIHtcbiAgICAgICAgdmFyIG9sZEluZGV4ID0gdGhpcy5maW5kSXRlbUluZGV4KG9sZElkLCB0aGlzLnN0YXRlLnZhbHVlcyk7XG4gICAgICAgIHZhciBvbGRJdGVtID0gdGhpcy5zdGF0ZS52YWx1ZXNbb2xkSW5kZXhdO1xuICAgICAgICB2YXIgbmV3SW5kZXggPSB0aGlzLmZpbmRJdGVtSW5kZXgobmV3SWQsIHRoaXMuc3RhdGUudmFsdWVzKTtcbiAgICAgICAgdmFyIG5ld0l0ZW0gPSB0aGlzLnN0YXRlLnZhbHVlc1tuZXdJbmRleF07XG5cbiAgICAgICAgdmFyIGN1cnJlbnRWYWx1ZXMgPSB0aGlzLnN0YXRlLnZhbHVlcy5zbGljZSgpO1xuICAgICAgICBjdXJyZW50VmFsdWVzW29sZEluZGV4XSA9IG5ld0l0ZW07XG4gICAgICAgIGN1cnJlbnRWYWx1ZXNbbmV3SW5kZXhdID0gb2xkSXRlbTtcblxuICAgICAgICAvLyBDaGVjayB0aGF0IGl0IGRpZCBub3QgY29tZSBiYWNrIHRvIG9yaWdpbmFsIHN0YXRlXG4gICAgICAgIHZhciBvbGRQcmV2aW91cyA9IHRoaXMuZmluZEl0ZW1JbmRleChvbGRJZCwgdGhpcy5wcm9wcy52YWx1ZXMpO1xuICAgICAgICB2YXIgbmV3UHJldmlvdXMgPSB0aGlzLmZpbmRJdGVtSW5kZXgobmV3SWQsIHRoaXMucHJvcHMudmFsdWVzKTtcbiAgICAgICAgaWYgKG9sZFByZXZpb3VzID09IG5ld0luZGV4ICYmIG5ld1ByZXZpb3VzID09IG9sZEluZGV4KSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgdmFsdWVzOiBjdXJyZW50VmFsdWVzLCBzd2l0Y2hEYXRhOiBudWxsIH0pO1xuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIm5vIG1vcmUgbW92ZXNcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHZhbHVlczogY3VycmVudFZhbHVlcywgc3dpdGNoRGF0YTogeyBvbGRJZDogb2xkSWQsIG5ld0lkOiBuZXdJZCB9IH0pO1xuICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coe29sZElkOm9sZEluZGV4LCBuZXdJZDpuZXdJbmRleH0pO1xuICAgICAgICAgICAgfVxuICAgIH0sXG5cbiAgICBlbmRTd2l0Y2hpbmc6IGZ1bmN0aW9uIGVuZFN3aXRjaGluZygpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuc3dpdGNoRGF0YSkge1xuICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCBpdCBkaWQgbm90IGNvbWUgYmFjayB0byBvcmlnaW5hbCBzdGF0ZVxuICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMub25PcmRlclVwZGF0ZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLm9uT3JkZXJVcGRhdGVkKHRoaXMuc3RhdGUuc3dpdGNoRGF0YS5vbGRJZCwgdGhpcy5zdGF0ZS5zd2l0Y2hEYXRhLm5ld0lkLCB0aGlzLnN0YXRlLnZhbHVlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHN3aXRjaERhdGE6IG51bGwgfSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgc3dpdGNoSXRlbXMgPSB0aGlzLnN3aXRjaEl0ZW1zO1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgIFwiZGl2XCIsXG4gICAgICAgICAgICB7IGNsYXNzTmFtZTogdGhpcy5wcm9wcy5jbGFzc05hbWUgfSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUudmFsdWVzLm1hcCgoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChEcmFnZ2FibGVMaXN0SXRlbSwge1xuICAgICAgICAgICAgICAgICAgICBpZDogaXRlbS5wYXlsb2FkLFxuICAgICAgICAgICAgICAgICAgICBrZXk6IGl0ZW0ucGF5bG9hZCxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGl0ZW0udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoSXRlbXM6IHN3aXRjaEl0ZW1zLFxuICAgICAgICAgICAgICAgICAgICBlbmRTd2l0Y2hpbmc6IHRoaXMuZW5kU3dpdGNoaW5nLFxuICAgICAgICAgICAgICAgICAgICByZW1vdmFibGU6IHRoaXMucHJvcHMucmVtb3ZhYmxlLFxuICAgICAgICAgICAgICAgICAgICBvblJlbW92ZTogdGhpcy5wcm9wcy5vblJlbW92ZSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiB0aGlzLnByb3BzLml0ZW1DbGFzc05hbWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcykpXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5cbmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gU29ydGFibGVMaXN0O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfTGlzdEVudHJ5Tm9kZUxpc3RlbmVyTWl4aW4gPSByZXF1aXJlKCcuL0xpc3RFbnRyeU5vZGVMaXN0ZW5lck1peGluJyk7XG5cbnZhciBfTGlzdEVudHJ5Tm9kZUxpc3RlbmVyTWl4aW4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTGlzdEVudHJ5Tm9kZUxpc3RlbmVyTWl4aW4pO1xuXG52YXIgX0xpc3RFbnRyeSA9IHJlcXVpcmUoJy4vTGlzdEVudHJ5Jyk7XG5cbnZhciBfSW5saW5lRWRpdG9yID0gcmVxdWlyZSgnLi9JbmxpbmVFZGl0b3InKTtcblxudmFyIF9JbmxpbmVFZGl0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfSW5saW5lRWRpdG9yKTtcblxuLyoqXG4gKiBTcGVjaWZpYyBsaXN0IGVudHJ5IHJlbmRlcmVkIGFzIGEgdGFibGUgcm93LiBOb3QgYSByZWFsIHRhYmxlLCBDU1MgdXNlZC5cbiAqL1xuZXhwb3J0c1snZGVmYXVsdCddID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnVGFibGVMaXN0RW50cnknLFxuXG4gICAgbWl4aW5zOiBbX0xpc3RFbnRyeU5vZGVMaXN0ZW5lck1peGluMlsnZGVmYXVsdCddXSxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBub2RlOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihBanhwTm9kZSksXG4gICAgICAgIHRhYmxlS2V5czogUmVhY3QuUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgICByZW5kZXJBY3Rpb25zOiBSZWFjdC5Qcm9wVHlwZXMuZnVuY1xuICAgICAgICAvLyBTZWUgYWxzbyBMaXN0RW50cnkgbm9kZXNcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIGFjdGlvbnMgPSB0aGlzLnByb3BzLmFjdGlvbnM7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnJlbmRlckFjdGlvbnMpIHtcbiAgICAgICAgICAgIGFjdGlvbnMgPSB0aGlzLnByb3BzLnJlbmRlckFjdGlvbnModGhpcy5wcm9wcy5ub2RlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjZWxscyA9IFtdO1xuICAgICAgICB2YXIgZmlyc3RLZXkgPSB0cnVlO1xuICAgICAgICB2YXIgbWV0YSA9IHRoaXMucHJvcHMubm9kZS5nZXRNZXRhZGF0YSgpO1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gdGhpcy5wcm9wcy50YWJsZUtleXMpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5wcm9wcy50YWJsZUtleXMuaGFzT3duUHJvcGVydHkoa2V5KSkgY29udGludWU7XG5cbiAgICAgICAgICAgIHZhciBkYXRhID0gdGhpcy5wcm9wcy50YWJsZUtleXNba2V5XTtcbiAgICAgICAgICAgIHZhciBzdHlsZSA9IGRhdGFbJ3dpZHRoJ10gPyB7IHdpZHRoOiBkYXRhWyd3aWR0aCddIH0gOiBudWxsO1xuICAgICAgICAgICAgdmFyIHZhbHVlID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIHJhd1ZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKGRhdGEucmVuZGVyQ2VsbCkge1xuICAgICAgICAgICAgICAgIGRhdGFbJ25hbWUnXSA9IGtleTtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGRhdGEucmVuZGVyQ2VsbCh0aGlzLnByb3BzLm5vZGUsIGRhdGEpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChrZXkgPT09ICdhanhwX21vZGlmdGltZScgJiYgbWV0YS5nZXQoJ2FqeHBfcmVsYXRpdmV0aW1lJykpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IG1ldGEuZ2V0KCdhanhwX3JlbGF0aXZldGltZScpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IG1ldGEuZ2V0KGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByYXdWYWx1ZSA9IG1ldGEuZ2V0KGtleSk7XG4gICAgICAgICAgICB2YXIgaW5saW5lRWRpdG9yID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgJiYgdGhpcy5zdGF0ZS5pbmxpbmVFZGl0aW9uICYmIGZpcnN0S2V5KSB7XG4gICAgICAgICAgICAgICAgaW5saW5lRWRpdG9yID0gUmVhY3QuY3JlYXRlRWxlbWVudChfSW5saW5lRWRpdG9yMlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGU6IHRoaXMucHJvcHMubm9kZSxcbiAgICAgICAgICAgICAgICAgICAgb25DbG9zZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBpbmxpbmVFZGl0aW9uOiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMuc3RhdGUuaW5saW5lRWRpdGlvbkNhbGxiYWNrXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdmFyIF9zdHlsZSA9IHRoaXMucHJvcHMuc3R5bGUgfHwge307XG4gICAgICAgICAgICAgICAgX3N0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnN0eWxlID0gX3N0eWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2VsbHMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgICAgICB7IGtleToga2V5LCBjbGFzc05hbWU6ICdjZWxsIGNlbGwtJyArIGtleSwgdGl0bGU6IHJhd1ZhbHVlLCBzdHlsZTogc3R5bGUsICdkYXRhLWxhYmVsJzogZGF0YVsnbGFiZWwnXSB9LFxuICAgICAgICAgICAgICAgIGlubGluZUVkaXRvcixcbiAgICAgICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgKSk7XG4gICAgICAgICAgICBmaXJzdEtleSA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX0xpc3RFbnRyeS5EcmFnRHJvcExpc3RFbnRyeSwgX2V4dGVuZHMoe30sIHRoaXMucHJvcHMsIHtcbiAgICAgICAgICAgIGljb25DZWxsOiBudWxsLFxuICAgICAgICAgICAgZmlyc3RMaW5lOiBjZWxscyxcbiAgICAgICAgICAgIGFjdGlvbnM6IGFjdGlvbnNcbiAgICAgICAgfSkpO1xuICAgIH1cblxufSk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfdXRpbE1lc3NhZ2VzQ29uc3VtZXJNaXhpbiA9IHJlcXVpcmUoJy4uL3V0aWwvTWVzc2FnZXNDb25zdW1lck1peGluJyk7XG5cbnZhciBfdXRpbE1lc3NhZ2VzQ29uc3VtZXJNaXhpbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF91dGlsTWVzc2FnZXNDb25zdW1lck1peGluKTtcblxudmFyIF9Tb3J0Q29sdW1ucyA9IHJlcXVpcmUoJy4vU29ydENvbHVtbnMnKTtcblxudmFyIF9Tb3J0Q29sdW1uczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Tb3J0Q29sdW1ucyk7XG5cbnZhciBfTGlzdFBhZ2luYXRvciA9IHJlcXVpcmUoJy4vTGlzdFBhZ2luYXRvcicpO1xuXG52YXIgX0xpc3RQYWdpbmF0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTGlzdFBhZ2luYXRvcik7XG5cbi8qKlxuICogU3BlY2lmaWMgaGVhZGVyIGZvciBUYWJsZSBsYXlvdXQsIHJlYWRpbmcgbWV0YWRhdGEgZnJvbSBub2RlIGFuZCB1c2luZyBrZXlzXG4gKi9cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ1RhYmxlTGlzdEhlYWRlcicsXG5cbiAgICBtaXhpbnM6IFtfdXRpbE1lc3NhZ2VzQ29uc3VtZXJNaXhpbjJbJ2RlZmF1bHQnXV0sXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgdGFibGVLZXlzOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICAgIGxvYWRpbmc6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICByZWxvYWQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBkbTogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW9EYXRhTW9kZWwpLFxuICAgICAgICBub2RlOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihBanhwTm9kZSksXG4gICAgICAgIG9uSGVhZGVyQ2xpY2s6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBzb3J0aW5nSW5mbzogUmVhY3QuUHJvcFR5cGVzLm9iamVjdFxuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIGhlYWRlcnMgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICBwYWdpbmF0b3IgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm5vZGUuZ2V0TWV0YWRhdGEoKS5nZXQoXCJwYWdpbmF0aW9uRGF0YVwiKSAmJiB0aGlzLnByb3BzLm5vZGUuZ2V0TWV0YWRhdGEoKS5nZXQoXCJwYWdpbmF0aW9uRGF0YVwiKS5nZXQoJ3RvdGFsJykgPiAxKSB7XG4gICAgICAgICAgICBwYWdpbmF0b3IgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9MaXN0UGFnaW5hdG9yMlsnZGVmYXVsdCddLCB7IGRhdGFNb2RlbDogdGhpcy5wcm9wcy5kbSwgbm9kZTogdGhpcy5wcm9wcy5ub2RlIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgUmVhY3RNVUkuVG9vbGJhcixcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAndG9vbGJhclRhYmxlSGVhZGVyJyB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChfU29ydENvbHVtbnMyWydkZWZhdWx0J10sIF9leHRlbmRzKHsgZGlzcGxheU1vZGU6ICd0YWJsZUhlYWRlcicgfSwgdGhpcy5wcm9wcywgeyBjb2x1bW5DbGlja2VkOiB0aGlzLnByb3BzLm9uSGVhZGVyQ2xpY2sgfSkpLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBSZWFjdE1VSS5Ub29sYmFyR3JvdXAsXG4gICAgICAgICAgICAgICAgeyBmbG9hdDogJ3JpZ2h0JyB9LFxuICAgICAgICAgICAgICAgIHBhZ2luYXRvcixcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLkZvbnRJY29uLCB7XG4gICAgICAgICAgICAgICAgICAgIGtleTogMSxcbiAgICAgICAgICAgICAgICAgICAgdG9vbHRpcDogdGhpcy5jb250ZXh0LmdldE1lc3NhZ2UoJzE0OScsICcnKSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcImljb24tcmVmcmVzaFwiICsgKHRoaXMucHJvcHMubG9hZGluZyA/IFwiIHJvdGF0aW5nXCIgOiBcIlwiKSxcbiAgICAgICAgICAgICAgICAgICAgb25DbGljazogdGhpcy5wcm9wcy5yZWxvYWRcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmFkZGl0aW9uYWxBY3Rpb25zXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfVXRpbHMgPSByZXF1aXJlKCcuL1V0aWxzJyk7XG5cbnZhciBfVXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXRpbHMpO1xuXG52YXIgX01lbnVJdGVtc0NvbnN1bWVyID0gcmVxdWlyZSgnLi9NZW51SXRlbXNDb25zdW1lcicpO1xuXG52YXIgX01lbnVJdGVtc0NvbnN1bWVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX01lbnVJdGVtc0NvbnN1bWVyKTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcbnZhciBSZWFjdERPTSA9IHJlcXVpcmUoJ3JlYWN0LWRvbScpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgTWVudSA9IF9yZXF1aXJlLk1lbnU7XG5cbnZhciBDb250cm9sbGVyID0gcmVxdWlyZSgncHlkaW8vbW9kZWwvY29udHJvbGxlcicpO1xuXG52YXIgQnV0dG9uTWVudSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ0J1dHRvbk1lbnUnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIGJ1dHRvblRpdGxlOiBSZWFjdC5Qcm9wVHlwZXMub25lT2ZUeXBlKFtSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLCBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0XSkuaXNSZXF1aXJlZCxcbiAgICAgICAgbWVudUl0ZW1zOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXkuaXNSZXF1aXJlZCxcbiAgICAgICAgY2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICByYWlzZWQ6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBkaXJlY3Rpb246IFJlYWN0LlByb3BUeXBlcy5vbmVPZihbJ2xlZnQnLCAncmlnaHQnXSlcbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9wZW5PbkV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLnB5ZGlvLm9ic2VydmUodGhpcy5wcm9wcy5vcGVuT25FdmVudCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF90aGlzLnNob3dNZW51KCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHsgc2hvd01lbnU6IGZhbHNlIH07XG4gICAgfSxcblxuICAgIHNob3dNZW51OiBmdW5jdGlvbiBzaG93TWVudShldmVudCkge1xuICAgICAgICB2YXIgYW5jaG9yID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgIGFuY2hvciA9IGV2ZW50LmN1cnJlbnRUYXJnZXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbmNob3IgPSB0aGlzLl9idXR0b25ET007XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzaG93TWVudTogdHJ1ZSxcbiAgICAgICAgICAgIGFuY2hvcjogYW5jaG9yXG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBtZW51Q2xpY2tlZDogZnVuY3Rpb24gbWVudUNsaWNrZWQoZXZlbnQsIGluZGV4LCBvYmplY3QpIHtcbiAgICAgICAgLy9vYmplY3QucGF5bG9hZCgpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2hvd01lbnU6IGZhbHNlIH0pO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIGxhYmVsID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICB0aGlzLnByb3BzLmJ1dHRvblRpdGxlLFxuICAgICAgICAgICAgJyAnLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudCgnc3BhbicsIHsgY2xhc3NOYW1lOiAnaWNvbi1jYXJldC1kb3duJyB9KVxuICAgICAgICApO1xuICAgICAgICB2YXIgYnV0dG9uID0gdW5kZWZpbmVkO1xuICAgICAgICB2YXIgcHJvcHMgPSB7XG4gICAgICAgICAgICBwcmltYXJ5OiB0aGlzLnByb3BzLnByaW1hcnksXG4gICAgICAgICAgICBzZWNvbmRhcnk6IHRoaXMucHJvcHMuc2Vjb25kYXJ5LFxuICAgICAgICAgICAgZGlzYWJsZWQ6IHRoaXMucHJvcHMuZGlzYWJlbGQsXG4gICAgICAgICAgICBsYWJlbDogbGFiZWwsXG4gICAgICAgICAgICBvblRvdWNoVGFwOiB0aGlzLnNob3dNZW51XG4gICAgICAgIH07XG4gICAgICAgIHZhciBtZW51SXRlbXMgPSB0aGlzLnByb3BzLm1lbnVJdGVtcztcbiAgICAgICAgdmFyIF9zdGF0ZSA9IHRoaXMuc3RhdGU7XG4gICAgICAgIHZhciBzaG93TWVudSA9IF9zdGF0ZS5zaG93TWVudTtcbiAgICAgICAgdmFyIGFuY2hvciA9IF9zdGF0ZS5hbmNob3I7XG5cbiAgICAgICAgaWYgKG1lbnVJdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLnJhaXNlZCkge1xuICAgICAgICAgICAgICAgIGJ1dHRvbiA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWF0ZXJpYWxVSS5SYWlzZWRCdXR0b24sIF9leHRlbmRzKHt9LCBwcm9wcywgeyBzdHlsZTogdGhpcy5wcm9wcy5idXR0b25TdHlsZSwgbGFiZWxTdHlsZTogdGhpcy5wcm9wcy5idXR0b25MYWJlbFN0eWxlLCByZWY6IGZ1bmN0aW9uIChiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpczIuX2J1dHRvbkRPTSA9IFJlYWN0RE9NLmZpbmRET01Ob2RlKGIpO1xuICAgICAgICAgICAgICAgICAgICB9IH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYnV0dG9uID0gUmVhY3QuY3JlYXRlRWxlbWVudChNYXRlcmlhbFVJLkZsYXRCdXR0b24sIF9leHRlbmRzKHt9LCBwcm9wcywgeyBzdHlsZTogdGhpcy5wcm9wcy5idXR0b25TdHlsZSwgbGFiZWxTdHlsZTogdGhpcy5wcm9wcy5idXR0b25MYWJlbFN0eWxlLCByZWY6IGZ1bmN0aW9uIChiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpczIuX2J1dHRvbkRPTSA9IFJlYWN0RE9NLmZpbmRET01Ob2RlKGIpO1xuICAgICAgICAgICAgICAgICAgICB9IH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgIHsgaWQ6IHRoaXMucHJvcHMuaWQsIGNsYXNzTmFtZTogdGhpcy5wcm9wcy5jbGFzc05hbWUgfSxcbiAgICAgICAgICAgIGJ1dHRvbixcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgTWF0ZXJpYWxVSS5Qb3BvdmVyLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAnbWVudVBvcG92ZXInLFxuICAgICAgICAgICAgICAgICAgICBvcGVuOiBzaG93TWVudSxcbiAgICAgICAgICAgICAgICAgICAgYW5jaG9yRWw6IGFuY2hvcixcbiAgICAgICAgICAgICAgICAgICAgYW5jaG9yT3JpZ2luOiB7IGhvcml6b250YWw6IHRoaXMucHJvcHMuZGlyZWN0aW9uIHx8ICdsZWZ0JywgdmVydGljYWw6ICdib3R0b20nIH0sXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldE9yaWdpbjogeyBob3Jpem9udGFsOiB0aGlzLnByb3BzLmRpcmVjdGlvbiB8fCAnbGVmdCcsIHZlcnRpY2FsOiAndG9wJyB9LFxuICAgICAgICAgICAgICAgICAgICBvblJlcXVlc3RDbG9zZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMyLnNldFN0YXRlKHsgc2hvd01lbnU6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogeyBtYXJnaW5Ub3A6IDEgfSxcbiAgICAgICAgICAgICAgICAgICAgdXNlTGF5ZXJGb3JDbGlja0F3YXk6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBfVXRpbHMyWydkZWZhdWx0J10uaXRlbXNUb01lbnUobWVudUl0ZW1zLCB0aGlzLm1lbnVDbGlja2VkKVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cblxufSk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IF9NZW51SXRlbXNDb25zdW1lcjJbJ2RlZmF1bHQnXShCdXR0b25NZW51KTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfcHlkaW9Nb2RlbENvbnRleHRNZW51ID0gcmVxdWlyZSgncHlkaW8vbW9kZWwvY29udGV4dC1tZW51Jyk7XG5cbnZhciBfcHlkaW9Nb2RlbENvbnRleHRNZW51MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3B5ZGlvTW9kZWxDb250ZXh0TWVudSk7XG5cbnZhciBfVXRpbHMgPSByZXF1aXJlKCcuL1V0aWxzJyk7XG5cbnZhciBfVXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXRpbHMpO1xuXG52YXIgX1BvcHVwTWVudSA9IHJlcXVpcmUoJy4vUG9wdXBNZW51Jyk7XG5cbnZhciBfUG9wdXBNZW51MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1BvcHVwTWVudSk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBDb21wb25lbnQgPSBfcmVxdWlyZS5Db21wb25lbnQ7XG5cbnZhciBkaW1zID0ge1xuICAgIE1FTlVfSVRFTV9IRUlHSFQ6IDMyLCAvLzQ4IGlmIG5vdCBkaXNwbGF5OmNvbXBhY3RcbiAgICBNRU5VX1NFUF9IRUlHSFQ6IDE2LFxuICAgIE1FTlVfVkVSVElDQUxfUEFERElORzogOCxcbiAgICBNRU5VX1dJRFRIOiAyNTAsXG4gICAgT0ZGU0VUX1ZFUlRJQ0FMOiA4LFxuICAgIE9GRlNFVF9IT1JJWk9OVEFMOiA4XG59O1xuXG52YXIgQ29udGV4dE1lbnUgPSAoZnVuY3Rpb24gKF9Db21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoQ29udGV4dE1lbnUsIF9Db21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gQ29udGV4dE1lbnUoKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDb250ZXh0TWVudSk7XG5cbiAgICAgICAgX0NvbXBvbmVudC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIENvbnRleHRNZW51LnByb3RvdHlwZS5tb2RlbE9wZW4gPSBmdW5jdGlvbiBtb2RlbE9wZW4obm9kZSkge1xuICAgICAgICB2YXIgcG9zaXRpb24gPSBfcHlkaW9Nb2RlbENvbnRleHRNZW51MlsnZGVmYXVsdCddLmdldEluc3RhbmNlKCkuZ2V0UG9zaXRpb24oKTtcbiAgICAgICAgdmFyIGl0ZW1zID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAobm9kZSkge1xuICAgICAgICAgICAgdmFyIGRtID0gcHlkaW8uZ2V0Q29udGV4dEhvbGRlcigpO1xuICAgICAgICAgICAgaWYgKGRtLmdldFNlbGVjdGVkTm9kZXMoKS5pbmRleE9mKG5vZGUpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3Blbk1lbnUoJ3NlbGVjdGlvbkNvbnRleHQnLCBwb3NpdGlvbik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHB5ZGlvLm9ic2VydmVPbmNlKFwiYWN0aW9uc19yZWZyZXNoZWRcIiwgKGZ1bmN0aW9uIChkYXRhTW9kZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVuTWVudSgnc2VsZWN0aW9uQ29udGV4dCcsIHBvc2l0aW9uKTtcbiAgICAgICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgICAgICBkbS5zZXRTZWxlY3RlZE5vZGVzKFtub2RlXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm9wZW5NZW51KCdnZW5lcmljQ29udGV4dCcsIHBvc2l0aW9uKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBDb250ZXh0TWVudS5wcm90b3R5cGUub3Blbk1lbnUgPSBmdW5jdGlvbiBvcGVuTWVudShjb250ZXh0LCBwb3NpdGlvbikge1xuICAgICAgICB2YXIgaXRlbXMgPSB0aGlzLmNvbXB1dGVNZW51SXRlbXMoY29udGV4dCk7XG4gICAgICAgIHRoaXMuX2l0ZW1zID0gaXRlbXM7XG4gICAgICAgIHZhciBtb2JpbGUgPSB0aGlzLnByb3BzLnB5ZGlvLlVJLk1PQklMRV9FWFRFTlNJT05TO1xuICAgICAgICBpZiAoIW1vYmlsZSkge1xuICAgICAgICAgICAgcG9zaXRpb24gPSB0aGlzLmNvbXB1dGVWaXNpYmxlUG9zaXRpb24ocG9zaXRpb24sIGl0ZW1zKTtcbiAgICAgICAgICAgIHRoaXMucmVmc1snbWVudSddLnNob3dNZW51KHtcbiAgICAgICAgICAgICAgICB0b3A6IHBvc2l0aW9uLnksXG4gICAgICAgICAgICAgICAgbGVmdDogcG9zaXRpb24ueFxuICAgICAgICAgICAgfSwgaXRlbXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5yZWZzWydtZW51J10uc2hvd01lbnUoe1xuICAgICAgICAgICAgICAgIGJvdHRvbTogMCxcbiAgICAgICAgICAgICAgICBsZWZ0OiAwLFxuICAgICAgICAgICAgICAgIHJpZ2h0OiAwLFxuICAgICAgICAgICAgICAgIGhlaWdodDogMjAwLFxuICAgICAgICAgICAgICAgIHpJbmRleDogMTAwMDAsXG4gICAgICAgICAgICAgICAgb3ZlcmZsb3dZOiAnYXV0bydcbiAgICAgICAgICAgIH0sIGl0ZW1zKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBDb250ZXh0TWVudS5wcm90b3R5cGUuY29tcHV0ZU1lbnVJdGVtcyA9IGZ1bmN0aW9uIGNvbXB1dGVNZW51SXRlbXMoY29udGV4dCkge1xuICAgICAgICB2YXIgYWN0aW9ucyA9IHRoaXMucHJvcHMucHlkaW8uQ29udHJvbGxlci5nZXRDb250ZXh0QWN0aW9ucyhjb250ZXh0LCBbJ2lubGluZScsICdpbmZvX3BhbmVsJywgJ2luZm9fcGFuZWxfc2hhcmUnXSk7XG4gICAgICAgIHJldHVybiBfVXRpbHMyWydkZWZhdWx0J10ucHlkaW9BY3Rpb25zVG9JdGVtcyhhY3Rpb25zKTtcbiAgICB9O1xuXG4gICAgQ29udGV4dE1lbnUucHJvdG90eXBlLmNvbXB1dGVWaXNpYmxlUG9zaXRpb24gPSBmdW5jdGlvbiBjb21wdXRlVmlzaWJsZVBvc2l0aW9uKHBvc2l0aW9uLCBpdGVtcykge1xuICAgICAgICB2YXIgbWVudUhlaWdodCA9IGRpbXMuTUVOVV9WRVJUSUNBTF9QQURESU5HICogMjtcbiAgICAgICAgaXRlbXMubWFwKGZ1bmN0aW9uIChpdCkge1xuICAgICAgICAgICAgaWYgKGl0LnNlcGFyYXRvcikgbWVudUhlaWdodCArPSBkaW1zLk1FTlVfU0VQX0hFSUdIVDtlbHNlIG1lbnVIZWlnaHQgKz0gZGltcy5NRU5VX0lURU1fSEVJR0hUO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIG1lbnVXaWR0aCA9IGRpbXMuTUVOVV9XSURUSDtcbiAgICAgICAgdmFyIHdpbmRvd1cgPSBNYXRoLm1heChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgsIHdpbmRvdy5pbm5lcldpZHRoIHx8IDApO1xuICAgICAgICB2YXIgd2luZG93SCA9IE1hdGgubWF4KGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQsIHdpbmRvdy5pbm5lckhlaWdodCB8fCAwKTtcbiAgICAgICAgaWYgKHBvc2l0aW9uLnggKyBtZW51V2lkdGggPiB3aW5kb3dXKSB7XG4gICAgICAgICAgICBwb3NpdGlvbi54ID0gTWF0aC5tYXgocG9zaXRpb24ueCAtIG1lbnVXaWR0aCwgMTApIC0gZGltcy5PRkZTRVRfSE9SSVpPTlRBTDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBvc2l0aW9uLnggKz0gZGltcy5PRkZTRVRfSE9SSVpPTlRBTDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zaXRpb24ueSArIG1lbnVIZWlnaHQgPiB3aW5kb3dIKSB7XG4gICAgICAgICAgICBwb3NpdGlvbi55ID0gTWF0aC5tYXgocG9zaXRpb24ueSAtIG1lbnVIZWlnaHQsIDEwKSAtIGRpbXMuT0ZGU0VUX1ZFUlRJQ0FMO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcG9zaXRpb24ueSArPSBkaW1zLk9GRlNFVF9WRVJUSUNBTDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcG9zaXRpb247XG4gICAgfTtcblxuICAgIENvbnRleHRNZW51LnByb3RvdHlwZS5jb21wb25lbnREaWRNb3VudCA9IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB0aGlzLl9tb2RlbE9wZW4gPSB0aGlzLm1vZGVsT3Blbi5iaW5kKHRoaXMpO1xuICAgICAgICBfcHlkaW9Nb2RlbENvbnRleHRNZW51MlsnZGVmYXVsdCddLmdldEluc3RhbmNlKCkub2JzZXJ2ZShcIm9wZW5cIiwgdGhpcy5fbW9kZWxPcGVuKTtcbiAgICB9O1xuXG4gICAgQ29udGV4dE1lbnUucHJvdG90eXBlLmNvbXBvbmVudFdpbGxVbm1vdW50ID0gZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIF9weWRpb01vZGVsQ29udGV4dE1lbnUyWydkZWZhdWx0J10uZ2V0SW5zdGFuY2UoKS5zdG9wT2JzZXJ2aW5nKFwib3BlblwiLCB0aGlzLl9tb2RlbE9wZW4pO1xuICAgIH07XG5cbiAgICBDb250ZXh0TWVudS5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgbW9iaWxlID0gdGhpcy5wcm9wcy5weWRpby5VSS5NT0JJTEVfRVhURU5TSU9OUztcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX1BvcHVwTWVudTJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgcmVmOiAnbWVudScsXG4gICAgICAgICAgICBtZW51SXRlbXM6IHRoaXMuX2l0ZW1zIHx8IFtdLFxuICAgICAgICAgICAgb25NZW51Q2xvc2VkOiB0aGlzLnByb3BzLm9uTWVudUNsb3NlZCxcbiAgICAgICAgICAgIG1lbnVQcm9wczogbW9iaWxlID8geyB3aWR0aDogNjAwLCBhdXRvV2lkdGg6IGZhbHNlLCBkZXNrdG9wOiBmYWxzZSB9IDoge30sXG4gICAgICAgICAgICB6RGVwdGg6IG1vYmlsZSA/IDIgOiAxXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICByZXR1cm4gQ29udGV4dE1lbnU7XG59KShDb21wb25lbnQpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBDb250ZXh0TWVudTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfVXRpbHMgPSByZXF1aXJlKCcuL1V0aWxzJyk7XG5cbnZhciBfVXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXRpbHMpO1xuXG52YXIgX01lbnVJdGVtc0NvbnN1bWVyID0gcmVxdWlyZSgnLi9NZW51SXRlbXNDb25zdW1lcicpO1xuXG52YXIgX01lbnVJdGVtc0NvbnN1bWVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX01lbnVJdGVtc0NvbnN1bWVyKTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIEljb25CdXR0b24gPSBfcmVxdWlyZS5JY29uQnV0dG9uO1xudmFyIFBvcG92ZXIgPSBfcmVxdWlyZS5Qb3BvdmVyO1xuXG52YXIgSWNvbkJ1dHRvbk1lbnUgPSAoZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoSWNvbkJ1dHRvbk1lbnUsIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gSWNvbkJ1dHRvbk1lbnUocHJvcHMsIGNvbnRleHQpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEljb25CdXR0b25NZW51KTtcblxuICAgICAgICBfUmVhY3QkQ29tcG9uZW50LmNhbGwodGhpcywgcHJvcHMsIGNvbnRleHQpO1xuICAgICAgICB0aGlzLnN0YXRlID0geyBzaG93TWVudTogZmFsc2UgfTtcbiAgICB9XG5cbiAgICBJY29uQnV0dG9uTWVudS5wcm90b3R5cGUuc2hvd01lbnUgPSBmdW5jdGlvbiBzaG93TWVudShldmVudCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNob3dNZW51OiB0cnVlLFxuICAgICAgICAgICAgYW5jaG9yOiBldmVudC5jdXJyZW50VGFyZ2V0XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBJY29uQnV0dG9uTWVudS5wcm90b3R5cGUuY2xvc2VNZW51ID0gZnVuY3Rpb24gY2xvc2VNZW51KGV2ZW50LCBpbmRleCwgbWVudUl0ZW0pIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dNZW51OiBmYWxzZSB9KTtcbiAgICB9O1xuXG4gICAgSWNvbkJ1dHRvbk1lbnUucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiBcInRvb2xiYXJzLWJ1dHRvbi1tZW51IFwiICsgKHRoaXMucHJvcHMuY2xhc3NOYW1lID8gdGhpcy5wcm9wcy5jbGFzc05hbWUgOiAnJykgfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoSWNvbkJ1dHRvbiwge1xuICAgICAgICAgICAgICAgIHJlZjogJ21lbnVCdXR0b24nLFxuICAgICAgICAgICAgICAgIHRvb2x0aXA6IHRoaXMucHJvcHMuYnV0dG9uVGl0bGUsXG4gICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogdGhpcy5wcm9wcy5idXR0b25DbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogdGhpcy5zaG93TWVudS5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIGljb25TdHlsZTogdGhpcy5wcm9wcy5idXR0b25TdHlsZVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFBvcG92ZXIsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBvcGVuOiB0aGlzLnN0YXRlLnNob3dNZW51LFxuICAgICAgICAgICAgICAgICAgICBhbmNob3JFbDogdGhpcy5zdGF0ZS5hbmNob3IsXG4gICAgICAgICAgICAgICAgICAgIGFuY2hvck9yaWdpbjogeyBob3Jpem9udGFsOiB0aGlzLnByb3BzLnBvcG92ZXJEaXJlY3Rpb24gfHwgJ3JpZ2h0JywgdmVydGljYWw6IHRoaXMucHJvcHMucG9wb3ZlclRhcmdldFBvc2l0aW9uIHx8ICdib3R0b20nIH0sXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldE9yaWdpbjogeyBob3Jpem9udGFsOiB0aGlzLnByb3BzLnBvcG92ZXJEaXJlY3Rpb24gfHwgJ3JpZ2h0JywgdmVydGljYWw6ICd0b3AnIH0sXG4gICAgICAgICAgICAgICAgICAgIG9uUmVxdWVzdENsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IHNob3dNZW51OiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgdXNlTGF5ZXJGb3JDbGlja0F3YXk6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBfVXRpbHMyWydkZWZhdWx0J10uaXRlbXNUb01lbnUodGhpcy5wcm9wcy5tZW51SXRlbXMsIHRoaXMuY2xvc2VNZW51LmJpbmQodGhpcyksIGZhbHNlLCB0aGlzLnByb3BzLm1lbnVQcm9wcyB8fCB1bmRlZmluZWQpXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBJY29uQnV0dG9uTWVudTtcbn0pKFJlYWN0LkNvbXBvbmVudCk7XG5cbkljb25CdXR0b25NZW51LnByb3BUeXBlcyA9IHtcbiAgICBidXR0b25UaXRsZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgIGJ1dHRvbkNsYXNzTmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgIGNsYXNzTmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICBwb3BvdmVyRGlyZWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMub25lT2YoWydyaWdodCcsICdsZWZ0J10pLFxuICAgIHBvcG92ZXJQb3NpdGlvbjogUmVhY3QuUHJvcFR5cGVzLm9uZU9mKFsndG9wJywgJ2JvdHRvbSddKSxcbiAgICBtZW51UHJvcHM6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgbWVudUl0ZW1zOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXkuaXNSZXF1aXJlZFxufTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gX01lbnVJdGVtc0NvbnN1bWVyMlsnZGVmYXVsdCddKEljb25CdXR0b25NZW51KTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgSWNvbkJ1dHRvbiA9IF9yZXF1aXJlLkljb25CdXR0b247XG52YXIgUG9wb3ZlciA9IF9yZXF1aXJlLlBvcG92ZXI7XG5cbnZhciBJY29uQnV0dG9uUG9wb3ZlciA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhJY29uQnV0dG9uUG9wb3ZlciwgX1JlYWN0JENvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBJY29uQnV0dG9uUG9wb3Zlcihwcm9wcywgY29udGV4dCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgSWNvbkJ1dHRvblBvcG92ZXIpO1xuXG4gICAgICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IHNob3dQb3BvdmVyOiBmYWxzZSB9O1xuICAgIH1cblxuICAgIEljb25CdXR0b25Qb3BvdmVyLnByb3RvdHlwZS5zaG93UG9wb3ZlciA9IGZ1bmN0aW9uIHNob3dQb3BvdmVyKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2hvd1BvcG92ZXI6IHRydWUsXG4gICAgICAgICAgICBhbmNob3I6IGV2ZW50LmN1cnJlbnRUYXJnZXRcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIEljb25CdXR0b25Qb3BvdmVyLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICB7IGNsYXNzTmFtZTogXCJ0b29sYmFycy1idXR0b24tbWVudSBcIiArICh0aGlzLnByb3BzLmNsYXNzTmFtZSA/IHRoaXMucHJvcHMuY2xhc3NOYW1lIDogJycpIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEljb25CdXR0b24sIHtcbiAgICAgICAgICAgICAgICByZWY6ICdtZW51QnV0dG9uJyxcbiAgICAgICAgICAgICAgICB0b29sdGlwOiB0aGlzLnByb3BzLmJ1dHRvblRpdGxlLFxuICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU6IHRoaXMucHJvcHMuYnV0dG9uQ2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IHRoaXMuc2hvd1BvcG92ZXIuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBpY29uU3R5bGU6IHRoaXMucHJvcHMuYnV0dG9uU3R5bGVcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBQb3BvdmVyLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgb3BlbjogdGhpcy5zdGF0ZS5zaG93UG9wb3ZlcixcbiAgICAgICAgICAgICAgICAgICAgYW5jaG9yRWw6IHRoaXMuc3RhdGUuYW5jaG9yLFxuICAgICAgICAgICAgICAgICAgICBhbmNob3JPcmlnaW46IHsgaG9yaXpvbnRhbDogdGhpcy5wcm9wcy5kaXJlY3Rpb24gfHwgJ3JpZ2h0JywgdmVydGljYWw6ICdib3R0b20nIH0sXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldE9yaWdpbjogeyBob3Jpem9udGFsOiB0aGlzLnByb3BzLmRpcmVjdGlvbiB8fCAncmlnaHQnLCB2ZXJ0aWNhbDogJ3RvcCcgfSxcbiAgICAgICAgICAgICAgICAgICAgb25SZXF1ZXN0Q2xvc2U6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgc2hvd1BvcG92ZXI6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB1c2VMYXllckZvckNsaWNrQXdheTogZmFsc2VcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMucG9wb3ZlckNvbnRlbnRcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEljb25CdXR0b25Qb3BvdmVyO1xufSkoUmVhY3QuQ29tcG9uZW50KTtcblxuSWNvbkJ1dHRvblBvcG92ZXIucHJvcFR5cGVzID0ge1xuICAgIGJ1dHRvblRpdGxlOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgYnV0dG9uQ2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgY2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIGRpcmVjdGlvbjogUmVhY3QuUHJvcFR5cGVzLm9uZU9mKFsncmlnaHQnLCAnbGVmdCddKSxcbiAgICBwb3BvdmVyQ29udGVudDogUmVhY3QuUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkXG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBJY29uQnV0dG9uUG9wb3Zlcjtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfVXRpbHMgPSByZXF1aXJlKCcuL1V0aWxzJyk7XG5cbnZhciBfVXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXRpbHMpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIENvbnRyb2xsZXIgPSByZXF1aXJlKCdweWRpby9tb2RlbC9jb250cm9sbGVyJyk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IGZ1bmN0aW9uIChDb21wb25lbnQpIHtcbiAgICB2YXIgV3JhcHBlZCA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgICAgICBfaW5oZXJpdHMoV3JhcHBlZCwgX1JlYWN0JENvbXBvbmVudCk7XG5cbiAgICAgICAgZnVuY3Rpb24gV3JhcHBlZChwcm9wcywgY29udGV4dCkge1xuICAgICAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFdyYXBwZWQpO1xuXG4gICAgICAgICAgICBfUmVhY3QkQ29tcG9uZW50LmNhbGwodGhpcywgcHJvcHMsIGNvbnRleHQpO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgICAgICBtZW51SXRlbXM6IHRoaXMucHJvcHMubWVudUl0ZW1zIHx8IFtdXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgV3JhcHBlZC5wcm90b3R5cGUuY29tcG9uZW50RGlkTW91bnQgPSBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmNvbnRyb2xsZXIgJiYgIXRoaXMucHJvcHMubWVudUl0ZW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb2JzZXJ2ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhY3Rpb25zID0gX3RoaXMucHJvcHMuY29udHJvbGxlci5nZXRDb250ZXh0QWN0aW9ucygnZ2VuZXJpY0NvbnRleHQnLCBudWxsLCBfdGhpcy5wcm9wcy50b29sYmFycyk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBtZW51SXRlbXMgPSBfVXRpbHMyWydkZWZhdWx0J10ucHlkaW9BY3Rpb25zVG9JdGVtcyhhY3Rpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBtZW51SXRlbXM6IG1lbnVJdGVtcyB9KTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmNvbnRyb2xsZXIgPT09IHRoaXMucHJvcHMucHlkaW8uQ29udHJvbGxlcikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnB5ZGlvLm9ic2VydmUoXCJhY3Rpb25zX3JlZnJlc2hlZFwiLCB0aGlzLl9vYnNlcnZlcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5jb250cm9sbGVyLm9ic2VydmUoXCJhY3Rpb25zX3JlZnJlc2hlZFwiLCB0aGlzLl9vYnNlcnZlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX29ic2VydmVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgV3JhcHBlZC5wcm90b3R5cGUuY29tcG9uZW50V2lsbFVubW91bnQgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vYnNlcnZlcikge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmNvbnRyb2xsZXIgPT09IHRoaXMucHJvcHMucHlkaW8uQ29udHJvbGxlcikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnB5ZGlvLnN0b3BPYnNlcnZpbmcoXCJhY3Rpb25zX3JlZnJlc2hlZFwiLCB0aGlzLl9vYnNlcnZlcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5jb250cm9sbGVyLnN0b3BPYnNlcnZpbmcoXCJhY3Rpb25zX3JlZnJlc2hlZFwiLCB0aGlzLl9vYnNlcnZlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIFdyYXBwZWQucHJvdG90eXBlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykge1xuICAgICAgICAgICAgaWYgKG5leHRQcm9wcy5tZW51SXRlbXMgJiYgbmV4dFByb3BzLm1lbnVJdGVtcyAhPT0gdGhpcy5wcm9wcy5tZW51SXRlbXMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgbWVudUl0ZW1zOiBuZXh0UHJvcHMubWVudUl0ZW1zIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIFdyYXBwZWQucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KENvbXBvbmVudCwgX2V4dGVuZHMoe30sIHRoaXMucHJvcHMsIHsgbWVudUl0ZW1zOiB0aGlzLnN0YXRlLm1lbnVJdGVtcyB9KSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIFdyYXBwZWQ7XG4gICAgfSkoUmVhY3QuQ29tcG9uZW50KTtcblxuICAgIFdyYXBwZWQucHJvcFR5cGVzID0ge1xuICAgICAgICBtZW51SXRlbXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcbiAgICAgICAgdG9vbGJhcnM6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcbiAgICAgICAgY29udHJvbGxlcjogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoQ29udHJvbGxlciksXG4gICAgICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbylcbiAgICB9O1xuXG4gICAgcmV0dXJuIFdyYXBwZWQ7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfVXRpbHMgPSByZXF1aXJlKCcuL1V0aWxzJyk7XG5cbnZhciBfVXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXRpbHMpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIFJlYWN0RE9NID0gcmVxdWlyZSgncmVhY3QtZG9tJyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBNZW51ID0gX3JlcXVpcmUuTWVudTtcbnZhciBQYXBlciA9IF9yZXF1aXJlLlBhcGVyO1xuZXhwb3J0c1snZGVmYXVsdCddID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnUG9wdXBNZW51JyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBtZW51SXRlbXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheS5pc1JlcXVpcmVkLFxuICAgICAgICBvbkV4dGVybmFsQ2xpY2tDaGVja0VsZW1lbnRzOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgY2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICBzdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgb25NZW51Q2xvc2VkOiBSZWFjdC5Qcm9wVHlwZXMuZnVuY1xuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHsgc2hvd01lbnU6IGZhbHNlLCBtZW51SXRlbXM6IHRoaXMucHJvcHMubWVudUl0ZW1zIH07XG4gICAgfSxcbiAgICBzaG93TWVudTogZnVuY3Rpb24gc2hvd01lbnUoKSB7XG4gICAgICAgIHZhciBzdHlsZSA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMCB8fCBhcmd1bWVudHNbMF0gPT09IHVuZGVmaW5lZCA/IG51bGwgOiBhcmd1bWVudHNbMF07XG4gICAgICAgIHZhciBtZW51SXRlbXMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyBudWxsIDogYXJndW1lbnRzWzFdO1xuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2hvd01lbnU6IHRydWUsXG4gICAgICAgICAgICBzdHlsZTogc3R5bGUsXG4gICAgICAgICAgICBtZW51SXRlbXM6IG1lbnVJdGVtcyA/IG1lbnVJdGVtcyA6IHRoaXMuc3RhdGUubWVudUl0ZW1zXG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgaGlkZU1lbnU6IGZ1bmN0aW9uIGhpZGVNZW51KGV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93TWVudTogZmFsc2UgfSk7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5vbk1lbnVDbG9zZWQpIHRoaXMucHJvcHMub25NZW51Q2xvc2VkKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG5vZGUgPSBSZWFjdERPTS5maW5kRE9NTm9kZSh0aGlzLnJlZnMubWVudUNvbnRhaW5lcik7XG4gICAgICAgIGlmIChub2RlLmNvbnRhaW5zKGV2ZW50LnRhcmdldCkgfHwgbm9kZSA9PT0gZXZlbnQudGFyZ2V0KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2hvd01lbnU6IGZhbHNlIH0pO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5vbk1lbnVDbG9zZWQpIHRoaXMucHJvcHMub25NZW51Q2xvc2VkKCk7XG4gICAgfSxcbiAgICBjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHRoaXMuX29ic2VydmVyID0gdGhpcy5oaWRlTWVudTtcbiAgICB9LFxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50OiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9vYnNlcnZlciwgZmFsc2UpO1xuICAgIH0sXG4gICAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wczogZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHtcbiAgICAgICAgaWYgKG5leHRQcm9wcy5tZW51SXRlbXMpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBtZW51SXRlbXM6IG5leHRQcm9wcy5tZW51SXRlbXMgfSk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGNvbXBvbmVudERpZFVwZGF0ZTogZnVuY3Rpb24gY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wcywgbmV4dFByb3BzKSB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLnNob3dNZW51KSB7XG4gICAgICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX29ic2VydmVyLCBmYWxzZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX29ic2VydmVyLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgbWVudUNsaWNrZWQ6IGZ1bmN0aW9uIG1lbnVDbGlja2VkKGV2ZW50LCBpbmRleCwgbWVudUl0ZW0pIHtcbiAgICAgICAgdGhpcy5oaWRlTWVudSgpO1xuICAgIH0sXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cbiAgICAgICAgdmFyIHN0eWxlID0gdGhpcy5zdGF0ZS5zdHlsZSB8fCB7fTtcbiAgICAgICAgc3R5bGUgPSBfZXh0ZW5kcyh7fSwgc3R5bGUsIHsgekluZGV4OiAxMDAwIH0pO1xuICAgICAgICB2YXIgbWVudSA9IF9VdGlsczJbJ2RlZmF1bHQnXS5pdGVtc1RvTWVudSh0aGlzLnN0YXRlLm1lbnVJdGVtcywgdGhpcy5tZW51Q2xpY2tlZCwgZmFsc2UsIF9leHRlbmRzKHsgZGVza3RvcDogdHJ1ZSwgZGlzcGxheTogJ3JpZ2h0Jywgd2lkdGg6IDI1MCB9LCB0aGlzLnByb3BzLm1lbnVQcm9wcykpO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5zaG93TWVudSkge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgUGFwZXIsXG4gICAgICAgICAgICAgICAgeyB6RGVwdGg6IHRoaXMucHJvcHMuekRlcHRoIHx8IDEsIHJlZjogJ21lbnVDb250YWluZXInLCBjbGFzc05hbWU6ICdtZW51LXBvc2l0aW9uZXInLCBzdHlsZTogc3R5bGUgfSxcbiAgICAgICAgICAgICAgICBtZW51XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbn0pO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG52YXIgX1V0aWxzID0gcmVxdWlyZSgnLi9VdGlscycpO1xuXG52YXIgX1V0aWxzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1V0aWxzKTtcblxudmFyIF9JY29uQnV0dG9uTWVudSA9IHJlcXVpcmUoJy4vSWNvbkJ1dHRvbk1lbnUnKTtcblxudmFyIF9JY29uQnV0dG9uTWVudTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9JY29uQnV0dG9uTWVudSk7XG5cbnZhciBfQnV0dG9uTWVudSA9IHJlcXVpcmUoJy4vQnV0dG9uTWVudScpO1xuXG52YXIgX0J1dHRvbk1lbnUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQnV0dG9uTWVudSk7XG5cbnZhciBfSWNvbkJ1dHRvblBvcG92ZXIgPSByZXF1aXJlKCcuL0ljb25CdXR0b25Qb3BvdmVyJyk7XG5cbnZhciBfSWNvbkJ1dHRvblBvcG92ZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfSWNvbkJ1dHRvblBvcG92ZXIpO1xuXG4oZnVuY3Rpb24gKGdsb2JhbCkge1xuICAgIGV4cG9ydHNbJ2RlZmF1bHQnXSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICAgICAgZGlzcGxheU5hbWU6ICdUb29sYmFyJyxcblxuICAgICAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgICAgIHRvb2xiYXJzOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXksXG4gICAgICAgICAgICBncm91cE90aGVyTGlzdDogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuICAgICAgICAgICAgcmVuZGVyaW5nVHlwZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgICAgIGNvbnRyb2xsZXI6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKENvbnRyb2xsZXIpLFxuICAgICAgICAgICAgdG9vbGJhclN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICAgICAgYnV0dG9uU3R5bGU6IFJlYWN0LlByb3BUeXBlcy5vYmplY3RcbiAgICAgICAgfSxcblxuICAgICAgICBjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgICAgICB0aGlzLl9vYnNlcnZlciA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzTW91bnRlZCgpKSByZXR1cm47XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwczogdGhpcy5wcm9wcy5jb250cm9sbGVyLmdldFRvb2xiYXJzQWN0aW9ucyh0aGlzLnByb3BzLnRvb2xiYXJzLCB0aGlzLnByb3BzLmdyb3VwT3RoZXJMaXN0KVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmNvbnRyb2xsZXIgPT09IHB5ZGlvLkNvbnRyb2xsZXIpIHtcbiAgICAgICAgICAgICAgICBweWRpby5vYnNlcnZlKFwiYWN0aW9uc19yZWZyZXNoZWRcIiwgdGhpcy5fb2JzZXJ2ZXIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmNvbnRyb2xsZXIub2JzZXJ2ZShcImFjdGlvbnNfcmVmcmVzaGVkXCIsIHRoaXMuX29ic2VydmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBjb21wb25lbnRXaWxsVW5tb3VudDogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5jb250cm9sbGVyID09PSBweWRpby5Db250cm9sbGVyKSB7XG4gICAgICAgICAgICAgICAgcHlkaW8uc3RvcE9ic2VydmluZyhcImFjdGlvbnNfcmVmcmVzaGVkXCIsIHRoaXMuX29ic2VydmVyKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5jb250cm9sbGVyLnN0b3BPYnNlcnZpbmcoXCJhY3Rpb25zX3JlZnJlc2hlZFwiLCB0aGlzLl9vYnNlcnZlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wczogZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHtcbiAgICAgICAgICAgIGlmIChuZXh0UHJvcHMudG9vbGJhcnMgIT09IHRoaXMucHJvcHMudG9vbGJhcnMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzOiB0aGlzLnByb3BzLmNvbnRyb2xsZXIuZ2V0VG9vbGJhcnNBY3Rpb25zKG5leHRQcm9wcy50b29sYmFycywgbmV4dFByb3BzLmdyb3VwT3RoZXJMaXN0KVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBncm91cHM6IHRoaXMucHJvcHMuY29udHJvbGxlci5nZXRUb29sYmFyc0FjdGlvbnModGhpcy5wcm9wcy50b29sYmFycywgdGhpcy5wcm9wcy5ncm91cE90aGVyTGlzdClcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sXG5cbiAgICAgICAgZ2V0RGVmYXVsdFByb3BzOiBmdW5jdGlvbiBnZXREZWZhdWx0UHJvcHMoKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXI6IGdsb2JhbC5weWRpby5Db250cm9sbGVyLFxuICAgICAgICAgICAgICAgIHJlbmRlcmluZ1R5cGU6ICdidXR0b24nLFxuICAgICAgICAgICAgICAgIGdyb3VwT3RoZXJMaXN0OiBbXVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcblxuICAgICAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgICAgIHZhciBncm91cHMgPSB0aGlzLnN0YXRlLmdyb3VwcztcbiAgICAgICAgICAgIHZhciBhY3Rpb25zID0gW107XG4gICAgICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcztcbiAgICAgICAgICAgIHZhciB0b29sYmFycyA9IF9wcm9wcy50b29sYmFycztcbiAgICAgICAgICAgIHZhciByZW5kZXJpbmdUeXBlID0gX3Byb3BzLnJlbmRlcmluZ1R5cGU7XG4gICAgICAgICAgICB2YXIgZ3JvdXBPdGhlckxpc3QgPSBfcHJvcHMuZ3JvdXBPdGhlckxpc3Q7XG4gICAgICAgICAgICB2YXIgYnV0dG9uU3R5bGUgPSBfcHJvcHMuYnV0dG9uU3R5bGU7XG4gICAgICAgICAgICB2YXIgdG9vbHRpcFBvc2l0aW9uID0gX3Byb3BzLnRvb2x0aXBQb3NpdGlvbjtcbiAgICAgICAgICAgIHZhciBjb250cm9sbGVyID0gX3Byb3BzLmNvbnRyb2xsZXI7XG5cbiAgICAgICAgICAgIHZhciBhbGxUb29sYmFycyA9IFtdLmNvbmNhdCh0b29sYmFycyk7XG4gICAgICAgICAgICBpZiAoZ3JvdXBPdGhlckxpc3QubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgYWxsVG9vbGJhcnMgPSBhbGxUb29sYmFycy5jb25jYXQoWydNT1JFX0FDVElPTiddKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGFsbFRvb2xiYXJzLm1hcChmdW5jdGlvbiAoYmFyTmFtZSkge1xuICAgICAgICAgICAgICAgIGlmICghZ3JvdXBzLmhhcyhiYXJOYW1lKSkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGdyb3Vwcy5nZXQoYmFyTmFtZSkubWFwKGZ1bmN0aW9uIChhY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFjdGlvbi5kZW55KSByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIHZhciBtZW51SXRlbXMgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3BvdmVyQ29udGVudCA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnVUaXRsZSA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnVJY29uID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICB2YXIgYWN0aW9uTmFtZSA9IGFjdGlvbi5vcHRpb25zLm5hbWU7XG5cbiAgICAgICAgICAgICAgICAgICAgbWVudVRpdGxlID0gYWN0aW9uLm9wdGlvbnMudGV4dDtcbiAgICAgICAgICAgICAgICAgICAgbWVudUljb24gPSBhY3Rpb24ub3B0aW9ucy5pY29uX2NsYXNzO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChiYXJOYW1lID09PSAnTU9SRV9BQ1RJT04nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdWJJdGVtcyA9IGFjdGlvbi5zdWJNZW51SXRlbXMuZHluYW1pY0l0ZW1zO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpdGVtcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Ykl0ZW1zLm1hcChmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvYmouc2VwYXJhdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtcy5wdXNoKG9iaik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAob2JqLmFjdGlvbklkICYmICFvYmouYWN0aW9uSWQuZGVueSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMucHVzaChvYmouYWN0aW9uSWQuZ2V0TWVudURhdGEoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW51SXRlbXMgPSBfVXRpbHMyWydkZWZhdWx0J10ucHlkaW9BY3Rpb25zVG9JdGVtcyhpdGVtcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSgpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbi5zdWJNZW51SXRlbXMuc3RhdGljSXRlbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnVJdGVtcyA9IF9VdGlsczJbJ2RlZmF1bHQnXS5weWRpb0FjdGlvbnNUb0l0ZW1zKGFjdGlvbi5zdWJNZW51SXRlbXMuc3RhdGljSXRlbXMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbi5zdWJNZW51SXRlbXMuZHluYW1pY0J1aWxkZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnVJdGVtcyA9IF9VdGlsczJbJ2RlZmF1bHQnXS5weWRpb0FjdGlvbnNUb0l0ZW1zKGFjdGlvbi5zdWJNZW51SXRlbXMuZHluYW1pY0J1aWxkZXIoY29udHJvbGxlcikpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbi5zdWJNZW51SXRlbXMucG9wb3ZlckNvbnRlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvcG92ZXJDb250ZW50ID0gYWN0aW9uLnN1Yk1lbnVJdGVtcy5wb3BvdmVyQ29udGVudDtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHt9XG4gICAgICAgICAgICAgICAgICAgIHZhciBpZCA9ICdhY3Rpb24tJyArIGFjdGlvbi5vcHRpb25zLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZW5kZXJpbmdUeXBlID09PSAnYnV0dG9uLWljb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZW51VGl0bGUgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2J1dHRvbi1pY29uJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCB7IGNsYXNzTmFtZTogXCJidXR0b24taWNvbi1pY29uIFwiICsgbWVudUljb24gfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2J1dHRvbi1pY29uLWxhYmVsJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW51VGl0bGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChtZW51SXRlbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZW5kZXJpbmdUeXBlID09PSAnYnV0dG9uJyB8fCByZW5kZXJpbmdUeXBlID09PSAnYnV0dG9uLWljb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9ucy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoX0J1dHRvbk1lbnUyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5OiBhY3Rpb25OYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25UaXRsZTogbWVudVRpdGxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW51SXRlbXM6IG1lbnVJdGVtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9uTGFiZWxTdHlsZTogYnV0dG9uU3R5bGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbnMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KF9JY29uQnV0dG9uTWVudTJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IGFjdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uTWVudUNsaWNrZWQ6IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5wYXlsb2FkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbkNsYXNzTmFtZTogbWVudUljb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvblRpdGxlOiBtZW51VGl0bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbnVJdGVtczogbWVudUl0ZW1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25TdHlsZTogYnV0dG9uU3R5bGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocG9wb3ZlckNvbnRlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbnMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KF9JY29uQnV0dG9uUG9wb3ZlcjJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleTogYWN0aW9uTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbkNsYXNzTmFtZTogbWVudUljb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9uVGl0bGU6IG1lbnVUaXRsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25TdHlsZTogYnV0dG9uU3R5bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9wb3ZlckNvbnRlbnQ6IHBvcG92ZXJDb250ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2xpY2sgPSBmdW5jdGlvbiBjbGljayhzeW50aEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uLmFwcGx5KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlbmRlcmluZ1R5cGUgPT09ICdidXR0b24taWNvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb25zLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5GbGF0QnV0dG9uLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleTogYWN0aW9uTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBpZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogY2xpY2ssXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBtZW51VGl0bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsU3R5bGU6IGJ1dHRvblN0eWxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZW5kZXJpbmdUeXBlID09PSAnYnV0dG9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbnMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KE1hdGVyaWFsVUkuRmxhdEJ1dHRvbiwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IGFjdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IGNsaWNrLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogbWVudVRpdGxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbFN0eWxlOiBidXR0b25TdHlsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9ucy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWF0ZXJpYWxVSS5JY29uQnV0dG9uLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleTogYWN0aW9uTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogbWVudUljb24gKyAnICcgKyBpZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvblN0eWxlOiBidXR0b25TdHlsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogY2xpY2ssXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXA6IG1lbnVUaXRsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9vbHRpcFBvc2l0aW9uOiB0b29sdGlwUG9zaXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIGNOYW1lID0gdGhpcy5wcm9wcy5jbGFzc05hbWUgPyB0aGlzLnByb3BzLmNsYXNzTmFtZSA6ICcnO1xuICAgICAgICAgICAgY05hbWUgKz0gJyAnICsgJ3Rvb2xiYXInO1xuICAgICAgICAgICAgaWYgKCFhY3Rpb25zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNOYW1lICs9ICcgZW1wdHktdG9vbGJhcic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogY05hbWUsIHN0eWxlOiB0aGlzLnByb3BzLnRvb2xiYXJTdHlsZSwgaWQ6IHRoaXMucHJvcHMuaWQgfSxcbiAgICAgICAgICAgICAgICBhY3Rpb25zXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICB9KTtcbn0pKHdpbmRvdyk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgRGl2aWRlciA9IF9yZXF1aXJlLkRpdmlkZXI7XG52YXIgTWVudSA9IF9yZXF1aXJlLk1lbnU7XG52YXIgTWVudUl0ZW0gPSBfcmVxdWlyZS5NZW51SXRlbTtcbnZhciBGb250SWNvbiA9IF9yZXF1aXJlLkZvbnRJY29uO1xuXG5mdW5jdGlvbiBweWRpb0FjdGlvbnNUb0l0ZW1zKCkge1xuICAgIHZhciBhY3Rpb25zID0gYXJndW1lbnRzLmxlbmd0aCA8PSAwIHx8IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gW10gOiBhcmd1bWVudHNbMF07XG5cbiAgICB2YXIgaXRlbXMgPSBbXTtcbiAgICB2YXIgbGFzdElzU2VwYXJhdG9yID0gZmFsc2U7XG4gICAgYWN0aW9ucy5tYXAoKGZ1bmN0aW9uIChhY3Rpb24sIGluZGV4KSB7XG4gICAgICAgIGlmIChhY3Rpb24uc2VwYXJhdG9yKSB7XG4gICAgICAgICAgICBpZiAobGFzdElzU2VwYXJhdG9yKSByZXR1cm47XG4gICAgICAgICAgICBpdGVtcy5wdXNoKGFjdGlvbik7XG4gICAgICAgICAgICBsYXN0SXNTZXBhcmF0b3IgPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RJc1NlcGFyYXRvciA9IGZhbHNlO1xuICAgICAgICB2YXIgbGFiZWwgPSBhY3Rpb24ucmF3X25hbWUgPyBhY3Rpb24ucmF3X25hbWUgOiBhY3Rpb24ubmFtZTtcbiAgICAgICAgdmFyIGljb25DbGFzcyA9IGFjdGlvbi5pY29uX2NsYXNzO1xuICAgICAgICB2YXIgcGF5bG9hZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGFjdGlvbi5zdWJNZW51KSB7XG4gICAgICAgICAgICB2YXIgc3ViSXRlbXMgPSBhY3Rpb24uc3ViTWVudUJlZm9yZVNob3cgPyBweWRpb0FjdGlvbnNUb0l0ZW1zKGFjdGlvbi5zdWJNZW51QmVmb3JlU2hvdygpKSA6IGFjdGlvbi5zdWJNZW51O1xuICAgICAgICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgICAgICAgICAgdGV4dDogbGFiZWwsXG4gICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogaWNvbkNsYXNzLFxuICAgICAgICAgICAgICAgIHN1Ykl0ZW1zOiBzdWJJdGVtc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgICAgICAgICB0ZXh0OiBsYWJlbCxcbiAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lOiBpY29uQ2xhc3MsXG4gICAgICAgICAgICAgICAgcGF5bG9hZDogYWN0aW9uLmNhbGxiYWNrXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0pLmJpbmQodGhpcykpO1xuICAgIGlmIChsYXN0SXNTZXBhcmF0b3IpIHtcbiAgICAgICAgaXRlbXMgPSBpdGVtcy5zbGljZSgwLCBpdGVtcy5sZW5ndGggLSAxKTtcbiAgICB9XG4gICAgaWYgKGl0ZW1zLmxlbmd0aCAmJiBpdGVtc1swXSAmJiBpdGVtc1swXS5zZXBhcmF0b3IpIHtcbiAgICAgICAgaXRlbXMuc2hpZnQoKTtcbiAgICB9XG4gICAgcmV0dXJuIGl0ZW1zO1xufVxuXG5mdW5jdGlvbiBpdGVtc1RvTWVudShpdGVtcywgY2xvc2VNZW51Q2FsbGJhY2spIHtcbiAgICB2YXIgc3ViSXRlbXNPbmx5ID0gYXJndW1lbnRzLmxlbmd0aCA8PSAyIHx8IGFyZ3VtZW50c1syXSA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiBhcmd1bWVudHNbMl07XG4gICAgdmFyIG1lbnVQcm9wcyA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMyB8fCBhcmd1bWVudHNbM10gPT09IHVuZGVmaW5lZCA/IHt9IDogYXJndW1lbnRzWzNdO1xuXG4gICAgbWVudVByb3BzID0gX2V4dGVuZHMoe1xuICAgICAgICBkaXNwbGF5OiAnbm9ybWFsJyxcbiAgICAgICAgd2lkdGg6IDIxNixcbiAgICAgICAgZGVza3RvcDogdHJ1ZSxcbiAgICAgICAgYXV0b1dpZHRoOiBmYWxzZVxuICAgIH0sIG1lbnVQcm9wcyk7XG5cbiAgICB2YXIgbWVudUl0ZW1zID0gaXRlbXMubWFwKGZ1bmN0aW9uIChpdGVtLCBpbmRleCkge1xuXG4gICAgICAgIGlmIChpdGVtLnNlcGFyYXRvcikgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRGl2aWRlciwgeyBrZXk6IFwiZGl2aWRlclwiICsgaW5kZXggfSk7XG5cbiAgICAgICAgdmFyIHN1Ykl0ZW1zID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgcGF5bG9hZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGl0ZW0uc3ViSXRlbXMpIHtcbiAgICAgICAgICAgIHN1Ykl0ZW1zID0gaXRlbXNUb01lbnUoaXRlbS5zdWJJdGVtcywgY2xvc2VNZW51Q2FsbGJhY2ssIHRydWUpO1xuICAgICAgICB9IGVsc2UgaWYgKGl0ZW0ucGF5bG9hZCkge1xuICAgICAgICAgICAgcGF5bG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBpdGVtLnBheWxvYWQoKTtcbiAgICAgICAgICAgICAgICBjbG9zZU1lbnVDYWxsYmFjaygpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBsZWZ0SWNvbiA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHJpZ2h0SWNvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgdmFyIGljb25DbGFzc05hbWUgPSBpdGVtLmljb25DbGFzc05hbWU7dmFyIGluc2V0ID0gZmFsc2U7XG4gICAgICAgIGlmIChpY29uQ2xhc3NOYW1lID09PSAnX19JTlNFVF9fJykge1xuICAgICAgICAgICAgaWNvbkNsYXNzTmFtZSA9ICcnO1xuICAgICAgICAgICAgaW5zZXQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1lbnVQcm9wcy5kaXNwbGF5ID09PSAnbm9ybWFsJykge1xuICAgICAgICAgICAgbGVmdEljb24gPSBpY29uQ2xhc3NOYW1lID8gUmVhY3QuY3JlYXRlRWxlbWVudChGb250SWNvbiwgeyBjbGFzc05hbWU6IGl0ZW0uaWNvbkNsYXNzTmFtZSArICcgbWVudS1pY29ucycsIHN0eWxlOiB7IGZvbnRTaXplOiAxNiwgcGFkZGluZzogNSB9IH0pIDogbnVsbDtcbiAgICAgICAgfSBlbHNlIGlmIChtZW51UHJvcHMuZGlzcGxheSA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICAgICAgcmlnaHRJY29uID0gaWNvbkNsYXNzTmFtZSA/IFJlYWN0LmNyZWF0ZUVsZW1lbnQoRm9udEljb24sIHsgY2xhc3NOYW1lOiBpdGVtLmljb25DbGFzc05hbWUgKyAnIG1lbnUtaWNvbnMnLCBzdHlsZTogeyBmb250U2l6ZTogMTYsIHBhZGRpbmc6IDUgfSB9KSA6IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmlnaHRJY29uID0gc3ViSXRlbXMgJiYgc3ViSXRlbXMubGVuZ3RoID8gUmVhY3QuY3JlYXRlRWxlbWVudChGb250SWNvbiwgeyBjbGFzc05hbWU6ICdtZGkgbWRpLW1lbnUtcmlnaHQgbWVudS1pY29ucycgfSkgOiByaWdodEljb247XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWVudUl0ZW0sIHtcbiAgICAgICAgICAgIGtleTogaXRlbS50ZXh0LFxuICAgICAgICAgICAgcHJpbWFyeVRleHQ6IGl0ZW0udGV4dCxcbiAgICAgICAgICAgIGluc2V0Q2hpbGRyZW46IGluc2V0LFxuICAgICAgICAgICAgbGVmdEljb246IGxlZnRJY29uLFxuICAgICAgICAgICAgcmlnaHRJY29uOiByaWdodEljb24sXG4gICAgICAgICAgICBvblRvdWNoVGFwOiBwYXlsb2FkLFxuICAgICAgICAgICAgbWVudUl0ZW1zOiBzdWJJdGVtc1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGlmIChzdWJJdGVtc09ubHkpIHtcbiAgICAgICAgcmV0dXJuIG1lbnVJdGVtcztcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgIE1lbnUsXG4gICAgICAgICAgICBtZW51UHJvcHMsXG4gICAgICAgICAgICBtZW51SXRlbXNcbiAgICAgICAgKTtcbiAgICB9XG59XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IHsgcHlkaW9BY3Rpb25zVG9JdGVtczogcHlkaW9BY3Rpb25zVG9JdGVtcywgaXRlbXNUb01lbnU6IGl0ZW1zVG9NZW51IH07XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIENvbXBvbmVudCA9IF9yZXF1aXJlLkNvbXBvbmVudDtcbnZhciBQcm9wVHlwZXMgPSBfcmVxdWlyZS5Qcm9wVHlwZXM7XG5cbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgVGV4dEZpZWxkID0gX3JlcXVpcmUyLlRleHRGaWVsZDtcbnZhciBGbGF0QnV0dG9uID0gX3JlcXVpcmUyLkZsYXRCdXR0b247XG5cbnZhciBfcmVxdWlyZSRyZXF1aXJlTGliID0gcmVxdWlyZSgncHlkaW8nKS5yZXF1aXJlTGliKCdib290Jyk7XG5cbnZhciBQeWRpb0NvbnRleHRDb25zdW1lciA9IF9yZXF1aXJlJHJlcXVpcmVMaWIuUHlkaW9Db250ZXh0Q29uc3VtZXI7XG5cbi8qKlxuICogU2ltcGxlIGZvcm0gZm9yIGNyZWF0aW5nIGEgdGVhbVxuICovXG5cbnZhciBUZWFtQ3JlYXRpb25Gb3JtID0gKGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7XG4gICAgX2luaGVyaXRzKFRlYW1DcmVhdGlvbkZvcm0sIF9Db21wb25lbnQpO1xuXG4gICAgVGVhbUNyZWF0aW9uRm9ybS51cGRhdGVUZWFtVXNlcnMgPSBmdW5jdGlvbiB1cGRhdGVUZWFtVXNlcnModGVhbSwgb3BlcmF0aW9uLCB1c2VycywgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHRlYW1JZCA9IHRlYW0uaWQucmVwbGFjZSgnL0FKWFBfVEVBTS8nLCAnJyk7XG4gICAgICAgIHZhciBjbGVhclVzZXJDYWNoZSA9IGZ1bmN0aW9uIGNsZWFyVXNlckNhY2hlKHVJZCkge1xuICAgICAgICAgICAgTWV0YUNhY2hlU2VydmljZS5nZXRJbnN0YW5jZSgpLmRlbGV0ZUtleSgndXNlcl9wdWJsaWNfZGF0YS1yaWNoJywgdUlkKTtcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gJ2FkZCcpIHtcbiAgICAgICAgICAgIHVzZXJzLmZvckVhY2goZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgICAgICAgICAgICB2YXIgdXNlcklkID0gdXNlci5nZXRJZCA/IHVzZXIuZ2V0SWQoKSA6IHVzZXIuaWQ7XG4gICAgICAgICAgICAgICAgUHlkaW9Vc2Vycy5DbGllbnQuYWRkVXNlclRvVGVhbSh0ZWFtSWQsIHVzZXJJZCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgIGNsZWFyVXNlckNhY2hlKHVzZXJJZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChvcGVyYXRpb24gPT09ICdkZWxldGUnKSB7XG4gICAgICAgICAgICB1c2Vycy5mb3JFYWNoKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICAgICAgICAgICAgdmFyIHVzZXJJZCA9IHVzZXIuZ2V0SWQgPyB1c2VyLmdldElkKCkgOiB1c2VyLmlkO1xuICAgICAgICAgICAgICAgIFB5ZGlvVXNlcnMuQ2xpZW50LnJlbW92ZVVzZXJGcm9tVGVhbSh0ZWFtSWQsIHVzZXJJZCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgIGNsZWFyVXNlckNhY2hlKHVzZXJJZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChvcGVyYXRpb24gPT09ICdjcmVhdGUnKSB7XG4gICAgICAgICAgICBQeWRpb1VzZXJzLkNsaWVudC5zYXZlU2VsZWN0aW9uQXNUZWFtKHRlYW1JZCwgdXNlcnMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIHVzZXJzLmZvckVhY2goZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgICAgICAgICAgICBjbGVhclVzZXJDYWNoZSh1c2VyLmdldElkID8gdXNlci5nZXRJZCgpIDogdXNlci5pZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBUZWFtQ3JlYXRpb25Gb3JtKHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBUZWFtQ3JlYXRpb25Gb3JtKTtcblxuICAgICAgICBfQ29tcG9uZW50LmNhbGwodGhpcywgcHJvcHMsIGNvbnRleHQpO1xuICAgICAgICB0aGlzLnN0YXRlID0geyB2YWx1ZTogJycgfTtcbiAgICB9XG5cbiAgICBUZWFtQ3JlYXRpb25Gb3JtLnByb3RvdHlwZS5vbkNoYW5nZSA9IGZ1bmN0aW9uIG9uQ2hhbmdlKGUsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyB2YWx1ZTogdmFsdWUgfSk7XG4gICAgfTtcblxuICAgIFRlYW1DcmVhdGlvbkZvcm0ucHJvdG90eXBlLnN1Ym1pdENyZWF0aW9uRm9ybSA9IGZ1bmN0aW9uIHN1Ym1pdENyZWF0aW9uRm9ybSgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5zdGF0ZS52YWx1ZTtcbiAgICAgICAgVGVhbUNyZWF0aW9uRm9ybS51cGRhdGVUZWFtVXNlcnMoeyBpZDogdmFsdWUgfSwgJ2NyZWF0ZScsIFtdLCB0aGlzLnByb3BzLm9uVGVhbUNyZWF0ZWQpO1xuICAgIH07XG5cbiAgICBUZWFtQ3JlYXRpb25Gb3JtLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gdGhpcy5wcm9wcy5nZXRNZXNzYWdlO1xuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiB7IHBhZGRpbmc6IDIwIH0gfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICBnZXRNZXNzYWdlKDU5MSlcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFRleHRGaWVsZCwgeyBmbG9hdGluZ0xhYmVsVGV4dDogZ2V0TWVzc2FnZSg1NzgpLCB2YWx1ZTogdGhpcy5zdGF0ZS52YWx1ZSwgb25DaGFuZ2U6IHRoaXMub25DaGFuZ2UuYmluZCh0aGlzKSwgZnVsbFdpZHRoOiB0cnVlIH0pLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IHRleHRBbGlnbjogJ3JpZ2h0JywgcGFkZGluZ1RvcDogMTAgfSB9LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEZsYXRCdXR0b24sIHsgbGFiZWw6IGdldE1lc3NhZ2UoNDkpLCBvblRvdWNoVGFwOiB0aGlzLnByb3BzLm9uQ2FuY2VsLmJpbmQodGhpcykgfSksXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmxhdEJ1dHRvbiwgeyBsYWJlbDogZ2V0TWVzc2FnZSg1NzkpLCBzZWNvbmRhcnk6IHRydWUsIG9uVG91Y2hUYXA6IHRoaXMuc3VibWl0Q3JlYXRpb25Gb3JtLmJpbmQodGhpcykgfSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBUZWFtQ3JlYXRpb25Gb3JtO1xufSkoQ29tcG9uZW50KTtcblxuVGVhbUNyZWF0aW9uRm9ybS5wcm9wVHlwZXMgPSB7XG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgdHJpZ2dlcmVkIGFmdGVyIHRlYW0gY3JlYXRpb24gc3VjY2VlZGVkXG4gICAgICovXG4gICAgb25UZWFtQ3JlYXRlZDogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICAvKipcbiAgICAgKiBSZXF1ZXN0IG1vZGFsIGNsb3NlXG4gICAgICovXG4gICAgb25DYW5jZWw6IFByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWRcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFRlYW1DcmVhdGlvbkZvcm0gPSBQeWRpb0NvbnRleHRDb25zdW1lcihUZWFtQ3JlYXRpb25Gb3JtKTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gVGVhbUNyZWF0aW9uRm9ybTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfYWRkcmVzc2Jvb2tBZGRyZXNzQm9vayA9IHJlcXVpcmUoJy4vYWRkcmVzc2Jvb2svQWRkcmVzc0Jvb2snKTtcblxudmFyIF9hZGRyZXNzYm9va0FkZHJlc3NCb29rMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2FkZHJlc3Nib29rQWRkcmVzc0Jvb2spO1xuXG52YXIgX3JlcXVpcmUkcmVxdWlyZUxpYiA9IHJlcXVpcmUoJ3B5ZGlvL2h0dHAvcmVzb3VyY2VzLW1hbmFnZXInKS5yZXF1aXJlTGliKCdib290Jyk7XG5cbnZhciBBc3luY0NvbXBvbmVudCA9IF9yZXF1aXJlJHJlcXVpcmVMaWIuQXN5bmNDb21wb25lbnQ7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBUZXh0RmllbGQgPSBfcmVxdWlyZS5UZXh0RmllbGQ7XG52YXIgQXV0b0NvbXBsZXRlID0gX3JlcXVpcmUuQXV0b0NvbXBsZXRlO1xudmFyIFJlZnJlc2hJbmRpY2F0b3IgPSBfcmVxdWlyZS5SZWZyZXNoSW5kaWNhdG9yO1xudmFyIEljb25CdXR0b24gPSBfcmVxdWlyZS5JY29uQnV0dG9uO1xudmFyIFBvcG92ZXIgPSBfcmVxdWlyZS5Qb3BvdmVyO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIEZ1bmNVdGlscyA9IHJlcXVpcmUoJ3B5ZGlvL3V0aWwvZnVuYycpO1xuXG4vKipcbiAqIFJlYWR5IHRvIHVzZSBhdXRvY29tcGxldGUgZmllbGQgdGhhdCB3aWxsIGxvYWQgdXNlcnMvZ3JvdXBzL3JvbGVzIGZyb21cbiAqIHRoZSBzZXJ2ZXIgKHVzaW5nIHVzZXJfbGlzdF9hdXRob3JpemVkX3VzZXJzIEFQSSkuXG4gKiBVc2VkIGZvciBzaGFyaW5nLCBhZGRyZXNzYm9va3MsIHNlbmQgZW1haWwsIGV0Yy5cbiAqXG4gKiBDYW4gYWxzbyBvcGVuIGEgXCJzZWxlY3Rvci1zdHlsZVwiIGFkcmVzcyBib29rLlxuICovXG52YXIgVXNlcnNMb2FkZXIgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdVc2Vyc0xvYWRlcicsXG5cbiAgICBwcm9wVHlwZXM6IHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTWV0aG9kIGNhbGxlZCB0byByZW5kZXIgYSBjb21tcG9uZW50LCB0YWtpbmcgYSBVc2VyT2JqZWN0IGFzIGlucHV0XG4gICAgICAgICAqL1xuICAgICAgICByZW5kZXJTdWdnZXN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGJhY2sgd2hlbiBhIHZhbHVlIGlzIGZpbmFsbHkgc2VsZWN0ZWRcbiAgICAgICAgICovXG4gICAgICAgIG9uVmFsdWVTZWxlY3RlZDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEZsb2F0aW5nIExhYmVsIFRleHQgZGlzcGxheWVkIG9uIHRoZSBmaWVsZFxuICAgICAgICAgKi9cbiAgICAgICAgZmllbGRMYWJlbDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgICAgICAvKipcbiAgICAgICAgICogQXJyYXkgb2YgdmFsdWVzIHRvIGlnbm9yZVxuICAgICAgICAgKi9cbiAgICAgICAgZXhjbHVkZXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheS5pc1JlcXVpcmVkLFxuICAgICAgICAvKipcbiAgICAgICAgICogRGlzcGxheSBvbmx5IHVzZXJzLCBubyBncm91cHMgbm9yIHJvbGVzXG4gICAgICAgICAqL1xuICAgICAgICB1c2Vyc09ubHk6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICAvKipcbiAgICAgICAgICogRGlzcGxheSB1c2VycyBmcm9tIGxvY2FsIGRpcmVjdG9yeSBhbmQvb3IgZnJvbSByZW1vdGUuXG4gICAgICAgICAqL1xuICAgICAgICB1c2Vyc0Zyb206IFJlYWN0LlByb3BUeXBlcy5vbmVPZihbJ2xvY2FsJywgJ3JlbW90ZScsICdhbnknXSksXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEbyBub3QgcHJvcG9zZSBhIFwiQ3JlYXRlIHVzZXJcIiBvcHRpb25cbiAgICAgICAgICovXG4gICAgICAgIGV4aXN0aW5nT25seTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGxvdyBmcmVlIHR5cGluZ1xuICAgICAgICAgKi9cbiAgICAgICAgZnJlZVZhbHVlQWxsb3dlZDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaWxsIGJlIHBhc3NlZCB0byB0aGUgcm9vdCBjb21wb25lbnRcbiAgICAgICAgICovXG4gICAgICAgIGNsYXNzTmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZ1xuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGRhdGFTb3VyY2U6IFtdLFxuICAgICAgICAgICAgbG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgICBzZWFyY2hUZXh0OiAnJyxcbiAgICAgICAgICAgIG1pbkNoYXJzOiBwYXJzZUludChnbG9iYWwucHlkaW8uZ2V0UGx1Z2luQ29uZmlncyhcImNvcmUuY29uZlwiKS5nZXQoXCJVU0VSU19MSVNUX0NPTVBMRVRFX01JTl9DSEFSU1wiKSlcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogTG9hZHMgdmFsdWVzIGZyb20gc2VydmVyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IEN1cnJlbnRseSBzZWFyY2hlZCB0ZXh0XG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIHdpdGggdGhlIHZhbHVlc1xuICAgICAqL1xuICAgIHN1Z2dlc3Rpb25Mb2FkZXI6IGZ1bmN0aW9uIHN1Z2dlc3Rpb25Mb2FkZXIoaW5wdXQsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBleGNsdWRlcyA9IHRoaXMucHJvcHMuZXhjbHVkZXM7XG4gICAgICAgIHZhciBkaXNhbGxvd1RlbXBvcmFyeSA9IHRoaXMucHJvcHMuZXhpc3RpbmdPbmx5ICYmICF0aGlzLnByb3BzLmZyZWVWYWx1ZUFsbG93ZWQ7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBsb2FkaW5nOiB0aGlzLnN0YXRlLmxvYWRpbmcgKyAxIH0pO1xuICAgICAgICBQeWRpb1VzZXJzLkNsaWVudC5hdXRob3JpemVkVXNlcnNTdGFydGluZ1dpdGgoaW5wdXQsIChmdW5jdGlvbiAodXNlcnMpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBsb2FkaW5nOiB0aGlzLnN0YXRlLmxvYWRpbmcgLSAxIH0pO1xuICAgICAgICAgICAgaWYgKGRpc2FsbG93VGVtcG9yYXJ5KSB7XG4gICAgICAgICAgICAgICAgdXNlcnMgPSB1c2Vycy5maWx0ZXIoZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICF1c2VyLmdldFRlbXBvcmFyeSgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGV4Y2x1ZGVzICYmIGV4Y2x1ZGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHVzZXJzID0gdXNlcnMuZmlsdGVyKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBleGNsdWRlcy5pbmRleE9mKHVzZXIuZ2V0SWQoKSkgPT0gLTE7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYWxsYmFjayh1c2Vycyk7XG4gICAgICAgIH0pLmJpbmQodGhpcyksIHRoaXMucHJvcHMudXNlcnNPbmx5LCB0aGlzLnByb3BzLmV4aXN0aW5nT25seSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENhbGxlZCB3aGVuIHRoZSBmaWVsZCBpcyB1cGRhdGVkXG4gICAgICogQHBhcmFtIHZhbHVlXG4gICAgICovXG4gICAgdGV4dEZpZWxkVXBkYXRlOiBmdW5jdGlvbiB0ZXh0RmllbGRVcGRhdGUodmFsdWUpIHtcblxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VhcmNoVGV4dDogdmFsdWUgfSk7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLm1pbkNoYXJzICYmIHZhbHVlICYmIHZhbHVlLmxlbmd0aCA8IHRoaXMuc3RhdGUubWluQ2hhcnMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxvYWRCdWZmZXJlZCh2YWx1ZSwgMzUwKTtcbiAgICB9LFxuXG4gICAgZ2V0UGVuZGluZ1NlYXJjaFRleHQ6IGZ1bmN0aW9uIGdldFBlbmRpbmdTZWFyY2hUZXh0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZS5zZWFyY2hUZXh0IHx8IGZhbHNlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBEZWJvdW5jZWQgY2FsbCBmb3IgcmVuZGVyaW5nIHNlYXJjaFxuICAgICAqIEBwYXJhbSB2YWx1ZSB7c3RyaW5nfVxuICAgICAqIEBwYXJhbSB0aW1lb3V0IHtpbnR9XG4gICAgICovXG4gICAgbG9hZEJ1ZmZlcmVkOiBmdW5jdGlvbiBsb2FkQnVmZmVyZWQodmFsdWUsIHRpbWVvdXQpIHtcblxuICAgICAgICBpZiAoIXZhbHVlICYmIHRoaXMuX2VtcHR5VmFsdWVMaXN0KSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZGF0YVNvdXJjZTogdGhpcy5fZW1wdHlWYWx1ZUxpc3QgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgRnVuY1V0aWxzLmJ1ZmZlckNhbGxiYWNrKCdyZW1vdGVfdXNlcnNfc2VhcmNoJywgdGltZW91dCwgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBsb2FkaW5nOiB0cnVlIH0pO1xuICAgICAgICAgICAgdGhpcy5zdWdnZXN0aW9uTG9hZGVyKHZhbHVlLCAoZnVuY3Rpb24gKHVzZXJzKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNydFZhbHVlRm91bmQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gdXNlcnMubWFwKChmdW5jdGlvbiAodXNlck9iamVjdCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgY29tcG9uZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgIE1hdGVyaWFsVUkuTWVudUl0ZW0sXG4gICAgICAgICAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5yZW5kZXJTdWdnZXN0aW9uKHVzZXJPYmplY3QpXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1c2VyT2JqZWN0OiB1c2VyT2JqZWN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogdXNlck9iamVjdC5nZXRFeHRlbmRlZExhYmVsKCksXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogY29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9lbXB0eVZhbHVlTGlzdCA9IHZhbHVlcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGRhdGFTb3VyY2U6IHZhbHVlcywgbG9hZGluZzogZmFsc2UgfSk7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENhbGxlZCB3aGVuIHVzZXIgc2VsZWN0cyBhIHZhbHVlIGZyb20gdGhlIGxpc3RcbiAgICAgKiBAcGFyYW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gaW5kZXhcbiAgICAgKi9cbiAgICBvbkNvbXBsZXRlclJlcXVlc3Q6IGZ1bmN0aW9uIG9uQ29tcGxldGVyUmVxdWVzdCh2YWx1ZSwgaW5kZXgpIHtcblxuICAgICAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlLmRhdGFTb3VyY2UubWFwKGZ1bmN0aW9uIChlbnRyeSkge1xuICAgICAgICAgICAgICAgIGlmIChlbnRyeS50ZXh0ID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGVudHJ5O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKHZhbHVlICYmICF2YWx1ZS51c2VyT2JqZWN0ICYmIHRoaXMucHJvcHMuZnJlZVZhbHVlQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHZhciBmYWtlID0gbmV3IFB5ZGlvVXNlcnMuVXNlcih2YWx1ZSwgdmFsdWUsICd1c2VyJywgbnVsbCwgbnVsbCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vblZhbHVlU2VsZWN0ZWQoZmFrZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlYXJjaFRleHQ6ICcnLCBkYXRhU291cmNlOiBbXSB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlICYmIHZhbHVlLnVzZXJPYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSB2YWx1ZS51c2VyT2JqZWN0O1xuICAgICAgICAgICAgaWYgKG9iamVjdC5nZXRUZW1wb3JhcnkoKSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmZyZWVWYWx1ZUFsbG93ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vblZhbHVlU2VsZWN0ZWQob2JqZWN0KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgY3JlYXRlVXNlcjogb2JqZWN0LmdldExhYmVsKCkgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLm9uVmFsdWVTZWxlY3RlZChvYmplY3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlYXJjaFRleHQ6ICcnLCBkYXRhU291cmNlOiBbXSB9KTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VycyBvblZhbHVlU2VsZWN0ZWQgcHJvcHMgY2FsbGJhY2tcbiAgICAgKiBAcGFyYW0ge1B5ZGlvLlVzZXJ9IG5ld1VzZXJcbiAgICAgKi9cbiAgICBvblVzZXJDcmVhdGVkOiBmdW5jdGlvbiBvblVzZXJDcmVhdGVkKG5ld1VzZXIpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblZhbHVlU2VsZWN0ZWQobmV3VXNlcik7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjcmVhdGVVc2VyOiBudWxsIH0pO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDbG9zZSB1c2VyIGNyZWF0aW9uIGZvcm1cbiAgICAgKi9cbiAgICBvbkNyZWF0aW9uQ2FuY2VsbGVkOiBmdW5jdGlvbiBvbkNyZWF0aW9uQ2FuY2VsbGVkKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgY3JlYXRlVXNlcjogbnVsbCB9KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogT3BlbiBhZGRyZXNzIGJvb2sgaW5zaWRlIGEgUG9wb3ZlclxuICAgICAqIEBwYXJhbSBldmVudFxuICAgICAqL1xuICAgIG9wZW5BZGRyZXNzQm9vazogZnVuY3Rpb24gb3BlbkFkZHJlc3NCb29rKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgYWRkcmVzc0Jvb2tPcGVuOiB0cnVlLFxuICAgICAgICAgICAgYWRkcmVzc0Jvb2tBbmNob3I6IGV2ZW50LmN1cnJlbnRUYXJnZXRcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENsb3NlIGFkZHJlc3MgYm9vayBwb3BvdmVyXG4gICAgICovXG4gICAgY2xvc2VBZGRyZXNzQm9vazogZnVuY3Rpb24gY2xvc2VBZGRyZXNzQm9vaygpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGFkZHJlc3NCb29rT3BlbjogZmFsc2UgfSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJlZCB3aGVuIHVzZXIgY2xpY2tzIG9uIGFuIGVudHJ5IGZyb20gYWRyZXNzIGJvb2suXG4gICAgICogQHBhcmFtIGl0ZW1cbiAgICAgKi9cbiAgICBvbkFkZHJlc3NCb29rSXRlbVNlbGVjdGVkOiBmdW5jdGlvbiBvbkFkZHJlc3NCb29rSXRlbVNlbGVjdGVkKGl0ZW0pIHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblZhbHVlU2VsZWN0ZWQoaXRlbSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciBfc3RhdGUgPSB0aGlzLnN0YXRlO1xuICAgICAgICB2YXIgZGF0YVNvdXJjZSA9IF9zdGF0ZS5kYXRhU291cmNlO1xuICAgICAgICB2YXIgY3JlYXRlVXNlciA9IF9zdGF0ZS5jcmVhdGVVc2VyO1xuXG4gICAgICAgIHZhciBjb250YWluZXJTdHlsZSA9IHsgcG9zaXRpb246ICdyZWxhdGl2ZScsIG92ZXJmbG93OiAndmlzaWJsZScgfTtcblxuICAgICAgICAvKlxuICAgICAgICBpZihjcmVhdGVVc2VyKXtcbiAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9e2NvbnRhaW5lclN0eWxlfT5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT17e3Bvc2l0aW9uOiAnYWJzb2x1dGUnLCB0b3A6IDczLCBsZWZ0OiAwLCByaWdodDogMCwgekluZGV4OiAxMH19PlxuICAgICAgICAgICAgICAgICAgICAgICAgPEFzeW5jQ29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlPXtcIlB5ZGlvRm9ybVwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU9e1wiVXNlckNyZWF0aW9uRm9ybVwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdVc2VyTmFtZT17dGhpcy5zdGF0ZS5jcmVhdGVVc2VyfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uVXNlckNyZWF0ZWQ9e3RoaXMub25Vc2VyQ3JlYXRlZH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNhbmNlbD17dGhpcy5vbkNyZWF0aW9uQ2FuY2VsbGVkfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB5ZGlvPXt0aGlzLnByb3BzLnB5ZGlvfVxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICApO1xuICAgICAgICAgfVxuICAgICAgICAqL1xuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiBjb250YWluZXJTdHlsZSwgcmVmOiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuX3BvcG92ZXJBbmNob3IgPSBlbDtcbiAgICAgICAgICAgICAgICB9IH0sXG4gICAgICAgICAgICAhY3JlYXRlVXNlciAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KEF1dG9Db21wbGV0ZSwge1xuICAgICAgICAgICAgICAgIGZpbHRlcjogTWF0ZXJpYWxVSS5BdXRvQ29tcGxldGUubm9GaWx0ZXIsXG4gICAgICAgICAgICAgICAgZGF0YVNvdXJjZTogZGF0YVNvdXJjZSxcbiAgICAgICAgICAgICAgICBzZWFyY2hUZXh0OiB0aGlzLnN0YXRlLnNlYXJjaFRleHQsXG4gICAgICAgICAgICAgICAgb25VcGRhdGVJbnB1dDogdGhpcy50ZXh0RmllbGRVcGRhdGUsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiB0aGlzLnByb3BzLmNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICBvcGVuT25Gb2N1czogdHJ1ZSxcbiAgICAgICAgICAgICAgICBmbG9hdGluZ0xhYmVsVGV4dDogdGhpcy5wcm9wcy5maWVsZExhYmVsLFxuICAgICAgICAgICAgICAgIHVuZGVybGluZVNob3c6ICF0aGlzLnByb3BzLnVuZGVybGluZUhpZGUsXG4gICAgICAgICAgICAgICAgZnVsbFdpZHRoOiB0cnVlLFxuICAgICAgICAgICAgICAgIG9uTmV3UmVxdWVzdDogdGhpcy5vbkNvbXBsZXRlclJlcXVlc3QsXG4gICAgICAgICAgICAgICAgbGlzdFN0eWxlOiB7IG1heEhlaWdodDogMzUwLCBvdmVyZmxvd1k6ICdhdXRvJyB9LFxuICAgICAgICAgICAgICAgIG9uRm9jdXM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMubG9hZEJ1ZmZlcmVkKF90aGlzLnN0YXRlLnNlYXJjaFRleHQsIDEwMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBjcmVhdGVVc2VyICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoVGV4dEZpZWxkLCB7XG4gICAgICAgICAgICAgICAgZmxvYXRpbmdMYWJlbFRleHQ6IHRoaXMucHJvcHMuZmllbGRMYWJlbCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogZ2xvYmFsLnB5ZGlvLk1lc3NhZ2VIYXNoWzQ4NV0gKyAnICgnICsgdGhpcy5zdGF0ZS5jcmVhdGVVc2VyICsgJyknLFxuICAgICAgICAgICAgICAgIGRpc2FibGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGZ1bGxXaWR0aDogdHJ1ZSxcbiAgICAgICAgICAgICAgICB1bmRlcmxpbmVTaG93OiAhdGhpcy5wcm9wcy51bmRlcmxpbmVIaWRlXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICFjcmVhdGVVc2VyICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBwb3NpdGlvbjogJ2Fic29sdXRlJywgcmlnaHQ6IDQsIGJvdHRvbTogMTQsIGhlaWdodDogMjAsIHdpZHRoOiAyMCB9IH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSZWZyZXNoSW5kaWNhdG9yLCB7XG4gICAgICAgICAgICAgICAgICAgIHNpemU6IDIwLFxuICAgICAgICAgICAgICAgICAgICBsZWZ0OiAwLFxuICAgICAgICAgICAgICAgICAgICB0b3A6IDAsXG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogdGhpcy5zdGF0ZS5sb2FkaW5nID8gJ2xvYWRpbmcnIDogJ2hpZGUnXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICB0aGlzLnByb3BzLnNob3dBZGRyZXNzQm9vayAmJiAhY3JlYXRlVXNlciAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KF9hZGRyZXNzYm9va0FkZHJlc3NCb29rMlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICAgICAgbW9kZTogJ3BvcG92ZXInLFxuICAgICAgICAgICAgICAgIHB5ZGlvOiB0aGlzLnByb3BzLnB5ZGlvLFxuICAgICAgICAgICAgICAgIGxvYWRlclN0eWxlOiB7IHdpZHRoOiAzMjAsIGhlaWdodDogNDIwIH0sXG4gICAgICAgICAgICAgICAgb25JdGVtU2VsZWN0ZWQ6IHRoaXMub25BZGRyZXNzQm9va0l0ZW1TZWxlY3RlZCxcbiAgICAgICAgICAgICAgICB1c2Vyc0Zyb206IHRoaXMucHJvcHMudXNlcnNGcm9tLFxuICAgICAgICAgICAgICAgIGRpc2FibGVTZWFyY2g6IHRydWVcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBQb3BvdmVyLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgb3BlbjogY3JlYXRlVXNlcixcbiAgICAgICAgICAgICAgICAgICAgYW5jaG9yRWw6IHRoaXMuX3BvcG92ZXJBbmNob3IsXG4gICAgICAgICAgICAgICAgICAgIGFuY2hvck9yaWdpbjogeyBob3Jpem9udGFsOiAnbGVmdCcsIHZlcnRpY2FsOiAnYm90dG9tJyB9LFxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRPcmlnaW46IHsgaG9yaXpvbnRhbDogJ2xlZnQnLCB2ZXJ0aWNhbDogJ3RvcCcgfSxcbiAgICAgICAgICAgICAgICAgICAgb25SZXF1ZXN0Q2xvc2U6IHRoaXMub25DcmVhdGlvbkNhbmNlbGxlZCxcbiAgICAgICAgICAgICAgICAgICAgY2FuQXV0b1Bvc2l0aW9uOiBmYWxzZVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgY3JlYXRlVXNlciAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KEFzeW5jQ29tcG9uZW50LCB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZTogXCJQeWRpb0Zvcm1cIixcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogXCJVc2VyQ3JlYXRpb25Gb3JtXCIsXG5cbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHsgd2lkdGg6IDM1MCwgaGVpZ2h0OiAzMjAgfSxcbiAgICAgICAgICAgICAgICAgICAgbmV3VXNlck5hbWU6IHRoaXMuc3RhdGUuY3JlYXRlVXNlcixcbiAgICAgICAgICAgICAgICAgICAgb25Vc2VyQ3JlYXRlZDogdGhpcy5vblVzZXJDcmVhdGVkLFxuICAgICAgICAgICAgICAgICAgICBvbkNhbmNlbDogdGhpcy5vbkNyZWF0aW9uQ2FuY2VsbGVkLFxuICAgICAgICAgICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpb1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gVXNlcnNMb2FkZXI7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfTmVzdGVkTGlzdEl0ZW0gPSByZXF1aXJlKCcuL05lc3RlZExpc3RJdGVtJyk7XG5cbnZhciBfTmVzdGVkTGlzdEl0ZW0yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTmVzdGVkTGlzdEl0ZW0pO1xuXG52YXIgX1VzZXJzTGlzdCA9IHJlcXVpcmUoJy4vVXNlcnNMaXN0Jyk7XG5cbnZhciBfVXNlcnNMaXN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1VzZXJzTGlzdCk7XG5cbnZhciBfUmlnaHRQYW5lbENhcmQgPSByZXF1aXJlKCcuL1JpZ2h0UGFuZWxDYXJkJyk7XG5cbnZhciBfUmlnaHRQYW5lbENhcmQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfUmlnaHRQYW5lbENhcmQpO1xuXG52YXIgX1NlYXJjaFBhbmVsID0gcmVxdWlyZSgnLi9TZWFyY2hQYW5lbCcpO1xuXG52YXIgX1NlYXJjaFBhbmVsMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1NlYXJjaFBhbmVsKTtcblxudmFyIF9Mb2FkZXJzID0gcmVxdWlyZSgnLi9Mb2FkZXJzJyk7XG5cbnZhciBfTG9hZGVyczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Mb2FkZXJzKTtcblxudmFyIF9UZWFtQ3JlYXRpb25Gb3JtID0gcmVxdWlyZSgnLi4vVGVhbUNyZWF0aW9uRm9ybScpO1xuXG52YXIgX1RlYW1DcmVhdGlvbkZvcm0yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVGVhbUNyZWF0aW9uRm9ybSk7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG52YXIgUHlkaW8gPSByZXF1aXJlKCdweWRpbycpO1xuXG52YXIgX1B5ZGlvJHJlcXVpcmVMaWIgPSBQeWRpby5yZXF1aXJlTGliKCdib290Jyk7XG5cbnZhciBBc3luY0NvbXBvbmVudCA9IF9QeWRpbyRyZXF1aXJlTGliLkFzeW5jQ29tcG9uZW50O1xudmFyIFB5ZGlvQ29udGV4dENvbnN1bWVyID0gX1B5ZGlvJHJlcXVpcmVMaWIuUHlkaW9Db250ZXh0Q29uc3VtZXI7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBQb3BvdmVyID0gX3JlcXVpcmUuUG9wb3ZlcjtcbnZhciBJY29uQnV0dG9uID0gX3JlcXVpcmUuSWNvbkJ1dHRvbjtcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpL3N0eWxlcycpO1xuXG52YXIgbXVpVGhlbWVhYmxlID0gX3JlcXVpcmUyLm11aVRoZW1lYWJsZTtcbnZhciBjb2xvcnMgPSBfcmVxdWlyZTIuY29sb3JzO1xuXG4vKipcbiAqIEhpZ2ggbGV2ZWwgY29tcG9uZW50IHRvIGJyb3dzZSB1c2VycywgZ3JvdXBzIGFuZCB0ZWFtcywgZWl0aGVyIGluIGEgbGFyZ2UgZm9ybWF0IChtb2RlPSdib29rJykgb3IgYSBtb3JlIGNvbXBhY3RcbiAqIGZvcm1hdCAobW9kZT0nc2VsZWN0b3InfCdwb3BvdmVyJykuXG4gKiBBZGRyZXNzIGJvb2sgYWxsb3dzIHRvIGNyZWF0ZSBleHRlcm5hbCB1c2VycywgdGVhbXMsIGFuZCBhbHNvIHRvIGJyb3dzZSB0cnVzdGVkIHNlcnZlciBkaXJlY3RvcmllcyBpZiBGZWRlcmF0ZWQgU2hhcmluZ1xuICogaXMgYWN0aXZlLlxuICovXG52YXIgQWRkcmVzc0Jvb2sgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdBZGRyZXNzQm9vaycsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1haW4gaW5zdGFuY2Ugb2YgcHlkaW9cbiAgICAgICAgICovXG4gICAgICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbyksXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEaXNwbGF5IG1vZGUsIGVpdGhlciBsYXJnZSAoYm9vaykgb3Igc21hbGwgcGlja2VyICgnc2VsZWN0b3InLCAncG9wb3ZlcicpLlxuICAgICAgICAgKi9cbiAgICAgICAgbW9kZTogUmVhY3QuUHJvcFR5cGVzLm9uZU9mKFsnYm9vaycsICdzZWxlY3RvcicsICdwb3BvdmVyJ10pLmlzUmVxdWlyZWQsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYWxsYmFjayB0cmlnZ2VyZWQgaW4gJ3NlbGVjdG9yJyBtb2RlIHdoZW5ldmVyIGFuIGl0ZW0gaXMgY2xpY2tlZC5cbiAgICAgICAgICovXG4gICAgICAgIG9uSXRlbVNlbGVjdGVkOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERpc3BsYXkgdXNlcnMgb25seSwgbm8gdGVhbXMgb3IgZ3JvdXBzXG4gICAgICAgICAqL1xuICAgICAgICB1c2Vyc09ubHk6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICAvKipcbiAgICAgICAgICogQ2hvb3NlIHZhcmlvdXMgdXNlciBzb3VyY2VzLCBlaXRoZXIgdGhlIGxvY2FsIGRpcmVjdG9yeSBvciByZW1vdGUgKCA9IHRydXN0ZWQgKSBzZXJ2ZXJzLlxuICAgICAgICAgKi9cbiAgICAgICAgdXNlcnNGcm9tOiBSZWFjdC5Qcm9wVHlwZXMub25lT2YoWydsb2NhbCcsICdyZW1vdGUnLCAnYW55J10pLFxuICAgICAgICAvKipcbiAgICAgICAgICogRGlzYWJsZSB0aGUgc2VhcmNoIGVuZ2luZVxuICAgICAgICAgKi9cbiAgICAgICAgZGlzYWJsZVNlYXJjaDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGVtZSBvYmplY3QgcGFzc2VkIGJ5IG11aVRoZW1lYWJsZSgpIHdyYXBwZXJcbiAgICAgICAgICovXG4gICAgICAgIG11aVRoZW1lOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICAvKipcbiAgICAgICAgICogV2lsbCBiZSBwYXNzZWQgdG8gdGhlIFBvcG92ZXIgb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBwb3BvdmVyU3R5bGU6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBVc2VkIGFzIGEgYnV0dG9uIHRvIG9wZW4gdGhlIHNlbGVjdG9yIGluIGEgcG9wb3ZlclxuICAgICAgICAgKi9cbiAgICAgICAgcG9wb3ZlckJ1dHRvbjogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdpbGwgYmUgcGFzc2VkIHRvIHRoZSBQb3BvdmVyIGNvbnRhaW5lciBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIHBvcG92ZXJDb250YWluZXJTdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdpbGwgYmUgcGFzc2VkIHRvIHRoZSBQb3BvdmVyIEljb24gQnV0dG9uLlxuICAgICAgICAgKi9cbiAgICAgICAgcG9wb3Zlckljb25CdXR0b25TdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdFxuICAgIH0sXG5cbiAgICBnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uIGdldERlZmF1bHRQcm9wcygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG1vZGU6ICdib29rJyxcbiAgICAgICAgICAgIHVzZXJzT25seTogZmFsc2UsXG4gICAgICAgICAgICB1c2Vyc0Zyb206ICdhbnknLFxuICAgICAgICAgICAgdGVhbXNPbmx5OiBmYWxzZSxcbiAgICAgICAgICAgIGRpc2FibGVTZWFyY2g6IGZhbHNlXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgcHlkaW8gPSBfcHJvcHMucHlkaW87XG4gICAgICAgIHZhciBtb2RlID0gX3Byb3BzLm1vZGU7XG4gICAgICAgIHZhciB1c2Vyc09ubHkgPSBfcHJvcHMudXNlcnNPbmx5O1xuICAgICAgICB2YXIgdXNlcnNGcm9tID0gX3Byb3BzLnVzZXJzRnJvbTtcbiAgICAgICAgdmFyIHRlYW1zT25seSA9IF9wcm9wcy50ZWFtc09ubHk7XG4gICAgICAgIHZhciBkaXNhYmxlU2VhcmNoID0gX3Byb3BzLmRpc2FibGVTZWFyY2g7XG5cbiAgICAgICAgdmFyIGdldE1lc3NhZ2UgPSBmdW5jdGlvbiBnZXRNZXNzYWdlKGlkKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMucHJvcHMuZ2V0TWVzc2FnZShpZCwgJycpO1xuICAgICAgICB9O1xuICAgICAgICB2YXIgY29uZkNvbmZpZ3MgPSBweWRpby5nZXRQbHVnaW5Db25maWdzKCdjb3JlLmNvbmYnKTtcblxuICAgICAgICB2YXIgcm9vdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHRlYW1zT25seSkge1xuICAgICAgICAgICAgcm9vdCA9IHtcbiAgICAgICAgICAgICAgICBpZDogJ3RlYW1zJyxcbiAgICAgICAgICAgICAgICBsYWJlbDogZ2V0TWVzc2FnZSg1NjgpLFxuICAgICAgICAgICAgICAgIGNoaWxkcmVuTG9hZGVyOiBfTG9hZGVyczJbJ2RlZmF1bHQnXS5sb2FkVGVhbXMsXG4gICAgICAgICAgICAgICAgX3BhcmVudDogbnVsbCxcbiAgICAgICAgICAgICAgICBfbm90U2VsZWN0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBhY3Rpb25zOiB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZWFtcycsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZTogJysgJyArIGdldE1lc3NhZ2UoNTY5KSxcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlOiBnZXRNZXNzYWdlKDU3MCksXG4gICAgICAgICAgICAgICAgICAgIG11bHRpcGxlOiB0cnVlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgcm9vdDogcm9vdCxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEl0ZW06IHJvb3QsXG4gICAgICAgICAgICAgICAgbG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgICAgICAgcmlnaHRQYW5lSXRlbTogbnVsbFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJvb3QgPSB7XG4gICAgICAgICAgICBpZDogJ3Jvb3QnLFxuICAgICAgICAgICAgbGFiZWw6IGdldE1lc3NhZ2UoNTkyKSxcbiAgICAgICAgICAgIHR5cGU6ICdyb290JyxcbiAgICAgICAgICAgIGNvbGxlY3Rpb25zOiBbXVxuICAgICAgICB9O1xuICAgICAgICBpZiAodXNlcnNGcm9tICE9PSAncmVtb3RlJykge1xuICAgICAgICAgICAgaWYgKGNvbmZDb25maWdzLmdldCgnVVNFUl9DUkVBVEVfVVNFUlMnKSkge1xuICAgICAgICAgICAgICAgIHJvb3QuY29sbGVjdGlvbnMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGlkOiAnZXh0JyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGdldE1lc3NhZ2UoNTkzKSxcbiAgICAgICAgICAgICAgICAgICAgLy9pY29uOidtZGkgbWRpLWFjY291bnQtbmV0d29yaycsXG4gICAgICAgICAgICAgICAgICAgIGl0ZW1zTG9hZGVyOiBfTG9hZGVyczJbJ2RlZmF1bHQnXS5sb2FkRXh0ZXJuYWxVc2VycyxcbiAgICAgICAgICAgICAgICAgICAgX3BhcmVudDogcm9vdCxcbiAgICAgICAgICAgICAgICAgICAgX25vdFNlbGVjdGFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICd1c2VycycsXG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGU6ICcrICcgKyBnZXRNZXNzYWdlKDQ4NCksXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmU6IGdldE1lc3NhZ2UoNTgyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG11bHRpcGxlOiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdXNlcnNPbmx5KSB7XG4gICAgICAgICAgICAgICAgcm9vdC5jb2xsZWN0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6ICd0ZWFtcycsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBnZXRNZXNzYWdlKDU2OCksXG4gICAgICAgICAgICAgICAgICAgIC8vaWNvbjogJ21kaSBtZGktYWNjb3VudC1tdWx0aXBsZScsXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuTG9hZGVyOiBfTG9hZGVyczJbJ2RlZmF1bHQnXS5sb2FkVGVhbXMsXG4gICAgICAgICAgICAgICAgICAgIF9wYXJlbnQ6IHJvb3QsXG4gICAgICAgICAgICAgICAgICAgIF9ub3RTZWxlY3RhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhY3Rpb25zOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGVhbXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlOiAnKyAnICsgZ2V0TWVzc2FnZSg1NjkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlOiBnZXRNZXNzYWdlKDU3MCksXG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZTogdHJ1ZVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY29uZkNvbmZpZ3MuZ2V0KCdBTExPV19DUk9TU1VTRVJTX1NIQVJJTkcnKSkge1xuICAgICAgICAgICAgICAgIHZhciBncm91cE9yVXNlcnMgPSBjb25mQ29uZmlncy5nZXQoJ0FERFJFU1NCT09LX0dST1VQX09SX1VTRVJTJyk7XG4gICAgICAgICAgICAgICAgaWYgKGdyb3VwT3JVc2VycyAmJiBncm91cE9yVXNlcnMuZ3JvdXBfc3dpdGNoX3ZhbHVlKSBncm91cE9yVXNlcnMgPSBncm91cE9yVXNlcnMuZ3JvdXBfc3dpdGNoX3ZhbHVlO2Vsc2UgZ3JvdXBPclVzZXJzID0gJ2JvdGgnO1xuXG4gICAgICAgICAgICAgICAgaWYgKGdyb3VwT3JVc2VycyA9PT0gJ3NlYXJjaCcpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkaXNhYmxlU2VhcmNoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByb290LmNvbGxlY3Rpb25zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkOiAnc2VhcmNoJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogZ2V0TWVzc2FnZSg1ODMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWNvbjonbWRpIG1kaS1hY2NvdW50LXNlYXJjaCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3NlYXJjaCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BhcmVudDogcm9vdCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbm90U2VsZWN0YWJsZTogdHJ1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByb290LmNvbGxlY3Rpb25zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgaWQ6ICdBSlhQX0dSUF8vJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBnZXRNZXNzYWdlKDU4NCksXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2ljb246J21kaSBtZGktYWNjb3VudC1ib3gnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5Mb2FkZXI6IGdyb3VwT3JVc2VycyA9PT0gJ2JvdGgnIHx8IGdyb3VwT3JVc2VycyA9PT0gJ2dyb3VwcycgPyBfTG9hZGVyczJbJ2RlZmF1bHQnXS5sb2FkR3JvdXBzIDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zTG9hZGVyOiBncm91cE9yVXNlcnMgPT09ICdib3RoJyB8fCBncm91cE9yVXNlcnMgPT09ICd1c2VycycgPyBfTG9hZGVyczJbJ2RlZmF1bHQnXS5sb2FkR3JvdXBVc2VycyA6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBfcGFyZW50OiByb290LFxuICAgICAgICAgICAgICAgICAgICAgICAgX25vdFNlbGVjdGFibGU6IHRydWVcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG9jc1JlbW90ZXMgPSBweWRpby5nZXRQbHVnaW5Db25maWdzKCdjb3JlLm9jcycpLmdldCgnVFJVU1RFRF9TRVJWRVJTJyk7XG4gICAgICAgIGlmIChvY3NSZW1vdGVzICYmICF1c2Vyc09ubHkgJiYgdXNlcnNGcm9tICE9PSAnbG9jYWwnKSB7XG4gICAgICAgICAgICB2YXIgcmVtb3RlcyA9IEpTT04ucGFyc2Uob2NzUmVtb3Rlcyk7XG4gICAgICAgICAgICB2YXIgcmVtb3Rlc05vZGVzID0ge1xuICAgICAgICAgICAgICAgIGlkOiAncmVtb3RlcycsXG4gICAgICAgICAgICAgICAgbGFiZWw6IGdldE1lc3NhZ2UoNTk0KSxcbiAgICAgICAgICAgICAgICAvL2ljb246J21kaSBtZGktc2VydmVyJyxcbiAgICAgICAgICAgICAgICBjb2xsZWN0aW9uczogW10sXG4gICAgICAgICAgICAgICAgX3BhcmVudDogcm9vdCxcbiAgICAgICAgICAgICAgICBfbm90U2VsZWN0YWJsZTogdHJ1ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGZvciAodmFyIGsgaW4gcmVtb3Rlcykge1xuICAgICAgICAgICAgICAgIGlmICghcmVtb3Rlcy5oYXNPd25Qcm9wZXJ0eShrKSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgcmVtb3Rlc05vZGVzLmNvbGxlY3Rpb25zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBpZDogayxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHJlbW90ZXNba10sXG4gICAgICAgICAgICAgICAgICAgIGljb246ICdtZGkgbWRpLXNlcnZlci1uZXR3b3JrJyxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3JlbW90ZScsXG4gICAgICAgICAgICAgICAgICAgIF9wYXJlbnQ6IHJlbW90ZXNOb2RlcyxcbiAgICAgICAgICAgICAgICAgICAgX25vdFNlbGVjdGFibGU6IHRydWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZW1vdGVzTm9kZXMuY29sbGVjdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcm9vdC5jb2xsZWN0aW9ucy5wdXNoKHJlbW90ZXNOb2Rlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcm9vdDogcm9vdCxcbiAgICAgICAgICAgIHNlbGVjdGVkSXRlbTogbW9kZSA9PT0gJ3NlbGVjdG9yJyA/IHJvb3QgOiByb290LmNvbGxlY3Rpb25zWzBdLFxuICAgICAgICAgICAgbG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgICByaWdodFBhbmVJdGVtOiBudWxsXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0gJiYgdGhpcy5vbkZvbGRlckNsaWNrZWQodGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0pO1xuICAgIH0sXG5cbiAgICBvbkZvbGRlckNsaWNrZWQ6IGZ1bmN0aW9uIG9uRm9sZGVyQ2xpY2tlZChpdGVtKSB7XG4gICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgIHZhciBjYWxsYmFjayA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMSB8fCBhcmd1bWVudHNbMV0gPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGFyZ3VtZW50c1sxXTtcblxuICAgICAgICAvLyBTcGVjaWFsIGNhc2UgZm9yIHRlYW1zXG4gICAgICAgIGlmIChpdGVtLnR5cGUgPT09ICdncm91cCcgJiYgaXRlbS5pZC5pbmRleE9mKCcvQUpYUF9URUFNLycpID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLm9uVXNlckxpc3RJdGVtQ2xpY2tlZChpdGVtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgbG9hZGluZzogdHJ1ZSB9KTtcblxuICAgICAgICBfTG9hZGVyczJbJ2RlZmF1bHQnXS5jaGlsZHJlbkFzUHJvbWlzZShpdGVtLCBmYWxzZSkudGhlbihmdW5jdGlvbiAoY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIF9Mb2FkZXJzMlsnZGVmYXVsdCddLmNoaWxkcmVuQXNQcm9taXNlKGl0ZW0sIHRydWUpLnRoZW4oZnVuY3Rpb24gKGNoaWxkcmVuKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMyLnNldFN0YXRlKHsgc2VsZWN0ZWRJdGVtOiBpdGVtLCBsb2FkaW5nOiBmYWxzZSB9LCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIG9uVXNlckxpc3RJdGVtQ2xpY2tlZDogZnVuY3Rpb24gb25Vc2VyTGlzdEl0ZW1DbGlja2VkKGl0ZW0pIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25JdGVtU2VsZWN0ZWQpIHtcbiAgICAgICAgICAgIHZhciB1T2JqZWN0ID0gbmV3IFB5ZGlvVXNlcnMuVXNlcihpdGVtLmlkLCBpdGVtLmxhYmVsLCBpdGVtLnR5cGUsIGl0ZW0uZ3JvdXAsIGl0ZW0uYXZhdGFyLCBpdGVtLnRlbXBvcmFyeSwgaXRlbS5leHRlcm5hbCk7XG4gICAgICAgICAgICBpZiAoaXRlbS50cnVzdGVkX3NlcnZlcl9pZCkge1xuICAgICAgICAgICAgICAgIHVPYmplY3QudHJ1c3RlZFNlcnZlcklkID0gaXRlbS50cnVzdGVkX3NlcnZlcl9pZDtcbiAgICAgICAgICAgICAgICB1T2JqZWN0LnRydXN0ZWRTZXJ2ZXJMYWJlbCA9IGl0ZW0udHJ1c3RlZF9zZXJ2ZXJfbGFiZWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uSXRlbVNlbGVjdGVkKHVPYmplY3QpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHJpZ2h0UGFuZUl0ZW06IGl0ZW0gfSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgb25DcmVhdGVBY3Rpb246IGZ1bmN0aW9uIG9uQ3JlYXRlQWN0aW9uKGl0ZW0pIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNyZWF0ZURpYWxvZ0l0ZW06IGl0ZW0gfSk7XG4gICAgfSxcblxuICAgIGNsb3NlQ3JlYXRlRGlhbG9nQW5kUmVsb2FkOiBmdW5jdGlvbiBjbG9zZUNyZWF0ZURpYWxvZ0FuZFJlbG9hZCgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNyZWF0ZURpYWxvZ0l0ZW06IG51bGwgfSk7XG4gICAgICAgIHRoaXMucmVsb2FkQ3VycmVudE5vZGUoKTtcbiAgICB9LFxuXG4gICAgb25DYXJkVXBkYXRlQWN0aW9uOiBmdW5jdGlvbiBvbkNhcmRVcGRhdGVBY3Rpb24oaXRlbSkge1xuICAgICAgICBpZiAoaXRlbS5fcGFyZW50ICYmIGl0ZW0uX3BhcmVudCA9PT0gdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0pIHtcbiAgICAgICAgICAgIHRoaXMucmVsb2FkQ3VycmVudE5vZGUoKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBvbkRlbGV0ZUFjdGlvbjogZnVuY3Rpb24gb25EZWxldGVBY3Rpb24ocGFyZW50SXRlbSwgc2VsZWN0aW9uKSB7XG4gICAgICAgIGlmICghY29uZmlybSh0aGlzLnByb3BzLmdldE1lc3NhZ2UoMjc4KSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKHBhcmVudEl0ZW0uYWN0aW9ucy50eXBlKSB7XG4gICAgICAgICAgICBjYXNlICd1c2Vycyc6XG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uLmZvckVhY2goKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnJpZ2h0UGFuZUl0ZW0gPT09IHVzZXIpIHRoaXMuc2V0U3RhdGUoeyByaWdodFBhbmVJdGVtOiBudWxsIH0pO1xuICAgICAgICAgICAgICAgICAgICBQeWRpb1VzZXJzLkNsaWVudC5kZWxldGVVc2VyKHVzZXIuaWQsIHRoaXMucmVsb2FkQ3VycmVudE5vZGUuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd0ZWFtcyc6XG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uLmZvckVhY2goKGZ1bmN0aW9uICh0ZWFtKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnJpZ2h0UGFuZUl0ZW0gPT09IHRlYW0pIHRoaXMuc2V0U3RhdGUoeyByaWdodFBhbmVJdGVtOiBudWxsIH0pO1xuICAgICAgICAgICAgICAgICAgICBQeWRpb1VzZXJzLkNsaWVudC5kZWxldGVUZWFtKHRlYW0uaWQucmVwbGFjZSgnL0FKWFBfVEVBTS8nLCAnJyksIHRoaXMucmVsb2FkQ3VycmVudE5vZGUuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd0ZWFtJzpcbiAgICAgICAgICAgICAgICBfVGVhbUNyZWF0aW9uRm9ybTJbJ2RlZmF1bHQnXS51cGRhdGVUZWFtVXNlcnMocGFyZW50SXRlbSwgJ2RlbGV0ZScsIHNlbGVjdGlvbiwgdGhpcy5yZWxvYWRDdXJyZW50Tm9kZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgb3BlblBvcG92ZXI6IGZ1bmN0aW9uIG9wZW5Qb3BvdmVyKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgcG9wb3Zlck9wZW46IHRydWUsXG4gICAgICAgICAgICBwb3BvdmVyQW5jaG9yOiBldmVudC5jdXJyZW50VGFyZ2V0XG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBjbG9zZVBvcG92ZXI6IGZ1bmN0aW9uIGNsb3NlUG9wb3ZlcigpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHBvcG92ZXJPcGVuOiBmYWxzZSB9KTtcbiAgICB9LFxuXG4gICAgcmVsb2FkQ3VycmVudE5vZGU6IGZ1bmN0aW9uIHJlbG9hZEN1cnJlbnROb2RlKCkge1xuICAgICAgICB2YXIgX3RoaXMzID0gdGhpcztcblxuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5sZWFmTG9hZGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtLmNvbGxlY3Rpb25zTG9hZGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMub25Gb2xkZXJDbGlja2VkKHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoX3RoaXMzLnN0YXRlLnJpZ2h0UGFuZUl0ZW0pIHtcbiAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgclBhbmVJZCA9IF90aGlzMy5zdGF0ZS5yaWdodFBhbmVJdGVtLmlkO1xuICAgICAgICAgICAgICAgICAgICB2YXIgZm91bmRJdGVtID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxlYWZzID0gX3RoaXMzLnN0YXRlLnNlbGVjdGVkSXRlbS5sZWFmcyB8fCBbXTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbGxlY3Rpb25zID0gX3RoaXMzLnN0YXRlLnNlbGVjdGVkSXRlbS5jb2xsZWN0aW9ucyB8fCBbXTtcbiAgICAgICAgICAgICAgICAgICAgW10uY29uY2F0KGxlYWZzLCBjb2xsZWN0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAobGVhZikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxlYWYuaWQgPT09IHJQYW5lSWQpIGZvdW5kSXRlbSA9IGxlYWY7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBfdGhpczMuc2V0U3RhdGUoeyByaWdodFBhbmVJdGVtOiBmb3VuZEl0ZW0gfSk7XG4gICAgICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIHJlbG9hZEN1cnJlbnRBdFBhZ2U6IGZ1bmN0aW9uIHJlbG9hZEN1cnJlbnRBdFBhZ2UobGV0dGVyT3JSYW5nZSkge1xuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5sZWFmTG9hZGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtLmNvbGxlY3Rpb25zTG9hZGVkID0gZmFsc2U7XG4gICAgICAgIGlmIChsZXR0ZXJPclJhbmdlID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0uY3VycmVudFBhcmFtcyA9IG51bGw7XG4gICAgICAgIH0gZWxzZSBpZiAobGV0dGVyT3JSYW5nZS5pbmRleE9mKCctJykgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5yYW5nZSA9IGxldHRlck9yUmFuZ2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5yYW5nZSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5jdXJyZW50UGFyYW1zID0geyBhbHBoYV9wYWdlczogJ3RydWUnLCB2YWx1ZTogbGV0dGVyT3JSYW5nZSB9O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub25Gb2xkZXJDbGlja2VkKHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtKTtcbiAgICB9LFxuXG4gICAgcmVsb2FkQ3VycmVudFdpdGhTZWFyY2g6IGZ1bmN0aW9uIHJlbG9hZEN1cnJlbnRXaXRoU2VhcmNoKHZhbHVlKSB7XG4gICAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMucmVsb2FkQ3VycmVudEF0UGFnZSgtMSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0ubGVhZkxvYWRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5jb2xsZWN0aW9uc0xvYWRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5jdXJyZW50UGFyYW1zID0geyBoYXNfc2VhcmNoOiB0cnVlLCB2YWx1ZTogdmFsdWUsIGV4aXN0aW5nX29ubHk6IHRydWUgfTtcbiAgICAgICAgdGhpcy5vbkZvbGRlckNsaWNrZWQodGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0pO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzNCA9IHRoaXM7XG5cbiAgICAgICAgdmFyIF9wcm9wczIgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgbW9kZSA9IF9wcm9wczIubW9kZTtcbiAgICAgICAgdmFyIG11aVRoZW1lID0gX3Byb3BzMi5tdWlUaGVtZTtcbiAgICAgICAgdmFyIGdldE1lc3NhZ2UgPSBfcHJvcHMyLmdldE1lc3NhZ2U7XG5cbiAgICAgICAgaWYgKG1vZGUgPT09ICdwb3BvdmVyJykge1xuXG4gICAgICAgICAgICB2YXIgcG9wb3ZlclN0eWxlID0gdGhpcy5wcm9wcy5wb3BvdmVyU3R5bGUgfHwge307XG4gICAgICAgICAgICB2YXIgcG9wb3ZlckNvbnRhaW5lclN0eWxlID0gdGhpcy5wcm9wcy5wb3BvdmVyQ29udGFpbmVyU3R5bGUgfHwge307XG4gICAgICAgICAgICB2YXIgaWNvbkJ1dHRvblN0eWxlID0gdGhpcy5wcm9wcy5wb3BvdmVySWNvbkJ1dHRvblN0eWxlIHx8IHt9O1xuICAgICAgICAgICAgdmFyIGljb25CdXR0b24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KEljb25CdXR0b24sIHtcbiAgICAgICAgICAgICAgICBzdHlsZTogX2V4dGVuZHMoeyBwb3NpdGlvbjogJ2Fic29sdXRlJywgcGFkZGluZzogMTUsIHpJbmRleDogMTAwLCByaWdodDogMCwgdG9wOiAyNSwgZGlzcGxheTogdGhpcy5zdGF0ZS5sb2FkaW5nID8gJ25vbmUnIDogJ2luaXRpYWwnIH0sIGljb25CdXR0b25TdHlsZSksXG4gICAgICAgICAgICAgICAgaWNvblN0eWxlOiB7IGZvbnRTaXplOiAxOSwgY29sb3I6ICdyZ2JhKDAsMCwwLDAuNiknIH0sXG4gICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogJ21kaSBtZGktYm9vay1vcGVuLXZhcmlhbnQnLFxuICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IHRoaXMub3BlblBvcG92ZXJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMucG9wb3ZlckJ1dHRvbikge1xuICAgICAgICAgICAgICAgIGljb25CdXR0b24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KHRoaXMucHJvcHMucG9wb3ZlckJ1dHRvbi50eXBlLCBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcy5wb3BvdmVyQnV0dG9uLnByb3BzLCB7IG9uVG91Y2hUYXA6IHRoaXMub3BlblBvcG92ZXIgfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgaWNvbkJ1dHRvbixcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICBQb3BvdmVyLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVuOiB0aGlzLnN0YXRlLnBvcG92ZXJPcGVuLFxuICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yRWw6IHRoaXMuc3RhdGUucG9wb3ZlckFuY2hvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvck9yaWdpbjogeyBob3Jpem9udGFsOiAncmlnaHQnLCB2ZXJ0aWNhbDogJ3RvcCcgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldE9yaWdpbjogeyBob3Jpem9udGFsOiAnbGVmdCcsIHZlcnRpY2FsOiAndG9wJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgb25SZXF1ZXN0Q2xvc2U6IHRoaXMuY2xvc2VQb3BvdmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IF9leHRlbmRzKHsgbWFyZ2luTGVmdDogMjAgfSwgcG9wb3ZlclN0eWxlKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHpEZXB0aDogMlxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiBfZXh0ZW5kcyh7IHdpZHRoOiAzMjAsIGhlaWdodDogNDIwIH0sIHBvcG92ZXJDb250YWluZXJTdHlsZSkgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoQWRkcmVzc0Jvb2ssIF9leHRlbmRzKHt9LCB0aGlzLnByb3BzLCB7IG1vZGU6ICdzZWxlY3RvcicgfSkpXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIF9zdGF0ZSA9IHRoaXMuc3RhdGU7XG4gICAgICAgIHZhciBzZWxlY3RlZEl0ZW0gPSBfc3RhdGUuc2VsZWN0ZWRJdGVtO1xuICAgICAgICB2YXIgcm9vdCA9IF9zdGF0ZS5yb290O1xuICAgICAgICB2YXIgcmlnaHRQYW5lSXRlbSA9IF9zdGF0ZS5yaWdodFBhbmVJdGVtO1xuICAgICAgICB2YXIgY3JlYXRlRGlhbG9nSXRlbSA9IF9zdGF0ZS5jcmVhdGVEaWFsb2dJdGVtO1xuXG4gICAgICAgIHZhciBsZWZ0Q29sdW1uU3R5bGUgPSB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9ycy5ncmV5MTAwLFxuICAgICAgICAgICAgd2lkdGg6IDI1NixcbiAgICAgICAgICAgIG92ZXJmbG93WTogJ2F1dG8nLFxuICAgICAgICAgICAgb3ZlcmZsb3dYOiAnaGlkZGVuJ1xuICAgICAgICB9O1xuICAgICAgICB2YXIgY2VudGVyQ29tcG9uZW50ID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgcmlnaHRQYW5lbCA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGxlZnRQYW5lbCA9IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAoc2VsZWN0ZWRJdGVtLmlkID09PSAnc2VhcmNoJykge1xuXG4gICAgICAgICAgICBjZW50ZXJDb21wb25lbnQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9TZWFyY2hQYW5lbDJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgIGl0ZW06IHNlbGVjdGVkSXRlbSxcbiAgICAgICAgICAgICAgICB0aXRsZTogZ2V0TWVzc2FnZSg1ODMsICcnKSxcbiAgICAgICAgICAgICAgICBzZWFyY2hMYWJlbDogZ2V0TWVzc2FnZSg1OTUsICcnKSxcbiAgICAgICAgICAgICAgICBvbkl0ZW1DbGlja2VkOiB0aGlzLm9uVXNlckxpc3RJdGVtQ2xpY2tlZCxcbiAgICAgICAgICAgICAgICBvbkZvbGRlckNsaWNrZWQ6IHRoaXMub25Gb2xkZXJDbGlja2VkLFxuICAgICAgICAgICAgICAgIG1vZGU6IG1vZGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHNlbGVjdGVkSXRlbS50eXBlID09PSAncmVtb3RlJykge1xuXG4gICAgICAgICAgICBjZW50ZXJDb21wb25lbnQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9TZWFyY2hQYW5lbDJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgIGl0ZW06IHNlbGVjdGVkSXRlbSxcbiAgICAgICAgICAgICAgICBwYXJhbXM6IHsgdHJ1c3RlZF9zZXJ2ZXJfaWQ6IHNlbGVjdGVkSXRlbS5pZCB9LFxuICAgICAgICAgICAgICAgIHNlYXJjaExhYmVsOiBnZXRNZXNzYWdlKDU5NSwgJycpLFxuICAgICAgICAgICAgICAgIHRpdGxlOiBnZXRNZXNzYWdlKDU5NiwgJycpLnJlcGxhY2UoJyVzJywgc2VsZWN0ZWRJdGVtLmxhYmVsKSxcbiAgICAgICAgICAgICAgICBvbkl0ZW1DbGlja2VkOiB0aGlzLm9uVXNlckxpc3RJdGVtQ2xpY2tlZCxcbiAgICAgICAgICAgICAgICBvbkZvbGRlckNsaWNrZWQ6IHRoaXMub25Gb2xkZXJDbGlja2VkLFxuICAgICAgICAgICAgICAgIG1vZGU6IG1vZGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICB2YXIgZW1wdHlTdGF0ZVByaW1hcnkgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB2YXIgZW1wdHlTdGF0ZVNlY29uZGFyeSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHZhciBvdGhlclByb3BzID0ge307XG4gICAgICAgICAgICBpZiAoc2VsZWN0ZWRJdGVtLmlkID09PSAndGVhbXMnKSB7XG4gICAgICAgICAgICAgICAgZW1wdHlTdGF0ZVByaW1hcnkgPSBnZXRNZXNzYWdlKDU3MSwgJycpO1xuICAgICAgICAgICAgICAgIGVtcHR5U3RhdGVTZWNvbmRhcnkgPSBnZXRNZXNzYWdlKDU3MiwgJycpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZEl0ZW0uaWQgPT09ICdleHQnKSB7XG4gICAgICAgICAgICAgICAgZW1wdHlTdGF0ZVByaW1hcnkgPSBnZXRNZXNzYWdlKDU4NSwgJycpO1xuICAgICAgICAgICAgICAgIGVtcHR5U3RhdGVTZWNvbmRhcnkgPSBnZXRNZXNzYWdlKDU4NiwgJycpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZEl0ZW0uaWQuaW5kZXhPZignQUpYUF9HUlBfLycpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgb3RoZXJQcm9wcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgc2hvd1N1YmhlYWRlcnM6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHBhZ2luYXRvclR5cGU6ICEoc2VsZWN0ZWRJdGVtLmN1cnJlbnRQYXJhbXMgJiYgc2VsZWN0ZWRJdGVtLmN1cnJlbnRQYXJhbXMuaGFzX3NlYXJjaCkgJiYgJ2FscGhhJyxcbiAgICAgICAgICAgICAgICAgICAgcGFnaW5hdG9yQ2FsbGJhY2s6IHRoaXMucmVsb2FkQ3VycmVudEF0UGFnZS5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgICAgICBlbmFibGVTZWFyY2g6ICF0aGlzLnByb3BzLmRpc2FibGVTZWFyY2gsXG4gICAgICAgICAgICAgICAgICAgIHNlYXJjaExhYmVsOiBnZXRNZXNzYWdlKDU5NSwgJycpLFxuICAgICAgICAgICAgICAgICAgICBvblNlYXJjaDogdGhpcy5yZWxvYWRDdXJyZW50V2l0aFNlYXJjaC5iaW5kKHRoaXMpXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2VudGVyQ29tcG9uZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudChfVXNlcnNMaXN0MlsnZGVmYXVsdCddLCBfZXh0ZW5kcyh7XG4gICAgICAgICAgICAgICAgaXRlbTogc2VsZWN0ZWRJdGVtLFxuICAgICAgICAgICAgICAgIG9uSXRlbUNsaWNrZWQ6IHRoaXMub25Vc2VyTGlzdEl0ZW1DbGlja2VkLFxuICAgICAgICAgICAgICAgIG9uRm9sZGVyQ2xpY2tlZDogdGhpcy5vbkZvbGRlckNsaWNrZWQsXG4gICAgICAgICAgICAgICAgb25DcmVhdGVBY3Rpb246IHRoaXMub25DcmVhdGVBY3Rpb24sXG4gICAgICAgICAgICAgICAgb25EZWxldGVBY3Rpb246IHRoaXMub25EZWxldGVBY3Rpb24sXG4gICAgICAgICAgICAgICAgbG9hZGluZzogdGhpcy5zdGF0ZS5sb2FkaW5nLFxuICAgICAgICAgICAgICAgIG1vZGU6IG1vZGUsXG4gICAgICAgICAgICAgICAgZW1wdHlTdGF0ZVByaW1hcnlUZXh0OiBlbXB0eVN0YXRlUHJpbWFyeSxcbiAgICAgICAgICAgICAgICBlbXB0eVN0YXRlU2Vjb25kYXJ5VGV4dDogZW1wdHlTdGF0ZVNlY29uZGFyeSxcbiAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiB0aGlzLnN0YXRlLnJpZ2h0UGFuZUl0ZW0gPyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzNC5zZXRTdGF0ZSh7IHJpZ2h0UGFuZUl0ZW06IG51bGwgfSk7XG4gICAgICAgICAgICAgICAgfSA6IG51bGxcbiAgICAgICAgICAgIH0sIG90aGVyUHJvcHMpKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcmlnaHRQYW5lbFN0eWxlID0gX2V4dGVuZHMoe30sIGxlZnRDb2x1bW5TdHlsZSwgeyB0cmFuc2Zvcm1PcmlnaW46ICdyaWdodCcsIGJhY2tncm91bmRDb2xvcjogJ3doaXRlJyB9KTtcbiAgICAgICAgaWYgKCFyaWdodFBhbmVJdGVtKSB7XG4gICAgICAgICAgICByaWdodFBhbmVsU3R5bGUgPSBfZXh0ZW5kcyh7fSwgcmlnaHRQYW5lbFN0eWxlLCB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMjU2cHgpJywgd2lkdGg6IDAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmlnaHRQYW5lbCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoX1JpZ2h0UGFuZWxDYXJkMlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpbyxcbiAgICAgICAgICAgIG9uUmVxdWVzdENsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3RoaXM0LnNldFN0YXRlKHsgcmlnaHRQYW5lSXRlbTogbnVsbCB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzdHlsZTogcmlnaHRQYW5lbFN0eWxlLFxuICAgICAgICAgICAgb25DcmVhdGVBY3Rpb246IHRoaXMub25DcmVhdGVBY3Rpb24sXG4gICAgICAgICAgICBvbkRlbGV0ZUFjdGlvbjogdGhpcy5vbkRlbGV0ZUFjdGlvbixcbiAgICAgICAgICAgIG9uVXBkYXRlQWN0aW9uOiB0aGlzLm9uQ2FyZFVwZGF0ZUFjdGlvbixcbiAgICAgICAgICAgIGl0ZW06IHJpZ2h0UGFuZUl0ZW0gfSk7XG4gICAgICAgIGlmIChtb2RlID09PSAnYm9vaycpIHtcbiAgICAgICAgICAgIGxlZnRQYW5lbCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgTWF0ZXJpYWxVSS5QYXBlcixcbiAgICAgICAgICAgICAgICB7IHpEZXB0aDogMCwgc3R5bGU6IF9leHRlbmRzKHt9LCBsZWZ0Q29sdW1uU3R5bGUsIHsgekluZGV4OiAyIH0pIH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgTWF0ZXJpYWxVSS5MaXN0LFxuICAgICAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICAgICByb290LmNvbGxlY3Rpb25zLm1hcCgoZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KF9OZXN0ZWRMaXN0SXRlbTJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleTogZS5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDogc2VsZWN0ZWRJdGVtLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lc3RlZExldmVsOiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJ5OiBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IHRoaXMub25Gb2xkZXJDbGlja2VkXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSkuYmluZCh0aGlzKSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGRpYWxvZ1RpdGxlID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgZGlhbG9nQ29udGVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGNyZWF0ZURpYWxvZ0l0ZW0pIHtcbiAgICAgICAgICAgIGlmIChjcmVhdGVEaWFsb2dJdGVtLmFjdGlvbnMudHlwZSA9PT0gJ3VzZXJzJykge1xuICAgICAgICAgICAgICAgIGRpYWxvZ1RpdGxlID0gZ2V0TWVzc2FnZSg0ODQsICcnKTtcbiAgICAgICAgICAgICAgICBkaWFsb2dDb250ZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgaGVpZ2h0OiA1MDAgfSB9LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEFzeW5jQ29tcG9uZW50LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2U6ICdQeWRpb0Zvcm0nLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogJ1VzZXJDcmVhdGlvbkZvcm0nLFxuICAgICAgICAgICAgICAgICAgICAgICAgekRlcHRoOiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHsgaGVpZ2h0OiA1MDAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1VzZXJOYW1lOiBcIlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgb25Vc2VyQ3JlYXRlZDogdGhpcy5jbG9zZUNyZWF0ZURpYWxvZ0FuZFJlbG9hZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2FuY2VsOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXM0LnNldFN0YXRlKHsgY3JlYXRlRGlhbG9nSXRlbTogbnVsbCB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpb1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNyZWF0ZURpYWxvZ0l0ZW0uYWN0aW9ucy50eXBlID09PSAndGVhbXMnKSB7XG4gICAgICAgICAgICAgICAgZGlhbG9nVGl0bGUgPSBnZXRNZXNzYWdlKDU2OSwgJycpO1xuICAgICAgICAgICAgICAgIGRpYWxvZ0NvbnRlbnQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9UZWFtQ3JlYXRpb25Gb3JtMlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICAgICAgICAgIG9uVGVhbUNyZWF0ZWQ6IHRoaXMuY2xvc2VDcmVhdGVEaWFsb2dBbmRSZWxvYWQsXG4gICAgICAgICAgICAgICAgICAgIG9uQ2FuY2VsOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpczQuc2V0U3RhdGUoeyBjcmVhdGVEaWFsb2dJdGVtOiBudWxsIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNyZWF0ZURpYWxvZ0l0ZW0uYWN0aW9ucy50eXBlID09PSAndGVhbScpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0VXNlciA9IGZ1bmN0aW9uIHNlbGVjdFVzZXIoaXRlbSkge1xuICAgICAgICAgICAgICAgICAgICBfVGVhbUNyZWF0aW9uRm9ybTJbJ2RlZmF1bHQnXS51cGRhdGVUZWFtVXNlcnMoY3JlYXRlRGlhbG9nSXRlbSwgJ2FkZCcsIFtpdGVtXSwgX3RoaXM0LnJlbG9hZEN1cnJlbnROb2RlLmJpbmQoX3RoaXM0KSk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBkaWFsb2dUaXRsZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgZGlhbG9nQ29udGVudCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoQWRkcmVzc0Jvb2ssIHtcbiAgICAgICAgICAgICAgICAgICAgcHlkaW86IHRoaXMucHJvcHMucHlkaW8sXG4gICAgICAgICAgICAgICAgICAgIG1vZGU6ICdzZWxlY3RvcicsXG4gICAgICAgICAgICAgICAgICAgIHVzZXJzT25seTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZVNlYXJjaDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgb25JdGVtU2VsZWN0ZWQ6IHNlbGVjdFVzZXJcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzdHlsZSA9IHRoaXMucHJvcHMuc3R5bGUgfHwge307XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiBfZXh0ZW5kcyh7IGRpc3BsYXk6ICdmbGV4JywgaGVpZ2h0OiBtb2RlID09PSAnc2VsZWN0b3InID8gNDIwIDogNDUwIH0sIHN0eWxlKSB9LFxuICAgICAgICAgICAgbGVmdFBhbmVsLFxuICAgICAgICAgICAgY2VudGVyQ29tcG9uZW50LFxuICAgICAgICAgICAgcmlnaHRQYW5lbCxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgTWF0ZXJpYWxVSS5EaWFsb2csXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb250ZW50U3R5bGU6IHsgd2lkdGg6IDM4MCwgbWluV2lkdGg6IDM4MCwgbWF4V2lkdGg6IDM4MCwgcGFkZGluZzogMCB9LFxuICAgICAgICAgICAgICAgICAgICBib2R5U3R5bGU6IHsgcGFkZGluZzogMCB9LFxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyBwYWRkaW5nOiAyMCB9IH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBkaWFsb2dUaXRsZVxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICBhY3Rpb25zOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBtb2RhbDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG9wZW46IGNyZWF0ZURpYWxvZ0l0ZW0gPyB0cnVlIDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG9uUmVxdWVzdENsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpczQuc2V0U3RhdGUoeyBjcmVhdGVEaWFsb2dJdGVtOiBudWxsIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBkaWFsb2dDb250ZW50XG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gQWRkcmVzc0Jvb2sgPSBQeWRpb0NvbnRleHRDb25zdW1lcihBZGRyZXNzQm9vayk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBBZGRyZXNzQm9vayA9IG11aVRoZW1lYWJsZSgpKEFkZHJlc3NCb29rKTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEFkZHJlc3NCb29rO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBfbWF0ZXJpYWxVaVN0eWxlcyA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpL3N0eWxlcycpO1xuXG52YXIgX3B5ZGlvID0gcmVxdWlyZSgncHlkaW8nKTtcblxudmFyIF9weWRpbzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9weWRpbyk7XG5cbnZhciBfbWF0ZXJpYWxVaSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbi8qKlxuICogQWxwaGFiZXQgYW5kIHBhZ2VzIGdlbmVyYXRvciB0byBnaXZlIGEgZmlyc3QtbGV0dGVyLWJhc2VkIHBhZ2luYXRpb25cbiAqL1xuXG52YXIgX1B5ZGlvJHJlcXVpcmVMaWIgPSBfcHlkaW8yWydkZWZhdWx0J10ucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgUHlkaW9Db250ZXh0Q29uc3VtZXIgPSBfUHlkaW8kcmVxdWlyZUxpYi5QeWRpb0NvbnRleHRDb25zdW1lcjtcblxudmFyIEFscGhhUGFnaW5hdG9yID0gKGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7XG4gICAgX2luaGVyaXRzKEFscGhhUGFnaW5hdG9yLCBfQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIEFscGhhUGFnaW5hdG9yKCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQWxwaGFQYWdpbmF0b3IpO1xuXG4gICAgICAgIF9Db21wb25lbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBBbHBoYVBhZ2luYXRvci5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuXG4gICAgICAgIHZhciBsZXR0ZXJzID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OScuc3BsaXQoJycpO1xuICAgICAgICBsZXR0ZXJzID0gWy0xXS5jb25jYXQobGV0dGVycyk7XG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgaXRlbSA9IF9wcm9wcy5pdGVtO1xuICAgICAgICB2YXIgcGFnaW5hdG9yQ2FsbGJhY2sgPSBfcHJvcHMucGFnaW5hdG9yQ2FsbGJhY2s7XG4gICAgICAgIHZhciBzdHlsZSA9IF9wcm9wcy5zdHlsZTtcbiAgICAgICAgdmFyIGdldE1lc3NhZ2UgPSBfcHJvcHMuZ2V0TWVzc2FnZTtcblxuICAgICAgICB2YXIgcGFnaW5hdG9yID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoaXRlbS5wYWdpbmF0aW9uKSB7XG4gICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBfaXRlbSRwYWdpbmF0aW9uID0gaXRlbS5wYWdpbmF0aW9uO1xuICAgICAgICAgICAgICAgIHZhciBzdGFydCA9IF9pdGVtJHBhZ2luYXRpb24uc3RhcnQ7XG4gICAgICAgICAgICAgICAgdmFyIGVuZCA9IF9pdGVtJHBhZ2luYXRpb24uZW5kO1xuICAgICAgICAgICAgICAgIHZhciBtYXggPSBfaXRlbSRwYWdpbmF0aW9uLm1heDtcbiAgICAgICAgICAgICAgICB2YXIgaW50ZXJ2YWwgPSBfaXRlbSRwYWdpbmF0aW9uLmludGVydmFsO1xuXG4gICAgICAgICAgICAgICAgdmFyIHRvdGFsX3BhZ2VzID0gTWF0aC5jZWlsKG1heCAvIGludGVydmFsKTtcbiAgICAgICAgICAgICAgICB2YXIgY3VycmVudCA9IE1hdGguY2VpbChzdGFydCAvIGludGVydmFsKTtcbiAgICAgICAgICAgICAgICB2YXIgcGFnZXMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRvdGFsX3BhZ2VzOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgcGFnZXMucHVzaChpKTtcbiAgICAgICAgICAgICAgICB9cGFnaW5hdG9yID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgX21hdGVyaWFsVWkuU2VsZWN0RmllbGQsXG4gICAgICAgICAgICAgICAgICAgIHsgZmxvYXRpbmdMYWJlbFRleHQ6IGdldE1lc3NhZ2UoMzMxKSwgc3R5bGU6IHsgd2lkdGg6IDYwIH0sIGZ1bGxXaWR0aDogdHJ1ZSwgdmFsdWU6IGN1cnJlbnQsIG9uQ2hhbmdlOiBmdW5jdGlvbiAoZSwgaSwgdikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2luYXRvckNhbGxiYWNrKHYgKiBpbnRlcnZhbCArICctJyArICh2ICsgMSkgKiBpbnRlcnZhbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IH0sXG4gICAgICAgICAgICAgICAgICAgIHBhZ2VzLm1hcChmdW5jdGlvbiAocCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX21hdGVyaWFsVWkuTWVudUl0ZW0sIHsgdmFsdWU6IHAsIGtleTogcCwgcHJpbWFyeVRleHQ6IHAgKyAxIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGN1cnJlbnRQYWdlID0gaXRlbS5jdXJyZW50UGFyYW1zICYmIGl0ZW0uY3VycmVudFBhcmFtcy5hbHBoYV9wYWdlcyAmJiBpdGVtLmN1cnJlbnRQYXJhbXMudmFsdWUgfHwgLTE7XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgc3R5bGU6IF9leHRlbmRzKHt9LCBzdHlsZSwgeyBkaXNwbGF5OiAnZmxleCcsIHBhZGRpbmdSaWdodDogOCwgYWxpZ25JdGVtczogJ2NlbnRlcicgfSkgfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBmbGV4OiAxIH0gfSxcbiAgICAgICAgICAgICAgICBnZXRNZXNzYWdlKDI0OSwgJycpXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgcGFnaW5hdG9yLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBfbWF0ZXJpYWxVaS5TZWxlY3RGaWVsZCxcbiAgICAgICAgICAgICAgICB7IGZsb2F0aW5nTGFiZWxUZXh0OiBnZXRNZXNzYWdlKDYyNSksIHN0eWxlOiB7IHdpZHRoOiA2MCwgbWFyZ2luTGVmdDogMjAgfSwgZnVsbFdpZHRoOiB0cnVlLCB2YWx1ZTogY3VycmVudFBhZ2UsIG9uQ2hhbmdlOiBmdW5jdGlvbiAoZSwgaSwgdikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFnaW5hdG9yQ2FsbGJhY2sodik7XG4gICAgICAgICAgICAgICAgICAgIH0gfSxcbiAgICAgICAgICAgICAgICBsZXR0ZXJzLm1hcChmdW5jdGlvbiAobCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChfbWF0ZXJpYWxVaS5NZW51SXRlbSwgeyB2YWx1ZTogbCwga2V5OiBsLCBwcmltYXJ5VGV4dDogbCA9PT0gLTEgPyBnZXRNZXNzYWdlKDU5NywgJycpIDogbCB9KTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH07XG5cbiAgICByZXR1cm4gQWxwaGFQYWdpbmF0b3I7XG59KShfcmVhY3QuQ29tcG9uZW50KTtcblxuQWxwaGFQYWdpbmF0b3IucHJvcFR5cGVzID0ge1xuICAgIC8qKlxuICAgICAqIEN1cnJlbnRseSBzZWxlY3RlZCBJdGVtXG4gICAgICovXG4gICAgaXRlbTogX3JlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICogV2hlbiBhIGxldHRlciBpcyBjbGlja2VkLCBmdW5jdGlvbihsZXR0ZXIpXG4gICAgICovXG4gICAgcGFnaW5hdG9yQ2FsbGJhY2s6IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICAgIC8qKlxuICAgICAqIE1haW4gaW5zdGFuY2Ugb2YgcHlkaW9cbiAgICAgKi9cbiAgICBweWRpbzogX3JlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKF9weWRpbzJbJ2RlZmF1bHQnXSksXG4gICAgLyoqXG4gICAgICogRGlzcGxheSBtb2RlLCBlaXRoZXIgbGFyZ2UgKGJvb2spIG9yIHNtYWxsIHBpY2tlciAoJ3NlbGVjdG9yJywgJ3BvcG92ZXInKS5cbiAgICAgKi9cbiAgICBtb2RlOiBfcmVhY3QuUHJvcFR5cGVzLm9uZU9mKFsnYm9vaycsICdzZWxlY3RvcicsICdwb3BvdmVyJ10pLmlzUmVxdWlyZWRcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEFscGhhUGFnaW5hdG9yID0gUHlkaW9Db250ZXh0Q29uc3VtZXIoQWxwaGFQYWdpbmF0b3IpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gQWxwaGFQYWdpbmF0b3IgPSBfbWF0ZXJpYWxVaVN0eWxlcy5tdWlUaGVtZWFibGUoKShBbHBoYVBhZ2luYXRvcik7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEFscGhhUGFnaW5hdG9yO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbnZhciBMb2FkZXJzID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBMb2FkZXJzKCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTG9hZGVycyk7XG4gICAgfVxuXG4gICAgTG9hZGVycy5jaGlsZHJlbkFzUHJvbWlzZSA9IGZ1bmN0aW9uIGNoaWxkcmVuQXNQcm9taXNlKGl0ZW0pIHtcbiAgICAgICAgdmFyIGxlYWYgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgdmFyIGNoaWxkcmVuTG9hZGVyID0gaXRlbS5jaGlsZHJlbkxvYWRlcjtcbiAgICAgICAgdmFyIGl0ZW1zTG9hZGVyID0gaXRlbS5pdGVtc0xvYWRlcjtcbiAgICAgICAgdmFyIGxlYWZMb2FkZWQgPSBpdGVtLmxlYWZMb2FkZWQ7XG4gICAgICAgIHZhciBjb2xsZWN0aW9uc0xvYWRlZCA9IGl0ZW0uY29sbGVjdGlvbnNMb2FkZWQ7XG4gICAgICAgIHZhciBsZWFmcyA9IGl0ZW0ubGVhZnM7XG4gICAgICAgIHZhciBjb2xsZWN0aW9ucyA9IGl0ZW0uY29sbGVjdGlvbnM7XG5cbiAgICAgICAgdmFyIGxvYWRlciA9IGxlYWYgPyBpdGVtc0xvYWRlciA6IGNoaWxkcmVuTG9hZGVyO1xuICAgICAgICB2YXIgbG9hZGVkID0gbGVhZiA/IGxlYWZMb2FkZWQgOiBjb2xsZWN0aW9uc0xvYWRlZDtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIGlmICghbG9hZGVkICYmIGxvYWRlcikge1xuICAgICAgICAgICAgICAgIGxvYWRlcihpdGVtLCBmdW5jdGlvbiAobmV3Q2hpbGRyZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxlYWYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0ubGVhZnMgPSBuZXdDaGlsZHJlbjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0ubGVhZkxvYWRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmNvbGxlY3Rpb25zID0gbmV3Q2hpbGRyZW47XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmNvbGxlY3Rpb25zTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG5ld0NoaWxkcmVuKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlcyA9IChsZWFmID8gbGVhZnMgOiBjb2xsZWN0aW9ucykgfHwgW107XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgTG9hZGVycy5saXN0VXNlcnMgPSBmdW5jdGlvbiBsaXN0VXNlcnMocGFyYW1zLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgcGFyZW50ID0gYXJndW1lbnRzLmxlbmd0aCA8PSAyIHx8IGFyZ3VtZW50c1syXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGFyZ3VtZW50c1syXTtcblxuICAgICAgICB2YXIgYmFzZVBhcmFtcyA9IHsgZ2V0X2FjdGlvbjogJ3VzZXJfbGlzdF9hdXRob3JpemVkX3VzZXJzJywgZm9ybWF0OiAnanNvbicgfTtcbiAgICAgICAgYmFzZVBhcmFtcyA9IF9leHRlbmRzKHt9LCBiYXNlUGFyYW1zLCBwYXJhbXMpO1xuICAgICAgICB2YXIgY2IgPSBjYWxsYmFjaztcbiAgICAgICAgaWYgKHBhcmVudCkge1xuICAgICAgICAgICAgaWYgKHBhcmVudC5yYW5nZSkge1xuICAgICAgICAgICAgICAgIGJhc2VQYXJhbXNbJ3JhbmdlJ10gPSBwYXJlbnQucmFuZ2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYiA9IGZ1bmN0aW9uIChjaGlsZHJlbikge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNoaWxkcmVuLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgICAgICAgICBjLl9wYXJlbnQgPSBwYXJlbnQ7cmV0dXJuIGM7XG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBQeWRpb0FwaS5nZXRDbGllbnQoKS5yZXF1ZXN0KGJhc2VQYXJhbXMsIGZ1bmN0aW9uICh0cmFuc3BvcnQpIHtcbiAgICAgICAgICAgIGNiKHRyYW5zcG9ydC5yZXNwb25zZUpTT04pO1xuICAgICAgICAgICAgdmFyIGNSYW5nZSA9IHRyYW5zcG9ydC5yZXNwb25zZU9iamVjdC5oZWFkZXJzLmdldCgnQ29udGVudC1SYW5nZScpO1xuICAgICAgICAgICAgdmFyIGFSYW5nZSA9IHRyYW5zcG9ydC5yZXNwb25zZU9iamVjdC5oZWFkZXJzLmdldCgnQWNjZXB0LVJhbmdlJyk7XG4gICAgICAgICAgICBpZiAoY1JhbmdlICYmIGFSYW5nZSAmJiBwYXJlbnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2FSYW5nZSRzcGxpdCA9IGFSYW5nZS5zcGxpdCgnICcpO1xuXG4gICAgICAgICAgICAgICAgdmFyIHR5cGUgPSBfYVJhbmdlJHNwbGl0WzBdO1xuICAgICAgICAgICAgICAgIHZhciBpbnRlcnZhbCA9IF9hUmFuZ2Ukc3BsaXRbMV07XG5cbiAgICAgICAgICAgICAgICB2YXIgX2NSYW5nZSRzcGxpdCA9IGNSYW5nZS5zcGxpdCgnLycpO1xuXG4gICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gX2NSYW5nZSRzcGxpdFswXTtcbiAgICAgICAgICAgICAgICB2YXIgbWF4ID0gX2NSYW5nZSRzcGxpdFsxXTtcblxuICAgICAgICAgICAgICAgIHZhciBfcmFuZ2Ukc3BsaXQgPSByYW5nZS5zcGxpdCgnLScpO1xuXG4gICAgICAgICAgICAgICAgdmFyIHN0YXJ0ID0gX3JhbmdlJHNwbGl0WzBdO1xuICAgICAgICAgICAgICAgIHZhciBlbmQgPSBfcmFuZ2Ukc3BsaXRbMV07XG5cbiAgICAgICAgICAgICAgICBwYXJlbnQucGFnaW5hdGlvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnQ6IHBhcnNlSW50KHN0YXJ0KSxcbiAgICAgICAgICAgICAgICAgICAgZW5kOiBwYXJzZUludChlbmQpLFxuICAgICAgICAgICAgICAgICAgICBtYXg6IHBhcnNlSW50KG1heCksXG4gICAgICAgICAgICAgICAgICAgIGludGVydmFsOiBwYXJzZUludChpbnRlcnZhbClcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgTG9hZGVycy5sb2FkVGVhbXMgPSBmdW5jdGlvbiBsb2FkVGVhbXMoZW50cnksIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciB3cmFwcGVkID0gZnVuY3Rpb24gd3JhcHBlZChjaGlsZHJlbikge1xuICAgICAgICAgICAgY2hpbGRyZW4ubWFwKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAgICAgICAgIGNoaWxkLmljb24gPSAnbWRpIG1kaS1hY2NvdW50LW11bHRpcGxlJztcbiAgICAgICAgICAgICAgICBjaGlsZC5pdGVtc0xvYWRlciA9IExvYWRlcnMubG9hZFRlYW1Vc2VycztcbiAgICAgICAgICAgICAgICBjaGlsZC5hY3Rpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGVhbScsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZTogJzU3MycsXG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZTogJzU3NCcsXG4gICAgICAgICAgICAgICAgICAgIG11bHRpcGxlOiB0cnVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBjaGlsZC5fbm90U2VsZWN0YWJsZSA9IHRydWU7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNhbGxiYWNrKGNoaWxkcmVuKTtcbiAgICAgICAgfTtcbiAgICAgICAgTG9hZGVycy5saXN0VXNlcnMoeyBmaWx0ZXJfdmFsdWU6IDggfSwgd3JhcHBlZCwgZW50cnkpO1xuICAgIH07XG5cbiAgICBMb2FkZXJzLmxvYWRHcm91cHMgPSBmdW5jdGlvbiBsb2FkR3JvdXBzKGVudHJ5LCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgd3JhcHBlZCA9IGZ1bmN0aW9uIHdyYXBwZWQoY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIGNoaWxkcmVuLm1hcChmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgICAgICAgICBjaGlsZC5pY29uID0gJ21kaSBtZGktYWNjb3VudC1tdWx0aXBsZSc7XG4gICAgICAgICAgICAgICAgY2hpbGQuY2hpbGRyZW5Mb2FkZXIgPSBlbnRyeS5jaGlsZHJlbkxvYWRlciA/IExvYWRlcnMubG9hZEdyb3VwcyA6IG51bGw7XG4gICAgICAgICAgICAgICAgY2hpbGQuaXRlbXNMb2FkZXIgPSBlbnRyeS5pdGVtc0xvYWRlciA/IExvYWRlcnMubG9hZEdyb3VwVXNlcnMgOiBudWxsO1xuICAgICAgICAgICAgICAgIGlmIChlbnRyeS5jdXJyZW50UGFyYW1zICYmIGVudHJ5LmN1cnJlbnRQYXJhbXMuYWxwaGFfcGFnZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGQuY3VycmVudFBhcmFtcyA9IF9leHRlbmRzKHt9LCBlbnRyeS5jdXJyZW50UGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNhbGxiYWNrKGNoaWxkcmVuKTtcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHBhdGggPSBlbnRyeS5pZC5yZXBsYWNlKCdBSlhQX0dSUF8nLCAnJyk7XG4gICAgICAgIHZhciBwYXJhbXMgPSB7IGZpbHRlcl92YWx1ZTogNCwgZ3JvdXBfcGF0aDogcGF0aCB9O1xuICAgICAgICBpZiAoZW50cnkuY3VycmVudFBhcmFtcyAmJiAhZW50cnkuY3VycmVudFBhcmFtcy5hbHBoYV9wYWdlcykge1xuICAgICAgICAgICAgcGFyYW1zID0gX2V4dGVuZHMoe30sIHBhcmFtcywgZW50cnkuY3VycmVudFBhcmFtcyk7XG4gICAgICAgIH1cbiAgICAgICAgTG9hZGVycy5saXN0VXNlcnMocGFyYW1zLCB3cmFwcGVkLCBlbnRyeSk7XG4gICAgfTtcblxuICAgIExvYWRlcnMubG9hZEV4dGVybmFsVXNlcnMgPSBmdW5jdGlvbiBsb2FkRXh0ZXJuYWxVc2VycyhlbnRyeSwgY2FsbGJhY2spIHtcbiAgICAgICAgTG9hZGVycy5saXN0VXNlcnMoeyBmaWx0ZXJfdmFsdWU6IDIgfSwgY2FsbGJhY2ssIGVudHJ5KTtcbiAgICB9O1xuXG4gICAgTG9hZGVycy5sb2FkR3JvdXBVc2VycyA9IGZ1bmN0aW9uIGxvYWRHcm91cFVzZXJzKGVudHJ5LCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgcGF0aCA9IGVudHJ5LmlkLnJlcGxhY2UoJ0FKWFBfR1JQXycsICcnKTtcbiAgICAgICAgdmFyIHBhcmFtcyA9IHsgZmlsdGVyX3ZhbHVlOiAxLCBncm91cF9wYXRoOiBwYXRoIH07XG4gICAgICAgIGlmIChlbnRyeS5jdXJyZW50UGFyYW1zKSB7XG4gICAgICAgICAgICBwYXJhbXMgPSBfZXh0ZW5kcyh7fSwgcGFyYW1zLCBlbnRyeS5jdXJyZW50UGFyYW1zKTtcbiAgICAgICAgfVxuICAgICAgICBMb2FkZXJzLmxpc3RVc2VycyhwYXJhbXMsIGNhbGxiYWNrLCBlbnRyeSk7XG4gICAgfTtcblxuICAgIExvYWRlcnMubG9hZFRlYW1Vc2VycyA9IGZ1bmN0aW9uIGxvYWRUZWFtVXNlcnMoZW50cnksIGNhbGxiYWNrKSB7XG4gICAgICAgIExvYWRlcnMubGlzdFVzZXJzKHsgZmlsdGVyX3ZhbHVlOiAzLCBncm91cF9wYXRoOiBlbnRyeS5pZCB9LCBjYWxsYmFjaywgZW50cnkpO1xuICAgIH07XG5cbiAgICByZXR1cm4gTG9hZGVycztcbn0pKCk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IExvYWRlcnM7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIENvbXBvbmVudCA9IF9yZXF1aXJlLkNvbXBvbmVudDtcbnZhciBQcm9wVHlwZXMgPSBfcmVxdWlyZS5Qcm9wVHlwZXM7XG5cbi8qKlxuICogTGVmdCBwYW5lbCBvZiB0aGUgYWRkcmVzcyBib29rXG4gKiBEaXNwbGF5IHRyZWV2aWV3IGhpZXJhcmNoeSBvZiB1c2VycywgdGVhbXMsIGdyb3Vwcy5cbiAqL1xuXG52YXIgTmVzdGVkTGlzdEl0ZW0gPSAoZnVuY3Rpb24gKF9Db21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoTmVzdGVkTGlzdEl0ZW0sIF9Db21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gTmVzdGVkTGlzdEl0ZW0oKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBOZXN0ZWRMaXN0SXRlbSk7XG5cbiAgICAgICAgX0NvbXBvbmVudC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJzIHRoaXMucHJvcHMub25Ub3VjaFRhcFxuICAgICAqL1xuXG4gICAgTmVzdGVkTGlzdEl0ZW0ucHJvdG90eXBlLm9uVG91Y2hUYXAgPSBmdW5jdGlvbiBvblRvdWNoVGFwKCkge1xuICAgICAgICB0aGlzLnByb3BzLm9uVG91Y2hUYXAodGhpcy5wcm9wcy5lbnRyeSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlY3Vyc2l2ZWx5IGJ1aWxkIG90aGVyIE5lc3RlZExpc3RJdGVtXG4gICAgICogQHBhcmFtIGRhdGFcbiAgICAgKi9cblxuICAgIE5lc3RlZExpc3RJdGVtLnByb3RvdHlwZS5idWlsZE5lc3RlZEl0ZW1zID0gZnVuY3Rpb24gYnVpbGROZXN0ZWRJdGVtcyhkYXRhKSB7XG4gICAgICAgIHJldHVybiBkYXRhLm1hcCgoZnVuY3Rpb24gKGVudHJ5KSB7XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChOZXN0ZWRMaXN0SXRlbSwge1xuICAgICAgICAgICAgICAgIG5lc3RlZExldmVsOiB0aGlzLnByb3BzLm5lc3RlZExldmVsICsgMSxcbiAgICAgICAgICAgICAgICBlbnRyeTogZW50cnksXG4gICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogdGhpcy5wcm9wcy5vblRvdWNoVGFwLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB0aGlzLnByb3BzLnNlbGVjdGVkXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgfTtcblxuICAgIE5lc3RlZExpc3RJdGVtLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfcHJvcHMkZW50cnkgPSB0aGlzLnByb3BzLmVudHJ5O1xuICAgICAgICB2YXIgaWQgPSBfcHJvcHMkZW50cnkuaWQ7XG4gICAgICAgIHZhciBsYWJlbCA9IF9wcm9wcyRlbnRyeS5sYWJlbDtcbiAgICAgICAgdmFyIGljb24gPSBfcHJvcHMkZW50cnkuaWNvbjtcbiAgICAgICAgdmFyIHNlbGVjdGVkID0gX3Byb3BzJGVudHJ5LnNlbGVjdGVkO1xuXG4gICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMucHJvcHMuZW50cnkuY29sbGVjdGlvbnMgfHwgW107XG4gICAgICAgIHZhciBuZXN0ZWQgPSB0aGlzLmJ1aWxkTmVzdGVkSXRlbXMoY2hpbGRyZW4pO1xuICAgICAgICB2YXIgZm9udEljb24gPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChpY29uKSB7XG4gICAgICAgICAgICBmb250SWNvbiA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWF0ZXJpYWxVSS5Gb250SWNvbiwgeyBjbGFzc05hbWU6IGljb24gfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWF0ZXJpYWxVSS5MaXN0SXRlbSwge1xuICAgICAgICAgICAgbmVzdGVkTGV2ZWw6IHRoaXMucHJvcHMubmVzdGVkTGV2ZWwsXG4gICAgICAgICAgICBrZXk6IGlkLFxuICAgICAgICAgICAgcHJpbWFyeVRleHQ6IGxhYmVsLFxuICAgICAgICAgICAgb25Ub3VjaFRhcDogdGhpcy5vblRvdWNoVGFwLmJpbmQodGhpcyksXG4gICAgICAgICAgICBuZXN0ZWRJdGVtczogbmVzdGVkLFxuICAgICAgICAgICAgaW5pdGlhbGx5T3BlbjogdHJ1ZSxcbiAgICAgICAgICAgIGxlZnRJY29uOiBmYWxzZSAmJiBmb250SWNvbixcbiAgICAgICAgICAgIGlubmVyRGl2U3R5bGU6IHsgZm9udFdlaWdodDogdGhpcy5wcm9wcy5zZWxlY3RlZCA9PT0gdGhpcy5wcm9wcy5lbnRyeS5pZCA/IDUwMCA6IDQwMCB9XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICByZXR1cm4gTmVzdGVkTGlzdEl0ZW07XG59KShDb21wb25lbnQpO1xuXG5OZXN0ZWRMaXN0SXRlbS5wcm9wVHlwZXMgPSB7XG4gICAgLyoqXG4gICAgICogS2VlcHMgdHJhY2sgb2YgdGhlIGN1cnJlbnQgZGVwdGggbGV2ZWxcbiAgICAgKi9cbiAgICBuZXN0ZWRMZXZlbDogUHJvcFR5cGVzLm51bWJlcixcbiAgICAvKipcbiAgICAgKiBDdXJyZW50bHkgc2VsZWN0ZWQgbm9kZSBpZFxuICAgICAqL1xuICAgIHNlbGVjdGVkOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIHRyaWdnZXJlZCB3aGVuIGFuIGVudHJ5IGlzIHNlbGVjdGVkXG4gICAgICovXG4gICAgb25Ub3VjaFRhcDogUHJvcFR5cGVzLmZ1bmNcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IE5lc3RlZExpc3RJdGVtO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9UZWFtQ2FyZCA9IHJlcXVpcmUoJy4vVGVhbUNhcmQnKTtcblxudmFyIF9UZWFtQ2FyZDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9UZWFtQ2FyZCk7XG5cbnZhciBfVXNlckNhcmQgPSByZXF1aXJlKCcuL1VzZXJDYXJkJyk7XG5cbnZhciBfVXNlckNhcmQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXNlckNhcmQpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgUGFwZXIgPSBfcmVxdWlyZS5QYXBlcjtcblxuLyoqXG4gKiBDb250YWluZXIgZm9yIFVzZXJDYXJkIG9yIFRlYW1DYXJkXG4gKi9cblxudmFyIFJpZ2h0UGFuZWxDYXJkID0gKGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7XG4gIF9pbmhlcml0cyhSaWdodFBhbmVsQ2FyZCwgX1JlYWN0JENvbXBvbmVudCk7XG5cbiAgZnVuY3Rpb24gUmlnaHRQYW5lbENhcmQoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFJpZ2h0UGFuZWxDYXJkKTtcblxuICAgIF9SZWFjdCRDb21wb25lbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIFJpZ2h0UGFuZWxDYXJkLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG5cbiAgICB2YXIgY29udGVudCA9IHVuZGVmaW5lZDtcbiAgICB2YXIgaXRlbSA9IHRoaXMucHJvcHMuaXRlbSB8fCB7fTtcbiAgICBpZiAoaXRlbS50eXBlID09PSAndXNlcicpIHtcbiAgICAgIGNvbnRlbnQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9Vc2VyQ2FyZDJbJ2RlZmF1bHQnXSwgdGhpcy5wcm9wcyk7XG4gICAgfSBlbHNlIGlmIChpdGVtLnR5cGUgPT09ICdncm91cCcgJiYgaXRlbS5pZC5pbmRleE9mKCcvQUpYUF9URUFNLycpID09PSAwKSB7XG4gICAgICBjb250ZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudChfVGVhbUNhcmQyWydkZWZhdWx0J10sIHRoaXMucHJvcHMpO1xuICAgIH1cblxuICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgUGFwZXIsXG4gICAgICB7IHpEZXB0aDogMiwgc3R5bGU6IF9leHRlbmRzKHsgcG9zaXRpb246ICdyZWxhdGl2ZScgfSwgdGhpcy5wcm9wcy5zdHlsZSkgfSxcbiAgICAgIGNvbnRlbnRcbiAgICApO1xuICB9O1xuXG4gIHJldHVybiBSaWdodFBhbmVsQ2FyZDtcbn0pKFJlYWN0LkNvbXBvbmVudCk7XG5cblJpZ2h0UGFuZWxDYXJkLnByb3BUeXBlcyA9IHtcbiAgLyoqXG4gICAqIFB5ZGlvIGluc3RhbmNlXG4gICAqL1xuICBweWRpbzogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW8pLFxuICAvKipcbiAgICogU2VsZWN0ZWQgaXRlbVxuICAgKi9cbiAgaXRlbTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgLyoqXG4gICAqIEFwcGxpZXMgdG8gcm9vdCBjb250YWluZXJcbiAgICovXG4gIHN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAvKipcbiAgICogRm9yd2FyZGVkIHRvIGNoaWxkXG4gICAqL1xuICBvblJlcXVlc3RDbG9zZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gIC8qKlxuICAgKiBGb3J3YXJkZWQgdG8gY2hpbGRcbiAgICovXG4gIG9uRGVsZXRlQWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgLyoqXG4gICAqIEZvcndhcmRlZCB0byBjaGlsZFxuICAgKi9cbiAgb25VcGRhdGVBY3Rpb246IFJlYWN0LlByb3BUeXBlcy5mdW5jXG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBSaWdodFBhbmVsQ2FyZDtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgQ29tcG9uZW50ID0gX3JlcXVpcmUuQ29tcG9uZW50O1xudmFyIFByb3BUeXBlcyA9IF9yZXF1aXJlLlByb3BUeXBlcztcblxuLyoqXG4gKiBSZWFkeSB0byB1c2UgRm9ybSArIFJlc3VsdCBMaXN0IGZvciBzZWFyY2ggdXNlcnNcbiAqL1xuXG52YXIgU2VhcmNoRm9ybSA9IChmdW5jdGlvbiAoX0NvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhTZWFyY2hGb3JtLCBfQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIFNlYXJjaEZvcm0ocHJvcHMsIGNvbnRleHQpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFNlYXJjaEZvcm0pO1xuXG4gICAgICAgIF9Db21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcy5jb250ZXh0KTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHsgdmFsdWU6ICcnIH07XG4gICAgfVxuXG4gICAgU2VhcmNoRm9ybS5wcm90b3R5cGUuc2VhcmNoID0gZnVuY3Rpb24gc2VhcmNoKCkge1xuICAgICAgICB0aGlzLnByb3BzLm9uU2VhcmNoKHRoaXMuc3RhdGUudmFsdWUpO1xuICAgIH07XG5cbiAgICBTZWFyY2hGb3JtLnByb3RvdHlwZS5vbkNoYW5nZSA9IGZ1bmN0aW9uIG9uQ2hhbmdlKGV2ZW50LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgdmFsdWU6IHZhbHVlIH0pO1xuICAgICAgICBGdW5jVXRpbHMuYnVmZmVyQ2FsbGJhY2soJ3NlYXJjaF91c2Vyc19saXN0JywgMzAwLCB0aGlzLnNlYXJjaC5iaW5kKHRoaXMpKTtcbiAgICB9O1xuXG4gICAgU2VhcmNoRm9ybS5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiBfZXh0ZW5kcyh7IG1pbldpZHRoOiAzMjAgfSwgdGhpcy5wcm9wcy5zdHlsZSkgfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWF0ZXJpYWxVSS5UZXh0RmllbGQsIHtcbiAgICAgICAgICAgICAgICBmdWxsV2lkdGg6IHRydWUsXG4gICAgICAgICAgICAgICAgdmFsdWU6IHRoaXMuc3RhdGUudmFsdWUsXG4gICAgICAgICAgICAgICAgb25DaGFuZ2U6IHRoaXMub25DaGFuZ2UuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBoaW50VGV4dDogdGhpcy5wcm9wcy5zZWFyY2hMYWJlbFxuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFNlYXJjaEZvcm07XG59KShDb21wb25lbnQpO1xuXG5TZWFyY2hGb3JtLnByb3BUeXBlcyA9IHtcbiAgICAvKipcbiAgICAgKiBMYWJlbCBkaXNwbGF5ZWQgaW4gdGhlIHNlYXJjaCBmaWVsZFxuICAgICAqL1xuICAgIHNlYXJjaExhYmVsOiBQcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgdHJpZ2dlcmVkIHRvIHNlYXJjaFxuICAgICAqL1xuICAgIG9uU2VhcmNoOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICAgIC8qKlxuICAgICAqIFdpbGwgYmUgYXBwZW5kZWQgdG8gdGhlIHJvb3QgZWxlbWVudFxuICAgICAqL1xuICAgIHN0eWxlOiBQcm9wVHlwZXMub2JqZWN0XG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBTZWFyY2hGb3JtO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9TZWFyY2hGb3JtID0gcmVxdWlyZSgnLi9TZWFyY2hGb3JtJyk7XG5cbnZhciBfU2VhcmNoRm9ybTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TZWFyY2hGb3JtKTtcblxudmFyIF9Vc2Vyc0xpc3QgPSByZXF1aXJlKCcuL1VzZXJzTGlzdCcpO1xuXG52YXIgX1VzZXJzTGlzdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Vc2Vyc0xpc3QpO1xuXG52YXIgX0xvYWRlcnMgPSByZXF1aXJlKCcuL0xvYWRlcnMnKTtcblxudmFyIF9Mb2FkZXJzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0xvYWRlcnMpO1xuXG4vKipcbiAqIFJlYWR5IHRvIHVzZSBGb3JtICsgUmVzdWx0IExpc3QgZm9yIHNlYXJjaCB1c2Vyc1xuICovXG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBDb21wb25lbnQgPSBfcmVxdWlyZS5Db21wb25lbnQ7XG52YXIgUHJvcFR5cGVzID0gX3JlcXVpcmUuUHJvcFR5cGVzO1xuXG52YXIgX3JlcXVpcmUkcmVxdWlyZUxpYiA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgUHlkaW9Db250ZXh0Q29uc3VtZXIgPSBfcmVxdWlyZSRyZXF1aXJlTGliLlB5ZGlvQ29udGV4dENvbnN1bWVyO1xuXG52YXIgU2VhcmNoUGFuZWwgPSAoZnVuY3Rpb24gKF9Db21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoU2VhcmNoUGFuZWwsIF9Db21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gU2VhcmNoUGFuZWwocHJvcHMsIGNvbnRleHQpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFNlYXJjaFBhbmVsKTtcblxuICAgICAgICBfQ29tcG9uZW50LmNhbGwodGhpcywgcHJvcHMuY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IGl0ZW1zOiBbXSB9O1xuICAgIH1cblxuICAgIFNlYXJjaFBhbmVsLnByb3RvdHlwZS5vblNlYXJjaCA9IGZ1bmN0aW9uIG9uU2VhcmNoKHZhbHVlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGl0ZW1zOiBbXSB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcGFyYW1zID0geyB2YWx1ZTogdmFsdWUsIGV4aXN0aW5nX29ubHk6ICd0cnVlJyB9O1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5wYXJhbXMpIHtcbiAgICAgICAgICAgIHBhcmFtcyA9IF9leHRlbmRzKHt9LCBwYXJhbXMsIHRoaXMucHJvcHMucGFyYW1zKTtcbiAgICAgICAgfVxuICAgICAgICBfTG9hZGVyczJbJ2RlZmF1bHQnXS5saXN0VXNlcnMocGFyYW1zLCBmdW5jdGlvbiAoY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgaXRlbXM6IGNoaWxkcmVuIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgU2VhcmNoUGFuZWwucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHM7XG4gICAgICAgIHZhciBtb2RlID0gX3Byb3BzLm1vZGU7XG4gICAgICAgIHZhciBpdGVtID0gX3Byb3BzLml0ZW07XG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gX3Byb3BzLmdldE1lc3NhZ2U7XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgc3R5bGU6IHsgZmxleDogMSwgZGlzcGxheTogJ2ZsZXgnLCBmbGV4RGlyZWN0aW9uOiAnY29sdW1uJyB9IH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgcGFkZGluZzogMTAsIGhlaWdodDogNTYsIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5zZWxlY3QgPyBhY3RpdmVUYmFyQ29sb3IgOiAnI2ZhZmFmYScsIGRpc3BsYXk6ICdmbGV4JywgYWxpZ25JdGVtczogJ2NlbnRlcicsIHRyYW5zaXRpb246IERPTVV0aWxzLmdldEJlemllcnNUcmFuc2l0aW9uKCkgfSB9LFxuICAgICAgICAgICAgICAgIG1vZGUgPT09IFwic2VsZWN0b3JcIiAmJiBpdGVtLl9wYXJlbnQgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChNYXRlcmlhbFVJLkljb25CdXR0b24sIHsgaWNvbkNsYXNzTmFtZTogJ21kaSBtZGktY2hldnJvbi1sZWZ0Jywgb25Ub3VjaFRhcDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMyLnByb3BzLm9uRm9sZGVyQ2xpY2tlZChpdGVtLl9wYXJlbnQpO1xuICAgICAgICAgICAgICAgICAgICB9IH0pLFxuICAgICAgICAgICAgICAgIG1vZGUgPT09ICdib29rJyAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyBmb250U2l6ZTogMjAsIGNvbG9yOiAncmdiYSgwLDAsMCwwLjg3KScsIGZsZXg6IDEgfSB9LFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnRpdGxlXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KF9TZWFyY2hGb3JtMlsnZGVmYXVsdCddLCB7IHN0eWxlOiBtb2RlID09PSAnYm9vaycgPyB7IG1pbldpZHRoOiAzMjAgfSA6IHsgZmxleDogMSB9LCBzZWFyY2hMYWJlbDogdGhpcy5wcm9wcy5zZWFyY2hMYWJlbCwgb25TZWFyY2g6IHRoaXMub25TZWFyY2guYmluZCh0aGlzKSB9KVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX1VzZXJzTGlzdDJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgIG1vZGU6IHRoaXMucHJvcHMubW9kZSxcbiAgICAgICAgICAgICAgICBvbkl0ZW1DbGlja2VkOiB0aGlzLnByb3BzLm9uSXRlbUNsaWNrZWQsXG4gICAgICAgICAgICAgICAgaXRlbTogeyBsZWFmczogdGhpcy5zdGF0ZS5pdGVtcyB9LFxuICAgICAgICAgICAgICAgIG5vVG9vbGJhcjogdHJ1ZSxcbiAgICAgICAgICAgICAgICBlbXB0eVN0YXRlUHJpbWFyeVRleHQ6IGdldE1lc3NhZ2UoNTg3LCAnJyksXG4gICAgICAgICAgICAgICAgZW1wdHlTdGF0ZVNlY29uZGFyeVRleHQ6IGdldE1lc3NhZ2UoNTg4LCAnJylcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBTZWFyY2hQYW5lbDtcbn0pKENvbXBvbmVudCk7XG5cblNlYXJjaFBhbmVsLnByb3BUeXBlcyA9IHtcbiAgICAvKipcbiAgICAgKiBPcHRpb25hbCBwYXJhbWV0ZXJzIGFkZGVkIHRvIGxpc3RVc2VycygpIHJlcXVlc3RcbiAgICAgKi9cbiAgICBwYXJhbXM6IFByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICogTGFiZWwgZGlzcGxheWVkIGluIHRoZSB0b29sYmFyXG4gICAgICovXG4gICAgc2VhcmNoTGFiZWw6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgdHJpZ2dlcmVkIHdoZW4gYSBzZWFyY2ggcmVzdWx0IGlzIGNsaWNrZWRcbiAgICAgKi9cbiAgICBvbkl0ZW1DbGlja2VkOiBQcm9wVHlwZXMuZnVuYyxcbiAgICAvKipcbiAgICAgKiBDdXJyZW50bHkgc2VsZWN0ZWQgaXRlbSwgcmVxdWlyZWQgZm9yIG5hdmlnYXRpb25cbiAgICAgKi9cbiAgICBpdGVtOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIHRyaWdnZXJlZCBpZiB0aGUgcmVzdWx0IGlzIGEgY29sbGVjdGlvblxuICAgICAqL1xuICAgIG9uRm9sZGVyQ2xpY2tlZDogUHJvcFR5cGVzLmZ1bmNcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFNlYXJjaFBhbmVsID0gUHlkaW9Db250ZXh0Q29uc3VtZXIoU2VhcmNoUGFuZWwpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gU2VhcmNoUGFuZWw7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX1VzZXJzTGlzdCA9IHJlcXVpcmUoJy4vVXNlcnNMaXN0Jyk7XG5cbnZhciBfVXNlcnNMaXN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1VzZXJzTGlzdCk7XG5cbnZhciBfTG9hZGVycyA9IHJlcXVpcmUoJy4vTG9hZGVycycpO1xuXG52YXIgX0xvYWRlcnMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTG9hZGVycyk7XG5cbnZhciBfYXZhdGFyQWN0aW9uc1BhbmVsID0gcmVxdWlyZSgnLi4vYXZhdGFyL0FjdGlvbnNQYW5lbCcpO1xuXG52YXIgX2F2YXRhckFjdGlvbnNQYW5lbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hdmF0YXJBY3Rpb25zUGFuZWwpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgVGV4dEZpZWxkID0gX3JlcXVpcmUuVGV4dEZpZWxkO1xudmFyIEZsYXRCdXR0b24gPSBfcmVxdWlyZS5GbGF0QnV0dG9uO1xudmFyIENhcmRUaXRsZSA9IF9yZXF1aXJlLkNhcmRUaXRsZTtcbnZhciBEaXZpZGVyID0gX3JlcXVpcmUuRGl2aWRlcjtcblxudmFyIF9yZXF1aXJlJHJlcXVpcmVMaWIgPSByZXF1aXJlKCdweWRpbycpLnJlcXVpcmVMaWIoJ2Jvb3QnKTtcblxudmFyIFB5ZGlvQ29udGV4dENvbnN1bWVyID0gX3JlcXVpcmUkcmVxdWlyZUxpYi5QeWRpb0NvbnRleHRDb25zdW1lcjtcblxuLyoqXG4gKiBEaXNwbGF5IGluZm8gYWJvdXQgYSBUZWFtIGluc2lkZSBhIHBvcG92ZXItYWJsZSBjYXJkXG4gKi9cblxudmFyIFRlYW1DYXJkID0gKGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7XG4gICAgX2luaGVyaXRzKFRlYW1DYXJkLCBfUmVhY3QkQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIFRlYW1DYXJkKHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBUZWFtQ2FyZCk7XG5cbiAgICAgICAgX1JlYWN0JENvbXBvbmVudC5jYWxsKHRoaXMsIHByb3BzLCBjb250ZXh0KTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHsgbGFiZWw6IHRoaXMucHJvcHMuaXRlbS5sYWJlbCB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVzZSBsb2FkZXIgdG8gZ2V0IHRlYW0gcGFydGljaXBhbnRzXG4gICAgICogQHBhcmFtIGl0ZW1cbiAgICAgKi9cblxuICAgIFRlYW1DYXJkLnByb3RvdHlwZS5sb2FkTWVtYmVycyA9IGZ1bmN0aW9uIGxvYWRNZW1iZXJzKGl0ZW0pIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgbG9hZGluZzogdHJ1ZSB9KTtcbiAgICAgICAgX0xvYWRlcnMyWydkZWZhdWx0J10uY2hpbGRyZW5Bc1Byb21pc2UoaXRlbSwgZmFsc2UpLnRoZW4oZnVuY3Rpb24gKGNoaWxkcmVuKSB7XG4gICAgICAgICAgICBfTG9hZGVyczJbJ2RlZmF1bHQnXS5jaGlsZHJlbkFzUHJvbWlzZShpdGVtLCB0cnVlKS50aGVuKGZ1bmN0aW9uIChjaGlsZHJlbikge1xuICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgbWVtYmVyczogaXRlbS5sZWFmcywgbG9hZGluZzogZmFsc2UgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIFRlYW1DYXJkLnByb3RvdHlwZS5jb21wb25lbnRXaWxsTW91bnQgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsTW91bnQoKSB7XG4gICAgICAgIHRoaXMubG9hZE1lbWJlcnModGhpcy5wcm9wcy5pdGVtKTtcbiAgICB9O1xuXG4gICAgVGVhbUNhcmQucHJvdG90eXBlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykge1xuICAgICAgICB0aGlzLmxvYWRNZW1iZXJzKG5leHRQcm9wcy5pdGVtKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGxhYmVsOiBuZXh0UHJvcHMuaXRlbS5sYWJlbCB9KTtcbiAgICB9O1xuXG4gICAgVGVhbUNhcmQucHJvdG90eXBlLm9uTGFiZWxDaGFuZ2UgPSBmdW5jdGlvbiBvbkxhYmVsQ2hhbmdlKGUsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBsYWJlbDogdmFsdWUgfSk7XG4gICAgfTtcblxuICAgIFRlYW1DYXJkLnByb3RvdHlwZS51cGRhdGVMYWJlbCA9IGZ1bmN0aW9uIHVwZGF0ZUxhYmVsKCkge1xuICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5sYWJlbCAhPT0gdGhpcy5wcm9wcy5pdGVtLmxhYmVsKSB7XG4gICAgICAgICAgICBQeWRpb1VzZXJzLkNsaWVudC51cGRhdGVUZWFtTGFiZWwodGhpcy5wcm9wcy5pdGVtLmlkLnJlcGxhY2UoJy9BSlhQX1RFQU0vJywgJycpLCB0aGlzLnN0YXRlLmxhYmVsLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMyLnByb3BzLm9uVXBkYXRlQWN0aW9uKF90aGlzMi5wcm9wcy5pdGVtKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlZGl0TW9kZTogZmFsc2UgfSk7XG4gICAgfTtcblxuICAgIFRlYW1DYXJkLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgaXRlbSA9IF9wcm9wcy5pdGVtO1xuICAgICAgICB2YXIgb25EZWxldGVBY3Rpb24gPSBfcHJvcHMub25EZWxldGVBY3Rpb247XG4gICAgICAgIHZhciBvbkNyZWF0ZUFjdGlvbiA9IF9wcm9wcy5vbkNyZWF0ZUFjdGlvbjtcbiAgICAgICAgdmFyIGdldE1lc3NhZ2UgPSBfcHJvcHMuZ2V0TWVzc2FnZTtcblxuICAgICAgICB2YXIgZWRpdFByb3BzID0ge1xuICAgICAgICAgICAgdGVhbTogaXRlbSxcbiAgICAgICAgICAgIHVzZXJFZGl0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIG9uRGVsZXRlQWN0aW9uOiBmdW5jdGlvbiBvbkRlbGV0ZUFjdGlvbigpIHtcbiAgICAgICAgICAgICAgICBfdGhpczMucHJvcHMub25EZWxldGVBY3Rpb24oaXRlbS5fcGFyZW50LCBbaXRlbV0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9uRWRpdEFjdGlvbjogZnVuY3Rpb24gb25FZGl0QWN0aW9uKCkge1xuICAgICAgICAgICAgICAgIF90aGlzMy5zZXRTdGF0ZSh7IGVkaXRNb2RlOiAhX3RoaXMzLnN0YXRlLmVkaXRNb2RlIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbG9hZEFjdGlvbjogZnVuY3Rpb24gcmVsb2FkQWN0aW9uKCkge1xuICAgICAgICAgICAgICAgIF90aGlzMy5wcm9wcy5vblVwZGF0ZUFjdGlvbihpdGVtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgdGl0bGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRNb2RlKSB7XG4gICAgICAgICAgICB0aXRsZSA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBkaXNwbGF5OiAnZmxleCcsIGFsaWduSXRlbXM6ICdjZW50ZXInLCBtYXJnaW46IDE2IH0gfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFRleHRGaWVsZCwgeyBzdHlsZTogeyBmbGV4OiAxLCBmb250U2l6ZTogMjQgfSwgZnVsbFdpZHRoOiB0cnVlLCBkaXNhYmxlZDogZmFsc2UsIHVuZGVybGluZVNob3c6IGZhbHNlLCB2YWx1ZTogdGhpcy5zdGF0ZS5sYWJlbCwgb25DaGFuZ2U6IHRoaXMub25MYWJlbENoYW5nZS5iaW5kKHRoaXMpIH0pLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmxhdEJ1dHRvbiwgeyBzZWNvbmRhcnk6IHRydWUsIGxhYmVsOiBnZXRNZXNzYWdlKDQ4KSwgb25Ub3VjaFRhcDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMzLnVwZGF0ZUxhYmVsKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aXRsZSA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoQ2FyZFRpdGxlLCB7IHRpdGxlOiB0aGlzLnN0YXRlLmxhYmVsLCBzdWJ0aXRsZTogaXRlbS5sZWFmcyAmJiBpdGVtLmxlYWZzLmxlbmd0aCA/IGdldE1lc3NhZ2UoNTc2KS5yZXBsYWNlKCclcycsIGl0ZW0ubGVhZnMubGVuZ3RoKSA6IGdldE1lc3NhZ2UoNTc3KSB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChfYXZhdGFyQWN0aW9uc1BhbmVsMlsnZGVmYXVsdCddLCBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcywgZWRpdFByb3BzKSksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KERpdmlkZXIsIG51bGwpLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChfVXNlcnNMaXN0MlsnZGVmYXVsdCddLCB7IHN1YkhlYWRlcjogZ2V0TWVzc2FnZSg1NzUpLCBvbkl0ZW1DbGlja2VkOiBmdW5jdGlvbiAoKSB7fSwgaXRlbTogaXRlbSwgbW9kZTogJ2lubmVyJywgb25EZWxldGVBY3Rpb246IG9uRGVsZXRlQWN0aW9uIH0pXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBUZWFtQ2FyZDtcbn0pKFJlYWN0LkNvbXBvbmVudCk7XG5cblRlYW1DYXJkLnByb3BUeXBlcyA9IHtcbiAgICAvKipcbiAgICAgKiBQeWRpbyBpbnN0YW5jZVxuICAgICAqL1xuICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbyksXG4gICAgLyoqXG4gICAgICogVGVhbSBkYXRhIG9iamVjdFxuICAgICAqL1xuICAgIGl0ZW06IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICogQXBwbGllZCB0byByb290IGNvbnRhaW5lclxuICAgICAqL1xuICAgIHN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgIC8qKlxuICAgICAqIENhbGxlZCB0byBkaXNtaXNzIHRoZSBwb3BvdmVyXG4gICAgICovXG4gICAgb25SZXF1ZXN0Q2xvc2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgIC8qKlxuICAgICAqIERlbGV0ZSBjdXJyZW50IHRlYW1cbiAgICAgKi9cbiAgICBvbkRlbGV0ZUFjdGlvbjogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgLyoqXG4gICAgICogVXBkYXRlIGN1cnJlbnQgdGVhbVxuICAgICAqL1xuICAgIG9uVXBkYXRlQWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuY1xufTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gVGVhbUNhcmQgPSBQeWRpb0NvbnRleHRDb25zdW1lcihUZWFtQ2FyZCk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFRlYW1DYXJkO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9hdmF0YXJVc2VyQXZhdGFyID0gcmVxdWlyZSgnLi4vYXZhdGFyL1VzZXJBdmF0YXInKTtcblxudmFyIF9hdmF0YXJVc2VyQXZhdGFyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2F2YXRhclVzZXJBdmF0YXIpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlcXVpcmUkcmVxdWlyZUxpYiA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgQXN5bmNDb21wb25lbnQgPSBfcmVxdWlyZSRyZXF1aXJlTGliLkFzeW5jQ29tcG9uZW50O1xuXG4vKipcbiAqIENhcmQgcHJlc2VudGF0aW9uIG9mIGEgdXNlci4gUmVsaWVzIG9uIHRoZSBVc2VyQXZhdGFyIG9iamVjdCxcbiAqIHBsdXMgdGhlIFB5ZGlvRm9ybS5Vc2VyQ3JlYXRpb25Gb3JtIHdoZW4gaW4gZWRpdCBtb2RlLlxuICovXG5cbnZhciBVc2VyQ2FyZCA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhVc2VyQ2FyZCwgX1JlYWN0JENvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBVc2VyQ2FyZChwcm9wcywgY29udGV4dCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVXNlckNhcmQpO1xuXG4gICAgICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IGVkaXRGb3JtOiBmYWxzZSB9O1xuICAgIH1cblxuICAgIFVzZXJDYXJkLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIGl0ZW0gPSB0aGlzLnByb3BzLml0ZW07XG5cbiAgICAgICAgdmFyIGVkaXRhYmxlUHJvcHMgPSB7fSxcbiAgICAgICAgICAgIGVkaXRGb3JtID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoaXRlbS5fcGFyZW50ICYmIGl0ZW0uX3BhcmVudC5pZCA9PT0gJ2V4dCcpIHtcbiAgICAgICAgICAgIGVkaXRhYmxlUHJvcHMgPSB7XG4gICAgICAgICAgICAgICAgdXNlckVkaXRhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIG9uRGVsZXRlQWN0aW9uOiBmdW5jdGlvbiBvbkRlbGV0ZUFjdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMucHJvcHMub25EZWxldGVBY3Rpb24oaXRlbS5fcGFyZW50LCBbaXRlbV0pO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgb25FZGl0QWN0aW9uOiBmdW5jdGlvbiBvbkVkaXRBY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgZWRpdEZvcm06IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWxvYWRBY3Rpb246IGZ1bmN0aW9uIHJlbG9hZEFjdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMucHJvcHMub25VcGRhdGVBY3Rpb24oaXRlbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRGb3JtKSB7XG4gICAgICAgICAgICBlZGl0Rm9ybSA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoQXN5bmNDb21wb25lbnQsIHtcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2U6ICdQeWRpb0Zvcm0nLFxuICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICdVc2VyQ3JlYXRpb25Gb3JtJyxcbiAgICAgICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpbyxcbiAgICAgICAgICAgICAgICB6RGVwdGg6IDAsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHsgaGVpZ2h0OiA1MDAgfSxcbiAgICAgICAgICAgICAgICBuZXdVc2VyTmFtZTogaXRlbS5pZCxcbiAgICAgICAgICAgICAgICBlZGl0TW9kZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB1c2VyRGF0YTogaXRlbSxcbiAgICAgICAgICAgICAgICBvblVzZXJDcmVhdGVkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnByb3BzLm9uVXBkYXRlQWN0aW9uKGl0ZW0pO190aGlzLnNldFN0YXRlKHsgZWRpdEZvcm06IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgb25DYW5jZWw6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBlZGl0Rm9ybTogZmFsc2UgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgX2F2YXRhclVzZXJBdmF0YXIyWydkZWZhdWx0J10sXG4gICAgICAgICAgICAgICAgX2V4dGVuZHMoe1xuICAgICAgICAgICAgICAgICAgICB1c2VySWQ6IHRoaXMucHJvcHMuaXRlbS5pZCxcbiAgICAgICAgICAgICAgICAgICAgcmljaENhcmQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHB5ZGlvOiB0aGlzLnByb3BzLnB5ZGlvLFxuICAgICAgICAgICAgICAgICAgICBjYXJkU2l6ZTogdGhpcy5wcm9wcy5zdHlsZS53aWR0aFxuICAgICAgICAgICAgICAgIH0sIGVkaXRhYmxlUHJvcHMpLFxuICAgICAgICAgICAgICAgIGVkaXRGb3JtXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBVc2VyQ2FyZDtcbn0pKFJlYWN0LkNvbXBvbmVudCk7XG5cblVzZXJDYXJkLnByb3BUeXBlcyA9IHtcbiAgICAvKipcbiAgICAgKiBQeWRpbyBpbnN0YW5jZVxuICAgICAqL1xuICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbyksXG4gICAgLyoqXG4gICAgICogVGVhbSBkYXRhIG9iamVjdFxuICAgICAqL1xuICAgIGl0ZW06IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICogQXBwbGllZCB0byByb290IGNvbnRhaW5lclxuICAgICAqL1xuICAgIHN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgIC8qKlxuICAgICAqIENhbGxlZCB0byBkaXNtaXNzIHRoZSBwb3BvdmVyXG4gICAgICovXG4gICAgb25SZXF1ZXN0Q2xvc2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgIC8qKlxuICAgICAqIERlbGV0ZSBjdXJyZW50IHRlYW1cbiAgICAgKi9cbiAgICBvbkRlbGV0ZUFjdGlvbjogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgLyoqXG4gICAgICogVXBkYXRlIGN1cnJlbnQgdGVhbVxuICAgICAqL1xuICAgIG9uVXBkYXRlQWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuY1xufTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gVXNlckNhcmQ7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX2F2YXRhclVzZXJBdmF0YXIgPSByZXF1aXJlKCcuLi9hdmF0YXIvVXNlckF2YXRhcicpO1xuXG52YXIgX2F2YXRhclVzZXJBdmF0YXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXZhdGFyVXNlckF2YXRhcik7XG5cbnZhciBfdmlld3NFbXB0eVN0YXRlVmlldyA9IHJlcXVpcmUoJy4uLy4uL3ZpZXdzL0VtcHR5U3RhdGVWaWV3Jyk7XG5cbnZhciBfdmlld3NFbXB0eVN0YXRlVmlldzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF92aWV3c0VtcHR5U3RhdGVWaWV3KTtcblxudmFyIF9BbHBoYVBhZ2luYXRvciA9IHJlcXVpcmUoJy4vQWxwaGFQYWdpbmF0b3InKTtcblxudmFyIF9BbHBoYVBhZ2luYXRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9BbHBoYVBhZ2luYXRvcik7XG5cbnZhciBfU2VhcmNoRm9ybSA9IHJlcXVpcmUoJy4vU2VhcmNoRm9ybScpO1xuXG52YXIgX1NlYXJjaEZvcm0yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2VhcmNoRm9ybSk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBJY29uQnV0dG9uID0gX3JlcXVpcmUuSWNvbkJ1dHRvbjtcbnZhciBDaGVja2JveCA9IF9yZXF1aXJlLkNoZWNrYm94O1xudmFyIEZsYXRCdXR0b24gPSBfcmVxdWlyZS5GbGF0QnV0dG9uO1xudmFyIFJhaXNlZEJ1dHRvbiA9IF9yZXF1aXJlLlJhaXNlZEJ1dHRvbjtcbnZhciBMaXN0SXRlbSA9IF9yZXF1aXJlLkxpc3RJdGVtO1xudmFyIEZvbnRJY29uID0gX3JlcXVpcmUuRm9udEljb247XG52YXIgQXZhdGFyID0gX3JlcXVpcmUuQXZhdGFyO1xudmFyIERpdmlkZXIgPSBfcmVxdWlyZS5EaXZpZGVyO1xudmFyIFN1YmhlYWRlciA9IF9yZXF1aXJlLlN1YmhlYWRlcjtcbnZhciBMaXN0ID0gX3JlcXVpcmUuTGlzdDtcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpL3N0eWxlcycpO1xuXG52YXIgbXVpVGhlbWVhYmxlID0gX3JlcXVpcmUyLm11aVRoZW1lYWJsZTtcblxudmFyIF9yZXF1aXJlJHJlcXVpcmVMaWIgPSByZXF1aXJlKCdweWRpbycpLnJlcXVpcmVMaWIoJ2Jvb3QnKTtcblxudmFyIExvYWRlciA9IF9yZXF1aXJlJHJlcXVpcmVMaWIuTG9hZGVyO1xudmFyIFB5ZGlvQ29udGV4dENvbnN1bWVyID0gX3JlcXVpcmUkcmVxdWlyZUxpYi5QeWRpb0NvbnRleHRDb25zdW1lcjtcblxudmFyIFVzZXJzTGlzdCA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhVc2Vyc0xpc3QsIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gVXNlcnNMaXN0KHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBVc2Vyc0xpc3QpO1xuXG4gICAgICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IHNlbGVjdDogZmFsc2UsIHNlbGVjdGlvbjogW10gfTtcbiAgICB9XG5cbiAgICBVc2Vyc0xpc3QucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcztcbiAgICAgICAgdmFyIGl0ZW0gPSBfcHJvcHMuaXRlbTtcbiAgICAgICAgdmFyIG1vZGUgPSBfcHJvcHMubW9kZTtcbiAgICAgICAgdmFyIHBhZ2luYXRvclR5cGUgPSBfcHJvcHMucGFnaW5hdG9yVHlwZTtcbiAgICAgICAgdmFyIGxvYWRpbmcgPSBfcHJvcHMubG9hZGluZztcbiAgICAgICAgdmFyIGVuYWJsZVNlYXJjaCA9IF9wcm9wcy5lbmFibGVTZWFyY2g7XG4gICAgICAgIHZhciBzaG93U3ViaGVhZGVycyA9IF9wcm9wcy5zaG93U3ViaGVhZGVycztcbiAgICAgICAgdmFyIGdldE1lc3NhZ2UgPSBfcHJvcHMuZ2V0TWVzc2FnZTtcblxuICAgICAgICB2YXIgZm9sZGVycyA9IGl0ZW0uY29sbGVjdGlvbnMgfHwgW107XG4gICAgICAgIHZhciBsZWFmcyA9IGl0ZW0ubGVhZnMgfHwgW107XG4gICAgICAgIHZhciBmb2xkZXJzU3ViSGVhZGVyID0gZm9sZGVycy5sZW5ndGggJiYgKGxlYWZzLmxlbmd0aCB8fCBzaG93U3ViaGVhZGVycykgPyBbeyBzdWJoZWFkZXI6IGdldE1lc3NhZ2UoJzUzMicpIH1dIDogW107XG4gICAgICAgIHZhciB1c2Vyc1N1YkhlYWRlciA9IFtdO1xuICAgICAgICBpZiAoKHNob3dTdWJoZWFkZXJzIHx8IHBhZ2luYXRvclR5cGUpICYmIGxlYWZzLmxlbmd0aCkge1xuICAgICAgICAgICAgdXNlcnNTdWJIZWFkZXIgPSBbeyBzdWJoZWFkZXI6IHBhZ2luYXRvclR5cGUgPyBSZWFjdC5jcmVhdGVFbGVtZW50KF9BbHBoYVBhZ2luYXRvcjJbJ2RlZmF1bHQnXSwgX2V4dGVuZHMoe30sIHRoaXMucHJvcHMsIHsgc3R5bGU6IHsgbGluZUhlaWdodDogJzIwcHgnLCBwYWRkaW5nOiAnMTRweCAwJyB9IH0pKSA6IGdldE1lc3NhZ2UoJzI0OScpIH1dO1xuICAgICAgICB9XG4gICAgICAgIHZhciBpdGVtcyA9IFtdLmNvbmNhdChmb2xkZXJzU3ViSGVhZGVyLCBmb2xkZXJzLCB1c2Vyc1N1YkhlYWRlciwgbGVhZnMpO1xuICAgICAgICB2YXIgdG90YWwgPSBpdGVtcy5sZW5ndGg7XG4gICAgICAgIHZhciBlbGVtZW50cyA9IFtdO1xuICAgICAgICB2YXIgdG9nZ2xlU2VsZWN0ID0gZnVuY3Rpb24gdG9nZ2xlU2VsZWN0KCkge1xuICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBzZWxlY3Q6ICFfdGhpcy5zdGF0ZS5zZWxlY3QsIHNlbGVjdGlvbjogW10gfSk7XG4gICAgICAgIH07XG4gICAgICAgIHZhciBjcmVhdGVBY3Rpb24gPSBmdW5jdGlvbiBjcmVhdGVBY3Rpb24oKSB7XG4gICAgICAgICAgICBfdGhpcy5wcm9wcy5vbkNyZWF0ZUFjdGlvbihpdGVtKTtcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIGRlbGV0ZUFjdGlvbiA9IGZ1bmN0aW9uIGRlbGV0ZUFjdGlvbigpIHtcbiAgICAgICAgICAgIF90aGlzLnByb3BzLm9uRGVsZXRlQWN0aW9uKGl0ZW0sIF90aGlzLnN0YXRlLnNlbGVjdGlvbik7X3RoaXMuc2V0U3RhdGUoeyBzZWxlY3Q6IGZhbHNlLCBzZWxlY3Rpb246IFtdIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIHZhciBhY3RpdmVUYmFyQ29sb3IgPSB0aGlzLnByb3BzLm11aVRoZW1lLnBhbGV0dGUuYWNjZW50MkNvbG9yO1xuICAgICAgICB2YXIgdG9vbGJhciA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgc3R5bGU6IHsgcGFkZGluZzogMTAsIGhlaWdodDogNTYsIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5zZWxlY3QgPyBhY3RpdmVUYmFyQ29sb3IgOiAnI2ZhZmFmYScsIGRpc3BsYXk6ICdmbGV4JywgYWxpZ25JdGVtczogJ2NlbnRlcicsIHRyYW5zaXRpb246IERPTVV0aWxzLmdldEJlemllcnNUcmFuc2l0aW9uKCkgfSB9LFxuICAgICAgICAgICAgbW9kZSA9PT0gXCJzZWxlY3RvclwiICYmIGl0ZW0uX3BhcmVudCAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KEljb25CdXR0b24sIHsgaWNvbkNsYXNzTmFtZTogJ21kaSBtZGktY2hldnJvbi1sZWZ0Jywgb25Ub3VjaFRhcDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5wcm9wcy5vbkZvbGRlckNsaWNrZWQoaXRlbS5fcGFyZW50KTtcbiAgICAgICAgICAgICAgICB9IH0pLFxuICAgICAgICAgICAgbW9kZSA9PT0gJ2Jvb2snICYmIHRvdGFsID4gMCAmJiBpdGVtLmFjdGlvbnMgJiYgaXRlbS5hY3Rpb25zLm11bHRpcGxlICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoQ2hlY2tib3gsIHsgc3R5bGU6IHsgd2lkdGg6ICdpbml0aWFsJywgbWFyZ2luTGVmdDogdGhpcy5zdGF0ZS5zZWxlY3QgPyA3IDogMTQgfSwgY2hlY2tlZDogdGhpcy5zdGF0ZS5zZWxlY3QsIG9uQ2hlY2s6IHRvZ2dsZVNlbGVjdCB9KSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBmbGV4OiAxLCBmb250U2l6ZTogMjAsIGNvbG9yOiB0aGlzLnN0YXRlLnNlbGVjdCA/ICd3aGl0ZScgOiAncmdiYSgwLDAsMCwwLjg3KScgfSB9LFxuICAgICAgICAgICAgICAgIGl0ZW0ubGFiZWxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBtb2RlID09PSAnYm9vaycgJiYgaXRlbS5hY3Rpb25zICYmIGl0ZW0uYWN0aW9ucy5jcmVhdGUgJiYgIXRoaXMuc3RhdGUuc2VsZWN0ICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmxhdEJ1dHRvbiwgeyBzZWNvbmRhcnk6IHRydWUsIGxhYmVsOiBnZXRNZXNzYWdlKGl0ZW0uYWN0aW9ucy5jcmVhdGUpLCBvblRvdWNoVGFwOiBjcmVhdGVBY3Rpb24gfSksXG4gICAgICAgICAgICBtb2RlID09PSAnYm9vaycgJiYgaXRlbS5hY3Rpb25zICYmIGl0ZW0uYWN0aW9ucy5yZW1vdmUgJiYgdGhpcy5zdGF0ZS5zZWxlY3QgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChSYWlzZWRCdXR0b24sIHsgc2Vjb25kYXJ5OiB0cnVlLCBsYWJlbDogZ2V0TWVzc2FnZShpdGVtLmFjdGlvbnMucmVtb3ZlKSwgZGlzYWJsZWQ6ICF0aGlzLnN0YXRlLnNlbGVjdGlvbi5sZW5ndGgsIG9uVG91Y2hUYXA6IGRlbGV0ZUFjdGlvbiB9KSxcbiAgICAgICAgICAgIGVuYWJsZVNlYXJjaCAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KF9TZWFyY2hGb3JtMlsnZGVmYXVsdCddLCB7IHNlYXJjaExhYmVsOiB0aGlzLnByb3BzLnNlYXJjaExhYmVsLCBvblNlYXJjaDogdGhpcy5wcm9wcy5vblNlYXJjaCwgc3R5bGU6IHsgZmxleDogMSwgbWluV2lkdGg6IDIwMCB9IH0pXG4gICAgICAgICk7XG4gICAgICAgIC8vIFBBUkVOVCBOT0RFXG4gICAgICAgIGlmIChpdGVtLl9wYXJlbnQgJiYgbW9kZSA9PT0gJ2Jvb2snICYmIGl0ZW0uX3BhcmVudC5fcGFyZW50KSB7XG4gICAgICAgICAgICBlbGVtZW50cy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoTGlzdEl0ZW0sIHtcbiAgICAgICAgICAgICAgICBrZXk6ICdfX3BhcmVudF9fJyxcbiAgICAgICAgICAgICAgICBwcmltYXJ5VGV4dDogXCIuLlwiLFxuICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7X3RoaXMucHJvcHMub25Gb2xkZXJDbGlja2VkKGl0ZW0uX3BhcmVudCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsZWZ0QXZhdGFyOiBSZWFjdC5jcmVhdGVFbGVtZW50KEF2YXRhciwgeyBpY29uOiBSZWFjdC5jcmVhdGVFbGVtZW50KEZvbnRJY29uLCB7IGNsYXNzTmFtZTogJ21kaSBtZGktYXJyb3ctdXAnIH0pIH0pXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBpZiAodG90YWwpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoRGl2aWRlciwgeyBpbnNldDogdHJ1ZSwga2V5OiAncGFyZW50LWRpdmlkZXInIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBJVEVNU1xuICAgICAgICBpdGVtcy5mb3JFYWNoKChmdW5jdGlvbiAoaXRlbSwgaW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgICAgICBpZiAoaXRlbS5zdWJoZWFkZXIpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgIFN1YmhlYWRlcixcbiAgICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgaXRlbS5zdWJoZWFkZXJcbiAgICAgICAgICAgICAgICApKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZm9udEljb24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9hdmF0YXJVc2VyQXZhdGFyMlsnZGVmYXVsdCddLCB7IGF2YXRhclNpemU6IDM2LCBweWRpbzogdGhpcy5wcm9wcy5weWRpbyB8fCBweWRpbyxcbiAgICAgICAgICAgICAgICB1c2VySWQ6IGl0ZW0uaWQsXG4gICAgICAgICAgICAgICAgdXNlckxhYmVsOiBpdGVtLmxhYmVsLFxuICAgICAgICAgICAgICAgIGF2YXRhcjogaXRlbS5hdmF0YXIsXG4gICAgICAgICAgICAgICAgaWNvbjogaXRlbS5pY29uLFxuICAgICAgICAgICAgICAgIGF2YXRhck9ubHk6IHRydWUsXG4gICAgICAgICAgICAgICAgdXNlRGVmYXVsdEF2YXRhcjogdHJ1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgcmlnaHRJY29uQnV0dG9uID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdmFyIHRvdWNoVGFwID0gZnVuY3Rpb24gdG91Y2hUYXAoZSkge1xuICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7X3RoaXMyLnByb3BzLm9uSXRlbUNsaWNrZWQoaXRlbSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGZvbGRlcnMuaW5kZXhPZihpdGVtKSA+IC0xICYmIHRoaXMucHJvcHMub25Gb2xkZXJDbGlja2VkKSB7XG4gICAgICAgICAgICAgICAgdG91Y2hUYXAgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO190aGlzMi5wcm9wcy5vbkZvbGRlckNsaWNrZWQoaXRlbSk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAobW9kZSA9PT0gJ3NlbGVjdG9yJyAmJiAhaXRlbS5fbm90U2VsZWN0YWJsZSkge1xuICAgICAgICAgICAgICAgICAgICByaWdodEljb25CdXR0b24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KEljb25CdXR0b24sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU6IFwibWRpIG1kaS1hY2NvdW50LW11bHRpcGxlLXBsdXNcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXA6IFwiU2VsZWN0IHRoaXMgZ3JvdXBcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbjogJ2JvdHRvbS1sZWZ0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpczIucHJvcHMub25JdGVtQ2xpY2tlZChpdGVtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChtb2RlID09PSAnaW5uZXInICYmIHRoaXMucHJvcHMub25EZWxldGVBY3Rpb24pIHtcbiAgICAgICAgICAgICAgICByaWdodEljb25CdXR0b24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KEljb25CdXR0b24sIHtcbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogXCJtZGkgbWRpLWRlbGV0ZVwiLFxuICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiBnZXRNZXNzYWdlKDI1NyksXG4gICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbjogJ2JvdHRvbS1sZWZ0JyxcbiAgICAgICAgICAgICAgICAgICAgaWNvblN0eWxlOiB7IGNvbG9yOiAncmdiYSgwLDAsMCwwLjEzKScsIGhvdmVyQ29sb3I6ICdyZ2JhKDAsMCwwLDAuNTMpJyB9LFxuICAgICAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpczIucHJvcHMub25EZWxldGVBY3Rpb24oX3RoaXMyLnByb3BzLml0ZW0sIFtpdGVtXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBzZWxlY3QgPSBmdW5jdGlvbiBzZWxlY3QoZSwgY2hlY2tlZCkge1xuICAgICAgICAgICAgICAgIGlmIChjaGVja2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzMi5zZXRTdGF0ZSh7IHNlbGVjdGlvbjogW10uY29uY2F0KF90aGlzMi5zdGF0ZS5zZWxlY3Rpb24sIFtpdGVtXSkgfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0YXRlU2VsID0gX3RoaXMyLnN0YXRlLnNlbGVjdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdGlvbiA9IFtdLmNvbmNhdChzdGF0ZVNlbC5zbGljZSgwLCBzdGF0ZVNlbC5pbmRleE9mKGl0ZW0pKSwgc3RhdGVTZWwuc2xpY2Uoc3RhdGVTZWwuaW5kZXhPZihpdGVtKSArIDEpKTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMyLnNldFN0YXRlKHsgc2VsZWN0aW9uOiBzZWxlY3Rpb24gfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGVsZW1lbnRzLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChMaXN0SXRlbSwge1xuICAgICAgICAgICAgICAgIGtleTogaXRlbS5pZCxcbiAgICAgICAgICAgICAgICBwcmltYXJ5VGV4dDogaXRlbS5sYWJlbCxcbiAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiB0b3VjaFRhcCxcbiAgICAgICAgICAgICAgICBkaXNhYmxlZDogbW9kZSA9PT0gJ2lubmVyJyxcbiAgICAgICAgICAgICAgICBsZWZ0QXZhdGFyOiAhdGhpcy5zdGF0ZS5zZWxlY3QgJiYgZm9udEljb24sXG4gICAgICAgICAgICAgICAgcmlnaHRJY29uQnV0dG9uOiByaWdodEljb25CdXR0b24sXG4gICAgICAgICAgICAgICAgbGVmdENoZWNrYm94OiB0aGlzLnN0YXRlLnNlbGVjdCAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KENoZWNrYm94LCB7IGNoZWNrZWQ6IHRoaXMuc3RhdGUuc2VsZWN0aW9uLmluZGV4T2YoaXRlbSkgPiAtMSwgb25DaGVjazogc2VsZWN0IH0pXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBpZiAobW9kZSAhPT0gJ2lubmVyJyAmJiBpbmRleCA8IHRvdGFsIC0gMSkge1xuICAgICAgICAgICAgICAgIGVsZW1lbnRzLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChEaXZpZGVyLCB7IGluc2V0OiB0cnVlLCBrZXk6IGl0ZW0uaWQgKyAnLWRpdmlkZXInIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgdmFyIGVtcHR5U3RhdGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICghZWxlbWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICB2YXIgZW1wdHlTdGF0ZVByb3BzID0ge1xuICAgICAgICAgICAgICAgIHN0eWxlOiB7IGJhY2tncm91bmRDb2xvcjogJ3JnYigyNTAsIDI1MCwgMjUwKScgfSxcbiAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lOiAnbWRpIG1kaS1hY2NvdW50LW9mZicsXG4gICAgICAgICAgICAgICAgcHJpbWFyeVRleHRJZDogdGhpcy5wcm9wcy5lbXB0eVN0YXRlUHJpbWFyeVRleHQgfHwgZ2V0TWVzc2FnZSg2MjkpLFxuICAgICAgICAgICAgICAgIHNlY29uZGFyeVRleHRJZDogbW9kZSA9PT0gJ2Jvb2snID8gdGhpcy5wcm9wcy5lbXB0eVN0YXRlU2Vjb25kYXJ5VGV4dCB8fCBudWxsIDogbnVsbFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChtb2RlID09PSAnYm9vaycgJiYgaXRlbS5hY3Rpb25zICYmIGl0ZW0uYWN0aW9ucy5jcmVhdGUpIHtcbiAgICAgICAgICAgICAgICBlbXB0eVN0YXRlUHJvcHMgPSBfZXh0ZW5kcyh7fSwgZW1wdHlTdGF0ZVByb3BzLCB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbkxhYmVsSWQ6IGdldE1lc3NhZ2UoaXRlbS5hY3Rpb25zLmNyZWF0ZSksXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbkNhbGxiYWNrOiBjcmVhdGVBY3Rpb25cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVtcHR5U3RhdGUgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF92aWV3c0VtcHR5U3RhdGVWaWV3MlsnZGVmYXVsdCddLCBlbXB0eVN0YXRlUHJvcHMpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgc3R5bGU6IHsgZmxleDogMSwgZmxleERpcmVjdGlvbjogJ2NvbHVtbicsIGRpc3BsYXk6ICdmbGV4JyB9LCBvblRvdWNoVGFwOiB0aGlzLnByb3BzLm9uVG91Y2hUYXAgfSxcbiAgICAgICAgICAgIG1vZGUgIT09ICdpbm5lcicgJiYgLyooIWVtcHR5U3RhdGUgfHwgbW9kZSAhPT0gJ2Jvb2snKSAmJiovIXRoaXMucHJvcHMubm9Ub29sYmFyICYmIHRvb2xiYXIsXG4gICAgICAgICAgICAhZW1wdHlTdGF0ZSAmJiAhbG9hZGluZyAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIExpc3QsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBmbGV4OiAxLCBvdmVyZmxvd1k6IG1vZGUgIT09ICdpbm5lcicgPyAnYXV0bycgOiAnaW5pdGlhbCcgfSB9LFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuc3ViSGVhZGVyICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgIFN1YmhlYWRlcixcbiAgICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5zdWJIZWFkZXJcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIGVsZW1lbnRzXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgbG9hZGluZyAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KExvYWRlciwgeyBzdHlsZTogeyBmbGV4OiAxIH0gfSksXG4gICAgICAgICAgICAhbG9hZGluZyAmJiBlbXB0eVN0YXRlXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBVc2Vyc0xpc3Q7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5Vc2Vyc0xpc3QucHJvcFR5cGVzID0ge1xuICAgIGl0ZW06IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgb25DcmVhdGVBY3Rpb246IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgIG9uRGVsZXRlQWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICBvbkl0ZW1DbGlja2VkOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICBvbkZvbGRlckNsaWNrZWQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgIG1vZGU6IFJlYWN0LlByb3BUeXBlcy5vbmVPZihbJ2Jvb2snLCAnc2VsZWN0b3InLCAnaW5uZXInXSlcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFVzZXJzTGlzdCA9IFB5ZGlvQ29udGV4dENvbnN1bWVyKFVzZXJzTGlzdCk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBVc2Vyc0xpc3QgPSBtdWlUaGVtZWFibGUoKShVc2Vyc0xpc3QpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBVc2Vyc0xpc3Q7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX2FkZHJlc3Nib29rQWRkcmVzc0Jvb2sgPSByZXF1aXJlKCcuLi9hZGRyZXNzYm9vay9BZGRyZXNzQm9vaycpO1xuXG52YXIgX2FkZHJlc3Nib29rQWRkcmVzc0Jvb2syID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYWRkcmVzc2Jvb2tBZGRyZXNzQm9vayk7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ3B5ZGlvL2h0dHAvdXNlcnMtYXBpJyk7XG5cbnZhciBVc2Vyc0FwaSA9IF9yZXF1aXJlLlVzZXJzQXBpO1xuXG52YXIgUmVzb3VyY2VzTWFuYWdlciA9IHJlcXVpcmUoJ3B5ZGlvL2h0dHAvcmVzb3VyY2VzLW1hbmFnZXInKTtcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBJY29uQnV0dG9uID0gX3JlcXVpcmUyLkljb25CdXR0b247XG52YXIgUG9wb3ZlciA9IF9yZXF1aXJlMi5Qb3BvdmVyO1xuXG52YXIgX3JlcXVpcmUzID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWkvc3R5bGVzJyk7XG5cbnZhciBtdWlUaGVtZWFibGUgPSBfcmVxdWlyZTMubXVpVGhlbWVhYmxlO1xuXG52YXIgX3JlcXVpcmUkcmVxdWlyZUxpYiA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgUHlkaW9Db250ZXh0Q29uc3VtZXIgPSBfcmVxdWlyZSRyZXF1aXJlTGliLlB5ZGlvQ29udGV4dENvbnN1bWVyO1xudmFyIEFzeW5jQ29tcG9uZW50ID0gX3JlcXVpcmUkcmVxdWlyZUxpYi5Bc3luY0NvbXBvbmVudDtcblxudmFyIEFjdGlvbnNQYW5lbCA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhBY3Rpb25zUGFuZWwsIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gQWN0aW9uc1BhbmVsKHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBBY3Rpb25zUGFuZWwpO1xuXG4gICAgICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IHNob3dQaWNrZXI6IGZhbHNlLCBwaWNrZXJBbmNob3I6IG51bGwsIHNob3dNYWlsZXI6IGZhbHNlLCBtYWlsZXJBbmNob3I6IG51bGwgfTtcbiAgICB9XG5cbiAgICBBY3Rpb25zUGFuZWwucHJvdG90eXBlLm9uVGVhbVNlbGVjdGVkID0gZnVuY3Rpb24gb25UZWFtU2VsZWN0ZWQoaXRlbSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2hvd1BpY2tlcjogZmFsc2UgfSk7XG4gICAgICAgIGlmIChpdGVtLmdldFR5cGUoKSA9PT0gJ2dyb3VwJyAmJiBpdGVtLmdldElkKCkuaW5kZXhPZignL0FKWFBfVEVBTS8nKSA9PT0gMCkge1xuICAgICAgICAgICAgVXNlcnNBcGkuYWRkVXNlclRvVGVhbShpdGVtLmdldElkKCkucmVwbGFjZSgnL0FKWFBfVEVBTS8nLCAnJyksIHRoaXMucHJvcHMudXNlcklkLCB0aGlzLnByb3BzLnJlbG9hZEFjdGlvbik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgQWN0aW9uc1BhbmVsLnByb3RvdHlwZS5vblVzZXJTZWxlY3RlZCA9IGZ1bmN0aW9uIG9uVXNlclNlbGVjdGVkKGl0ZW0pIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dQaWNrZXI6IGZhbHNlIH0pO1xuICAgICAgICBVc2Vyc0FwaS5hZGRVc2VyVG9UZWFtKHRoaXMucHJvcHMudGVhbS5pZCwgaXRlbS5nZXRJZCgpLCB0aGlzLnByb3BzLnJlbG9hZEFjdGlvbik7XG4gICAgfTtcblxuICAgIEFjdGlvbnNQYW5lbC5wcm90b3R5cGUub3BlblBpY2tlciA9IGZ1bmN0aW9uIG9wZW5QaWNrZXIoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dQaWNrZXI6IHRydWUsIHBpY2tlckFuY2hvcjogZXZlbnQuY3VycmVudFRhcmdldCB9KTtcbiAgICB9O1xuXG4gICAgQWN0aW9uc1BhbmVsLnByb3RvdHlwZS5vcGVuTWFpbGVyID0gZnVuY3Rpb24gb3Blbk1haWxlcihldmVudCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciB0YXJnZXQgPSBldmVudC5jdXJyZW50VGFyZ2V0O1xuICAgICAgICBSZXNvdXJjZXNNYW5hZ2VyLmxvYWRDbGFzc2VzQW5kQXBwbHkoWydQeWRpb01haWxlciddLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IG1haWxlckxpYkxvYWRlZDogdHJ1ZSB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBzaG93TWFpbGVyOiB0cnVlLCBtYWlsZXJBbmNob3I6IHRhcmdldCB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgQWN0aW9uc1BhbmVsLnByb3RvdHlwZS5jb21wb25lbnREaWRVcGRhdGUgPSBmdW5jdGlvbiBjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzLCBwcmV2U3RhdGUpIHtcbiAgICAgICAgaWYgKCF0aGlzLnByb3BzLmxvY2tPblN1YlBvcG92ZXJPcGVuKSByZXR1cm47XG4gICAgICAgIGlmICgodGhpcy5zdGF0ZS5zaG93UGlja2VyIHx8IHRoaXMuc3RhdGUuc2hvd01haWxlcikgJiYgIShwcmV2U3RhdGUuc2hvd1BpY2tlciB8fCBwcmV2U3RhdGUuc2hvd01haWxlcikpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMubG9ja09uU3ViUG9wb3Zlck9wZW4odHJ1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoISh0aGlzLnN0YXRlLnNob3dQaWNrZXIgfHwgdGhpcy5zdGF0ZS5zaG93TWFpbGVyKSAmJiAocHJldlN0YXRlLnNob3dQaWNrZXIgfHwgcHJldlN0YXRlLnNob3dNYWlsZXIpKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLmxvY2tPblN1YlBvcG92ZXJPcGVuKGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBBY3Rpb25zUGFuZWwucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHM7XG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gX3Byb3BzLmdldE1lc3NhZ2U7XG4gICAgICAgIHZhciBtdWlUaGVtZSA9IF9wcm9wcy5tdWlUaGVtZTtcbiAgICAgICAgdmFyIHRlYW0gPSBfcHJvcHMudGVhbTtcbiAgICAgICAgdmFyIHVzZXIgPSBfcHJvcHMudXNlcjtcbiAgICAgICAgdmFyIHVzZXJFZGl0YWJsZSA9IF9wcm9wcy51c2VyRWRpdGFibGU7XG5cbiAgICAgICAgdmFyIHN0eWxlcyA9IHtcbiAgICAgICAgICAgIGJ1dHRvbjoge1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogbXVpVGhlbWUucGFsZXR0ZS5hY2NlbnQyQ29sb3IsXG4gICAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNTAlJyxcbiAgICAgICAgICAgICAgICBtYXJnaW46ICcwIDRweCcsXG4gICAgICAgICAgICAgICAgd2lkdGg6IDQ0LFxuICAgICAgICAgICAgICAgIGhlaWdodDogNDQsXG4gICAgICAgICAgICAgICAgcGFkZGluZzogMTBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpY29uOiB7XG4gICAgICAgICAgICAgICAgY29sb3I6ICd3aGl0ZSdcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdmFyIG1haWxlciA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHVzZXJtYWlscyA9IHt9O1xuICAgICAgICB2YXIgYWN0aW9ucyA9IFtdO1xuICAgICAgICBpZiAodXNlciAmJiB1c2VyLmhhc0VtYWlsKSB7XG4gICAgICAgICAgICBhY3Rpb25zLnB1c2goeyBrZXk6ICdtZXNzYWdlJywgbGFiZWw6IGdldE1lc3NhZ2UoNTk4KSwgaWNvbjogJ2VtYWlsJywgY2FsbGJhY2s6IHRoaXMub3Blbk1haWxlci5iaW5kKHRoaXMpIH0pO1xuICAgICAgICAgICAgdXNlcm1haWxzW3RoaXMucHJvcHMudXNlci5pZF0gPSBQeWRpb1VzZXJzLlVzZXIuZnJvbU9iamVjdCh0aGlzLnByb3BzLnVzZXIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0ZWFtKSB7XG4gICAgICAgICAgICBhY3Rpb25zLnB1c2goeyBrZXk6ICd1c2VycycsIGxhYmVsOiBnZXRNZXNzYWdlKDU5OSksIGljb246ICdhY2NvdW50LW11bHRpcGxlLXBsdXMnLCBjYWxsYmFjazogdGhpcy5vcGVuUGlja2VyLmJpbmQodGhpcykgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhY3Rpb25zLnB1c2goeyBrZXk6ICd0ZWFtcycsIGxhYmVsOiBnZXRNZXNzYWdlKDU3MyksIGljb246ICdhY2NvdW50LW11bHRpcGxlLXBsdXMnLCBjYWxsYmFjazogdGhpcy5vcGVuUGlja2VyLmJpbmQodGhpcykgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVzZXJFZGl0YWJsZSkge1xuICAgICAgICAgICAgYWN0aW9ucy5wdXNoKHsga2V5OiAnZWRpdCcsIGxhYmVsOiB0aGlzLnByb3BzLnRlYW0gPyBnZXRNZXNzYWdlKDU4MCkgOiBnZXRNZXNzYWdlKDYwMCksIGljb246ICdwZW5jaWwnLCBjYWxsYmFjazogdGhpcy5wcm9wcy5vbkVkaXRBY3Rpb24gfSk7XG4gICAgICAgICAgICBhY3Rpb25zLnB1c2goeyBrZXk6ICdkZWxldGUnLCBsYWJlbDogdGhpcy5wcm9wcy50ZWFtID8gZ2V0TWVzc2FnZSg1NzApIDogZ2V0TWVzc2FnZSg1ODIpLCBpY29uOiAnZGVsZXRlJywgY2FsbGJhY2s6IHRoaXMucHJvcHMub25EZWxldGVBY3Rpb24gfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgeyBzdHlsZTogeyB0ZXh0QWxpZ246ICdjZW50ZXInLCBtYXJnaW5Cb3R0b206IDE2IH0gfSxcbiAgICAgICAgICAgIGFjdGlvbnMubWFwKGZ1bmN0aW9uIChhKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoSWNvbkJ1dHRvbiwge1xuICAgICAgICAgICAgICAgICAgICBrZXk6IGEua2V5LFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogc3R5bGVzLmJ1dHRvbixcbiAgICAgICAgICAgICAgICAgICAgaWNvblN0eWxlOiBzdHlsZXMuaWNvbixcbiAgICAgICAgICAgICAgICAgICAgdG9vbHRpcDogYS5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogXCJtZGkgbWRpLVwiICsgYS5pY29uLFxuICAgICAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiBhLmNhbGxiYWNrXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgUG9wb3ZlcixcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG9wZW46IHRoaXMuc3RhdGUuc2hvd1BpY2tlcixcbiAgICAgICAgICAgICAgICAgICAgYW5jaG9yRWw6IHRoaXMuc3RhdGUucGlja2VyQW5jaG9yLFxuICAgICAgICAgICAgICAgICAgICBhbmNob3JPcmlnaW46IHsgaG9yaXpvbnRhbDogJ3JpZ2h0JywgdmVydGljYWw6ICd0b3AnIH0sXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldE9yaWdpbjogeyBob3Jpem9udGFsOiAncmlnaHQnLCB2ZXJ0aWNhbDogJ3RvcCcgfSxcbiAgICAgICAgICAgICAgICAgICAgb25SZXF1ZXN0Q2xvc2U6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMi5zZXRTdGF0ZSh7IHNob3dQaWNrZXI6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB1c2VMYXllckZvckNsaWNrQXdheTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7IHpJbmRleDogMjIwMCB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyB3aWR0aDogMjU2LCBoZWlnaHQ6IDMyMCB9IH0sXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX2FkZHJlc3Nib29rQWRkcmVzc0Jvb2syWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGU6ICdzZWxlY3RvcicsXG4gICAgICAgICAgICAgICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpbyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRlclN0eWxlOiB7IHdpZHRoOiAzMjAsIGhlaWdodDogNDIwIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkl0ZW1TZWxlY3RlZDogdGhpcy5wcm9wcy50ZWFtID8gdGhpcy5vblVzZXJTZWxlY3RlZC5iaW5kKHRoaXMpIDogdGhpcy5vblRlYW1TZWxlY3RlZC5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGVhbXNPbmx5OiB0aGlzLnByb3BzLnRlYW0gPyBmYWxzZSA6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB1c2Vyc09ubHk6IHRoaXMucHJvcHMudGVhbSA/IHRydWUgOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFBvcG92ZXIsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBvcGVuOiB0aGlzLnN0YXRlLnNob3dNYWlsZXIsXG4gICAgICAgICAgICAgICAgICAgIGFuY2hvckVsOiB0aGlzLnN0YXRlLm1haWxlckFuY2hvcixcbiAgICAgICAgICAgICAgICAgICAgYW5jaG9yT3JpZ2luOiB7IGhvcml6b250YWw6ICdyaWdodCcsIHZlcnRpY2FsOiAndG9wJyB9LFxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRPcmlnaW46IHsgaG9yaXpvbnRhbDogJ3JpZ2h0JywgdmVydGljYWw6ICd0b3AnIH0sXG4gICAgICAgICAgICAgICAgICAgIHVzZUxheWVyRm9yQ2xpY2tBd2F5OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHsgekluZGV4OiAyMjAwIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IHdpZHRoOiAyNTYsIGhlaWdodDogMzIwIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5tYWlsZXJMaWJMb2FkZWQgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChBc3luY0NvbXBvbmVudCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlOiAnUHlkaW9NYWlsZXInLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogJ1BhbmUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgekRlcHRoOiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFuZWxUaXRsZTogZ2V0TWVzc2FnZSg1OTgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgdW5pcXVlVXNlclN0eWxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlcnM6IHVzZXJtYWlscyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uRGlzbWlzczogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMi5zZXRTdGF0ZSh7IHNob3dNYWlsZXI6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uRmllbGRGb2N1czogdGhpcy5wcm9wcy5vdGhlclBvcG92ZXJNb3VzZU92ZXJcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBBY3Rpb25zUGFuZWw7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5BY3Rpb25zUGFuZWwucHJvcFR5cGVzID0ge1xuXG4gICAgLyoqXG4gICAgICogVXNlciBkYXRhLCBwcm9wcyBtdXN0IHBhc3MgYXQgbGVhc3Qgb25lIG9mICd1c2VyJyBvciAndGVhbSdcbiAgICAgKi9cbiAgICB1c2VyOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgIC8qKlxuICAgICAqIFRlYW0gZGF0YSwgcHJvcHMgbXVzdCBwYXNzIGF0IGxlYXN0IG9uZSBvZiAndXNlcicgb3IgJ3RlYW0nXG4gICAgICovXG4gICAgdGVhbTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAvKipcbiAgICAgKiBGb3IgdXNlcnMsIHdoZXRoZXIgaXQgaXMgZWRpdGFibGUgb3Igbm90XG4gICAgICovXG4gICAgdXNlckVkaXRhYmxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0XG5cbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEFjdGlvbnNQYW5lbCA9IFB5ZGlvQ29udGV4dENvbnN1bWVyKEFjdGlvbnNQYW5lbCk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBBY3Rpb25zUGFuZWwgPSBtdWlUaGVtZWFibGUoKShBY3Rpb25zUGFuZWwpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBBY3Rpb25zUGFuZWw7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX2FkZHJlc3Nib29rVXNlcnNMaXN0ID0gcmVxdWlyZSgnLi4vYWRkcmVzc2Jvb2svVXNlcnNMaXN0Jyk7XG5cbnZhciBfYWRkcmVzc2Jvb2tVc2Vyc0xpc3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYWRkcmVzc2Jvb2tVc2Vyc0xpc3QpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgQ29tcG9uZW50ID0gX3JlcXVpcmUuQ29tcG9uZW50O1xudmFyIFByb3BUeXBlcyA9IF9yZXF1aXJlLlByb3BUeXBlcztcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBEaXZpZGVyID0gX3JlcXVpcmUyLkRpdmlkZXI7XG5cbnZhciBfcmVxdWlyZTMgPSByZXF1aXJlKCdweWRpby9odHRwL3VzZXJzLWFwaScpO1xuXG52YXIgVXNlcnNBcGkgPSBfcmVxdWlyZTMuVXNlcnNBcGk7XG5cbnZhciBfcmVxdWlyZSRyZXF1aXJlTGliID0gcmVxdWlyZSgncHlkaW8nKS5yZXF1aXJlTGliKCdib290Jyk7XG5cbnZhciBQeWRpb0NvbnRleHRDb25zdW1lciA9IF9yZXF1aXJlJHJlcXVpcmVMaWIuUHlkaW9Db250ZXh0Q29uc3VtZXI7XG5cbi8qKlxuICogRGlzcGxheSBpbmZvcm1hdGlvbiBhYm91dCB1c2VyIG9yIHRlYW0gcmVsYXRpb25zXG4gKi9cblxudmFyIEdyYXBoUGFuZWwgPSAoZnVuY3Rpb24gKF9Db21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoR3JhcGhQYW5lbCwgX0NvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBHcmFwaFBhbmVsKCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgR3JhcGhQYW5lbCk7XG5cbiAgICAgICAgX0NvbXBvbmVudC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIEdyYXBoUGFuZWwucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHM7XG4gICAgICAgIHZhciBncmFwaCA9IF9wcm9wcy5ncmFwaDtcbiAgICAgICAgdmFyIHVzZXJMYWJlbCA9IF9wcm9wcy51c2VyTGFiZWw7XG4gICAgICAgIHZhciBweWRpbyA9IF9wcm9wcy5weWRpbztcbiAgICAgICAgdmFyIGdldE1lc3NhZ2UgPSBfcHJvcHMuZ2V0TWVzc2FnZTtcblxuICAgICAgICB2YXIgZWxlbWVudHMgPSBbXTtcbiAgICAgICAgaWYgKGdyYXBoLnRlYW1zICYmIGdyYXBoLnRlYW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgdmFyIG9uRGVsZXRlQWN0aW9uID0gKGZ1bmN0aW9uIChwYXJlbnRJdGVtLCB0ZWFtKSB7XG4gICAgICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICAgICAgICAgIFVzZXJzQXBpLnJlbW92ZVVzZXJGcm9tVGVhbSh0ZWFtWzBdLmlkLCB0aGlzLnByb3BzLnVzZXJJZCwgZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5tZXNzYWdlKSBweWRpby5VSS5kaXNwbGF5TWVzc2FnZSgnU1VDQ0VTUycsIHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5wcm9wcy5yZWxvYWRBY3Rpb24oKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgICAgICBlbGVtZW50cy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBrZXk6ICd0ZWFtcycgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KERpdmlkZXIsIG51bGwpLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX2FkZHJlc3Nib29rVXNlcnNMaXN0MlsnZGVmYXVsdCddLCB7IHN1YkhlYWRlcjogZ2V0TWVzc2FnZSg1ODEpLnJlcGxhY2UoJyVzJywgZ3JhcGgudGVhbXMubGVuZ3RoKSwgb25JdGVtQ2xpY2tlZDogZnVuY3Rpb24gKCkge30sIGl0ZW06IHsgbGVhZnM6IGdyYXBoLnRlYW1zIH0sIG1vZGU6ICdpbm5lcicsIG9uRGVsZXRlQWN0aW9uOiBvbkRlbGV0ZUFjdGlvbiB9KVxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGdyYXBoLnNvdXJjZSAmJiBPYmplY3Qua2V5cyhncmFwaC5zb3VyY2UpLmxlbmd0aCkge1xuICAgICAgICAgICAgZWxlbWVudHMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsga2V5OiAnc291cmNlJyB9LFxuICAgICAgICAgICAgICAgIGVsZW1lbnRzLmxlbmd0aCA/IFJlYWN0LmNyZWF0ZUVsZW1lbnQoRGl2aWRlciwgbnVsbCkgOiBudWxsLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IHBhZGRpbmc6IDE2IH0gfSxcbiAgICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZSg2MDEpLnJlcGxhY2UoJyUxJywgdXNlckxhYmVsKS5yZXBsYWNlKCclMicsIE9iamVjdC5rZXlzKGdyYXBoLnNvdXJjZSkubGVuZ3RoKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChncmFwaC50YXJnZXQgJiYgT2JqZWN0LmtleXMoZ3JhcGgudGFyZ2V0KS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGVsZW1lbnRzLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGtleTogJ3RhcmdldCcgfSxcbiAgICAgICAgICAgICAgICBlbGVtZW50cy5sZW5ndGggPyBSZWFjdC5jcmVhdGVFbGVtZW50KERpdmlkZXIsIG51bGwpIDogbnVsbCxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyBwYWRkaW5nOiAxNiB9IH0sXG4gICAgICAgICAgICAgICAgICAgIGdldE1lc3NhZ2UoNjAyKS5yZXBsYWNlKCclMScsIHVzZXJMYWJlbCkucmVwbGFjZSgnJTInLCBPYmplY3Qua2V5cyhncmFwaC50YXJnZXQpLmxlbmd0aClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIGVsZW1lbnRzXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBHcmFwaFBhbmVsO1xufSkoQ29tcG9uZW50KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gR3JhcGhQYW5lbCA9IFB5ZGlvQ29udGV4dENvbnN1bWVyKEdyYXBoUGFuZWwpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gR3JhcGhQYW5lbDtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfR3JhcGhQYW5lbCA9IHJlcXVpcmUoJy4vR3JhcGhQYW5lbCcpO1xuXG52YXIgX0dyYXBoUGFuZWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfR3JhcGhQYW5lbCk7XG5cbnZhciBfQWN0aW9uc1BhbmVsID0gcmVxdWlyZSgnLi9BY3Rpb25zUGFuZWwnKTtcblxudmFyIF9BY3Rpb25zUGFuZWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQWN0aW9uc1BhbmVsKTtcblxudmFyIGRlYm91bmNlID0gcmVxdWlyZSgnbG9kYXNoLmRlYm91bmNlJyk7XG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIENvbG9yID0gcmVxdWlyZSgnY29sb3InKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIEZvbnRJY29uID0gX3JlcXVpcmUuRm9udEljb247XG52YXIgUG9wb3ZlciA9IF9yZXF1aXJlLlBvcG92ZXI7XG52YXIgUGFwZXIgPSBfcmVxdWlyZS5QYXBlcjtcbnZhciBBdmF0YXIgPSBfcmVxdWlyZS5BdmF0YXI7XG52YXIgQ2FyZFRpdGxlID0gX3JlcXVpcmUuQ2FyZFRpdGxlO1xuXG52YXIgX3JlcXVpcmUyID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWkvc3R5bGVzJyk7XG5cbnZhciBtdWlUaGVtZWFibGUgPSBfcmVxdWlyZTIubXVpVGhlbWVhYmxlO1xuXG52YXIgTWV0YUNhY2hlU2VydmljZSA9IHJlcXVpcmUoJ3B5ZGlvL2h0dHAvbWV0YS1jYWNoZS1zZXJ2aWNlJyk7XG52YXIgUHlkaW9BcGkgPSByZXF1aXJlKCdweWRpby9odHRwL2FwaScpO1xuXG4vKipcbiAqIEdlbmVyaWMgY29tcG9uZW50IGZvciBkaXNwbGF5IGEgdXNlciBhbmQgaGVyIGF2YXRhciAoZmlyc3QgbGV0dGVycyBvciBwaG90bylcbiAqL1xuXG52YXIgVXNlckF2YXRhciA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhVc2VyQXZhdGFyLCBfUmVhY3QkQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIFVzZXJBdmF0YXIocHJvcHMsIGNvbnRleHQpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFVzZXJBdmF0YXIpO1xuXG4gICAgICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICB1c2VyOiBudWxsLFxuICAgICAgICAgICAgYXZhdGFyOiBudWxsLFxuICAgICAgICAgICAgZ3JhcGg6IG51bGxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBVc2VyQXZhdGFyLnByb3RvdHlwZS5jb21wb25lbnREaWRNb3VudCA9IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5weWRpby51c2VyICYmIHRoaXMucHJvcHMucHlkaW8udXNlci5pZCA9PT0gdGhpcy5wcm9wcy51c2VySWQpIHtcbiAgICAgICAgICAgIHRoaXMubG9hZExvY2FsRGF0YSgpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLl91c2VyTG9nZ2VkT2JzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdXNlckxvZ2dlZE9icyA9IHRoaXMubG9hZExvY2FsRGF0YS5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMucHlkaW8ub2JzZXJ2ZSgndXNlcl9sb2dnZWQnLCB0aGlzLl91c2VyTG9nZ2VkT2JzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByb3BzLnVzZXJUeXBlID09PSAndXNlcicpIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGUgPSBNZXRhQ2FjaGVTZXJ2aWNlLmdldEluc3RhbmNlKCk7XG4gICAgICAgICAgICB0aGlzLmNhY2hlLnJlZ2lzdGVyTWV0YVN0cmVhbSgndXNlcl9wdWJsaWNfZGF0YScsICdFWFBJUkFUSU9OX01BTlVBTF9UUklHR0VSJyk7XG4gICAgICAgICAgICB0aGlzLmNhY2hlLnJlZ2lzdGVyTWV0YVN0cmVhbSgndXNlcl9wdWJsaWNfZGF0YS1yaWNoJywgJ0VYUElSQVRJT05fTUFOVUFMX1RSSUdHRVInKTtcbiAgICAgICAgICAgIHRoaXMubG9hZFB1YmxpY0RhdGEodGhpcy5wcm9wcy51c2VySWQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIFVzZXJBdmF0YXIucHJvdG90eXBlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykge1xuICAgICAgICBpZiAoIXRoaXMucHJvcHMudXNlcklkIHx8IHRoaXMucHJvcHMudXNlcklkICE9PSBuZXh0UHJvcHMudXNlcklkKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgbGFiZWw6IG5leHRQcm9wcy51c2VySWQgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMucHlkaW8gJiYgdGhpcy5wcm9wcy5weWRpby51c2VyICYmIHRoaXMucHJvcHMucHlkaW8udXNlci5pZCA9PT0gbmV4dFByb3BzLnVzZXJJZCkge1xuICAgICAgICAgICAgdGhpcy5sb2FkTG9jYWxEYXRhKCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuX3VzZXJMb2dnZWRPYnMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl91c2VyTG9nZ2VkT2JzID0gdGhpcy5sb2FkTG9jYWxEYXRhLmJpbmQodGhpcyk7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5weWRpby5vYnNlcnZlKCd1c2VyX2xvZ2dlZCcsIHRoaXMuX3VzZXJMb2dnZWRPYnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3VzZXJMb2dnZWRPYnMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnB5ZGlvLnN0b3BPYnNlcnZpbmcoJ3VzZXJfbG9nZ2VkJywgdGhpcy5fdXNlckxvZ2dlZE9icyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmNhY2hlID0gTWV0YUNhY2hlU2VydmljZS5nZXRJbnN0YW5jZSgpO1xuICAgICAgICAgICAgdGhpcy5jYWNoZS5yZWdpc3Rlck1ldGFTdHJlYW0oJ3VzZXJfcHVibGljX2RhdGEnLCAnRVhQSVJBVElPTl9NQU5VQUxfVFJJR0dFUicpO1xuICAgICAgICAgICAgdGhpcy5jYWNoZS5yZWdpc3Rlck1ldGFTdHJlYW0oJ3VzZXJfcHVibGljX2RhdGEtcmljaCcsICdFWFBJUkFUSU9OX01BTlVBTF9UUklHR0VSJyk7XG4gICAgICAgICAgICB0aGlzLmxvYWRQdWJsaWNEYXRhKG5leHRQcm9wcy51c2VySWQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIFVzZXJBdmF0YXIucHJvdG90eXBlLmNvbXBvbmVudFdpbGxVbm1vdW50ID0gZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIGlmICh0aGlzLl91c2VyTG9nZ2VkT2JzKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLnB5ZGlvLnN0b3BPYnNlcnZpbmcoJ3VzZXJfbG9nZ2VkJywgdGhpcy5fdXNlckxvZ2dlZE9icyk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgVXNlckF2YXRhci5wcm90b3R5cGUubG9hZExvY2FsRGF0YSA9IGZ1bmN0aW9uIGxvYWRMb2NhbERhdGEoKSB7XG4gICAgICAgIHZhciBweWRpbyA9IHRoaXMucHJvcHMucHlkaW87XG5cbiAgICAgICAgaWYgKCFweWRpby51c2VyKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgbGFiZWw6ICcnLCBhdmF0YXI6IG51bGwgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHVzZXJOYW1lID0gcHlkaW8udXNlci5nZXRQcmVmZXJlbmNlKCdVU0VSX0RJU1BMQVlfTkFNRScpIHx8IHB5ZGlvLnVzZXIuaWQ7XG4gICAgICAgIHZhciBhdmF0YXJJZCA9IHB5ZGlvLnVzZXIuZ2V0UHJlZmVyZW5jZSgnYXZhdGFyJyk7XG4gICAgICAgIHZhciBhdmF0YXJVcmwgPSBQeWRpb0FwaS5nZXRDbGllbnQoKS5idWlsZFVzZXJBdmF0YXJVcmwocHlkaW8udXNlci5pZCwgYXZhdGFySWQpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGxhYmVsOiB1c2VyTmFtZSxcbiAgICAgICAgICAgIGF2YXRhcjogYXZhdGFyVXJsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIWF2YXRhclVybCkge1xuICAgICAgICAgICAgdGhpcy5sb2FkRnJvbUV4dGVybmFsUHJvdmlkZXIoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBVc2VyQXZhdGFyLnByb3RvdHlwZS5sb2FkUHVibGljRGF0YSA9IGZ1bmN0aW9uIGxvYWRQdWJsaWNEYXRhKHVzZXJJZCkge1xuXG4gICAgICAgIHZhciBuYW1lc3BhY2UgPSB0aGlzLnByb3BzLnJpY2hDYXJkID8gJ3VzZXJfcHVibGljX2RhdGEtcmljaCcgOiAndXNlcl9wdWJsaWNfZGF0YSc7XG4gICAgICAgIGlmICh0aGlzLmNhY2hlLmhhc0tleShuYW1lc3BhY2UsIHVzZXJJZCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUodGhpcy5jYWNoZS5nZXRCeUtleShuYW1lc3BhY2UsIHVzZXJJZCkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIFB5ZGlvQXBpLmdldENsaWVudCgpLnJlcXVlc3Qoe1xuICAgICAgICAgICAgZ2V0X2FjdGlvbjogJ3VzZXJfcHVibGljX2RhdGEnLFxuICAgICAgICAgICAgdXNlcl9pZDogdXNlcklkLFxuICAgICAgICAgICAgZ3JhcGg6IHRoaXMucHJvcHMucmljaENhcmQgPyAndHJ1ZScgOiAnZmFsc2UnXG4gICAgICAgIH0sIChmdW5jdGlvbiAodHJhbnNwb3J0KSB7XG4gICAgICAgICAgICB2YXIgZGF0YSA9IHRyYW5zcG9ydC5yZXNwb25zZUpTT047XG4gICAgICAgICAgICBpZiAoIWRhdGEgfHwgZGF0YS5lcnJvcikge1xuICAgICAgICAgICAgICAgIHRoaXMuY2FjaGUuc2V0S2V5KG5hbWVzcGFjZSwgdXNlcklkLCB7fSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHVzZXIgPSBkYXRhLnVzZXI7XG4gICAgICAgICAgICB2YXIgZ3JhcGggPSBkYXRhLmdyYXBoO1xuXG4gICAgICAgICAgICB2YXIgYXZhdGFyVXJsID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdmFyIGF2YXRhcklkID0gdXNlci5hdmF0YXIgfHwgbnVsbDtcbiAgICAgICAgICAgIHZhciBsYWJlbCA9IHVzZXIubGFiZWwgfHwgdXNlcklkO1xuICAgICAgICAgICAgaWYgKCF1c2VyLmF2YXRhcikge1xuICAgICAgICAgICAgICAgIHRoaXMubG9hZEZyb21FeHRlcm5hbFByb3ZpZGVyKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGF2YXRhclVybCA9IFB5ZGlvQXBpLmdldENsaWVudCgpLmJ1aWxkVXNlckF2YXRhclVybCh1c2VySWQsIGF2YXRhcklkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY2FjaGUuc2V0S2V5KG5hbWVzcGFjZSwgdXNlcklkLCB7XG4gICAgICAgICAgICAgICAgdXNlcjogdXNlcixcbiAgICAgICAgICAgICAgICBncmFwaDogZ3JhcGgsXG4gICAgICAgICAgICAgICAgYXZhdGFyOiBhdmF0YXJVcmxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgdXNlcjogdXNlcixcbiAgICAgICAgICAgICAgICBncmFwaDogZ3JhcGgsXG4gICAgICAgICAgICAgICAgYXZhdGFyOiBhdmF0YXJVcmxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICB9O1xuXG4gICAgVXNlckF2YXRhci5wcm90b3R5cGUubG9hZEZyb21FeHRlcm5hbFByb3ZpZGVyID0gZnVuY3Rpb24gbG9hZEZyb21FeHRlcm5hbFByb3ZpZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMucHJvcHMucHlkaW8uZ2V0UGx1Z2luQ29uZmlncyhcImFqeHBfcGx1Z2luW0BpZD0nYWN0aW9uLmF2YXRhciddXCIpLmdldChcIkFWQVRBUl9QUk9WSURFUlwiKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciBuYW1lc3BhY2UgPSB0aGlzLnByb3BzLnJpY2hDYXJkID8gJ3VzZXJfcHVibGljX2RhdGEtcmljaCcgOiAndXNlcl9wdWJsaWNfZGF0YSc7XG4gICAgICAgIFB5ZGlvQXBpLmdldENsaWVudCgpLnJlcXVlc3Qoe1xuICAgICAgICAgICAgZ2V0X2FjdGlvbjogJ2dldF9hdmF0YXJfdXJsJyxcbiAgICAgICAgICAgIHVzZXJpZDogdGhpcy5wcm9wcy51c2VySWRcbiAgICAgICAgfSwgKGZ1bmN0aW9uICh0cmFuc3BvcnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBhdmF0YXI6IHRyYW5zcG9ydC5yZXNwb25zZVRleHQgfSk7XG4gICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgIH07XG5cbiAgICBVc2VyQXZhdGFyLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIF9zdGF0ZSA9IHRoaXMuc3RhdGU7XG4gICAgICAgIHZhciB1c2VyID0gX3N0YXRlLnVzZXI7XG4gICAgICAgIHZhciBhdmF0YXIgPSBfc3RhdGUuYXZhdGFyO1xuICAgICAgICB2YXIgZ3JhcGggPSBfc3RhdGUuZ3JhcGg7XG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgcHlkaW8gPSBfcHJvcHMucHlkaW87XG4gICAgICAgIHZhciB1c2VySWQgPSBfcHJvcHMudXNlcklkO1xuICAgICAgICB2YXIgdXNlclR5cGUgPSBfcHJvcHMudXNlclR5cGU7XG4gICAgICAgIHZhciBpY29uID0gX3Byb3BzLmljb247XG4gICAgICAgIHZhciBzdHlsZSA9IF9wcm9wcy5zdHlsZTtcbiAgICAgICAgdmFyIGxhYmVsU3R5bGUgPSBfcHJvcHMubGFiZWxTdHlsZTtcbiAgICAgICAgdmFyIGF2YXRhclN0eWxlID0gX3Byb3BzLmF2YXRhclN0eWxlO1xuICAgICAgICB2YXIgYXZhdGFyU2l6ZSA9IF9wcm9wcy5hdmF0YXJTaXplO1xuICAgICAgICB2YXIgY2xhc3NOYW1lID0gX3Byb3BzLmNsYXNzTmFtZTtcbiAgICAgICAgdmFyIGF2YXRhckNsYXNzTmFtZSA9IF9wcm9wcy5hdmF0YXJDbGFzc05hbWU7XG4gICAgICAgIHZhciBsYWJlbENsYXNzTmFtZSA9IF9wcm9wcy5sYWJlbENsYXNzTmFtZTtcbiAgICAgICAgdmFyIGRpc3BsYXlMYWJlbCA9IF9wcm9wcy5kaXNwbGF5TGFiZWw7XG4gICAgICAgIHZhciBkaXNwbGF5QXZhdGFyID0gX3Byb3BzLmRpc3BsYXlBdmF0YXI7XG4gICAgICAgIHZhciB1c2VEZWZhdWx0QXZhdGFyID0gX3Byb3BzLnVzZURlZmF1bHRBdmF0YXI7XG4gICAgICAgIHZhciByaWNoQ2FyZCA9IF9wcm9wcy5yaWNoQ2FyZDtcbiAgICAgICAgdmFyIGNhcmRTaXplID0gX3Byb3BzLmNhcmRTaXplO1xuICAgICAgICB2YXIgbXVpVGhlbWUgPSBfcHJvcHMubXVpVGhlbWU7XG4gICAgICAgIHZhciBsYWJlbCA9IHRoaXMuc3RhdGUubGFiZWw7XG5cbiAgICAgICAgdmFyIHVzZXJUeXBlTGFiZWwgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh1c2VyKSB7XG4gICAgICAgICAgICBsYWJlbCA9IHVzZXIubGFiZWw7XG4gICAgICAgIH0gZWxzZSBpZiAoIWxhYmVsKSB7XG4gICAgICAgICAgICBsYWJlbCA9IHRoaXMucHJvcHMudXNlckxhYmVsIHx8IHRoaXMucHJvcHMudXNlcklkO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGF2YXRhckNvbnRlbnQgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICBhdmF0YXJDb2xvciA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGF2YXRhckljb24gPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChyaWNoQ2FyZCkge1xuICAgICAgICAgICAgZGlzcGxheUF2YXRhciA9IHVzZURlZmF1bHRBdmF0YXIgPSBkaXNwbGF5TGFiZWwgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkaXNwbGF5QXZhdGFyICYmICFhdmF0YXIgJiYgbGFiZWwgJiYgKCFkaXNwbGF5TGFiZWwgfHwgdXNlRGVmYXVsdEF2YXRhcikpIHtcbiAgICAgICAgICAgIHZhciBhdmF0YXJzQ29sb3IgPSBtdWlUaGVtZS5wYWxldHRlLmF2YXRhcnNDb2xvcjtcbiAgICAgICAgICAgIGlmICh1c2VyVHlwZSA9PT0gJ2dyb3VwJyB8fCB1c2VyVHlwZSA9PT0gJ3RlYW0nIHx8IHVzZXJJZC5pbmRleE9mKCdBSlhQX0dSUF8vJykgPT09IDAgfHwgdXNlcklkLmluZGV4T2YoJy9BSlhQX1RFQU0vJykgPT09IDApIHtcbiAgICAgICAgICAgICAgICBhdmF0YXJzQ29sb3IgPSBDb2xvcihhdmF0YXJzQ29sb3IpLmRhcmtlbigwLjIpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgaWNvbkNsYXNzTmFtZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHN3aXRjaCAodXNlclR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdncm91cCc6XG4gICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWUgPSAnbWRpIG1kaS1hY2NvdW50LW11bHRpcGxlJztcbiAgICAgICAgICAgICAgICAgICAgdXNlclR5cGVMYWJlbCA9ICcyODknO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICd0ZWFtJzpcbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZSA9ICdtZGkgbWRpLWFjY291bnQtbXVsdGlwbGUtb3V0bGluZSc7XG4gICAgICAgICAgICAgICAgICAgIHVzZXJUeXBlTGFiZWwgPSAnNjAzJztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAncmVtb3RlJzpcbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZSA9ICdtZGkgbWRpLWFjY291bnQtbmV0d29yayc7XG4gICAgICAgICAgICAgICAgICAgIHVzZXJUeXBlTGFiZWwgPSAnNjA0JztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZSA9ICdtZGkgbWRpLWFjY291bnQnO1xuICAgICAgICAgICAgICAgICAgICB1c2VyVHlwZUxhYmVsID0gdXNlciA/IHVzZXIuZXh0ZXJuYWwgPyAnNTg5JyA6ICc1OTAnIDogJzI4OCc7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGljb24pIGljb25DbGFzc05hbWUgPSBpY29uO1xuICAgICAgICAgICAgaWYgKHVzZXJUeXBlTGFiZWwpIHVzZXJUeXBlTGFiZWwgPSBweWRpby5NZXNzYWdlSGFzaFt1c2VyVHlwZUxhYmVsXTtcbiAgICAgICAgICAgIGlmIChyaWNoQ2FyZCkge1xuICAgICAgICAgICAgICAgIGF2YXRhckljb24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KEZvbnRJY29uLCB7IGNsYXNzTmFtZTogaWNvbkNsYXNzTmFtZSwgc3R5bGU6IHsgY29sb3I6IGF2YXRhcnNDb2xvciB9IH0pO1xuICAgICAgICAgICAgICAgIGF2YXRhckNvbG9yID0gJyNmNWY1ZjUnO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhdmF0YXJDb2xvciA9IGF2YXRhcnNDb2xvcjtcbiAgICAgICAgICAgICAgICBpZiAoaWNvbkNsYXNzTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBhdmF0YXJJY29uID0gUmVhY3QuY3JlYXRlRWxlbWVudChGb250SWNvbiwgeyBjbGFzc05hbWU6IGljb25DbGFzc05hbWUgfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXZhdGFyQ29udGVudCA9IGxhYmVsLnNwbGl0KCcgJykubWFwKGZ1bmN0aW9uICh3b3JkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gd29yZFswXTtcbiAgICAgICAgICAgICAgICAgICAgfSkuam9pbignJykuc3Vic3RyaW5nKDAsIDIpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXZhdGFyQ29udGVudC5sZW5ndGggPCAyKSBhdmF0YXJDb250ZW50ID0gbGFiZWwuc3Vic3RyaW5nKDAsIDIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgcmVsb2FkQWN0aW9uID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgb25FZGl0QWN0aW9uID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgb25Nb3VzZU92ZXIgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICBvbk1vdXNlT3V0ID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgcG9wb3ZlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHJpY2hDYXJkKSB7XG4gICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgZGlzcGxheUF2YXRhciA9IHRydWU7XG4gICAgICAgICAgICAgICAgc3R5bGUgPSBfZXh0ZW5kcyh7fSwgc3R5bGUsIHsgZmxleERpcmVjdGlvbjogJ2NvbHVtbicgfSk7XG4gICAgICAgICAgICAgICAgYXZhdGFyU2l6ZSA9IGNhcmRTaXplID8gY2FyZFNpemUgOiAnMTAwJSc7XG4gICAgICAgICAgICAgICAgYXZhdGFyU3R5bGUgPSB7IGJvcmRlclJhZGl1czogMCB9O1xuICAgICAgICAgICAgICAgIHZhciBsb2NhbFJlbG9hZCA9IGZ1bmN0aW9uIGxvY2FsUmVsb2FkKCkge1xuICAgICAgICAgICAgICAgICAgICBNZXRhQ2FjaGVTZXJ2aWNlLmdldEluc3RhbmNlKCkuZGVsZXRlS2V5KCd1c2VyX3B1YmxpY19kYXRhLXJpY2gnLCBfdGhpcy5wcm9wcy51c2VySWQpO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5sb2FkUHVibGljRGF0YShfdGhpcy5wcm9wcy51c2VySWQpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmVsb2FkQWN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBsb2NhbFJlbG9hZCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMucHJvcHMucmVsb2FkQWN0aW9uKSBfdGhpcy5wcm9wcy5yZWxvYWRBY3Rpb24oKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG9uRWRpdEFjdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9jYWxSZWxvYWQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzLnByb3BzLm9uRWRpdEFjdGlvbikgX3RoaXMucHJvcHMub25FZGl0QWN0aW9uKCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0pKCk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy5yaWNoT25Ib3Zlcikge1xuICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIG9uTW91c2VPdXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghX3RoaXMubG9ja2VkQnlTdWJQb3BvdmVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IHNob3dQb3BvdmVyOiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgb25Nb3VzZU91dCA9IGRlYm91bmNlKG9uTW91c2VPdXQsIDM1MCk7XG4gICAgICAgICAgICAgICAgb25Nb3VzZU92ZXIgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IHNob3dQb3BvdmVyOiB0cnVlLCBwb3BvdmVyQW5jaG9yOiBlLmN1cnJlbnRUYXJnZXQgfSk7XG4gICAgICAgICAgICAgICAgICAgIG9uTW91c2VPdXQuY2FuY2VsKCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB2YXIgb25Nb3VzZU92ZXJJbm5lciA9IGZ1bmN0aW9uIG9uTW91c2VPdmVySW5uZXIoZSkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IHNob3dQb3BvdmVyOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgICAgICBvbk1vdXNlT3V0LmNhbmNlbCgpO1xuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICB2YXIgbG9ja09uU3ViUG9wb3Zlck9wZW4gPSBmdW5jdGlvbiBsb2NrT25TdWJQb3BvdmVyT3BlbihzdGF0dXMpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMubG9ja2VkQnlTdWJQb3BvdmVyID0gc3RhdHVzO1xuICAgICAgICAgICAgICAgICAgICBvbk1vdXNlT3ZlcklubmVyKCk7XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIHBvcG92ZXIgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICBQb3BvdmVyLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVuOiBfdGhpcy5zdGF0ZS5zaG93UG9wb3ZlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvckVsOiBfdGhpcy5zdGF0ZS5wb3BvdmVyQW5jaG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgb25SZXF1ZXN0Q2xvc2U6IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVhc29uICE9PSAnY2xpY2tBd2F5JyB8fCAhX3RoaXMubG9ja2VkQnlTdWJQb3BvdmVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgc2hvd1BvcG92ZXI6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JPcmlnaW46IHsgaG9yaXpvbnRhbDogXCJsZWZ0XCIsIHZlcnRpY2FsOiBcImNlbnRlclwiIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRPcmlnaW46IHsgaG9yaXpvbnRhbDogXCJyaWdodFwiLCB2ZXJ0aWNhbDogXCJjZW50ZXJcIiB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlTGF5ZXJGb3JDbGlja0F3YXk6IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICBQYXBlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgekRlcHRoOiAyLCBzdHlsZTogeyB3aWR0aDogMjIwLCBoZWlnaHQ6IDMyMCwgb3ZlcmZsb3dZOiAnYXV0bycgfSwgb25Nb3VzZU92ZXI6IG9uTW91c2VPdmVySW5uZXIsIG9uTW91c2VPdXQ6IG9uTW91c2VPdXQgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoVXNlckF2YXRhciwgX2V4dGVuZHMoe30sIF90aGlzLnByb3BzLCB7IHJpY2hDYXJkOiB0cnVlLCByaWNoT25Ib3ZlcjogZmFsc2UsIGNhcmRTaXplOiAyMjAsIGxvY2tPblN1YlBvcG92ZXJPcGVuOiBsb2NrT25TdWJQb3BvdmVyT3BlbiB9KSlcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGF2YXRhckNvbXBvbmVudCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICBBdmF0YXIsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgc3JjOiBhdmF0YXIsXG4gICAgICAgICAgICAgICAgaWNvbjogYXZhdGFySWNvbixcbiAgICAgICAgICAgICAgICBzaXplOiBhdmF0YXJTaXplLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB0aGlzLnByb3BzLmF2YXRhck9ubHkgPyB0aGlzLnByb3BzLnN0eWxlIDogYXZhdGFyU3R5bGUsXG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBhdmF0YXJDb2xvclxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGF2YXRhckNvbnRlbnRcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAodGhpcy5wcm9wcy5hdmF0YXJPbmx5KSB7XG4gICAgICAgICAgICByZXR1cm4gYXZhdGFyQ29tcG9uZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiBjbGFzc05hbWUsIHN0eWxlOiBzdHlsZSwgb25Nb3VzZU92ZXI6IG9uTW91c2VPdmVyLCBvbk1vdXNlT3V0OiBvbk1vdXNlT3V0IH0sXG4gICAgICAgICAgICBkaXNwbGF5QXZhdGFyICYmIChhdmF0YXIgfHwgYXZhdGFyQ29udGVudCB8fCBhdmF0YXJJY29uKSAmJiBhdmF0YXJDb21wb25lbnQsXG4gICAgICAgICAgICBkaXNwbGF5TGFiZWwgJiYgIXJpY2hDYXJkICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGxhYmVsQ2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogbGFiZWxTdHlsZSB9LFxuICAgICAgICAgICAgICAgIGxhYmVsXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgZGlzcGxheUxhYmVsICYmIHJpY2hDYXJkICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoQ2FyZFRpdGxlLCB7IHN0eWxlOiB7IHRleHRBbGlnbjogJ2NlbnRlcicgfSwgdGl0bGU6IGxhYmVsLCBzdWJ0aXRsZTogdXNlclR5cGVMYWJlbCB9KSxcbiAgICAgICAgICAgIHJpY2hDYXJkICYmIHVzZXIgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChfQWN0aW9uc1BhbmVsMlsnZGVmYXVsdCddLCBfZXh0ZW5kcyh7fSwgdGhpcy5zdGF0ZSwgdGhpcy5wcm9wcywgeyByZWxvYWRBY3Rpb246IHJlbG9hZEFjdGlvbiwgb25FZGl0QWN0aW9uOiBvbkVkaXRBY3Rpb24gfSkpLFxuICAgICAgICAgICAgZ3JhcGggJiYgUmVhY3QuY3JlYXRlRWxlbWVudChfR3JhcGhQYW5lbDJbJ2RlZmF1bHQnXSwgX2V4dGVuZHMoeyBncmFwaDogZ3JhcGggfSwgdGhpcy5wcm9wcywgeyB1c2VyTGFiZWw6IGxhYmVsLCByZWxvYWRBY3Rpb246IHJlbG9hZEFjdGlvbiwgb25FZGl0QWN0aW9uOiBvbkVkaXRBY3Rpb24gfSkpLFxuICAgICAgICAgICAgdGhpcy5wcm9wcy5jaGlsZHJlbixcbiAgICAgICAgICAgIHBvcG92ZXJcbiAgICAgICAgKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFVzZXJBdmF0YXI7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5Vc2VyQXZhdGFyLnByb3BUeXBlcyA9IHtcbiAgICAvKipcbiAgICAgKiBJZCBvZiB0aGUgdXNlciB0byBiZSBsb2FkZWRcbiAgICAgKi9cbiAgICB1c2VySWQ6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICAvKipcbiAgICAgKiBQeWRpbyBpbnN0YW5jZVxuICAgICAqL1xuICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbyksXG4gICAgLyoqXG4gICAgICogTGFiZWwgb2YgdGhlIHVzZXIsIGlmIHdlIGFscmVhZHkgaGF2ZSBpdCAob3RoZXJ3aXNlIHdpbGwgYmUgbG9hZGVkKVxuICAgICAqL1xuICAgIHVzZXJMYWJlbDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAvKipcbiAgICAgKiBUeXBlIG9mIHVzZXJcbiAgICAgKi9cbiAgICB1c2VyVHlwZTogUmVhY3QuUHJvcFR5cGVzLm9uZU9mKFsndXNlcicsICdncm91cCcsICdyZW1vdGUnLCAndGVhbSddKSxcbiAgICAvKipcbiAgICAgKiBJY29uIHRvIGJlIGRpc3BsYXllZCBpbiBhdmF0YXJcbiAgICAgKi9cbiAgICBpY29uOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIERpc3BsYXkgYSByaWNoIGNhcmQgb3IgYSBzaW1wbGUgYXZhdGFyK2xhYmVsIGNoaXBcbiAgICAgKi9cbiAgICByaWNoQ2FyZDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgLyoqXG4gICAgICogSWYgbm90IHJpY2gsIGRpc3BsYXkgYSByaWNoIGNhcmQgYXMgcG9wb3ZlciBvbiBtb3VzZW92ZXJcbiAgICAgKi9cbiAgICByaWNoT25Ib3ZlcjogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG5cbiAgICAvKipcbiAgICAgKiBBZGQgZWRpdCBhY3Rpb24gdG8gdGhlIGNhcmRcbiAgICAgKi9cbiAgICB1c2VyRWRpdGFibGU6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJlZCBhZnRlciBzdWNjZXNzZnVsIGVkaXRpb25cbiAgICAgKi9cbiAgICBvbkVkaXRBY3Rpb246IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJlZCBhZnRlciBkZWxldGlvblxuICAgICAqL1xuICAgIG9uRGVsZXRlQWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyZWQgaWYgYSByZWxvYWQgaXMgcmVxdWlyZWRcbiAgICAgKi9cbiAgICByZWxvYWRBY3Rpb246IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuXG4gICAgLyoqXG4gICAgICogRGlzcGxheSBsYWJlbCBlbGVtZW50IG9yIG5vdFxuICAgICAqL1xuICAgIGRpc3BsYXlMYWJlbDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgLyoqXG4gICAgICogRGlzcGxheSBhdmF0YXIgZWxlbWVudCBvciBub3RcbiAgICAgKi9cbiAgICBkaXNwbGF5QXZhdGFyOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAvKipcbiAgICAgKiBEaXNwbGF5IG9ubHkgYXZhdGFyXG4gICAgICovXG4gICAgYXZhdGFyT25seTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgLyoqXG4gICAgICogVXNlIGRlZmF1bHQgYXZhdGFyXG4gICAgICovXG4gICAgdXNlRGVmYXVsdEF2YXRhcjogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgLyoqXG4gICAgICogQXZhdGFyIHNpemUsIDQwcHggYnkgZGVmYXVsdFxuICAgICAqL1xuICAgIGF2YXRhclNpemU6IFJlYWN0LlByb3BUeXBlcy5udW1iZXIsXG5cbiAgICAvKipcbiAgICAgKiBBZGQgY2xhc3MgbmFtZSB0byByb290IGVsZW1lbnRcbiAgICAgKi9cbiAgICBjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgLyoqXG4gICAgICogQWRkIGNsYXNzIG5hbWUgdG8gbGFiZWwgZWxlbWVudFxuICAgICAqL1xuICAgIGxhYmVsQ2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIEFkZCBjbGFzcyBuYW1lIHRvIGF2YXRhciBlbGVtZW50XG4gICAgICovXG4gICAgYXZhdGFyQ2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIEFkZCBzdHlsZSB0byByb290IGVsZW1lbnRcbiAgICAgKi9cbiAgICBzdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAvKipcbiAgICAgKiBBZGQgc3R5bGUgdG8gbGFiZWwgZWxlbWVudFxuICAgICAqL1xuICAgIGxhYmVsU3R5bGU6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICogQWRkIHN0eWxlIHRvIGF2YXRhciBlbGVtZW50XG4gICAgICovXG4gICAgYXZhdGFyU3R5bGU6IFJlYWN0LlByb3BUeXBlcy5vYmplY3Rcbn07XG5cblVzZXJBdmF0YXIuZGVmYXVsdFByb3BzID0ge1xuICAgIGRpc3BsYXlMYWJlbDogdHJ1ZSxcbiAgICBkaXNwbGF5QXZhdGFyOiB0cnVlLFxuICAgIGF2YXRhclNpemU6IDQwLFxuICAgIHVzZXJUeXBlOiAndXNlcicsXG4gICAgY2xhc3NOYW1lOiAndXNlci1hdmF0YXItd2lkZ2V0JyxcbiAgICBhdmF0YXJDbGFzc05hbWU6ICd1c2VyLWF2YXRhcicsXG4gICAgbGFiZWxDbGFzc05hbWU6ICd1c2VyLWxhYmVsJ1xufTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gVXNlckF2YXRhciA9IG11aVRoZW1lYWJsZSgpKFVzZXJBdmF0YXIpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBVc2VyQXZhdGFyO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cblwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgRnVuY1V0aWxzID0gcmVxdWlyZShcInB5ZGlvL3V0aWwvZnVuY1wiKTtcbnZhciBSZXNvdXJjZXNNYW5hZ2VyID0gcmVxdWlyZShcInB5ZGlvL2h0dHAvcmVzb3VyY2VzLW1hbmFnZXJcIik7XG5cbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiBSRUFDVCBETkQgR0VORVJJQyBDT01QT05FTlRTXG4gLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbnZhciBUeXBlcyA9IHtcbiAgICBOT0RFX1BST1ZJREVSOiAnbm9kZScsXG4gICAgU09SVEFCTEVfTElTVF9JVEVNOiAnc29ydGFibGUtbGlzdC1pdGVtJ1xufTtcblxuLyoqXG4gKiBTcGVjaWZpZXMgd2hpY2ggcHJvcHMgdG8gaW5qZWN0IGludG8geW91ciBjb21wb25lbnQuXG4gKi9cbmZ1bmN0aW9uIGNvbGxlY3QoY29ubmVjdCwgbW9uaXRvcikge1xuICAgIHJldHVybiB7XG4gICAgICAgIGNvbm5lY3REcmFnU291cmNlOiBjb25uZWN0LmRyYWdTb3VyY2UoKSxcbiAgICAgICAgaXNEcmFnZ2luZzogbW9uaXRvci5pc0RyYWdnaW5nKClcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBjb2xsZWN0RHJvcChjb25uZWN0LCBtb25pdG9yKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29ubmVjdERyb3BUYXJnZXQ6IGNvbm5lY3QuZHJvcFRhcmdldCgpLFxuICAgICAgICBjYW5Ecm9wOiBtb25pdG9yLmNhbkRyb3AoKSxcbiAgICAgICAgaXNPdmVyOiBtb25pdG9yLmlzT3ZlcigpLFxuICAgICAgICBpc092ZXJDdXJyZW50OiBtb25pdG9yLmlzT3Zlcih7IHNoYWxsb3c6IHRydWUgfSlcbiAgICB9O1xufVxuXG52YXIgRE5EQWN0aW9uUGFyYW1ldGVyID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBETkRBY3Rpb25QYXJhbWV0ZXIoc291cmNlLCB0YXJnZXQsIHN0ZXApIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEROREFjdGlvblBhcmFtZXRlcik7XG5cbiAgICAgICAgdGhpcy5fc291cmNlID0gc291cmNlO1xuICAgICAgICB0aGlzLl90YXJnZXQgPSB0YXJnZXQ7XG4gICAgICAgIHRoaXMuX3N0ZXAgPSBzdGVwO1xuICAgIH1cblxuICAgIEROREFjdGlvblBhcmFtZXRlci5wcm90b3R5cGUuZ2V0U291cmNlID0gZnVuY3Rpb24gZ2V0U291cmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc291cmNlO1xuICAgIH07XG5cbiAgICBETkRBY3Rpb25QYXJhbWV0ZXIucHJvdG90eXBlLmdldFRhcmdldCA9IGZ1bmN0aW9uIGdldFRhcmdldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RhcmdldDtcbiAgICB9O1xuXG4gICAgRE5EQWN0aW9uUGFyYW1ldGVyLnByb3RvdHlwZS5nZXRTdGVwID0gZnVuY3Rpb24gZ2V0U3RlcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0ZXA7XG4gICAgfTtcblxuICAgIHJldHVybiBETkRBY3Rpb25QYXJhbWV0ZXI7XG59KSgpO1xuXG5ETkRBY3Rpb25QYXJhbWV0ZXIuU1RFUF9CRUdJTl9EUkFHID0gJ2JlZ2luRHJhZyc7XG5ETkRBY3Rpb25QYXJhbWV0ZXIuU1RFUF9FTkRfRFJBRyA9ICdlbmREcmFnJztcbkROREFjdGlvblBhcmFtZXRlci5TVEVQX0NBTl9EUk9QID0gJ2NhbkRyb3AnO1xuRE5EQWN0aW9uUGFyYW1ldGVyLlNURVBfSE9WRVJfRFJPUCA9ICdob3Zlcic7XG5cbnZhciBhcHBseUROREFjdGlvbiA9IGZ1bmN0aW9uIGFwcGx5RE5EQWN0aW9uKHNvdXJjZSwgdGFyZ2V0LCBzdGVwKSB7XG4gICAgdmFyIENvbnRyb2xsZXIgPSB3aW5kb3cucHlkaW8uQ29udHJvbGxlcjtcblxuICAgIHZhciBkbmQgPSBDb250cm9sbGVyLmRlZmF1bHRBY3Rpb25zLmdldChcImRyYWduZHJvcFwiKTtcbiAgICBpZiAoZG5kKSB7XG4gICAgICAgIHZhciBkbmRBY3Rpb24gPSBDb250cm9sbGVyLmdldEFjdGlvbkJ5TmFtZShkbmQpO1xuICAgICAgICBkbmRBY3Rpb24uZW5hYmxlKCk7XG4gICAgICAgIHZhciBwYXJhbXMgPSBuZXcgRE5EQWN0aW9uUGFyYW1ldGVyKHNvdXJjZSwgdGFyZ2V0LCBzdGVwKTtcbiAgICAgICAgdmFyIGNoZWNrTW9kdWxlID0gZG5kQWN0aW9uLm9wdGlvbnMuZHJhZ25kcm9wQ2hlY2tNb2R1bGU7XG4gICAgICAgIGlmIChzdGVwID09PSBETkRBY3Rpb25QYXJhbWV0ZXIuU1RFUF9DQU5fRFJPUCAmJiBjaGVja01vZHVsZSkge1xuICAgICAgICAgICAgaWYgKCFGdW5jVXRpbHMuZ2V0RnVuY3Rpb25CeU5hbWUoY2hlY2tNb2R1bGUsIHdpbmRvdykpIHtcbiAgICAgICAgICAgICAgICBSZXNvdXJjZXNNYW5hZ2VyLmRldGVjdE1vZHVsZVRvTG9hZEFuZEFwcGx5KGNoZWNrTW9kdWxlLCBmdW5jdGlvbiAoKSB7fSk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgZmluZCB0ZXN0IG1vZHVsZSwgdHJ5aW5nIHRvIGxvYWQgaXQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEZ1bmNVdGlscy5leGVjdXRlRnVuY3Rpb25CeU5hbWUoZG5kQWN0aW9uLm9wdGlvbnMuZHJhZ25kcm9wQ2hlY2tNb2R1bGUsIHdpbmRvdywgQ29udHJvbGxlciwgcGFyYW1zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRuZEFjdGlvbi5hcHBseShwYXJhbXMpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBETkQgQWN0aW9ucyBhdmFpbGFibGUnKTtcbiAgICB9XG59O1xuXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qIFJFQUNUIERORCBEUkFHL0RST1AgTk9ERVNcbiAvKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG52YXIgbm9kZURyYWdTb3VyY2UgPSB7XG4gICAgYmVnaW5EcmFnOiBmdW5jdGlvbiBiZWdpbkRyYWcocHJvcHMpIHtcbiAgICAgICAgLy8gUmV0dXJuIHRoZSBkYXRhIGRlc2NyaWJpbmcgdGhlIGRyYWdnZWQgaXRlbVxuICAgICAgICByZXR1cm4geyBub2RlOiBwcm9wcy5ub2RlIH07XG4gICAgfSxcblxuICAgIGVuZERyYWc6IGZ1bmN0aW9uIGVuZERyYWcocHJvcHMsIG1vbml0b3IsIGNvbXBvbmVudCkge1xuICAgICAgICBpZiAoIW1vbml0b3IuZGlkRHJvcCgpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGl0ZW0gPSBtb25pdG9yLmdldEl0ZW0oKTtcbiAgICAgICAgdmFyIGRyb3BSZXN1bHQgPSBtb25pdG9yLmdldERyb3BSZXN1bHQoKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGFwcGx5RE5EQWN0aW9uKGl0ZW0ubm9kZSwgZHJvcFJlc3VsdC5ub2RlLCBETkRBY3Rpb25QYXJhbWV0ZXIuU1RFUF9FTkRfRFJBRyk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgfVxufTtcblxudmFyIG5vZGVEcm9wVGFyZ2V0ID0ge1xuXG4gICAgaG92ZXI6IGZ1bmN0aW9uIGhvdmVyKHByb3BzLCBtb25pdG9yKSB7fSxcblxuICAgIGNhbkRyb3A6IGZ1bmN0aW9uIGNhbkRyb3AocHJvcHMsIG1vbml0b3IpIHtcblxuICAgICAgICB2YXIgc291cmNlID0gbW9uaXRvci5nZXRJdGVtKCkubm9kZTtcbiAgICAgICAgdmFyIHRhcmdldCA9IHByb3BzLm5vZGU7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGFwcGx5RE5EQWN0aW9uKHNvdXJjZSwgdGFyZ2V0LCBETkRBY3Rpb25QYXJhbWV0ZXIuU1RFUF9DQU5fRFJPUCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9LFxuXG4gICAgZHJvcDogZnVuY3Rpb24gZHJvcChwcm9wcywgbW9uaXRvcikge1xuICAgICAgICB2YXIgaGFzRHJvcHBlZE9uQ2hpbGQgPSBtb25pdG9yLmRpZERyb3AoKTtcbiAgICAgICAgaWYgKGhhc0Ryb3BwZWRPbkNoaWxkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgbm9kZTogcHJvcHMubm9kZSB9O1xuICAgIH1cblxufTtcblxuZXhwb3J0cy5UeXBlcyA9IFR5cGVzO1xuZXhwb3J0cy5jb2xsZWN0ID0gY29sbGVjdDtcbmV4cG9ydHMuY29sbGVjdERyb3AgPSBjb2xsZWN0RHJvcDtcbmV4cG9ydHMubm9kZURyYWdTb3VyY2UgPSBub2RlRHJhZ1NvdXJjZTtcbmV4cG9ydHMubm9kZURyb3BUYXJnZXQgPSBub2RlRHJvcFRhcmdldDtcbmV4cG9ydHMuRE5EQWN0aW9uUGFyYW1ldGVyID0gRE5EQWN0aW9uUGFyYW1ldGVyO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbmV4cG9ydHNbXCJkZWZhdWx0XCJdID0ge1xuICAgIGNvbnRleHRUeXBlczoge1xuICAgICAgICBtZXNzYWdlczogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgZ2V0TWVzc2FnZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmNcbiAgICB9XG59O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIENvbXBvbmVudCA9IF9yZXF1aXJlLkNvbXBvbmVudDtcbnZhciBQcm9wVHlwZXMgPSBfcmVxdWlyZS5Qcm9wVHlwZXM7XG5cbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgRmxhdEJ1dHRvbiA9IF9yZXF1aXJlMi5GbGF0QnV0dG9uO1xudmFyIEZvbnRJY29uID0gX3JlcXVpcmUyLkZvbnRJY29uO1xuXG52YXIgX3JlcXVpcmUzID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWkvc3R5bGVzJyk7XG5cbnZhciBtdWlUaGVtZWFibGUgPSBfcmVxdWlyZTMubXVpVGhlbWVhYmxlO1xuXG52YXIgQ29sb3IgPSByZXF1aXJlKCdjb2xvcicpO1xudmFyIFB5ZGlvID0gcmVxdWlyZSgncHlkaW8nKTtcblxudmFyIF9QeWRpbyRyZXF1aXJlTGliID0gUHlkaW8ucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgUHlkaW9Db250ZXh0Q29uc3VtZXIgPSBfUHlkaW8kcmVxdWlyZUxpYi5QeWRpb0NvbnRleHRDb25zdW1lcjtcblxudmFyIEVtcHR5U3RhdGVWaWV3ID0gKGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7XG4gICAgX2luaGVyaXRzKEVtcHR5U3RhdGVWaWV3LCBfQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIEVtcHR5U3RhdGVWaWV3KHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBFbXB0eVN0YXRlVmlldyk7XG5cbiAgICAgICAgX0NvbXBvbmVudC5jYWxsKHRoaXMsIHByb3BzLCBjb250ZXh0KTtcbiAgICB9XG5cbiAgICBFbXB0eVN0YXRlVmlldy5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcztcbiAgICAgICAgdmFyIHN0eWxlID0gX3Byb3BzLnN0eWxlO1xuICAgICAgICB2YXIgaWNvbkNsYXNzTmFtZSA9IF9wcm9wcy5pY29uQ2xhc3NOYW1lO1xuICAgICAgICB2YXIgcHJpbWFyeVRleHRJZCA9IF9wcm9wcy5wcmltYXJ5VGV4dElkO1xuICAgICAgICB2YXIgc2Vjb25kYXJ5VGV4dElkID0gX3Byb3BzLnNlY29uZGFyeVRleHRJZDtcbiAgICAgICAgdmFyIGFjdGlvbkxhYmVsSWQgPSBfcHJvcHMuYWN0aW9uTGFiZWxJZDtcbiAgICAgICAgdmFyIGFjdGlvbkNhbGxiYWNrID0gX3Byb3BzLmFjdGlvbkNhbGxiYWNrO1xuICAgICAgICB2YXIgYWN0aW9uU3R5bGUgPSBfcHJvcHMuYWN0aW9uU3R5bGU7XG4gICAgICAgIHZhciBhY3Rpb25JY29uQ2xhc3NOYW1lID0gX3Byb3BzLmFjdGlvbkljb25DbGFzc05hbWU7XG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gX3Byb3BzLmdldE1lc3NhZ2U7XG5cbiAgICAgICAgdmFyIG1haW5Db2xvciA9IENvbG9yKHRoaXMucHJvcHMubXVpVGhlbWUucGFsZXR0ZS5wcmltYXJ5MUNvbG9yKTtcblxuICAgICAgICB2YXIgc3R5bGVzID0ge1xuICAgICAgICAgICAgY29udGFpbmVyOiBfZXh0ZW5kcyh7XG4gICAgICAgICAgICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgICAgICAgICAgIGFsaWduSXRlbXM6ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgIGp1c3RpZnlDb250ZW50OiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6ICcxMDAlJyxcbiAgICAgICAgICAgICAgICB3aWR0aDogJzEwMCUnLFxuICAgICAgICAgICAgICAgIGZsZXg6IDEsXG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBtYWluQ29sb3IubGlnaHRuZXNzKDk3KS5yZ2IoKS50b1N0cmluZygpXG4gICAgICAgICAgICB9LCBzdHlsZSksXG4gICAgICAgICAgICBjZW50ZXJlZDoge1xuICAgICAgICAgICAgICAgIG1heFdpZHRoOiAyODAsXG4gICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICBjb2xvcjogbWFpbkNvbG9yLmZhZGUoMC42KS50b1N0cmluZygpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaWNvbjoge1xuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMDBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwcmltYXJ5VGV4dDoge1xuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxNixcbiAgICAgICAgICAgICAgICBmb250V2VpZ2h0OiA1MDBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZWNvbmRhcnlUZXh0OiB7XG4gICAgICAgICAgICAgICAgbWFyZ2luVG9wOiAyMCxcbiAgICAgICAgICAgICAgICBmb250U2l6ZTogMTNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBidXR0b25Db250YWluZXI6IHtcbiAgICAgICAgICAgICAgICBtYXJnaW5Ub3A6IDEwMCxcbiAgICAgICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYnV0dG9uU3R5bGU6IHtcbiAgICAgICAgICAgICAgICBjb2xvcjogdGhpcy5wcm9wcy5tdWlUaGVtZS5wYWxldHRlLmFjY2VudDJDb2xvclxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB2YXIgYnV0dG9uSWNvbiA9IGFjdGlvbkljb25DbGFzc05hbWUgPyBSZWFjdC5jcmVhdGVFbGVtZW50KEZvbnRJY29uLCB7IGNsYXNzTmFtZTogYWN0aW9uSWNvbkNsYXNzTmFtZSB9KSA6IG51bGw7XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiBzdHlsZXMuY29udGFpbmVyIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHN0eWxlcy5jZW50ZXJlZCB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ2RpdicsIHsgY2xhc3NOYW1lOiBpY29uQ2xhc3NOYW1lLCBzdHlsZTogc3R5bGVzLmljb24gfSksXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IHN0eWxlcy5wcmltYXJ5VGV4dCB9LFxuICAgICAgICAgICAgICAgICAgICBnZXRNZXNzYWdlKHByaW1hcnlUZXh0SWQpXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBzZWNvbmRhcnlUZXh0SWQgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IHN0eWxlcy5zZWNvbmRhcnlUZXh0IH0sXG4gICAgICAgICAgICAgICAgICAgIGdldE1lc3NhZ2Uoc2Vjb25kYXJ5VGV4dElkKVxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgYWN0aW9uTGFiZWxJZCAmJiBhY3Rpb25DYWxsYmFjayAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogX2V4dGVuZHMoe30sIHN0eWxlcy5idXR0b25Db250YWluZXIsIGFjdGlvblN0eWxlKSB9LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEZsYXRCdXR0b24sIHsgc3R5bGU6IHN0eWxlcy5idXR0b25TdHlsZSwgbGFiZWw6IGdldE1lc3NhZ2UoYWN0aW9uTGFiZWxJZCksIG9uVG91Y2hUYXA6IGFjdGlvbkNhbGxiYWNrLCBpY29uOiBidXR0b25JY29uIH0pXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH07XG5cbiAgICByZXR1cm4gRW1wdHlTdGF0ZVZpZXc7XG59KShDb21wb25lbnQpO1xuXG5FbXB0eVN0YXRlVmlldy5wcm9wVHlwZXMgPSB7XG5cbiAgICBweWRpbzogUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW8pLmlzUmVxdWlyZWQsXG4gICAgaWNvbkNsYXNzTmFtZTogUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgIHByaW1hcnlUZXh0SWQ6IFByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcblxuICAgIHNlY29uZGFyeVRleHRJZDogUHJvcFR5cGVzLnN0cmluZyxcbiAgICBhY3Rpb25MYWJlbElkOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIGFjdGlvbkNhbGxiYWNrOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBhY3Rpb25TdHlsZTogUHJvcFR5cGVzLm9iamVjdCxcblxuICAgIHN0eWxlOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIGdldE1lc3NhZ2U6IFByb3BUeXBlcy5mdW5jXG5cbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEVtcHR5U3RhdGVWaWV3ID0gUHlkaW9Db250ZXh0Q29uc3VtZXIoRW1wdHlTdGF0ZVZpZXcpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gRW1wdHlTdGF0ZVZpZXcgPSBtdWlUaGVtZWFibGUoKShFbXB0eVN0YXRlVmlldyk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEVtcHR5U3RhdGVWaWV3O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMob2JqLCBrZXlzKSB7IHZhciB0YXJnZXQgPSB7fTsgZm9yICh2YXIgaSBpbiBvYmopIHsgaWYgKGtleXMuaW5kZXhPZihpKSA+PSAwKSBjb250aW51ZTsgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBpKSkgY29udGludWU7IHRhcmdldFtpXSA9IG9ialtpXTsgfSByZXR1cm4gdGFyZ2V0OyB9XG5cbnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTtcblxudmFyIF9tYXRlcmlhbFVpID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIE1vZGFsQXBwQmFyID0gZnVuY3Rpb24gTW9kYWxBcHBCYXIocHJvcHMpIHtcbiAgICB2YXIgc3R5bGUgPSBwcm9wcy5zdHlsZTtcbiAgICB2YXIgdGl0bGVTdHlsZSA9IHByb3BzLnRpdGxlU3R5bGU7XG4gICAgdmFyIGljb25TdHlsZVJpZ2h0ID0gcHJvcHMuaWNvblN0eWxlUmlnaHQ7XG4gICAgdmFyIGljb25TdHlsZUxlZnQgPSBwcm9wcy5pY29uU3R5bGVMZWZ0O1xuXG4gICAgdmFyIG90aGVyUHJvcHMgPSBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMocHJvcHMsIFsnc3R5bGUnLCAndGl0bGVTdHlsZScsICdpY29uU3R5bGVSaWdodCcsICdpY29uU3R5bGVMZWZ0J10pO1xuXG4gICAgdmFyIHN0eWxlcyA9IHtcbiAgICAgICAgc3R5bGU6IF9leHRlbmRzKHtcbiAgICAgICAgICAgIGZsZXhTaHJpbms6IDBcbiAgICAgICAgfSwgc3R5bGUpLFxuICAgICAgICB0aXRsZVN0eWxlOiBfZXh0ZW5kcyh7XG4gICAgICAgICAgICBsaW5lSGVpZ2h0OiAnNTZweCcsXG4gICAgICAgICAgICBoZWlnaHQ6IDU2LFxuICAgICAgICAgICAgbWFyZ2luTGVmdDogLThcbiAgICAgICAgfSwgdGl0bGVTdHlsZSksXG4gICAgICAgIGljb25TdHlsZVJpZ2h0OiBfZXh0ZW5kcyh7XG4gICAgICAgICAgICBtYXJnaW5Ub3A6IDRcbiAgICAgICAgfSwgaWNvblN0eWxlUmlnaHQpLFxuICAgICAgICBpY29uU3R5bGVMZWZ0OiBfZXh0ZW5kcyh7XG4gICAgICAgICAgICBtYXJnaW5Ub3A6IDRcbiAgICAgICAgfSwgaWNvblN0eWxlTGVmdClcbiAgICB9O1xuXG4gICAgcmV0dXJuIF9yZWFjdDJbJ2RlZmF1bHQnXS5jcmVhdGVFbGVtZW50KF9tYXRlcmlhbFVpLkFwcEJhciwgX2V4dGVuZHMoe30sIG90aGVyUHJvcHMsIHN0eWxlcykpO1xufTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gTW9kYWxBcHBCYXI7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbi8qYm9yZGVyUmFkaXVzOiAnMnB4IDJweCAwIDAnLCovXG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbi8qKlxuICogU2VhcmNoIGlucHV0IGJ1aWxkaW5nIGEgc2V0IG9mIHF1ZXJ5IHBhcmFtZXRlcnMgYW5kIGNhbGxpbmdcbiAqIHRoZSBjYWxsYmFja3MgdG8gZGlzcGxheSAvIGhpZGUgcmVzdWx0c1xuICovXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzWydkZWZhdWx0J10gPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdTZWFyY2hCb3gnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIC8vIFJlcXVpcmVkXG4gICAgICAgIHBhcmFtZXRlcnM6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgICAgcXVlcnlQYXJhbWV0ZXJOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgICAgIC8vIE90aGVyXG4gICAgICAgIHRleHRMYWJlbDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgZGlzcGxheVJlc3VsdHM6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBoaWRlUmVzdWx0czogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGRpc3BsYXlSZXN1bHRzU3RhdGU6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBsaW1pdDogUmVhY3QuUHJvcFR5cGVzLm51bWJlclxuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGRpc3BsYXlSZXN1bHQ6IHRoaXMucHJvcHMuZGlzcGxheVJlc3VsdHNTdGF0ZSA/IHRydWUgOiBmYWxzZVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uIGdldERlZmF1bHRQcm9wcygpIHtcbiAgICAgICAgdmFyIGRtID0gbmV3IFB5ZGlvRGF0YU1vZGVsKCk7XG4gICAgICAgIGRtLnNldFJvb3ROb2RlKG5ldyBBanhwTm9kZSgpKTtcbiAgICAgICAgcmV0dXJuIHsgZGF0YU1vZGVsOiBkbSB9O1xuICAgIH0sXG5cbiAgICBkaXNwbGF5UmVzdWx0c1N0YXRlOiBmdW5jdGlvbiBkaXNwbGF5UmVzdWx0c1N0YXRlKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGRpc3BsYXlSZXN1bHQ6IHRydWVcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIGhpZGVSZXN1bHRzU3RhdGU6IGZ1bmN0aW9uIGhpZGVSZXN1bHRzU3RhdGUoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgZGlzcGxheVJlc3VsdDogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucHJvcHMuaGlkZVJlc3VsdHMoKTtcbiAgICB9LFxuXG4gICAgb25DbGlja1NlYXJjaDogZnVuY3Rpb24gb25DbGlja1NlYXJjaCgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5yZWZzLnF1ZXJ5LmdldFZhbHVlKCk7XG4gICAgICAgIHZhciBkbSA9IHRoaXMucHJvcHMuZGF0YU1vZGVsO1xuICAgICAgICB2YXIgcGFyYW1zID0gdGhpcy5wcm9wcy5wYXJhbWV0ZXJzO1xuICAgICAgICBwYXJhbXNbdGhpcy5wcm9wcy5xdWVyeVBhcmFtZXRlck5hbWVdID0gdmFsdWU7XG4gICAgICAgIHBhcmFtc1snbGltaXQnXSA9IHRoaXMucHJvcHMubGltaXQgfHwgMTAwO1xuICAgICAgICBkbS5nZXRSb290Tm9kZSgpLnNldENoaWxkcmVuKFtdKTtcbiAgICAgICAgUHlkaW9BcGkuZ2V0Q2xpZW50KCkucmVxdWVzdChwYXJhbXMsIChmdW5jdGlvbiAodHJhbnNwb3J0KSB7XG4gICAgICAgICAgICB2YXIgcmVtb3RlTm9kZVByb3ZpZGVyID0gbmV3IFJlbW90ZU5vZGVQcm92aWRlcih7fSk7XG4gICAgICAgICAgICByZW1vdGVOb2RlUHJvdmlkZXIucGFyc2VOb2RlcyhkbS5nZXRSb290Tm9kZSgpLCB0cmFuc3BvcnQpO1xuICAgICAgICAgICAgZG0uZ2V0Um9vdE5vZGUoKS5zZXRMb2FkZWQodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLmRpc3BsYXlSZXN1bHRzU3RhdGUoKTtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuZGlzcGxheVJlc3VsdHModmFsdWUsIGRtKTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgfSxcblxuICAgIGtleURvd246IGZ1bmN0aW9uIGtleURvd24oZXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50LmtleSA9PSAnRW50ZXInKSB7XG4gICAgICAgICAgICB0aGlzLm9uQ2xpY2tTZWFyY2goKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiB0aGlzLnByb3BzLmNsYXNzTmFtZSA/IHRoaXMucHJvcHMuY2xhc3NOYW1lIDogJycgfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBwYWRkaW5nVG9wOiAyMiwgZmxvYXQ6ICdyaWdodCcsIG9wYWNpdHk6IDAuMyB9IH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5JY29uQnV0dG9uLCB7XG4gICAgICAgICAgICAgICAgICAgIHJlZjogJ2J1dHRvbicsXG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s6IHRoaXMub25DbGlja1NlYXJjaCxcbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogJ2ljb24tc2VhcmNoJyxcbiAgICAgICAgICAgICAgICAgICAgdG9vbHRpcDogJ1NlYXJjaCdcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdzZWFyY2hib3gtaW5wdXQtZmlsbCcsIHN0eWxlOiB7IHdpZHRoOiAyMjAsIGZsb2F0OiAncmlnaHQnIH0gfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLlRleHRGaWVsZCwgeyByZWY6ICdxdWVyeScsIG9uS2V5RG93bjogdGhpcy5rZXlEb3duLCBmbG9hdGluZ0xhYmVsVGV4dDogdGhpcy5wcm9wcy50ZXh0TGFiZWwgfSlcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG5cbn0pO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbi8qKlxuICogR2V0IGluZm8gZnJvbSBQeWRpbyBjb250cm9sbGVyIGFuIGJ1aWxkIGFuXG4gKiBhY3Rpb24gYmFyIHdpdGggYWN0aXZlIGFjdGlvbnMuXG4gKiBUQkNcbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0c1snZGVmYXVsdCddID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnU2ltcGxlUmVhY3RBY3Rpb25CYXInLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIGRhdGFNb2RlbDogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW9EYXRhTW9kZWwpLmlzUmVxdWlyZWQsXG4gICAgICAgIG5vZGU6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKEFqeHBOb2RlKS5pc1JlcXVpcmVkLFxuICAgICAgICBhY3Rpb25zOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXlcbiAgICB9LFxuXG4gICAgY2xpY2tBY3Rpb246IGZ1bmN0aW9uIGNsaWNrQWN0aW9uKGV2ZW50KSB7XG4gICAgICAgIHZhciBhY3Rpb25OYW1lID0gZXZlbnQuY3VycmVudFRhcmdldC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWFjdGlvblwiKTtcbiAgICAgICAgdGhpcy5wcm9wcy5kYXRhTW9kZWwuc2V0U2VsZWN0ZWROb2RlcyhbdGhpcy5wcm9wcy5ub2RlXSk7XG4gICAgICAgIHZhciBhID0gd2luZG93LnB5ZGlvLkNvbnRyb2xsZXIuZ2V0QWN0aW9uQnlOYW1lKGFjdGlvbk5hbWUpO1xuICAgICAgICBhLmZpcmVDb250ZXh0Q2hhbmdlKHRoaXMucHJvcHMuZGF0YU1vZGVsLCB0cnVlLCB3aW5kb3cucHlkaW8udXNlcik7XG4gICAgICAgIC8vYS5maXJlU2VsZWN0aW9uQ2hhbmdlKHRoaXMucHJvcHMuZGF0YU1vZGVsKTtcbiAgICAgICAgYS5hcHBseShbdGhpcy5wcm9wcy5kYXRhTW9kZWxdKTtcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgYWN0aW9ucyA9IHRoaXMucHJvcHMuYWN0aW9ucy5tYXAoKGZ1bmN0aW9uIChhKSB7XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudCgnZGl2Jywge1xuICAgICAgICAgICAgICAgIGtleTogYS5vcHRpb25zLm5hbWUsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBhLm9wdGlvbnMuaWNvbl9jbGFzcyArICcgbWF0ZXJpYWwtbGlzdC1hY3Rpb24taW5saW5lJyB8fCAnJyxcbiAgICAgICAgICAgICAgICB0aXRsZTogYS5vcHRpb25zLnRpdGxlLFxuICAgICAgICAgICAgICAgICdkYXRhLWFjdGlvbic6IGEub3B0aW9ucy5uYW1lLFxuICAgICAgICAgICAgICAgIG9uQ2xpY2s6IHRoaXMuY2xpY2tBY3Rpb24gfSk7XG4gICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICBhY3Rpb25zXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG52YXIgX3V0aWxETkQgPSByZXF1aXJlKCcuLi91dGlsL0RORCcpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX1B5ZGlvJHJlcXVpcmVMaWIgPSBQeWRpby5yZXF1aXJlTGliKCdob2MnKTtcblxudmFyIHdpdGhDb250ZXh0TWVudSA9IF9QeWRpbyRyZXF1aXJlTGliLndpdGhDb250ZXh0TWVudTtcblxudmFyIENvbnRleHRNZW51V3JhcHBlciA9IGZ1bmN0aW9uIENvbnRleHRNZW51V3JhcHBlcihwcm9wcykge1xuICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KCdkaXYnLCBwcm9wcyk7XG59O1xuQ29udGV4dE1lbnVXcmFwcGVyID0gd2l0aENvbnRleHRNZW51KENvbnRleHRNZW51V3JhcHBlcik7XG5cbi8qKlxuICogVHJlZSBOb2RlXG4gKi9cbnZhciBTaW1wbGVUcmVlTm9kZSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ1NpbXBsZVRyZWVOb2RlJyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBjb2xsYXBzZTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIGZvcmNlRXhwYW5kOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgY2hpbGRyZW5Pbmx5OiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgZGVwdGg6IFJlYWN0LlByb3BUeXBlcy5udW1iZXIsXG4gICAgICAgIG9uTm9kZVNlbGVjdDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIG5vZGU6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKEFqeHBOb2RlKSxcbiAgICAgICAgZGF0YU1vZGVsOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpb0RhdGFNb2RlbCksXG4gICAgICAgIGZvcmNlTGFiZWw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIC8vIE9wdGlvbmFsIGN1cnJlbnRseSBzZWxlY3RlZCBkZXRlY3Rpb25cbiAgICAgICAgbm9kZUlzU2VsZWN0ZWQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICAvLyBPcHRpb25hbCBjaGVja2JveGVzXG4gICAgICAgIGNoZWNrYm94ZXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcbiAgICAgICAgY2hlY2tib3hlc1ZhbHVlczogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgY2hlY2tib3hlc0NvbXB1dGVTdGF0dXM6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvbkNoZWNrYm94Q2hlY2s6IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgfSxcblxuICAgIGdldERlZmF1bHRQcm9wczogZnVuY3Rpb24gZ2V0RGVmYXVsdFByb3BzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29sbGFwc2U6IGZhbHNlLFxuICAgICAgICAgICAgY2hpbGRyZW5Pbmx5OiBmYWxzZSxcbiAgICAgICAgICAgIGRlcHRoOiAwLFxuICAgICAgICAgICAgb25Ob2RlU2VsZWN0OiBmdW5jdGlvbiBvbk5vZGVTZWxlY3Qobm9kZSkge31cbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgbGlzdGVuVG9Ob2RlOiBmdW5jdGlvbiBsaXN0ZW5Ub05vZGUobm9kZSkge1xuICAgICAgICB0aGlzLl9jaGlsZHJlbkxpc3RlbmVyID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc01vdW50ZWQoKSkgcmV0dXJuO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNoaWxkcmVuOiB0aGlzLl9ub2RlVG9DaGlsZHJlbihub2RlKSB9KTtcbiAgICAgICAgfSkuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5fbm9kZUxpc3RlbmVyID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc01vdW50ZWQoKSkgcmV0dXJuO1xuICAgICAgICAgICAgdGhpcy5mb3JjZVVwZGF0ZSgpO1xuICAgICAgICB9KS5iaW5kKHRoaXMpO1xuICAgICAgICBub2RlLm9ic2VydmUoXCJjaGlsZF9hZGRlZFwiLCB0aGlzLl9jaGlsZHJlbkxpc3RlbmVyKTtcbiAgICAgICAgbm9kZS5vYnNlcnZlKFwiY2hpbGRfcmVtb3ZlZFwiLCB0aGlzLl9jaGlsZHJlbkxpc3RlbmVyKTtcbiAgICAgICAgbm9kZS5vYnNlcnZlKFwibm9kZV9yZXBsYWNlZFwiLCB0aGlzLl9ub2RlTGlzdGVuZXIpO1xuICAgIH0sXG5cbiAgICBzdG9wTGlzdGVuaW5nOiBmdW5jdGlvbiBzdG9wTGlzdGVuaW5nKG5vZGUpIHtcbiAgICAgICAgbm9kZS5zdG9wT2JzZXJ2aW5nKFwiY2hpbGRfYWRkZWRcIiwgdGhpcy5fY2hpbGRyZW5MaXN0ZW5lcik7XG4gICAgICAgIG5vZGUuc3RvcE9ic2VydmluZyhcImNoaWxkX3JlbW92ZWRcIiwgdGhpcy5fY2hpbGRyZW5MaXN0ZW5lcik7XG4gICAgICAgIG5vZGUuc3RvcE9ic2VydmluZyhcIm5vZGVfcmVwbGFjZWRcIiwgdGhpcy5fbm9kZUxpc3RlbmVyKTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB0aGlzLmxpc3RlblRvTm9kZSh0aGlzLnByb3BzLm5vZGUpO1xuICAgIH0sXG5cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudDogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIHRoaXMuc3RvcExpc3RlbmluZyh0aGlzLnByb3BzLm5vZGUpO1xuICAgIH0sXG5cbiAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykge1xuICAgICAgICB2YXIgb2xkTm9kZSA9IHRoaXMucHJvcHMubm9kZTtcbiAgICAgICAgdmFyIG5ld05vZGUgPSBuZXh0UHJvcHMubm9kZTtcbiAgICAgICAgaWYgKG5ld05vZGUgPT0gb2xkTm9kZSAmJiBuZXdOb2RlLmdldE1ldGFkYXRhKCkuZ2V0KFwicGFnaW5hdGlvbkRhdGFcIikpIHtcbiAgICAgICAgICAgIHZhciByZW1hcGVkQ2hpbGRyZW4gPSB0aGlzLnN0YXRlLmNoaWxkcmVuLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgICAgIGMuc2V0UGFyZW50KG5ld05vZGUpO3JldHVybiBjO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgcmVtYXBlZFBhdGhlcyA9IHRoaXMuc3RhdGUuY2hpbGRyZW4ubWFwKGZ1bmN0aW9uIChjKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGMuZ2V0UGF0aCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgbmV3Q2hpbGRyZW4gPSB0aGlzLl9ub2RlVG9DaGlsZHJlbihuZXdOb2RlKTtcbiAgICAgICAgICAgIG5ld0NoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKG5jKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlbWFwZWRQYXRoZXMuaW5kZXhPZihuYy5nZXRQYXRoKCkpID09PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICByZW1hcGVkQ2hpbGRyZW4ucHVzaChuYyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgY2hpbGRyZW46IHJlbWFwZWRDaGlsZHJlbiB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjaGlsZHJlbjogdGhpcy5fbm9kZVRvQ2hpbGRyZW4obmV3Tm9kZSkgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5ld05vZGUgIT09IG9sZE5vZGUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcExpc3RlbmluZyhvbGROb2RlKTtcbiAgICAgICAgICAgIHRoaXMubGlzdGVuVG9Ob2RlKG5ld05vZGUpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2hvd0NoaWxkcmVuOiAhdGhpcy5wcm9wcy5jb2xsYXBzZSB8fCB0aGlzLnByb3BzLmZvcmNlRXhwYW5kLFxuICAgICAgICAgICAgY2hpbGRyZW46IHRoaXMuX25vZGVUb0NoaWxkcmVuKHRoaXMucHJvcHMubm9kZSlcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgX25vZGVUb0NoaWxkcmVuOiBmdW5jdGlvbiBfbm9kZVRvQ2hpbGRyZW4oKSB7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IFtdO1xuICAgICAgICB0aGlzLnByb3BzLm5vZGUuZ2V0Q2hpbGRyZW4oKS5mb3JFYWNoKGZ1bmN0aW9uIChjKSB7XG4gICAgICAgICAgICBpZiAoIWMuaXNMZWFmKCkgfHwgYy5nZXRBanhwTWltZSgpID09PSAnYWp4cF9icm93c2FibGVfYXJjaGl2ZScpIGNoaWxkcmVuLnB1c2goYyk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY2hpbGRyZW47XG4gICAgfSxcblxuICAgIG9uTm9kZVNlbGVjdDogZnVuY3Rpb24gb25Ob2RlU2VsZWN0KGV2KSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uTm9kZVNlbGVjdCkge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5vbk5vZGVTZWxlY3QodGhpcy5wcm9wcy5ub2RlKTtcbiAgICAgICAgfVxuICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9LFxuICAgIG9uQ2hpbGREaXNwbGF5VG9nZ2xlOiBmdW5jdGlvbiBvbkNoaWxkRGlzcGxheVRvZ2dsZShldikge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5ub2RlLmdldENoaWxkcmVuKCkuc2l6ZSkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dDaGlsZHJlbjogIXRoaXMuc3RhdGUuc2hvd0NoaWxkcmVuIH0pO1xuICAgICAgICB9XG4gICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0sXG4gICAgbm9kZUlzU2VsZWN0ZWQ6IGZ1bmN0aW9uIG5vZGVJc1NlbGVjdGVkKG4pIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMubm9kZUlzU2VsZWN0ZWQpIHJldHVybiB0aGlzLnByb3BzLm5vZGVJc1NlbGVjdGVkKG4pO2Vsc2UgcmV0dXJuIHRoaXMucHJvcHMuZGF0YU1vZGVsLmdldFNlbGVjdGVkTm9kZXMoKS5pbmRleE9mKG4pICE9PSAtMTtcbiAgICB9LFxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgbm9kZSA9IF9wcm9wcy5ub2RlO1xuICAgICAgICB2YXIgY2hpbGRyZW5Pbmx5ID0gX3Byb3BzLmNoaWxkcmVuT25seTtcbiAgICAgICAgdmFyIGNhbkRyb3AgPSBfcHJvcHMuY2FuRHJvcDtcbiAgICAgICAgdmFyIGlzT3ZlckN1cnJlbnQgPSBfcHJvcHMuaXNPdmVyQ3VycmVudDtcbiAgICAgICAgdmFyIGNoZWNrYm94ZXMgPSBfcHJvcHMuY2hlY2tib3hlcztcbiAgICAgICAgdmFyIGNoZWNrYm94ZXNDb21wdXRlU3RhdHVzID0gX3Byb3BzLmNoZWNrYm94ZXNDb21wdXRlU3RhdHVzO1xuICAgICAgICB2YXIgY2hlY2tib3hlc1ZhbHVlcyA9IF9wcm9wcy5jaGVja2JveGVzVmFsdWVzO1xuICAgICAgICB2YXIgb25DaGVja2JveENoZWNrID0gX3Byb3BzLm9uQ2hlY2tib3hDaGVjaztcbiAgICAgICAgdmFyIGRlcHRoID0gX3Byb3BzLmRlcHRoO1xuICAgICAgICB2YXIgZm9yY2VFeHBhbmQgPSBfcHJvcHMuZm9yY2VFeHBhbmQ7XG4gICAgICAgIHZhciBzZWxlY3RlZEl0ZW1TdHlsZSA9IF9wcm9wcy5zZWxlY3RlZEl0ZW1TdHlsZTtcbiAgICAgICAgdmFyIGdldEl0ZW1TdHlsZSA9IF9wcm9wcy5nZXRJdGVtU3R5bGU7XG4gICAgICAgIHZhciBmb3JjZUxhYmVsID0gX3Byb3BzLmZvcmNlTGFiZWw7XG5cbiAgICAgICAgdmFyIGhhc0ZvbGRlckNoaWxkcmVucyA9IHRoaXMuc3RhdGUuY2hpbGRyZW4ubGVuZ3RoID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICB2YXIgaGFzQ2hpbGRyZW47XG4gICAgICAgIGlmIChoYXNGb2xkZXJDaGlsZHJlbnMpIHtcbiAgICAgICAgICAgIGhhc0NoaWxkcmVuID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICAgICAgeyBvbkNsaWNrOiB0aGlzLm9uQ2hpbGREaXNwbGF5VG9nZ2xlIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5zaG93Q2hpbGRyZW4gfHwgZm9yY2VFeHBhbmQgPyBSZWFjdC5jcmVhdGVFbGVtZW50KCdzcGFuJywgeyBjbGFzc05hbWU6ICd0cmVlLWljb24gaWNvbi1hbmdsZS1kb3duJyB9KSA6IFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RyZWUtaWNvbiBpY29uLWFuZ2xlLXJpZ2h0JyB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBjbmFtZSA9IFwidHJlZS1pY29uIGljb24tYW5nbGUtcmlnaHRcIjtcbiAgICAgICAgICAgIGlmIChub2RlLmlzTG9hZGVkKCkpIHtcbiAgICAgICAgICAgICAgICBjbmFtZSArPSBcIiBuby1mb2xkZXItY2hpbGRyZW5cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhc0NoaWxkcmVuID0gUmVhY3QuY3JlYXRlRWxlbWVudCgnc3BhbicsIHsgY2xhc3NOYW1lOiBjbmFtZSB9KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaXNTZWxlY3RlZCA9IHRoaXMubm9kZUlzU2VsZWN0ZWQobm9kZSkgPyAnbXVpLW1lbnUtaXRlbSBtdWktaXMtc2VsZWN0ZWQnIDogJ211aS1tZW51LWl0ZW0nO1xuICAgICAgICB2YXIgc2VsZkxhYmVsO1xuICAgICAgICBpZiAoIWNoaWxkcmVuT25seSkge1xuICAgICAgICAgICAgaWYgKGNhbkRyb3AgJiYgaXNPdmVyQ3VycmVudCkge1xuICAgICAgICAgICAgICAgIGlzU2VsZWN0ZWQgKz0gJyBkcm9wcGFibGUtYWN0aXZlJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBib3hlcztcbiAgICAgICAgICAgIGlmIChjaGVja2JveGVzKSB7XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IHt9LFxuICAgICAgICAgICAgICAgICAgICBpbmhlcml0ZWQgPSBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQgPSB7fSxcbiAgICAgICAgICAgICAgICAgICAgYWRkaXRpb25hbENsYXNzTmFtZSA9ICcnO1xuICAgICAgICAgICAgICAgIGlmIChjaGVja2JveGVzQ29tcHV0ZVN0YXR1cykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgc3RhdHVzID0gY2hlY2tib3hlc0NvbXB1dGVTdGF0dXMobm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IHN0YXR1cy5WQUxVRVM7XG4gICAgICAgICAgICAgICAgICAgIGluaGVyaXRlZCA9IHN0YXR1cy5JTkhFUklURUQ7XG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVkID0gc3RhdHVzLkRJU0FCTEVEO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzLkNMQVNTTkFNRSkgYWRkaXRpb25hbENsYXNzTmFtZSA9ICcgJyArIHN0YXR1cy5DTEFTU05BTUU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVja2JveGVzVmFsdWVzICYmIGNoZWNrYm94ZXNWYWx1ZXNbbm9kZS5nZXRQYXRoKCldKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGNoZWNrYm94ZXNWYWx1ZXNbbm9kZS5nZXRQYXRoKCldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgdmFsdWVDbGFzc2VzID0gW107XG4gICAgICAgICAgICAgICAgYm94ZXMgPSBjaGVja2JveGVzLm1hcCgoZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkID0gdmFsdWVzW2NdICE9PSB1bmRlZmluZWQgPyB2YWx1ZXNbY10gOiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsaWNrID0gKGZ1bmN0aW9uIChldmVudCwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2hlY2tib3hDaGVjayhub2RlLCBjLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZCkgdmFsdWVDbGFzc2VzLnB1c2goYyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLkNoZWNrYm94LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBjLFxuICAgICAgICAgICAgICAgICAgICAgICAga2V5OiBjICsgXCItXCIgKyAoc2VsZWN0ZWQgPyBcInRydWVcIiA6IFwiZmFsc2VcIiksXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGVja2VkOiBzZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2hlY2s6IGNsaWNrLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ6IGRpc2FibGVkW2NdLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcImNib3gtXCIgKyBjXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgICAgIGlzU2VsZWN0ZWQgKz0gaW5oZXJpdGVkID8gXCIgaW5oZXJpdGVkIFwiIDogXCJcIjtcbiAgICAgICAgICAgICAgICBpc1NlbGVjdGVkICs9IHZhbHVlQ2xhc3Nlcy5sZW5ndGggPyBcIiBjaGVja2JveC12YWx1ZXMtXCIgKyB2YWx1ZUNsYXNzZXMuam9pbignLScpIDogXCIgY2hlY2tib3gtdmFsdWVzLWVtcHR5XCI7XG4gICAgICAgICAgICAgICAgYm94ZXMgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IFwidHJlZS1jaGVja2JveGVzXCIgKyBhZGRpdGlvbmFsQ2xhc3NOYW1lIH0sXG4gICAgICAgICAgICAgICAgICAgIGJveGVzXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBpdGVtU3R5bGUgPSB7IHBhZGRpbmdMZWZ0OiBkZXB0aCAqIDIwIH07XG4gICAgICAgICAgICBpZiAodGhpcy5ub2RlSXNTZWxlY3RlZChub2RlKSAmJiBzZWxlY3RlZEl0ZW1TdHlsZSkge1xuICAgICAgICAgICAgICAgIGl0ZW1TdHlsZSA9IF9leHRlbmRzKHt9LCBpdGVtU3R5bGUsIHNlbGVjdGVkSXRlbVN0eWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChnZXRJdGVtU3R5bGUpIHtcbiAgICAgICAgICAgICAgICBpdGVtU3R5bGUgPSBfZXh0ZW5kcyh7fSwgaXRlbVN0eWxlLCBnZXRJdGVtU3R5bGUobm9kZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGljb24gPSAnbWRpIG1kaS1mb2xkZXInO1xuICAgICAgICAgICAgdmFyIGFqeHBNaW1lID0gbm9kZS5nZXRBanhwTWltZSgpO1xuICAgICAgICAgICAgaWYgKGFqeHBNaW1lID09PSAnYWp4cF9icm93c2FibGVfYXJjaGl2ZScpIHtcbiAgICAgICAgICAgICAgICBpY29uID0gJ21kaSBtZGktYXJjaGl2ZSc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFqeHBNaW1lID09PSAnYWp4cF9yZWN5Y2xlJykge1xuICAgICAgICAgICAgICAgIGljb24gPSAnbWRpIG1kaS1kZWxldGUnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2VsZkxhYmVsID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBDb250ZXh0TWVudVdyYXBwZXIsXG4gICAgICAgICAgICAgICAgeyBub2RlOiBub2RlLCBjbGFzc05hbWU6ICd0cmVlLWl0ZW0gJyArIGlzU2VsZWN0ZWQgKyAoYm94ZXMgPyAnIGhhcy1jaGVja2JveGVzJyA6ICcnKSwgc3R5bGU6IGl0ZW1TdHlsZSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3RyZWUtaXRlbS1sYWJlbCcsIG9uQ2xpY2s6IHRoaXMub25Ob2RlU2VsZWN0LCB0aXRsZTogbm9kZS5nZXRMYWJlbCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2RhdGEtaWQnOiBub2RlLmdldFBhdGgoKSB9LFxuICAgICAgICAgICAgICAgICAgICBoYXNDaGlsZHJlbixcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudCgnc3BhbicsIHsgY2xhc3NOYW1lOiBcInRyZWUtaWNvbiBcIiArIGljb24gfSksXG4gICAgICAgICAgICAgICAgICAgIGZvcmNlTGFiZWwgPyBmb3JjZUxhYmVsIDogbm9kZS5nZXRMYWJlbCgpXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBib3hlc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjaGlsZHJlbiA9IFtdO1xuICAgICAgICB2YXIgY29ubmVjdG9yID0gZnVuY3Rpb24gY29ubmVjdG9yKGluc3RhbmNlKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICAgIH07XG4gICAgICAgIHZhciBkcmFnZ2FibGUgPSBmYWxzZTtcbiAgICAgICAgaWYgKHdpbmRvdy5SZWFjdERORCAmJiB0aGlzLnByb3BzLmNvbm5lY3REcm9wVGFyZ2V0ICYmIHRoaXMucHJvcHMuY29ubmVjdERyYWdTb3VyY2UpIHtcbiAgICAgICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNvbm5lY3REcmFnU291cmNlID0gX3RoaXMucHJvcHMuY29ubmVjdERyYWdTb3VyY2U7XG4gICAgICAgICAgICAgICAgdmFyIGNvbm5lY3REcm9wVGFyZ2V0ID0gX3RoaXMucHJvcHMuY29ubmVjdERyb3BUYXJnZXQ7XG4gICAgICAgICAgICAgICAgY29ubmVjdG9yID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3REcmFnU291cmNlKFJlYWN0RE9NLmZpbmRET01Ob2RlKGluc3RhbmNlKSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3REcm9wVGFyZ2V0KFJlYWN0RE9NLmZpbmRET01Ob2RlKGluc3RhbmNlKSk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBkcmFnZ2FibGUgPSB0cnVlO1xuICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlLnNob3dDaGlsZHJlbiB8fCBmb3JjZUV4cGFuZCkge1xuICAgICAgICAgICAgY2hpbGRyZW4gPSB0aGlzLnN0YXRlLmNoaWxkcmVuLm1hcCgoZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgICAgICAgICAgdmFyIHByb3BzID0gX2V4dGVuZHMoe30sIHRoaXMucHJvcHMsIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yY2VMYWJlbDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5Pbmx5OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAga2V5OiBjaGlsZC5nZXRQYXRoKCksXG4gICAgICAgICAgICAgICAgICAgIG5vZGU6IGNoaWxkLFxuICAgICAgICAgICAgICAgICAgICBkZXB0aDogZGVwdGggKyAxXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoZHJhZ2dhYmxlID8gRHJhZ0Ryb3BUcmVlTm9kZSA6IFNpbXBsZVRyZWVOb2RlLCBwcm9wcyk7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdsaScsXG4gICAgICAgICAgICB7IHJlZjogY29ubmVjdG9yLCBjbGFzc05hbWU6IFwidHJlZW5vZGVcIiArIG5vZGUuZ2V0UGF0aCgpLnJlcGxhY2UoL1xcLy9nLCAnXycpIH0sXG4gICAgICAgICAgICBzZWxmTGFiZWwsXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICd1bCcsXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICBjaGlsZHJlblxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG52YXIgRHJhZ0Ryb3BUcmVlTm9kZTtcbmlmICh3aW5kb3cuUmVhY3RETkQpIHtcbiAgICBEcmFnRHJvcFRyZWVOb2RlID0gUmVhY3RETkQuZmxvdyhSZWFjdERORC5EcmFnU291cmNlKF91dGlsRE5ELlR5cGVzLk5PREVfUFJPVklERVIsIF91dGlsRE5ELm5vZGVEcmFnU291cmNlLCBfdXRpbERORC5jb2xsZWN0KSwgUmVhY3RETkQuRHJvcFRhcmdldChfdXRpbERORC5UeXBlcy5OT0RFX1BST1ZJREVSLCBfdXRpbERORC5ub2RlRHJvcFRhcmdldCwgX3V0aWxETkQuY29sbGVjdERyb3ApKShTaW1wbGVUcmVlTm9kZSk7XG59IGVsc2Uge1xuICAgIERyYWdEcm9wVHJlZU5vZGUgPSBTaW1wbGVUcmVlTm9kZTtcbn1cblxuLyoqXG4gKiBTaW1wbGUgb3BlbmFibGUgLyBsb2FkYWJsZSB0cmVlIHRha2luZyBBanhwTm9kZSBhcyBpbnB1dHNcbiAqL1xudmFyIERORFRyZWVWaWV3ID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnRE5EVHJlZVZpZXcnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHNob3dSb290OiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgcm9vdExhYmVsOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICBvbk5vZGVTZWxlY3Q6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBub2RlOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihBanhwTm9kZSkuaXNSZXF1aXJlZCxcbiAgICAgICAgZGF0YU1vZGVsOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpb0RhdGFNb2RlbCkuaXNSZXF1aXJlZCxcbiAgICAgICAgc2VsZWN0YWJsZTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIHNlbGVjdGFibGVNdWx0aXBsZTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIGluaXRpYWxTZWxlY3Rpb25Nb2RlbDogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuICAgICAgICBvblNlbGVjdGlvbkNoYW5nZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGZvcmNlRXhwYW5kOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgLy8gT3B0aW9uYWwgY3VycmVudGx5IHNlbGVjdGVkIGRldGVjdGlvblxuICAgICAgICBub2RlSXNTZWxlY3RlZDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIC8vIE9wdGlvbmFsIGNoZWNrYm94ZXNcbiAgICAgICAgY2hlY2tib3hlczogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuICAgICAgICBjaGVja2JveGVzVmFsdWVzOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICBjaGVja2JveGVzQ29tcHV0ZVN0YXR1czogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIG9uQ2hlY2tib3hDaGVjazogUmVhY3QuUHJvcFR5cGVzLmZ1bmNcbiAgICB9LFxuXG4gICAgZ2V0RGVmYXVsdFByb3BzOiBmdW5jdGlvbiBnZXREZWZhdWx0UHJvcHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzaG93Um9vdDogdHJ1ZSxcbiAgICAgICAgICAgIG9uTm9kZVNlbGVjdDogdGhpcy5vbk5vZGVTZWxlY3RcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgb25Ob2RlU2VsZWN0OiBmdW5jdGlvbiBvbk5vZGVTZWxlY3Qobm9kZSkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5vbk5vZGVTZWxlY3QpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMub25Ob2RlU2VsZWN0KG5vZGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5kYXRhTW9kZWwuc2V0U2VsZWN0ZWROb2Rlcyhbbm9kZV0pO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICd1bCcsXG4gICAgICAgICAgICB7IGNsYXNzTmFtZTogdGhpcy5wcm9wcy5jbGFzc05hbWUgfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRHJhZ0Ryb3BUcmVlTm9kZSwge1xuICAgICAgICAgICAgICAgIGNoaWxkcmVuT25seTogIXRoaXMucHJvcHMuc2hvd1Jvb3QsXG4gICAgICAgICAgICAgICAgZm9yY2VFeHBhbmQ6IHRoaXMucHJvcHMuZm9yY2VFeHBhbmQsXG4gICAgICAgICAgICAgICAgbm9kZTogdGhpcy5wcm9wcy5ub2RlID8gdGhpcy5wcm9wcy5ub2RlIDogdGhpcy5wcm9wcy5kYXRhTW9kZWwuZ2V0Um9vdE5vZGUoKSxcbiAgICAgICAgICAgICAgICBkYXRhTW9kZWw6IHRoaXMucHJvcHMuZGF0YU1vZGVsLFxuICAgICAgICAgICAgICAgIG9uTm9kZVNlbGVjdDogdGhpcy5vbk5vZGVTZWxlY3QsXG4gICAgICAgICAgICAgICAgbm9kZUlzU2VsZWN0ZWQ6IHRoaXMucHJvcHMubm9kZUlzU2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgZm9yY2VMYWJlbDogdGhpcy5wcm9wcy5yb290TGFiZWwsXG4gICAgICAgICAgICAgICAgY2hlY2tib3hlczogdGhpcy5wcm9wcy5jaGVja2JveGVzLFxuICAgICAgICAgICAgICAgIGNoZWNrYm94ZXNWYWx1ZXM6IHRoaXMucHJvcHMuY2hlY2tib3hlc1ZhbHVlcyxcbiAgICAgICAgICAgICAgICBjaGVja2JveGVzQ29tcHV0ZVN0YXR1czogdGhpcy5wcm9wcy5jaGVja2JveGVzQ29tcHV0ZVN0YXR1cyxcbiAgICAgICAgICAgICAgICBvbkNoZWNrYm94Q2hlY2s6IHRoaXMucHJvcHMub25DaGVja2JveENoZWNrLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkSXRlbVN0eWxlOiB0aGlzLnByb3BzLnNlbGVjdGVkSXRlbVN0eWxlLFxuICAgICAgICAgICAgICAgIGdldEl0ZW1TdHlsZTogdGhpcy5wcm9wcy5nZXRJdGVtU3R5bGVcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5cbnZhciBUcmVlVmlldyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ1RyZWVWaWV3JyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBzaG93Um9vdDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIHJvb3RMYWJlbDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgb25Ob2RlU2VsZWN0OiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgbm9kZTogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoQWp4cE5vZGUpLmlzUmVxdWlyZWQsXG4gICAgICAgIGRhdGFNb2RlbDogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW9EYXRhTW9kZWwpLmlzUmVxdWlyZWQsXG4gICAgICAgIHNlbGVjdGFibGU6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBzZWxlY3RhYmxlTXVsdGlwbGU6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBpbml0aWFsU2VsZWN0aW9uTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcbiAgICAgICAgb25TZWxlY3Rpb25DaGFuZ2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBmb3JjZUV4cGFuZDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIC8vIE9wdGlvbmFsIGN1cnJlbnRseSBzZWxlY3RlZCBkZXRlY3Rpb25cbiAgICAgICAgbm9kZUlzU2VsZWN0ZWQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICAvLyBPcHRpb25hbCBjaGVja2JveGVzXG4gICAgICAgIGNoZWNrYm94ZXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcbiAgICAgICAgY2hlY2tib3hlc1ZhbHVlczogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgY2hlY2tib3hlc0NvbXB1dGVTdGF0dXM6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvbkNoZWNrYm94Q2hlY2s6IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgfSxcblxuICAgIGdldERlZmF1bHRQcm9wczogZnVuY3Rpb24gZ2V0RGVmYXVsdFByb3BzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2hvd1Jvb3Q6IHRydWUsXG4gICAgICAgICAgICBvbk5vZGVTZWxlY3Q6IHRoaXMub25Ob2RlU2VsZWN0XG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIG9uTm9kZVNlbGVjdDogZnVuY3Rpb24gb25Ob2RlU2VsZWN0KG5vZGUpIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25Ob2RlU2VsZWN0KSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uTm9kZVNlbGVjdChub2RlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuZGF0YU1vZGVsLnNldFNlbGVjdGVkTm9kZXMoW25vZGVdKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAndWwnLFxuICAgICAgICAgICAgeyBjbGFzc05hbWU6IHRoaXMucHJvcHMuY2xhc3NOYW1lIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFNpbXBsZVRyZWVOb2RlLCB7XG4gICAgICAgICAgICAgICAgY2hpbGRyZW5Pbmx5OiAhdGhpcy5wcm9wcy5zaG93Um9vdCxcbiAgICAgICAgICAgICAgICBmb3JjZUV4cGFuZDogdGhpcy5wcm9wcy5mb3JjZUV4cGFuZCxcbiAgICAgICAgICAgICAgICBub2RlOiB0aGlzLnByb3BzLm5vZGUgPyB0aGlzLnByb3BzLm5vZGUgOiB0aGlzLnByb3BzLmRhdGFNb2RlbC5nZXRSb290Tm9kZSgpLFxuICAgICAgICAgICAgICAgIGRhdGFNb2RlbDogdGhpcy5wcm9wcy5kYXRhTW9kZWwsXG4gICAgICAgICAgICAgICAgb25Ob2RlU2VsZWN0OiB0aGlzLm9uTm9kZVNlbGVjdCxcbiAgICAgICAgICAgICAgICBub2RlSXNTZWxlY3RlZDogdGhpcy5wcm9wcy5ub2RlSXNTZWxlY3RlZCxcbiAgICAgICAgICAgICAgICBmb3JjZUxhYmVsOiB0aGlzLnByb3BzLnJvb3RMYWJlbCxcbiAgICAgICAgICAgICAgICBjaGVja2JveGVzOiB0aGlzLnByb3BzLmNoZWNrYm94ZXMsXG4gICAgICAgICAgICAgICAgY2hlY2tib3hlc1ZhbHVlczogdGhpcy5wcm9wcy5jaGVja2JveGVzVmFsdWVzLFxuICAgICAgICAgICAgICAgIGNoZWNrYm94ZXNDb21wdXRlU3RhdHVzOiB0aGlzLnByb3BzLmNoZWNrYm94ZXNDb21wdXRlU3RhdHVzLFxuICAgICAgICAgICAgICAgIG9uQ2hlY2tib3hDaGVjazogdGhpcy5wcm9wcy5vbkNoZWNrYm94Q2hlY2ssXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRJdGVtU3R5bGU6IHRoaXMucHJvcHMuc2VsZWN0ZWRJdGVtU3R5bGUsXG4gICAgICAgICAgICAgICAgZ2V0SXRlbVN0eWxlOiB0aGlzLnByb3BzLmdldEl0ZW1TdHlsZVxuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9XG5cbn0pO1xuXG52YXIgRm9sZGVyc1RyZWUgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdGb2xkZXJzVHJlZScsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgcHlkaW86IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFB5ZGlvKS5pc1JlcXVpcmVkLFxuICAgICAgICBkYXRhTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFB5ZGlvRGF0YU1vZGVsKS5pc1JlcXVpcmVkLFxuICAgICAgICBjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIG9uTm9kZVNlbGVjdGVkOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgZHJhZ2dhYmxlOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbFxuICAgIH0sXG5cbiAgICBub2RlT2JzZXJ2ZXI6IGZ1bmN0aW9uIG5vZGVPYnNlcnZlcigpIHtcbiAgICAgICAgdmFyIHIgPSB0aGlzLnByb3BzLmRhdGFNb2RlbC5nZXRSb290Tm9kZSgpO1xuICAgICAgICBpZiAoIXIuaXNMb2FkZWQoKSkge1xuICAgICAgICAgICAgci5vYnNlcnZlT25jZShcImxvYWRlZFwiLCAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZm9yY2VVcGRhdGUoKTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5mb3JjZVVwZGF0ZSgpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgdmFyIGRtID0gdGhpcy5wcm9wcy5kYXRhTW9kZWw7XG4gICAgICAgIHRoaXMuX2RtT2JzID0gdGhpcy5ub2RlT2JzZXJ2ZXI7XG4gICAgICAgIGRtLm9ic2VydmUoXCJjb250ZXh0X2NoYW5nZWRcIiwgdGhpcy5fZG1PYnMpO1xuICAgICAgICBkbS5vYnNlcnZlKFwicm9vdF9ub2RlX2NoYW5nZWRcIiwgdGhpcy5fZG1PYnMpO1xuICAgICAgICB0aGlzLm5vZGVPYnNlcnZlcigpO1xuICAgIH0sXG5cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudDogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9kbU9icykge1xuICAgICAgICAgICAgdmFyIGRtID0gdGhpcy5wcm9wcy5kYXRhTW9kZWw7XG4gICAgICAgICAgICBkbS5zdG9wT2JzZXJ2aW5nKFwiY29udGV4dF9jaGFuZ2VkXCIsIHRoaXMuX2RtT2JzKTtcbiAgICAgICAgICAgIGRtLnN0b3BPYnNlcnZpbmcoXCJyb290X25vZGVfY2hhbmdlZFwiLCB0aGlzLl9kbU9icyk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgdHJlZU5vZGVTZWxlY3RlZDogZnVuY3Rpb24gdHJlZU5vZGVTZWxlY3RlZChuKSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uTm9kZVNlbGVjdGVkKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uTm9kZVNlbGVjdGVkKG4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5kYXRhTW9kZWwucmVxdWlyZUNvbnRleHRDaGFuZ2Uobik7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgbm9kZUlzU2VsZWN0ZWQ6IGZ1bmN0aW9uIG5vZGVJc1NlbGVjdGVkKG4pIHtcbiAgICAgICAgcmV0dXJuIG4gPT09IHRoaXMucHJvcHMuZGF0YU1vZGVsLmdldENvbnRleHROb2RlKCk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5kcmFnZ2FibGUpIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFB5ZGlvQ29tcG9uZW50cy5ETkRUcmVlVmlldywge1xuICAgICAgICAgICAgICAgIG9uTm9kZVNlbGVjdDogdGhpcy50cmVlTm9kZVNlbGVjdGVkLFxuICAgICAgICAgICAgICAgIG5vZGVJc1NlbGVjdGVkOiB0aGlzLm5vZGVJc1NlbGVjdGVkLFxuICAgICAgICAgICAgICAgIGRhdGFNb2RlbDogdGhpcy5wcm9wcy5kYXRhTW9kZWwsXG4gICAgICAgICAgICAgICAgbm9kZTogdGhpcy5wcm9wcy5kYXRhTW9kZWwuZ2V0Um9vdE5vZGUoKSxcbiAgICAgICAgICAgICAgICBzaG93Um9vdDogdGhpcy5wcm9wcy5zaG93Um9vdCA/IHRydWUgOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEl0ZW1TdHlsZTogdGhpcy5wcm9wcy5zZWxlY3RlZEl0ZW1TdHlsZSxcbiAgICAgICAgICAgICAgICBnZXRJdGVtU3R5bGU6IHRoaXMucHJvcHMuZ2V0SXRlbVN0eWxlLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJmb2xkZXJzLXRyZWVcIiArICh0aGlzLnByb3BzLmNsYXNzTmFtZSA/ICcgJyArIHRoaXMucHJvcHMuY2xhc3NOYW1lIDogJycpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFB5ZGlvQ29tcG9uZW50cy5UcmVlVmlldywge1xuICAgICAgICAgICAgICAgIG9uTm9kZVNlbGVjdDogdGhpcy50cmVlTm9kZVNlbGVjdGVkLFxuICAgICAgICAgICAgICAgIG5vZGVJc1NlbGVjdGVkOiB0aGlzLm5vZGVJc1NlbGVjdGVkLFxuICAgICAgICAgICAgICAgIGRhdGFNb2RlbDogdGhpcy5wcm9wcy5kYXRhTW9kZWwsXG4gICAgICAgICAgICAgICAgbm9kZTogdGhpcy5wcm9wcy5kYXRhTW9kZWwuZ2V0Um9vdE5vZGUoKSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEl0ZW1TdHlsZTogdGhpcy5wcm9wcy5zZWxlY3RlZEl0ZW1TdHlsZSxcbiAgICAgICAgICAgICAgICBnZXRJdGVtU3R5bGU6IHRoaXMucHJvcHMuZ2V0SXRlbVN0eWxlLFxuICAgICAgICAgICAgICAgIHNob3dSb290OiB0aGlzLnByb3BzLnNob3dSb290ID8gdHJ1ZSA6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJmb2xkZXJzLXRyZWVcIiArICh0aGlzLnByb3BzLmNsYXNzTmFtZSA/ICcgJyArIHRoaXMucHJvcHMuY2xhc3NOYW1lIDogJycpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxufSk7XG5cbmV4cG9ydHMuVHJlZVZpZXcgPSBUcmVlVmlldztcbmV4cG9ydHMuRE5EVHJlZVZpZXcgPSBETkRUcmVlVmlldztcbmV4cG9ydHMuRm9sZGVyc1RyZWUgPSBGb2xkZXJzVHJlZTtcbiJdfQ==