(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){function n(){throw new Error("setTimeout has not been defined")}function o(){throw new Error("clearTimeout has not been defined")}function r(e){if(c===setTimeout)return setTimeout(e,0);if((c===n||!c)&&setTimeout)return c=setTimeout,setTimeout(e,0);try{return c(e,0)}catch(t){try{return c.call(null,e,0)}catch(t){return c.call(this,e,0)}}}function i(e){if(f===clearTimeout)return clearTimeout(e);if((f===o||!f)&&clearTimeout)return f=clearTimeout,clearTimeout(e);try{return f(e)}catch(t){try{return f.call(null,e)}catch(t){return f.call(this,e)}}}function a(){y&&d&&(y=!1,d.length?h=d.concat(h):v=-1,h.length&&l())}function l(){if(!y){var e=r(a);y=!0;for(var t=h.length;t;){for(d=h,h=[];++v1)for(var n=1;nt.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},g.api)}}},{key:"scrollXTo",value:function(e){if(this.canScrollX()){var t=this.normalizeLeftPosition(e,this.computeSizes());this.setStateFromEvent({leftPosition:t},g.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:"canScroll",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.state;return this.canScrollY(e)||this.canScrollX(e)}},{key:"getModifiedPositionsIfNeeded",value:function(e){var t=e.realHeight-e.containerHeight;this.state.topPosition>=t&&(e.topPosition=this.canScrollY(e)?(0,m.positiveOrZero)(t):0);var n=e.realWidth-e.containerWidth;return this.state.leftPosition>=n&&(e.leftPosition=this.canScrollX(e)?(0,m.positiveOrZero)(n):0),e}},{key:"focusContent",value:function(){this.content&&(0,m.findDOMNode)(this.content).focus()}}]),t}(f.default.Component);t.default=w,w.childContextTypes={scrollArea:d.default.object},w.propTypes={className:d.default.string,style:d.default.object,speed:d.default.number,contentClassName:d.default.string,contentStyle:d.default.object,vertical:d.default.bool,verticalContainerStyle:d.default.object,verticalScrollbarStyle:d.default.object,horizontal:d.default.bool,horizontalContainerStyle:d.default.object,horizontalScrollbarStyle:d.default.object,onScroll:d.default.func,contentWindow:d.default.any,ownerDocument:d.default.any,smoothScrolling:d.default.bool,minScrollSize:d.default.number,swapWheelAxes:d.default.bool,stopScrollPropagation:d.default.bool,focusableTabIndex:d.default.number},w.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;t10*k&&(o.accumulatedTime=0),0===o.accumulatedTime)return o.animationID=null,void o.startAnimationIfNecessary();var i=(o.accumulatedTime-Math.floor(o.accumulatedTime/k)*k)/k,a=Math.floor(o.accumulatedTime/k),l={},s={},u={},c={};for(var f in t)if(Object.prototype.hasOwnProperty.call(t,f)){var p=t[f];if("number"==typeof p)u[f]=p,c[f]=0,l[f]=p,s[f]=0;else{for(var h=o.state.lastIdealStyle[f],v=o.state.lastIdealVelocity[f],m=0;m10*O&&(o.accumulatedTime=0),0===o.accumulatedTime)return o.animationID=null,void o.startAnimationIfNecessary();for(var i=(o.accumulatedTime-Math.floor(o.accumulatedTime/O)*O)/O,l=Math.floor(o.accumulatedTime/O),s=[],u=[],c=[],f=[],p=0;p10*D&&(o.accumulatedTime=0),0===o.accumulatedTime)return o.animationID=null,void o.startAnimationIfNecessary();for(var u=(o.accumulatedTime-Math.floor(o.accumulatedTime/D)*D)/D,c=Math.floor(o.accumulatedTime/D),f=s(o.props.willEnter,o.props.willLeave,o.props.didLeave,o.state.mergedPropsStyles,n,o.state.currentStyles,o.state.currentVelocities,o.state.lastIdealStyles,o.state.lastIdealVelocities),p=f[0],d=f[1],h=f[2],y=f[3],m=f[4],b=0;bo[c])return-1;if(r>i[c]&&so[c])return 1;if(a>i[c]&&l=0&&S.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=b++;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=g(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,b=0,S=[];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, onClick: function onClick(e) { return e.stopPropagation(); } }; 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; } // Firefox trigger a click event when you mouse up on contextmenu event if (typeof event !== 'undefined' && event.button === 2 && event.type !== 'contextmenu') { 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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtc2Nyb2xsYmFyL2Rpc3Qvc2Nyb2xsQXJlYS5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2R5bmFtaWMtZ3JpZC9EeW5hbWljR3JpZC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2R5bmFtaWMtZ3JpZC9HcmlkQnVpbGRlci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2R5bmFtaWMtZ3JpZC9HcmlkSXRlbU1peGluLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvZHluYW1pYy1ncmlkL1N0b3JlLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvZHluYW1pYy1ncmlkL2FzR3JpZEl0ZW0uanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lZGl0b3IvUGFwZXJFZGl0b3IuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lZGl0b3IvUmVhY3RFZGl0b3JPcGVuZXIuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lbGVtZW50cy9DbGlwYm9hcmRUZXh0RmllbGQuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lbGVtZW50cy9MYWJlbFdpdGhUaXAuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lbGVtZW50cy9TaW1wbGVGaWd1cmVCYWRnZS5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2luZGV4LmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvbGlzdC9Db25maWd1cmFibGVMaXN0RW50cnkuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9saXN0L0lubGluZUVkaXRvci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvTGlzdEVudHJ5LmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvbGlzdC9MaXN0RW50cnlOb2RlTGlzdGVuZXJNaXhpbi5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvTGlzdFBhZ2luYXRvci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvTm9kZUxpc3RDdXN0b21Qcm92aWRlci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvU2ltcGxlTGlzdC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvU29ydENvbHVtbnMuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9saXN0L1NvcnRhYmxlTGlzdC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvVGFibGVMaXN0RW50cnkuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9saXN0L1RhYmxlTGlzdEhlYWRlci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvQnV0dG9uTWVudS5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvQ29udGV4dE1lbnUuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9tZW51L0ljb25CdXR0b25NZW51LmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvbWVudS9JY29uQnV0dG9uUG9wb3Zlci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvTWVudUl0ZW1zQ29uc3VtZXIuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9tZW51L1BvcHVwTWVudS5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvVG9vbGJhci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvVXRpbHMuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91c2Vycy9UZWFtQ3JlYXRpb25Gb3JtLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvVXNlcnNDb21wbGV0ZXIuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91c2Vycy9hZGRyZXNzYm9vay9BZGRyZXNzQm9vay5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3VzZXJzL2FkZHJlc3Nib29rL0FscGhhUGFnaW5hdG9yLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYWRkcmVzc2Jvb2svTG9hZGVycy5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3VzZXJzL2FkZHJlc3Nib29rL05lc3RlZExpc3RJdGVtLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYWRkcmVzc2Jvb2svUmlnaHRQYW5lbENhcmQuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91c2Vycy9hZGRyZXNzYm9vay9TZWFyY2hGb3JtLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYWRkcmVzc2Jvb2svU2VhcmNoUGFuZWwuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91c2Vycy9hZGRyZXNzYm9vay9UZWFtQ2FyZC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3VzZXJzL2FkZHJlc3Nib29rL1VzZXJDYXJkLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYWRkcmVzc2Jvb2svVXNlcnNMaXN0LmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYXZhdGFyL0FjdGlvbnNQYW5lbC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3VzZXJzL2F2YXRhci9HcmFwaFBhbmVsLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYXZhdGFyL1VzZXJBdmF0YXIuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91dGlsL0RORC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3V0aWwvTWVzc2FnZXNDb25zdW1lck1peGluLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdmlld3MvRW1wdHlTdGF0ZVZpZXcuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy92aWV3cy9Nb2RhbEFwcEJhci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3ZpZXdzL1NlYXJjaEJveC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3ZpZXdzL1NpbXBsZVJlYWN0QWN0aW9uQmFyLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdmlld3MvVHJlZVZpZXcuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBOzs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3pUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN4TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM5RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQy95Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL09BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNySUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDdldBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwb0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDektBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9KQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIiFmdW5jdGlvbihlLHQpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPXQocmVxdWlyZShcInJlYWN0XCIpKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtcInJlYWN0XCJdLHQpOlwib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzP2V4cG9ydHMuU2Nyb2xsQXJlYT10KHJlcXVpcmUoXCJyZWFjdFwiKSk6ZS5TY3JvbGxBcmVhPXQoZS5SZWFjdCl9KHRoaXMsZnVuY3Rpb24oZSl7cmV0dXJuIGZ1bmN0aW9uKGUpe2Z1bmN0aW9uIHQobyl7aWYobltvXSlyZXR1cm4gbltvXS5leHBvcnRzO3ZhciByPW5bb109e2V4cG9ydHM6e30saWQ6byxsb2FkZWQ6ITF9O3JldHVybiBlW29dLmNhbGwoci5leHBvcnRzLHIsci5leHBvcnRzLHQpLHIubG9hZGVkPSEwLHIuZXhwb3J0c312YXIgbj17fTtyZXR1cm4gdC5tPWUsdC5jPW4sdC5wPVwiXCIsdCgwKX0oW2Z1bmN0aW9uKGUsdCxuKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBvKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX1PYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIl9fZXNNb2R1bGVcIix7dmFsdWU6ITB9KSxuKDMxKTt2YXIgcj1uKDEzKSxpPW8ocik7dC5kZWZhdWx0PWkuZGVmYXVsdH0sZnVuY3Rpb24odCxuKXt0LmV4cG9ydHM9ZX0sZnVuY3Rpb24oZSx0LG4pe2UuZXhwb3J0cz1uKDE5KSgpfSxmdW5jdGlvbihlLHQpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG4oZSl7dmFyIHQ9e307Zm9yKHZhciBuIGluIGUpT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGUsbikmJih0W25dPVwibnVtYmVyXCI9PXR5cGVvZiBlW25dP2Vbbl06ZVtuXS52YWwpO3JldHVybiB0fXQuX19lc01vZHVsZT0hMCx0LmRlZmF1bHQ9bixlLmV4cG9ydHM9dC5kZWZhdWx0fSxmdW5jdGlvbihlLHQsbil7KGZ1bmN0aW9uKHQpeyhmdW5jdGlvbigpe3ZhciBuLG8scjtcInVuZGVmaW5lZFwiIT10eXBlb2YgcGVyZm9ybWFuY2UmJm51bGwhPT1wZXJmb3JtYW5jZSYmcGVyZm9ybWFuY2Uubm93P2UuZXhwb3J0cz1mdW5jdGlvbigpe3JldHVybiBwZXJmb3JtYW5jZS5ub3coKX06XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQmJm51bGwhPT10JiZ0LmhydGltZT8oZS5leHBvcnRzPWZ1bmN0aW9uKCl7cmV0dXJuKG4oKS1yKS8xZTZ9LG89dC5ocnRpbWUsbj1mdW5jdGlvbigpe3ZhciBlO3JldHVybiBlPW8oKSwxZTkqZVswXStlWzFdfSxyPW4oKSk6RGF0ZS5ub3c/KGUuZXhwb3J0cz1mdW5jdGlvbigpe3JldHVybiBEYXRlLm5vdygpLXJ9LHI9RGF0ZS5ub3coKSk6KGUuZXhwb3J0cz1mdW5jdGlvbigpe3JldHVybihuZXcgRGF0ZSkuZ2V0VGltZSgpLXJ9LHI9KG5ldyBEYXRlKS5nZXRUaW1lKCkpfSkuY2FsbCh0aGlzKX0pLmNhbGwodCxuKDEwKSl9LGZ1bmN0aW9uKGUsdCxuKXsoZnVuY3Rpb24odCl7Zm9yKHZhciBvPW4oMjMpLHI9XCJ1bmRlZmluZWRcIj09dHlwZW9mIHdpbmRvdz90OndpbmRvdyxpPVtcIm1velwiLFwid2Via2l0XCJdLGE9XCJBbmltYXRpb25GcmFtZVwiLGw9cltcInJlcXVlc3RcIithXSxzPXJbXCJjYW5jZWxcIithXXx8cltcImNhbmNlbFJlcXVlc3RcIithXSx1PTA7IWwmJnU8aS5sZW5ndGg7dSsrKWw9cltpW3VdK1wiUmVxdWVzdFwiK2FdLHM9cltpW3VdK1wiQ2FuY2VsXCIrYV18fHJbaVt1XStcIkNhbmNlbFJlcXVlc3RcIithXTtpZighbHx8IXMpe3ZhciBjPTAsZj0wLHA9W10sZD0xZTMvNjA7bD1mdW5jdGlvbihlKXtpZigwPT09cC5sZW5ndGgpe3ZhciB0PW8oKSxuPU1hdGgubWF4KDAsZC0odC1jKSk7Yz1uK3Qsc2V0VGltZW91dChmdW5jdGlvbigpe3ZhciBlPXAuc2xpY2UoMCk7cC5sZW5ndGg9MDtmb3IodmFyIHQ9MDt0PGUubGVuZ3RoO3QrKylpZighZVt0XS5jYW5jZWxsZWQpdHJ5e2VbdF0uY2FsbGJhY2soYyl9Y2F0Y2goZSl7c2V0VGltZW91dChmdW5jdGlvbigpe3Rocm93IGV9LDApfX0sTWF0aC5yb3VuZChuKSl9cmV0dXJuIHAucHVzaCh7aGFuZGxlOisrZixjYWxsYmFjazplLGNhbmNlbGxlZDohMX0pLGZ9LHM9ZnVuY3Rpb24oZSl7Zm9yKHZhciB0PTA7dDxwLmxlbmd0aDt0KyspcFt0XS5oYW5kbGU9PT1lJiYocFt0XS5jYW5jZWxsZWQ9ITApfX1lLmV4cG9ydHM9ZnVuY3Rpb24oZSl7cmV0dXJuIGwuY2FsbChyLGUpfSxlLmV4cG9ydHMuY2FuY2VsPWZ1bmN0aW9uKCl7cy5hcHBseShyLGFyZ3VtZW50cyl9LGUuZXhwb3J0cy5wb2x5ZmlsbD1mdW5jdGlvbihlKXtlfHwoZT1yKSxlLnJlcXVlc3RBbmltYXRpb25GcmFtZT1sLGUuY2FuY2VsQW5pbWF0aW9uRnJhbWU9c319KS5jYWxsKHQsZnVuY3Rpb24oKXtyZXR1cm4gdGhpc30oKSl9LGZ1bmN0aW9uKGUsdCl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbihlKXt2YXIgdD17fTtmb3IodmFyIG4gaW4gZSlPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZSxuKSYmKHRbbl09MCk7cmV0dXJuIHR9dC5fX2VzTW9kdWxlPSEwLHQuZGVmYXVsdD1uLGUuZXhwb3J0cz10LmRlZmF1bHR9LGZ1bmN0aW9uKGUsdCl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbihlLHQsbil7Zm9yKHZhciBvIGluIHQpaWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQsbykpe2lmKDAhPT1uW29dKXJldHVybiExO3ZhciByPVwibnVtYmVyXCI9PXR5cGVvZiB0W29dP3Rbb106dFtvXS52YWw7aWYoZVtvXSE9PXIpcmV0dXJuITF9cmV0dXJuITB9dC5fX2VzTW9kdWxlPSEwLHQuZGVmYXVsdD1uLGUuZXhwb3J0cz10LmRlZmF1bHR9LGZ1bmN0aW9uKGUsdCl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbihlLHQsbixyLGksYSxsKXt2YXIgcz0taSoodC1yKSx1PS1hKm4sYz1zK3UsZj1uK2MqZSxwPXQrZiplO3JldHVybiBNYXRoLmFicyhmKTxsJiZNYXRoLmFicyhwLXIpPGw/KG9bMF09cixvWzFdPTAsbyk6KG9bMF09cCxvWzFdPWYsbyl9dC5fX2VzTW9kdWxlPSEwLHQuZGVmYXVsdD1uO3ZhciBvPVswLDBdO2UuZXhwb3J0cz10LmRlZmF1bHR9LGZ1bmN0aW9uKGUsdCxuKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBvKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX1mdW5jdGlvbiByKGUpe3JldHVybiBwP2YuZGVmYXVsdC5maW5kRE9NTm9kZShlKTplfWZ1bmN0aW9uIGkoKXtkfHxwfHwoZD0hMCxjb25zb2xlLmVycm9yKFwiV2l0aCBSZWFjdCAwLjE0IGFuZCBsYXRlciB2ZXJzaW9ucywgeW91IG5vIGxvbmdlciBuZWVkIHRvIHdyYXAgPFNjcm9sbEFyZWE+IGNoaWxkIGludG8gYSBmdW5jdGlvbi5cIikpfWZ1bmN0aW9uIGEoKXshZCYmcCYmKGQ9ITAsY29uc29sZS5lcnJvcihcIldpdGggUmVhY3QgMC4xMywgeW91IG5lZWQgdG8gd3JhcCA8U2Nyb2xsQXJlYT4gY2hpbGQgaW50byBhIGZ1bmN0aW9uLlwiKSl9ZnVuY3Rpb24gbChlKXtyZXR1cm4gZTwwPzA6ZX1mdW5jdGlvbiBzKGUpe3ZhciB0PWFyZ3VtZW50cy5sZW5ndGg+MSYmdm9pZCAwIT09YXJndW1lbnRzWzFdP2FyZ3VtZW50c1sxXTpmdW5jdGlvbihlKXtyZXR1cm4gZX0sbj17fTtmb3IodmFyIG8gaW4gZSllLmhhc093blByb3BlcnR5KG8pJiYobltvXT10KGVbb10pKTtyZXR1cm4gbn1mdW5jdGlvbiB1KGUpe3ZhciB0PWUudmVyc2lvbjtpZihcInN0cmluZ1wiIT10eXBlb2YgdClyZXR1cm4hMDt2YXIgbj10LnNwbGl0KFwiLlwiKSxvPXBhcnNlSW50KG5bMF0sMTApLHI9cGFyc2VJbnQoblsxXSwxMCk7cmV0dXJuIDA9PT1vJiYxMz09PXJ9T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSksdC5maW5kRE9NTm9kZT1yLHQud2FybkFib3V0RnVuY3Rpb25DaGlsZD1pLHQud2FybkFib3V0RWxlbWVudENoaWxkPWEsdC5wb3NpdGl2ZU9yWmVybz1sLHQubW9kaWZ5T2JqVmFsdWVzPXMsdC5pc1JlYWN0MTM9dTt2YXIgYz1uKDEpLGY9byhjKSxwPXUoZi5kZWZhdWx0KSxkPSExfSxmdW5jdGlvbihlLHQpe2Z1bmN0aW9uIG4oKXt0aHJvdyBuZXcgRXJyb3IoXCJzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkXCIpfWZ1bmN0aW9uIG8oKXt0aHJvdyBuZXcgRXJyb3IoXCJjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWRcIil9ZnVuY3Rpb24gcihlKXtpZihjPT09c2V0VGltZW91dClyZXR1cm4gc2V0VGltZW91dChlLDApO2lmKChjPT09bnx8IWMpJiZzZXRUaW1lb3V0KXJldHVybiBjPXNldFRpbWVvdXQsc2V0VGltZW91dChlLDApO3RyeXtyZXR1cm4gYyhlLDApfWNhdGNoKHQpe3RyeXtyZXR1cm4gYy5jYWxsKG51bGwsZSwwKX1jYXRjaCh0KXtyZXR1cm4gYy5jYWxsKHRoaXMsZSwwKX19fWZ1bmN0aW9uIGkoZSl7aWYoZj09PWNsZWFyVGltZW91dClyZXR1cm4gY2xlYXJUaW1lb3V0KGUpO2lmKChmPT09b3x8IWYpJiZjbGVhclRpbWVvdXQpcmV0dXJuIGY9Y2xlYXJUaW1lb3V0LGNsZWFyVGltZW91dChlKTt0cnl7cmV0dXJuIGYoZSl9Y2F0Y2godCl7dHJ5e3JldHVybiBmLmNhbGwobnVsbCxlKX1jYXRjaCh0KXtyZXR1cm4gZi5jYWxsKHRoaXMsZSl9fX1mdW5jdGlvbiBhKCl7eSYmZCYmKHk9ITEsZC5sZW5ndGg/aD1kLmNvbmNhdChoKTp2PS0xLGgubGVuZ3RoJiZsKCkpfWZ1bmN0aW9uIGwoKXtpZigheSl7dmFyIGU9cihhKTt5PSEwO2Zvcih2YXIgdD1oLmxlbmd0aDt0Oyl7Zm9yKGQ9aCxoPVtdOysrdjx0OylkJiZkW3ZdLnJ1bigpO3Y9LTEsdD1oLmxlbmd0aH1kPW51bGwseT0hMSxpKGUpfX1mdW5jdGlvbiBzKGUsdCl7dGhpcy5mdW49ZSx0aGlzLmFycmF5PXR9ZnVuY3Rpb24gdSgpe312YXIgYyxmLHA9ZS5leHBvcnRzPXt9OyFmdW5jdGlvbigpe3RyeXtjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHNldFRpbWVvdXQ/c2V0VGltZW91dDpufWNhdGNoKGUpe2M9bn10cnl7Zj1cImZ1bmN0aW9uXCI9PXR5cGVvZiBjbGVhclRpbWVvdXQ/Y2xlYXJUaW1lb3V0Om99Y2F0Y2goZSl7Zj1vfX0oKTt2YXIgZCxoPVtdLHk9ITEsdj0tMTtwLm5leHRUaWNrPWZ1bmN0aW9uKGUpe3ZhciB0PW5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoLTEpO2lmKGFyZ3VtZW50cy5sZW5ndGg+MSlmb3IodmFyIG49MTtuPGFyZ3VtZW50cy5sZW5ndGg7bisrKXRbbi0xXT1hcmd1bWVudHNbbl07aC5wdXNoKG5ldyBzKGUsdCkpLDEhPT1oLmxlbmd0aHx8eXx8cihsKX0scy5wcm90b3R5cGUucnVuPWZ1bmN0aW9uKCl7dGhpcy5mdW4uYXBwbHkobnVsbCx0aGlzLmFycmF5KX0scC50aXRsZT1cImJyb3dzZXJcIixwLmJyb3dzZXI9ITAscC5lbnY9e30scC5hcmd2PVtdLHAudmVyc2lvbj1cIlwiLHAudmVyc2lvbnM9e30scC5vbj11LHAuYWRkTGlzdGVuZXI9dSxwLm9uY2U9dSxwLm9mZj11LHAucmVtb3ZlTGlzdGVuZXI9dSxwLnJlbW92ZUFsbExpc3RlbmVycz11LHAuZW1pdD11LHAuYmluZGluZz1mdW5jdGlvbihlKXt0aHJvdyBuZXcgRXJyb3IoXCJwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZFwiKX0scC5jd2Q9ZnVuY3Rpb24oKXtyZXR1cm5cIi9cIn0scC5jaGRpcj1mdW5jdGlvbihlKXt0aHJvdyBuZXcgRXJyb3IoXCJwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWRcIil9LHAudW1hc2s9ZnVuY3Rpb24oKXtyZXR1cm4gMH19LGZ1bmN0aW9uKGUsdCl7XCJ1c2Ugc3RyaWN0XCI7dC5fX2VzTW9kdWxlPSEwLHQuZGVmYXVsdD17bm9Xb2JibGU6e3N0aWZmbmVzczoxNzAsZGFtcGluZzoyNn0sZ2VudGxlOntzdGlmZm5lc3M6MTIwLGRhbXBpbmc6MTR9LHdvYmJseTp7c3RpZmZuZXNzOjE4MCxkYW1waW5nOjEyfSxzdGlmZjp7c3RpZmZuZXNzOjIxMCxkYW1waW5nOjIwfX0sZS5leHBvcnRzPXQuZGVmYXVsdH0sZnVuY3Rpb24oZSx0LG4pe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG8oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lLmRlZmF1bHQ6ZX10Ll9fZXNNb2R1bGU9ITA7dmFyIHI9bigyNCk7dC5Nb3Rpb249byhyKTt2YXIgaT1uKDI1KTt0LlN0YWdnZXJlZE1vdGlvbj1vKGkpO3ZhciBhPW4oMjYpO3QuVHJhbnNpdGlvbk1vdGlvbj1vKGEpO3ZhciBsPW4oMjkpO3Quc3ByaW5nPW8obCk7dmFyIHM9bigxMSk7dC5wcmVzZXRzPW8ocyk7dmFyIHU9bigzKTt0LnN0cmlwU3R5bGU9byh1KTt2YXIgYz1uKDI4KTt0LnJlb3JkZXJLZXlzPW8oYyl9LGZ1bmN0aW9uKGUsdCxuKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBvKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX1mdW5jdGlvbiByKGUsdCl7aWYoIShlIGluc3RhbmNlb2YgdCkpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKX1mdW5jdGlvbiBpKGUsdCl7aWYoIWUpdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkXCIpO3JldHVybiF0fHxcIm9iamVjdFwiIT10eXBlb2YgdCYmXCJmdW5jdGlvblwiIT10eXBlb2YgdD9lOnR9ZnVuY3Rpb24gYShlLHQpe2lmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIHQmJm51bGwhPT10KXRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiK3R5cGVvZiB0KTtlLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKHQmJnQucHJvdG90eXBlLHtjb25zdHJ1Y3Rvcjp7dmFsdWU6ZSxlbnVtZXJhYmxlOiExLHdyaXRhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMH19KSx0JiYoT2JqZWN0LnNldFByb3RvdHlwZU9mP09iamVjdC5zZXRQcm90b3R5cGVPZihlLHQpOmUuX19wcm90b19fPXQpfU9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pO3ZhciBsPVwiZnVuY3Rpb25cIj09dHlwZW9mIFN5bWJvbCYmXCJzeW1ib2xcIj09dHlwZW9mIFN5bWJvbC5pdGVyYXRvcj9mdW5jdGlvbihlKXtyZXR1cm4gdHlwZW9mIGV9OmZ1bmN0aW9uKGUpe3JldHVybiBlJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBTeW1ib2wmJmUuY29uc3RydWN0b3I9PT1TeW1ib2wmJmUhPT1TeW1ib2wucHJvdG90eXBlP1wic3ltYm9sXCI6dHlwZW9mIGV9LHM9T2JqZWN0LmFzc2lnbnx8ZnVuY3Rpb24oZSl7Zm9yKHZhciB0PTE7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyl7dmFyIG49YXJndW1lbnRzW3RdO2Zvcih2YXIgbyBpbiBuKU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChuLG8pJiYoZVtvXT1uW29dKX1yZXR1cm4gZX0sdT1mdW5jdGlvbigpe2Z1bmN0aW9uIGUoZSx0KXtmb3IodmFyIG49MDtuPHQubGVuZ3RoO24rKyl7dmFyIG89dFtuXTtvLmVudW1lcmFibGU9by5lbnVtZXJhYmxlfHwhMSxvLmNvbmZpZ3VyYWJsZT0hMCxcInZhbHVlXCJpbiBvJiYoby53cml0YWJsZT0hMCksT2JqZWN0LmRlZmluZVByb3BlcnR5KGUsby5rZXksbyl9fXJldHVybiBmdW5jdGlvbih0LG4sbyl7cmV0dXJuIG4mJmUodC5wcm90b3R5cGUsbiksbyYmZSh0LG8pLHR9fSgpLGM9bigxKSxmPW8oYykscD1uKDIpLGQ9byhwKSxoPW4oMTgpLHk9byhoKSx2PW4oMTIpLG09big5KSxiPW4oMTQpLFM9byhiKSxnPXt3aGVlbDpcIndoZWVsXCIsYXBpOlwiYXBpXCIsdG91Y2g6XCJ0b3VjaFwiLHRvdWNoRW5kOlwidG91Y2hFbmRcIixtb3VzZW1vdmU6XCJtb3VzZW1vdmVcIixrZXlQcmVzczpcImtleXByZXNzXCJ9LHc9ZnVuY3Rpb24oZSl7ZnVuY3Rpb24gdChlKXtyKHRoaXMsdCk7dmFyIG49aSh0aGlzLCh0Ll9fcHJvdG9fX3x8T2JqZWN0LmdldFByb3RvdHlwZU9mKHQpKS5jYWxsKHRoaXMsZSkpO3JldHVybiBuLnN0YXRlPXt0b3BQb3NpdGlvbjowLGxlZnRQb3NpdGlvbjowLHJlYWxIZWlnaHQ6MCxjb250YWluZXJIZWlnaHQ6MCxyZWFsV2lkdGg6MCxjb250YWluZXJXaWR0aDowfSxuLnNjcm9sbEFyZWE9e3JlZnJlc2g6ZnVuY3Rpb24oKXtuLnNldFNpemVzVG9TdGF0ZSgpfSxzY3JvbGxUb3A6ZnVuY3Rpb24oKXtuLnNjcm9sbFRvcCgpfSxzY3JvbGxCb3R0b206ZnVuY3Rpb24oKXtuLnNjcm9sbEJvdHRvbSgpfSxzY3JvbGxZVG86ZnVuY3Rpb24oZSl7bi5zY3JvbGxZVG8oZSl9LHNjcm9sbExlZnQ6ZnVuY3Rpb24oKXtuLnNjcm9sbExlZnQoKX0sc2Nyb2xsUmlnaHQ6ZnVuY3Rpb24oKXtuLnNjcm9sbFJpZ2h0KCl9LHNjcm9sbFhUbzpmdW5jdGlvbihlKXtuLnNjcm9sbFhUbyhlKX19LG4uZXZudHNQcmV2aW91c1ZhbHVlcz17Y2xpZW50WDowLGNsaWVudFk6MCxkZWx0YVg6MCxkZWx0YVk6MH0sbi5iaW5kZWRIYW5kbGVXaW5kb3dSZXNpemU9bi5oYW5kbGVXaW5kb3dSZXNpemUuYmluZChuKSxuLmJpbmRlZEhhbmRsZVdoZWVsPW4uaGFuZGxlV2hlZWwuYmluZChuKSxufXJldHVybiBhKHQsZSksdSh0LFt7a2V5OlwiZ2V0Q2hpbGRDb250ZXh0XCIsdmFsdWU6ZnVuY3Rpb24oKXtyZXR1cm57c2Nyb2xsQXJlYTp0aGlzLnNjcm9sbEFyZWF9fX0se2tleTpcImNvbXBvbmVudERpZE1vdW50XCIsdmFsdWU6ZnVuY3Rpb24oKXt0aGlzLnByb3BzLmNvbnRlbnRXaW5kb3cmJnRoaXMucHJvcHMuY29udGVudFdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicmVzaXplXCIsdGhpcy5iaW5kZWRIYW5kbGVXaW5kb3dSZXNpemUpLHRoaXMubGluZUhlaWdodFB4PSgwLHkuZGVmYXVsdCkoKDAsbS5maW5kRE9NTm9kZSkodGhpcy5jb250ZW50KSksdGhpcy5zZXRTaXplc1RvU3RhdGUoKSx0aGlzLndyYXBwZXIuYWRkRXZlbnRMaXN0ZW5lcihcIndoZWVsXCIsdGhpcy5iaW5kZWRIYW5kbGVXaGVlbCx7cGFzc2l2ZTohMX0pfX0se2tleTpcImNvbXBvbmVudFdpbGxVbm1vdW50XCIsdmFsdWU6ZnVuY3Rpb24oKXt0aGlzLnByb3BzLmNvbnRlbnRXaW5kb3cmJnRoaXMucHJvcHMuY29udGVudFdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwicmVzaXplXCIsdGhpcy5iaW5kZWRIYW5kbGVXaW5kb3dSZXNpemUpLHRoaXMud3JhcHBlci5yZW1vdmVFdmVudExpc3RlbmVyKFwid2hlZWxcIix0aGlzLmJpbmRlZEhhbmRsZVdoZWVsKX19LHtrZXk6XCJjb21wb25lbnREaWRVcGRhdGVcIix2YWx1ZTpmdW5jdGlvbigpe3RoaXMuc2V0U2l6ZXNUb1N0YXRlKCl9fSx7a2V5OlwicmVuZGVyXCIsdmFsdWU6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLHQ9dGhpcy5wcm9wcyxuPXQuY2hpbGRyZW4sbz10LmNsYXNzTmFtZSxyPXQuY29udGVudENsYXNzTmFtZSxpPXQub3duZXJEb2N1bWVudCxhPXRoaXMucHJvcHMuc21vb3RoU2Nyb2xsaW5nJiYodGhpcy5zdGF0ZS5ldmVudFR5cGU9PT1nLndoZWVsfHx0aGlzLnN0YXRlLmV2ZW50VHlwZT09PWcuYXBpfHx0aGlzLnN0YXRlLmV2ZW50VHlwZT09PWcudG91Y2hFbmR8fHRoaXMuc3RhdGUuZXZlbnRUeXBlPT09Zy5rZXlQcmVzcyksbD10aGlzLmNhblNjcm9sbFkoKT9mLmRlZmF1bHQuY3JlYXRlRWxlbWVudChTLmRlZmF1bHQse293bmVyRG9jdW1lbnQ6aSxyZWFsU2l6ZTp0aGlzLnN0YXRlLnJlYWxIZWlnaHQsY29udGFpbmVyU2l6ZTp0aGlzLnN0YXRlLmNvbnRhaW5lckhlaWdodCxwb3NpdGlvbjp0aGlzLnN0YXRlLnRvcFBvc2l0aW9uLG9uTW92ZTp0aGlzLmhhbmRsZVNjcm9sbGJhck1vdmUuYmluZCh0aGlzKSxvblBvc2l0aW9uQ2hhbmdlOnRoaXMuaGFuZGxlU2Nyb2xsYmFyWVBvc2l0aW9uQ2hhbmdlLmJpbmQodGhpcyksY29udGFpbmVyU3R5bGU6dGhpcy5wcm9wcy52ZXJ0aWNhbENvbnRhaW5lclN0eWxlLHNjcm9sbGJhclN0eWxlOnRoaXMucHJvcHMudmVydGljYWxTY3JvbGxiYXJTdHlsZSxzbW9vdGhTY3JvbGxpbmc6YSxtaW5TY3JvbGxTaXplOnRoaXMucHJvcHMubWluU2Nyb2xsU2l6ZSxvbkZvY3VzOnRoaXMuZm9jdXNDb250ZW50LmJpbmQodGhpcyksdHlwZTpcInZlcnRpY2FsXCJ9KTpudWxsLHU9dGhpcy5jYW5TY3JvbGxYKCk/Zi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoUy5kZWZhdWx0LHtvd25lckRvY3VtZW50OmkscmVhbFNpemU6dGhpcy5zdGF0ZS5yZWFsV2lkdGgsY29udGFpbmVyU2l6ZTp0aGlzLnN0YXRlLmNvbnRhaW5lcldpZHRoLHBvc2l0aW9uOnRoaXMuc3RhdGUubGVmdFBvc2l0aW9uLG9uTW92ZTp0aGlzLmhhbmRsZVNjcm9sbGJhck1vdmUuYmluZCh0aGlzKSxvblBvc2l0aW9uQ2hhbmdlOnRoaXMuaGFuZGxlU2Nyb2xsYmFyWFBvc2l0aW9uQ2hhbmdlLmJpbmQodGhpcyksY29udGFpbmVyU3R5bGU6dGhpcy5wcm9wcy5ob3Jpem9udGFsQ29udGFpbmVyU3R5bGUsc2Nyb2xsYmFyU3R5bGU6dGhpcy5wcm9wcy5ob3Jpem9udGFsU2Nyb2xsYmFyU3R5bGUsc21vb3RoU2Nyb2xsaW5nOmEsbWluU2Nyb2xsU2l6ZTp0aGlzLnByb3BzLm1pblNjcm9sbFNpemUsb25Gb2N1czp0aGlzLmZvY3VzQ29udGVudC5iaW5kKHRoaXMpLHR5cGU6XCJob3Jpem9udGFsXCJ9KTpudWxsO1wiZnVuY3Rpb25cIj09dHlwZW9mIG4/KCgwLG0ud2FybkFib3V0RnVuY3Rpb25DaGlsZCkoKSxuPW4oKSk6KDAsbS53YXJuQWJvdXRFbGVtZW50Q2hpbGQpKCk7dmFyIGM9XCJzY3JvbGxhcmVhIFwiKyhvfHxcIlwiKSxwPVwic2Nyb2xsYXJlYS1jb250ZW50IFwiKyhyfHxcIlwiKSxkPXttYXJnaW5Ub3A6LXRoaXMuc3RhdGUudG9wUG9zaXRpb24sbWFyZ2luTGVmdDotdGhpcy5zdGF0ZS5sZWZ0UG9zaXRpb259LGg9YT8oMCxtLm1vZGlmeU9ialZhbHVlcykoZCxmdW5jdGlvbihlKXtyZXR1cm4oMCx2LnNwcmluZykoZSl9KTpkO3JldHVybiBmLmRlZmF1bHQuY3JlYXRlRWxlbWVudCh2Lk1vdGlvbix7c3R5bGU6aH0sZnVuY3Rpb24odCl7cmV0dXJuIGYuZGVmYXVsdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIse3JlZjpmdW5jdGlvbih0KXtyZXR1cm4gZS53cmFwcGVyPXR9LGNsYXNzTmFtZTpjLHN0eWxlOmUucHJvcHMuc3R5bGV9LGYuZGVmYXVsdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIse3JlZjpmdW5jdGlvbih0KXtyZXR1cm4gZS5jb250ZW50PXR9LHN0eWxlOnMoe30sZS5wcm9wcy5jb250ZW50U3R5bGUsdCksY2xhc3NOYW1lOnAsb25Ub3VjaFN0YXJ0OmUuaGFuZGxlVG91Y2hTdGFydC5iaW5kKGUpLG9uVG91Y2hNb3ZlOmUuaGFuZGxlVG91Y2hNb3ZlLmJpbmQoZSksb25Ub3VjaEVuZDplLmhhbmRsZVRvdWNoRW5kLmJpbmQoZSksb25LZXlEb3duOmUuaGFuZGxlS2V5RG93bi5iaW5kKGUpLHRhYkluZGV4OmUucHJvcHMuZm9jdXNhYmxlVGFiSW5kZXh9LG4pLGwsdSl9KX19LHtrZXk6XCJzZXRTdGF0ZUZyb21FdmVudFwiLHZhbHVlOmZ1bmN0aW9uKGUsdCl7dGhpcy5wcm9wcy5vblNjcm9sbCYmdGhpcy5wcm9wcy5vblNjcm9sbChlKSx0aGlzLnNldFN0YXRlKHMoe30sZSx7ZXZlbnRUeXBlOnR9KSl9fSx7a2V5OlwiaGFuZGxlVG91Y2hTdGFydFwiLHZhbHVlOmZ1bmN0aW9uKGUpe3ZhciB0PWUudG91Y2hlcztpZigxPT09dC5sZW5ndGgpe3ZhciBuPXRbMF0sbz1uLmNsaWVudFgscj1uLmNsaWVudFk7dGhpcy5ldmVudFByZXZpb3VzVmFsdWVzPXMoe30sdGhpcy5ldmVudFByZXZpb3VzVmFsdWVzLHtjbGllbnRZOnIsY2xpZW50WDpvLHRpbWVzdGFtcDpEYXRlLm5vdygpfSl9fX0se2tleTpcImhhbmRsZVRvdWNoTW92ZVwiLHZhbHVlOmZ1bmN0aW9uKGUpe3RoaXMuY2FuU2Nyb2xsKCkmJihlLnByZXZlbnREZWZhdWx0KCksZS5zdG9wUHJvcGFnYXRpb24oKSk7dmFyIHQ9ZS50b3VjaGVzO2lmKDE9PT10Lmxlbmd0aCl7dmFyIG49dFswXSxvPW4uY2xpZW50WCxyPW4uY2xpZW50WSxpPXRoaXMuZXZlbnRQcmV2aW91c1ZhbHVlcy5jbGllbnRZLXIsYT10aGlzLmV2ZW50UHJldmlvdXNWYWx1ZXMuY2xpZW50WC1vO3RoaXMuZXZlbnRQcmV2aW91c1ZhbHVlcz1zKHt9LHRoaXMuZXZlbnRQcmV2aW91c1ZhbHVlcyx7ZGVsdGFZOmksZGVsdGFYOmEsY2xpZW50WTpyLGNsaWVudFg6byx0aW1lc3RhbXA6RGF0ZS5ub3coKX0pLHRoaXMuc2V0U3RhdGVGcm9tRXZlbnQodGhpcy5jb21wb3NlTmV3U3RhdGUoLWEsLWkpKX19fSx7a2V5OlwiaGFuZGxlVG91Y2hFbmRcIix2YWx1ZTpmdW5jdGlvbihlKXt2YXIgdD10aGlzLmV2ZW50UHJldmlvdXNWYWx1ZXMsbj10LmRlbHRhWCxvPXQuZGVsdGFZLHI9dC50aW1lc3RhbXA7XCJ1bmRlZmluZWRcIj09dHlwZW9mIG4mJihuPTApLFwidW5kZWZpbmVkXCI9PXR5cGVvZiBvJiYobz0wKSxEYXRlLm5vdygpLXI8MjAwJiZ0aGlzLnNldFN0YXRlRnJvbUV2ZW50KHRoaXMuY29tcG9zZU5ld1N0YXRlKDEwKi1uLDEwKi1vKSxnLnRvdWNoRW5kKSx0aGlzLmV2ZW50UHJldmlvdXNWYWx1ZXM9cyh7fSx0aGlzLmV2ZW50UHJldmlvdXNWYWx1ZXMse2RlbHRhWTowLGRlbHRhWDowfSl9fSx7a2V5OlwiaGFuZGxlU2Nyb2xsYmFyTW92ZVwiLHZhbHVlOmZ1bmN0aW9uKGUsdCl7dGhpcy5zZXRTdGF0ZUZyb21FdmVudCh0aGlzLmNvbXBvc2VOZXdTdGF0ZSh0LGUpKX19LHtrZXk6XCJoYW5kbGVTY3JvbGxiYXJYUG9zaXRpb25DaGFuZ2VcIix2YWx1ZTpmdW5jdGlvbihlKXt0aGlzLnNjcm9sbFhUbyhlKX19LHtrZXk6XCJoYW5kbGVTY3JvbGxiYXJZUG9zaXRpb25DaGFuZ2VcIix2YWx1ZTpmdW5jdGlvbihlKXt0aGlzLnNjcm9sbFlUbyhlKX19LHtrZXk6XCJoYW5kbGVXaGVlbFwiLHZhbHVlOmZ1bmN0aW9uKGUpe3ZhciB0PWUuZGVsdGFZLG49ZS5kZWx0YVg7aWYodGhpcy5wcm9wcy5zd2FwV2hlZWxBeGVzKXt2YXIgbz1bbix0XTt0PW9bMF0sbj1vWzFdfTE9PT1lLmRlbHRhTW9kZSYmKHQqPXRoaXMubGluZUhlaWdodFB4LG4qPXRoaXMubGluZUhlaWdodFB4KSx0Kj10aGlzLnByb3BzLnNwZWVkLG4qPXRoaXMucHJvcHMuc3BlZWQ7dmFyIHI9dGhpcy5jb21wb3NlTmV3U3RhdGUoLW4sLXQpOyhyLnRvcFBvc2l0aW9uJiZ0aGlzLnN0YXRlLnRvcFBvc2l0aW9uIT09ci50b3BQb3NpdGlvbnx8ci5sZWZ0UG9zaXRpb24mJnRoaXMuc3RhdGUubGVmdFBvc2l0aW9uIT09ci5sZWZ0UG9zaXRpb258fHRoaXMucHJvcHMuc3RvcFNjcm9sbFByb3BhZ2F0aW9uKSYmKGUucHJldmVudERlZmF1bHQoKSxlLnN0b3BQcm9wYWdhdGlvbigpKSx0aGlzLnNldFN0YXRlRnJvbUV2ZW50KHIsZy53aGVlbCksdGhpcy5mb2N1c0NvbnRlbnQoKX19LHtrZXk6XCJoYW5kbGVLZXlEb3duXCIsdmFsdWU6ZnVuY3Rpb24oZSl7aWYoXCJpbnB1dFwiIT09ZS50YXJnZXQudGFnTmFtZS50b0xvd2VyQ2FzZSgpJiZcInRleHRhcmVhXCIhPT1lLnRhcmdldC50YWdOYW1lLnRvTG93ZXJDYXNlKCkmJiFlLnRhcmdldC5pc0NvbnRlbnRFZGl0YWJsZSl7dmFyIHQ9MCxuPTAsbz10aGlzLmxpbmVIZWlnaHRQeD90aGlzLmxpbmVIZWlnaHRQeDoxMDtzd2l0Y2goZS5rZXlDb2RlKXtjYXNlIDMzOnQ9dGhpcy5zdGF0ZS5jb250YWluZXJIZWlnaHQtbzticmVhaztjYXNlIDM0OnQ9LXRoaXMuc3RhdGUuY29udGFpbmVySGVpZ2h0K287YnJlYWs7Y2FzZSAzNzpuPW87YnJlYWs7Y2FzZSAzODp0PW87YnJlYWs7Y2FzZSAzOTpuPS1vO2JyZWFrO2Nhc2UgNDA6dD0tb31pZigwIT09dHx8MCE9PW4pe3ZhciByPXRoaXMuY29tcG9zZU5ld1N0YXRlKG4sdCk7ZS5wcmV2ZW50RGVmYXVsdCgpLGUuc3RvcFByb3BhZ2F0aW9uKCksdGhpcy5zZXRTdGF0ZUZyb21FdmVudChyLGcua2V5UHJlc3MpfX19fSx7a2V5OlwiaGFuZGxlV2luZG93UmVzaXplXCIsdmFsdWU6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLmNvbXB1dGVTaXplcygpO2U9dGhpcy5nZXRNb2RpZmllZFBvc2l0aW9uc0lmTmVlZGVkKGUpLHRoaXMuc2V0U3RhdGVGcm9tRXZlbnQoZSl9fSx7a2V5OlwiY29tcG9zZU5ld1N0YXRlXCIsdmFsdWU6ZnVuY3Rpb24oZSx0KXt2YXIgbj10aGlzLmNvbXB1dGVTaXplcygpO3JldHVybiB0aGlzLmNhblNjcm9sbFkobik/bi50b3BQb3NpdGlvbj10aGlzLmNvbXB1dGVUb3BQb3NpdGlvbih0LG4pOm4udG9wUG9zaXRpb249MCx0aGlzLmNhblNjcm9sbFgobikmJihuLmxlZnRQb3NpdGlvbj10aGlzLmNvbXB1dGVMZWZ0UG9zaXRpb24oZSxuKSksbn19LHtrZXk6XCJjb21wdXRlVG9wUG9zaXRpb25cIix2YWx1ZTpmdW5jdGlvbihlLHQpe3ZhciBuPXRoaXMuc3RhdGUudG9wUG9zaXRpb24tZTtyZXR1cm4gdGhpcy5ub3JtYWxpemVUb3BQb3NpdGlvbihuLHQpfX0se2tleTpcImNvbXB1dGVMZWZ0UG9zaXRpb25cIix2YWx1ZTpmdW5jdGlvbihlLHQpe3ZhciBuPXRoaXMuc3RhdGUubGVmdFBvc2l0aW9uLWU7cmV0dXJuIHRoaXMubm9ybWFsaXplTGVmdFBvc2l0aW9uKG4sdCl9fSx7a2V5Olwibm9ybWFsaXplVG9wUG9zaXRpb25cIix2YWx1ZTpmdW5jdGlvbihlLHQpe3JldHVybiBlPnQucmVhbEhlaWdodC10LmNvbnRhaW5lckhlaWdodCYmKGU9dC5yZWFsSGVpZ2h0LXQuY29udGFpbmVySGVpZ2h0KSxlPDAmJihlPTApLGV9fSx7a2V5Olwibm9ybWFsaXplTGVmdFBvc2l0aW9uXCIsdmFsdWU6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gZT50LnJlYWxXaWR0aC10LmNvbnRhaW5lcldpZHRoP2U9dC5yZWFsV2lkdGgtdC5jb250YWluZXJXaWR0aDplPDAmJihlPTApLGV9fSx7a2V5OlwiY29tcHV0ZVNpemVzXCIsdmFsdWU6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLmNvbnRlbnQub2Zmc2V0SGVpZ2h0LHQ9dGhpcy53cmFwcGVyLm9mZnNldEhlaWdodCxuPXRoaXMuY29udGVudC5vZmZzZXRXaWR0aCxvPXRoaXMud3JhcHBlci5vZmZzZXRXaWR0aDtyZXR1cm57cmVhbEhlaWdodDplLGNvbnRhaW5lckhlaWdodDp0LHJlYWxXaWR0aDpuLGNvbnRhaW5lcldpZHRoOm99fX0se2tleTpcInNldFNpemVzVG9TdGF0ZVwiLHZhbHVlOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5jb21wdXRlU2l6ZXMoKTtlLnJlYWxIZWlnaHQ9PT10aGlzLnN0YXRlLnJlYWxIZWlnaHQmJmUucmVhbFdpZHRoPT09dGhpcy5zdGF0ZS5yZWFsV2lkdGh8fHRoaXMuc2V0U3RhdGVGcm9tRXZlbnQodGhpcy5nZXRNb2RpZmllZFBvc2l0aW9uc0lmTmVlZGVkKGUpKX19LHtrZXk6XCJzY3JvbGxUb3BcIix2YWx1ZTpmdW5jdGlvbigpe3RoaXMuc2Nyb2xsWVRvKDApfX0se2tleTpcInNjcm9sbEJvdHRvbVwiLHZhbHVlOmZ1bmN0aW9uKCl7dGhpcy5zY3JvbGxZVG8odGhpcy5zdGF0ZS5yZWFsSGVpZ2h0LXRoaXMuc3RhdGUuY29udGFpbmVySGVpZ2h0KX19LHtrZXk6XCJzY3JvbGxMZWZ0XCIsdmFsdWU6ZnVuY3Rpb24oKXt0aGlzLnNjcm9sbFhUbygwKX19LHtrZXk6XCJzY3JvbGxSaWdodFwiLHZhbHVlOmZ1bmN0aW9uKCl7dGhpcy5zY3JvbGxYVG8odGhpcy5zdGF0ZS5yZWFsV2lkdGgtdGhpcy5zdGF0ZS5jb250YWluZXJXaWR0aCl9fSx7a2V5Olwic2Nyb2xsWVRvXCIsdmFsdWU6ZnVuY3Rpb24oZSl7aWYodGhpcy5jYW5TY3JvbGxZKCkpe3ZhciB0PXRoaXMubm9ybWFsaXplVG9wUG9zaXRpb24oZSx0aGlzLmNvbXB1dGVTaXplcygpKTt0aGlzLnNldFN0YXRlRnJvbUV2ZW50KHt0b3BQb3NpdGlvbjp0fSxnLmFwaSl9fX0se2tleTpcInNjcm9sbFhUb1wiLHZhbHVlOmZ1bmN0aW9uKGUpe2lmKHRoaXMuY2FuU2Nyb2xsWCgpKXt2YXIgdD10aGlzLm5vcm1hbGl6ZUxlZnRQb3NpdGlvbihlLHRoaXMuY29tcHV0ZVNpemVzKCkpO3RoaXMuc2V0U3RhdGVGcm9tRXZlbnQoe2xlZnRQb3NpdGlvbjp0fSxnLmFwaSl9fX0se2tleTpcImNhblNjcm9sbFlcIix2YWx1ZTpmdW5jdGlvbigpe3ZhciBlPWFyZ3VtZW50cy5sZW5ndGg+MCYmdm9pZCAwIT09YXJndW1lbnRzWzBdP2FyZ3VtZW50c1swXTp0aGlzLnN0YXRlLHQ9ZS5yZWFsSGVpZ2h0PmUuY29udGFpbmVySGVpZ2h0O3JldHVybiB0JiZ0aGlzLnByb3BzLnZlcnRpY2FsfX0se2tleTpcImNhblNjcm9sbFhcIix2YWx1ZTpmdW5jdGlvbigpe3ZhciBlPWFyZ3VtZW50cy5sZW5ndGg+MCYmdm9pZCAwIT09YXJndW1lbnRzWzBdP2FyZ3VtZW50c1swXTp0aGlzLnN0YXRlLHQ9ZS5yZWFsV2lkdGg+ZS5jb250YWluZXJXaWR0aDtyZXR1cm4gdCYmdGhpcy5wcm9wcy5ob3Jpem9udGFsfX0se2tleTpcImNhblNjcm9sbFwiLHZhbHVlOmZ1bmN0aW9uKCl7dmFyIGU9YXJndW1lbnRzLmxlbmd0aD4wJiZ2b2lkIDAhPT1hcmd1bWVudHNbMF0/YXJndW1lbnRzWzBdOnRoaXMuc3RhdGU7cmV0dXJuIHRoaXMuY2FuU2Nyb2xsWShlKXx8dGhpcy5jYW5TY3JvbGxYKGUpfX0se2tleTpcImdldE1vZGlmaWVkUG9zaXRpb25zSWZOZWVkZWRcIix2YWx1ZTpmdW5jdGlvbihlKXt2YXIgdD1lLnJlYWxIZWlnaHQtZS5jb250YWluZXJIZWlnaHQ7dGhpcy5zdGF0ZS50b3BQb3NpdGlvbj49dCYmKGUudG9wUG9zaXRpb249dGhpcy5jYW5TY3JvbGxZKGUpPygwLG0ucG9zaXRpdmVPclplcm8pKHQpOjApO3ZhciBuPWUucmVhbFdpZHRoLWUuY29udGFpbmVyV2lkdGg7cmV0dXJuIHRoaXMuc3RhdGUubGVmdFBvc2l0aW9uPj1uJiYoZS5sZWZ0UG9zaXRpb249dGhpcy5jYW5TY3JvbGxYKGUpPygwLG0ucG9zaXRpdmVPclplcm8pKG4pOjApLGV9fSx7a2V5OlwiZm9jdXNDb250ZW50XCIsdmFsdWU6ZnVuY3Rpb24oKXt0aGlzLmNvbnRlbnQmJigwLG0uZmluZERPTU5vZGUpKHRoaXMuY29udGVudCkuZm9jdXMoKX19XSksdH0oZi5kZWZhdWx0LkNvbXBvbmVudCk7dC5kZWZhdWx0PXcsdy5jaGlsZENvbnRleHRUeXBlcz17c2Nyb2xsQXJlYTpkLmRlZmF1bHQub2JqZWN0fSx3LnByb3BUeXBlcz17Y2xhc3NOYW1lOmQuZGVmYXVsdC5zdHJpbmcsc3R5bGU6ZC5kZWZhdWx0Lm9iamVjdCxzcGVlZDpkLmRlZmF1bHQubnVtYmVyLGNvbnRlbnRDbGFzc05hbWU6ZC5kZWZhdWx0LnN0cmluZyxjb250ZW50U3R5bGU6ZC5kZWZhdWx0Lm9iamVjdCx2ZXJ0aWNhbDpkLmRlZmF1bHQuYm9vbCx2ZXJ0aWNhbENvbnRhaW5lclN0eWxlOmQuZGVmYXVsdC5vYmplY3QsdmVydGljYWxTY3JvbGxiYXJTdHlsZTpkLmRlZmF1bHQub2JqZWN0LGhvcml6b250YWw6ZC5kZWZhdWx0LmJvb2wsaG9yaXpvbnRhbENvbnRhaW5lclN0eWxlOmQuZGVmYXVsdC5vYmplY3QsaG9yaXpvbnRhbFNjcm9sbGJhclN0eWxlOmQuZGVmYXVsdC5vYmplY3Qsb25TY3JvbGw6ZC5kZWZhdWx0LmZ1bmMsY29udGVudFdpbmRvdzpkLmRlZmF1bHQuYW55LG93bmVyRG9jdW1lbnQ6ZC5kZWZhdWx0LmFueSxzbW9vdGhTY3JvbGxpbmc6ZC5kZWZhdWx0LmJvb2wsbWluU2Nyb2xsU2l6ZTpkLmRlZmF1bHQubnVtYmVyLHN3YXBXaGVlbEF4ZXM6ZC5kZWZhdWx0LmJvb2wsc3RvcFNjcm9sbFByb3BhZ2F0aW9uOmQuZGVmYXVsdC5ib29sLGZvY3VzYWJsZVRhYkluZGV4OmQuZGVmYXVsdC5udW1iZXJ9LHcuZGVmYXVsdFByb3BzPXtzcGVlZDoxLHZlcnRpY2FsOiEwLGhvcml6b250YWw6ITAsc21vb3RoU2Nyb2xsaW5nOiExLHN3YXBXaGVlbEF4ZXM6ITEsY29udGVudFdpbmRvdzpcIm9iamVjdFwiPT09KFwidW5kZWZpbmVkXCI9PXR5cGVvZiB3aW5kb3c/XCJ1bmRlZmluZWRcIjpsKHdpbmRvdykpP3dpbmRvdzp2b2lkIDAsb3duZXJEb2N1bWVudDpcIm9iamVjdFwiPT09KFwidW5kZWZpbmVkXCI9PXR5cGVvZiBkb2N1bWVudD9cInVuZGVmaW5lZFwiOmwoZG9jdW1lbnQpKT9kb2N1bWVudDp2b2lkIDAsZm9jdXNhYmxlVGFiSW5kZXg6MX19LGZ1bmN0aW9uKGUsdCxuKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBvKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX1mdW5jdGlvbiByKGUsdCl7aWYoIShlIGluc3RhbmNlb2YgdCkpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKX1mdW5jdGlvbiBpKGUsdCl7aWYoIWUpdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkXCIpO3JldHVybiF0fHxcIm9iamVjdFwiIT10eXBlb2YgdCYmXCJmdW5jdGlvblwiIT10eXBlb2YgdD9lOnR9ZnVuY3Rpb24gYShlLHQpe2lmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIHQmJm51bGwhPT10KXRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiK3R5cGVvZiB0KTtlLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKHQmJnQucHJvdG90eXBlLHtjb25zdHJ1Y3Rvcjp7dmFsdWU6ZSxlbnVtZXJhYmxlOiExLHdyaXRhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMH19KSx0JiYoT2JqZWN0LnNldFByb3RvdHlwZU9mP09iamVjdC5zZXRQcm90b3R5cGVPZihlLHQpOmUuX19wcm90b19fPXQpfU9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pO3ZhciBsPU9iamVjdC5hc3NpZ258fGZ1bmN0aW9uKGUpe2Zvcih2YXIgdD0xO3Q8YXJndW1lbnRzLmxlbmd0aDt0Kyspe3ZhciBuPWFyZ3VtZW50c1t0XTtmb3IodmFyIG8gaW4gbilPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobixvKSYmKGVbb109bltvXSl9cmV0dXJuIGV9LHM9ZnVuY3Rpb24oKXtmdW5jdGlvbiBlKGUsdCl7Zm9yKHZhciBuPTA7bjx0Lmxlbmd0aDtuKyspe3ZhciBvPXRbbl07by5lbnVtZXJhYmxlPW8uZW51bWVyYWJsZXx8ITEsby5jb25maWd1cmFibGU9ITAsXCJ2YWx1ZVwiaW4gbyYmKG8ud3JpdGFibGU9ITApLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlLG8ua2V5LG8pfX1yZXR1cm4gZnVuY3Rpb24odCxuLG8pe3JldHVybiBuJiZlKHQucHJvdG90eXBlLG4pLG8mJmUodCxvKSx0fX0oKSx1PW4oMSksYz1vKHUpLGY9bigyKSxwPW8oZiksZD1uKDEyKSxoPW4oOSkseT1mdW5jdGlvbihlKXtmdW5jdGlvbiB0KGUpe3IodGhpcyx0KTt2YXIgbj1pKHRoaXMsKHQuX19wcm90b19ffHxPYmplY3QuZ2V0UHJvdG90eXBlT2YodCkpLmNhbGwodGhpcyxlKSksbz1uLmNhbGN1bGF0ZVN0YXRlKGUpO3JldHVybiBuLnN0YXRlPXtwb3NpdGlvbjpvLnBvc2l0aW9uLHNjcm9sbFNpemU6by5zY3JvbGxTaXplLGlzRHJhZ2dpbmc6ITEsbGFzdENsaWVudFBvc2l0aW9uOjB9LFwidmVydGljYWxcIj09PWUudHlwZT9uLmJpbmRlZEhhbmRsZU1vdXNlTW92ZT1uLmhhbmRsZU1vdXNlTW92ZUZvclZlcnRpY2FsLmJpbmQobik6bi5iaW5kZWRIYW5kbGVNb3VzZU1vdmU9bi5oYW5kbGVNb3VzZU1vdmVGb3JIb3Jpem9udGFsLmJpbmQobiksbi5iaW5kZWRIYW5kbGVNb3VzZVVwPW4uaGFuZGxlTW91c2VVcC5iaW5kKG4pLG59cmV0dXJuIGEodCxlKSxzKHQsW3trZXk6XCJjb21wb25lbnREaWRNb3VudFwiLHZhbHVlOmZ1bmN0aW9uKCl7dGhpcy5wcm9wcy5vd25lckRvY3VtZW50JiYodGhpcy5wcm9wcy5vd25lckRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIix0aGlzLmJpbmRlZEhhbmRsZU1vdXNlTW92ZSksdGhpcy5wcm9wcy5vd25lckRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsdGhpcy5iaW5kZWRIYW5kbGVNb3VzZVVwKSl9fSx7a2V5OlwiY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1wiLHZhbHVlOmZ1bmN0aW9uKGUpe3RoaXMuc2V0U3RhdGUodGhpcy5jYWxjdWxhdGVTdGF0ZShlKSl9fSx7a2V5OlwiY29tcG9uZW50V2lsbFVubW91bnRcIix2YWx1ZTpmdW5jdGlvbigpe3RoaXMucHJvcHMub3duZXJEb2N1bWVudCYmKHRoaXMucHJvcHMub3duZXJEb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsdGhpcy5iaW5kZWRIYW5kbGVNb3VzZU1vdmUpLHRoaXMucHJvcHMub3duZXJEb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLHRoaXMuYmluZGVkSGFuZGxlTW91c2VVcCkpfX0se2tleTpcImNhbGN1bGF0ZUZyYWN0aW9uYWxQb3NpdGlvblwiLHZhbHVlOmZ1bmN0aW9uKGUsdCxuKXt2YXIgbz1lLXQ7cmV0dXJuIDEtKG8tbikvb319LHtrZXk6XCJjYWxjdWxhdGVTdGF0ZVwiLHZhbHVlOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMuY2FsY3VsYXRlRnJhY3Rpb25hbFBvc2l0aW9uKGUucmVhbFNpemUsZS5jb250YWluZXJTaXplLGUucG9zaXRpb24pLG49ZS5jb250YWluZXJTaXplKmUuY29udGFpbmVyU2l6ZS9lLnJlYWxTaXplLG89bjxlLm1pblNjcm9sbFNpemU/ZS5taW5TY3JvbGxTaXplOm4scj0oZS5jb250YWluZXJTaXplLW8pKnQ7cmV0dXJue3Njcm9sbFNpemU6byxwb3NpdGlvbjpNYXRoLnJvdW5kKHIpfX19LHtrZXk6XCJyZW5kZXJcIix2YWx1ZTpmdW5jdGlvbigpe3ZhciBlPXRoaXMsdD10aGlzLnByb3BzLG49dC5zbW9vdGhTY3JvbGxpbmcsbz10LmlzRHJhZ2dpbmcscj10LnR5cGUsaT10LnNjcm9sbGJhclN0eWxlLGE9dC5jb250YWluZXJTdHlsZSxzPVwiaG9yaXpvbnRhbFwiPT09cix1PVwidmVydGljYWxcIj09PXIsZj10aGlzLmNyZWF0ZVNjcm9sbFN0eWxlcygpLHA9bj8oMCxoLm1vZGlmeU9ialZhbHVlcykoZixmdW5jdGlvbihlKXtyZXR1cm4oMCxkLnNwcmluZykoZSl9KTpmLHk9XCJzY3JvbGxiYXItY29udGFpbmVyIFwiKyhvP1wiYWN0aXZlXCI6XCJcIikrXCIgXCIrKHM/XCJob3Jpem9udGFsXCI6XCJcIikrXCIgXCIrKHU/XCJ2ZXJ0aWNhbFwiOlwiXCIpO3JldHVybiBjLmRlZmF1bHQuY3JlYXRlRWxlbWVudChkLk1vdGlvbix7c3R5bGU6cH0sZnVuY3Rpb24odCl7cmV0dXJuIGMuZGVmYXVsdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIse2NsYXNzTmFtZTp5LHN0eWxlOmEsb25Nb3VzZURvd246ZS5oYW5kbGVTY3JvbGxCYXJDb250YWluZXJDbGljay5iaW5kKGUpLHJlZjpmdW5jdGlvbih0KXtyZXR1cm4gZS5zY3JvbGxiYXJDb250YWluZXI9dH19LGMuZGVmYXVsdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIse2NsYXNzTmFtZTpcInNjcm9sbGJhclwiLHN0eWxlOmwoe30saSx0KSxvbk1vdXNlRG93bjplLmhhbmRsZU1vdXNlRG93bi5iaW5kKGUpfSkpfSl9fSx7a2V5OlwiaGFuZGxlU2Nyb2xsQmFyQ29udGFpbmVyQ2xpY2tcIix2YWx1ZTpmdW5jdGlvbihlKXtlLnByZXZlbnREZWZhdWx0KCk7dmFyIHQ9dGhpcy5jb21wdXRlTXVsdGlwbGllcigpLG49dGhpcy5pc1ZlcnRpY2FsKCk/ZS5jbGllbnRZOmUuY2xpZW50WCxvPXRoaXMuc2Nyb2xsYmFyQ29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLHI9by50b3AsaT1vLmxlZnQsYT10aGlzLmlzVmVydGljYWwoKT9yOmksbD1uLWEscz10aGlzLnByb3BzLmNvbnRhaW5lclNpemUqdGhpcy5wcm9wcy5jb250YWluZXJTaXplL3RoaXMucHJvcHMucmVhbFNpemU7dGhpcy5zZXRTdGF0ZSh7aXNEcmFnZ2luZzohMCxsYXN0Q2xpZW50UG9zaXRpb246bn0pLHRoaXMucHJvcHMub25Qb3NpdGlvbkNoYW5nZSgobC1zLzIpL3QpfX0se2tleTpcImhhbmRsZU1vdXNlTW92ZUZvckhvcml6b250YWxcIix2YWx1ZTpmdW5jdGlvbihlKXt2YXIgdD10aGlzLmNvbXB1dGVNdWx0aXBsaWVyKCk7aWYodGhpcy5zdGF0ZS5pc0RyYWdnaW5nKXtlLnByZXZlbnREZWZhdWx0KCk7dmFyIG49dGhpcy5zdGF0ZS5sYXN0Q2xpZW50UG9zaXRpb24tZS5jbGllbnRYO3RoaXMuc2V0U3RhdGUoe2xhc3RDbGllbnRQb3NpdGlvbjplLmNsaWVudFh9KSx0aGlzLnByb3BzLm9uTW92ZSgwLG4vdCl9fX0se2tleTpcImhhbmRsZU1vdXNlTW92ZUZvclZlcnRpY2FsXCIsdmFsdWU6ZnVuY3Rpb24oZSl7dmFyIHQ9dGhpcy5jb21wdXRlTXVsdGlwbGllcigpO2lmKHRoaXMuc3RhdGUuaXNEcmFnZ2luZyl7ZS5wcmV2ZW50RGVmYXVsdCgpO3ZhciBuPXRoaXMuc3RhdGUubGFzdENsaWVudFBvc2l0aW9uLWUuY2xpZW50WTt0aGlzLnNldFN0YXRlKHtsYXN0Q2xpZW50UG9zaXRpb246ZS5jbGllbnRZfSksdGhpcy5wcm9wcy5vbk1vdmUobi90LDApfX19LHtrZXk6XCJoYW5kbGVNb3VzZURvd25cIix2YWx1ZTpmdW5jdGlvbihlKXtlLnByZXZlbnREZWZhdWx0KCksZS5zdG9wUHJvcGFnYXRpb24oKTt2YXIgdD10aGlzLmlzVmVydGljYWwoKT9lLmNsaWVudFk6ZS5jbGllbnRYO3RoaXMuc2V0U3RhdGUoe2lzRHJhZ2dpbmc6ITAsbGFzdENsaWVudFBvc2l0aW9uOnR9KSx0aGlzLnByb3BzLm9uRm9jdXMoKX19LHtrZXk6XCJoYW5kbGVNb3VzZVVwXCIsdmFsdWU6ZnVuY3Rpb24oZSl7dGhpcy5zdGF0ZS5pc0RyYWdnaW5nJiYoZS5wcmV2ZW50RGVmYXVsdCgpLHRoaXMuc2V0U3RhdGUoe2lzRHJhZ2dpbmc6ITF9KSl9fSx7a2V5OlwiY3JlYXRlU2Nyb2xsU3R5bGVzXCIsdmFsdWU6ZnVuY3Rpb24oKXtyZXR1cm5cInZlcnRpY2FsXCI9PT10aGlzLnByb3BzLnR5cGU/e2hlaWdodDp0aGlzLnN0YXRlLnNjcm9sbFNpemUsbWFyZ2luVG9wOnRoaXMuc3RhdGUucG9zaXRpb259Ont3aWR0aDp0aGlzLnN0YXRlLnNjcm9sbFNpemUsbWFyZ2luTGVmdDp0aGlzLnN0YXRlLnBvc2l0aW9ufX19LHtrZXk6XCJjb21wdXRlTXVsdGlwbGllclwiLHZhbHVlOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucHJvcHMuY29udGFpbmVyU2l6ZS90aGlzLnByb3BzLnJlYWxTaXplfX0se2tleTpcImlzVmVydGljYWxcIix2YWx1ZTpmdW5jdGlvbigpe3JldHVyblwidmVydGljYWxcIj09PXRoaXMucHJvcHMudHlwZX19XSksdH0oYy5kZWZhdWx0LkNvbXBvbmVudCk7eS5wcm9wVHlwZXM9e29uTW92ZTpwLmRlZmF1bHQuZnVuYyxvblBvc2l0aW9uQ2hhbmdlOnAuZGVmYXVsdC5mdW5jLG9uRm9jdXM6cC5kZWZhdWx0LmZ1bmMscmVhbFNpemU6cC5kZWZhdWx0Lm51bWJlcixjb250YWluZXJTaXplOnAuZGVmYXVsdC5udW1iZXIscG9zaXRpb246cC5kZWZhdWx0Lm51bWJlcixjb250YWluZXJTdHlsZTpwLmRlZmF1bHQub2JqZWN0LHNjcm9sbGJhclN0eWxlOnAuZGVmYXVsdC5vYmplY3QsdHlwZTpwLmRlZmF1bHQub25lT2YoW1widmVydGljYWxcIixcImhvcml6b250YWxcIl0pLG93bmVyRG9jdW1lbnQ6cC5kZWZhdWx0LmFueSxzbW9vdGhTY3JvbGxpbmc6cC5kZWZhdWx0LmJvb2wsbWluU2Nyb2xsU2l6ZTpwLmRlZmF1bHQubnVtYmVyfSx5LmRlZmF1bHRQcm9wcz17dHlwZTpcInZlcnRpY2FsXCIsc21vb3RoU2Nyb2xsaW5nOiExfSx0LmRlZmF1bHQ9eX0sZnVuY3Rpb24oZSx0KXt2YXIgbj1mdW5jdGlvbihlLHQsbil7cmV0dXJuIG49d2luZG93LmdldENvbXB1dGVkU3R5bGUsKG4/bihlKTplLmN1cnJlbnRTdHlsZSlbdC5yZXBsYWNlKC8tKFxcdykvZ2ksZnVuY3Rpb24oZSx0KXtyZXR1cm4gdC50b1VwcGVyQ2FzZSgpfSldfTtlLmV4cG9ydHM9bn0sZnVuY3Rpb24oZSx0LG4pe3Q9ZS5leHBvcnRzPW4oMTcpKCksdC5wdXNoKFtlLmlkLFwiLnNjcm9sbGFyZWEtY29udGVudHttYXJnaW46MDtwYWRkaW5nOjA7b3ZlcmZsb3c6aGlkZGVuO3Bvc2l0aW9uOnJlbGF0aXZlO3RvdWNoLWFjdGlvbjpub25lfS5zY3JvbGxhcmVhLWNvbnRlbnQ6Zm9jdXN7b3V0bGluZTowfS5zY3JvbGxhcmVhe3Bvc2l0aW9uOnJlbGF0aXZlO292ZXJmbG93OmhpZGRlbn0uc2Nyb2xsYXJlYSAuc2Nyb2xsYmFyLWNvbnRhaW5lcntwb3NpdGlvbjphYnNvbHV0ZTtiYWNrZ3JvdW5kOm5vbmU7b3BhY2l0eTouMTt6LWluZGV4Ojk5Oy13ZWJraXQtdHJhbnNpdGlvbjphbGwgLjRzO3RyYW5zaXRpb246YWxsIC40c30uc2Nyb2xsYXJlYSAuc2Nyb2xsYmFyLWNvbnRhaW5lci5ob3Jpem9udGFse3dpZHRoOjEwMCU7aGVpZ2h0OjEwcHg7bGVmdDowO2JvdHRvbTowfS5zY3JvbGxhcmVhIC5zY3JvbGxiYXItY29udGFpbmVyLmhvcml6b250YWwgLnNjcm9sbGJhcnt3aWR0aDoyMHB4O2hlaWdodDo4cHg7YmFja2dyb3VuZDojMDAwO21hcmdpbi10b3A6MXB4fS5zY3JvbGxhcmVhIC5zY3JvbGxiYXItY29udGFpbmVyLnZlcnRpY2Fse3dpZHRoOjEwcHg7aGVpZ2h0OjEwMCU7cmlnaHQ6MDt0b3A6MH0uc2Nyb2xsYXJlYSAuc2Nyb2xsYmFyLWNvbnRhaW5lci52ZXJ0aWNhbCAuc2Nyb2xsYmFye3dpZHRoOjhweDtoZWlnaHQ6MjBweDtiYWNrZ3JvdW5kOiMwMDA7bWFyZ2luLWxlZnQ6MXB4fS5zY3JvbGxhcmVhIC5zY3JvbGxiYXItY29udGFpbmVyLmFjdGl2ZSwuc2Nyb2xsYXJlYSAuc2Nyb2xsYmFyLWNvbnRhaW5lcjpob3ZlcntiYWNrZ3JvdW5kOmdyYXk7b3BhY2l0eTouNiFpbXBvcnRhbnR9LnNjcm9sbGFyZWE6aG92ZXIgLnNjcm9sbGJhci1jb250YWluZXJ7b3BhY2l0eTouM31cIixcIlwiXSl9LGZ1bmN0aW9uKGUsdCl7ZS5leHBvcnRzPWZ1bmN0aW9uKCl7dmFyIGU9W107cmV0dXJuIGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtmb3IodmFyIGU9W10sdD0wO3Q8dGhpcy5sZW5ndGg7dCsrKXt2YXIgbj10aGlzW3RdO25bMl0/ZS5wdXNoKFwiQG1lZGlhIFwiK25bMl0rXCJ7XCIrblsxXStcIn1cIik6ZS5wdXNoKG5bMV0pfXJldHVybiBlLmpvaW4oXCJcIil9LGUuaT1mdW5jdGlvbih0LG4pe1wic3RyaW5nXCI9PXR5cGVvZiB0JiYodD1bW251bGwsdCxcIlwiXV0pO2Zvcih2YXIgbz17fSxyPTA7cjx0aGlzLmxlbmd0aDtyKyspe3ZhciBpPXRoaXNbcl1bMF07XCJudW1iZXJcIj09dHlwZW9mIGkmJihvW2ldPSEwKX1mb3Iocj0wO3I8dC5sZW5ndGg7cisrKXt2YXIgYT10W3JdO1wibnVtYmVyXCI9PXR5cGVvZiBhWzBdJiZvW2FbMF1dfHwobiYmIWFbMl0/YVsyXT1uOm4mJihhWzJdPVwiKFwiK2FbMl0rXCIpIGFuZCAoXCIrbitcIilcIiksZS5wdXNoKGEpKX19LGV9fSxmdW5jdGlvbihlLHQsbil7ZnVuY3Rpb24gbyhlKXt2YXIgdD1yKGUsXCJsaW5lLWhlaWdodFwiKSxuPXBhcnNlRmxvYXQodCwxMCk7aWYodD09PW4rXCJcIil7dmFyIG89ZS5zdHlsZS5saW5lSGVpZ2h0O2Uuc3R5bGUubGluZUhlaWdodD10K1wiZW1cIix0PXIoZSxcImxpbmUtaGVpZ2h0XCIpLG49cGFyc2VGbG9hdCh0LDEwKSxvP2Uuc3R5bGUubGluZUhlaWdodD1vOmRlbGV0ZSBlLnN0eWxlLmxpbmVIZWlnaHR9aWYodC5pbmRleE9mKFwicHRcIikhPT0tMT8obio9NCxuLz0zKTp0LmluZGV4T2YoXCJtbVwiKSE9PS0xPyhuKj05NixuLz0yNS40KTp0LmluZGV4T2YoXCJjbVwiKSE9PS0xPyhuKj05NixuLz0yLjU0KTp0LmluZGV4T2YoXCJpblwiKSE9PS0xP24qPTk2OnQuaW5kZXhPZihcInBjXCIpIT09LTEmJihuKj0xNiksbj1NYXRoLnJvdW5kKG4pLFwibm9ybWFsXCI9PT10KXt2YXIgaT1lLm5vZGVOYW1lLGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChpKTthLmlubmVySFRNTD1cIiZuYnNwO1wiO3ZhciBsPXIoZSxcImZvbnQtc2l6ZVwiKTthLnN0eWxlLmZvbnRTaXplPWw7dmFyIHM9ZG9jdW1lbnQuYm9keTtzLmFwcGVuZENoaWxkKGEpO3ZhciB1PWEub2Zmc2V0SGVpZ2h0O249dSxzLnJlbW92ZUNoaWxkKGEpfXJldHVybiBufXZhciByPW4oMTUpO2UuZXhwb3J0cz1vfSxmdW5jdGlvbihlLHQsbil7XCJ1c2Ugc3RyaWN0XCI7dmFyIG89bigyMSkscj1uKDIyKSxpPW4oMjApO2UuZXhwb3J0cz1mdW5jdGlvbigpe2Z1bmN0aW9uIGUoZSx0LG4sbyxhLGwpe2whPT1pJiZyKCExLFwiQ2FsbGluZyBQcm9wVHlwZXMgdmFsaWRhdG9ycyBkaXJlY3RseSBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBgcHJvcC10eXBlc2AgcGFja2FnZS4gVXNlIFByb3BUeXBlcy5jaGVja1Byb3BUeXBlcygpIHRvIGNhbGwgdGhlbS4gUmVhZCBtb3JlIGF0IGh0dHA6Ly9mYi5tZS91c2UtY2hlY2stcHJvcC10eXBlc1wiKX1mdW5jdGlvbiB0KCl7cmV0dXJuIGV9ZS5pc1JlcXVpcmVkPWU7dmFyIG49e2FycmF5OmUsYm9vbDplLGZ1bmM6ZSxudW1iZXI6ZSxvYmplY3Q6ZSxzdHJpbmc6ZSxzeW1ib2w6ZSxhbnk6ZSxhcnJheU9mOnQsZWxlbWVudDplLGluc3RhbmNlT2Y6dCxub2RlOmUsb2JqZWN0T2Y6dCxvbmVPZjp0LG9uZU9mVHlwZTp0LHNoYXBlOnQsZXhhY3Q6dH07cmV0dXJuIG4uY2hlY2tQcm9wVHlwZXM9byxuLlByb3BUeXBlcz1uLG59fSxmdW5jdGlvbihlLHQpe1widXNlIHN0cmljdFwiO3ZhciBuPVwiU0VDUkVUX0RPX05PVF9QQVNTX1RISVNfT1JfWU9VX1dJTExfQkVfRklSRURcIjtlLmV4cG9ydHM9bn0sZnVuY3Rpb24oZSx0KXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBuKGUpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBlfX12YXIgbz1mdW5jdGlvbigpe307by50aGF0UmV0dXJucz1uLG8udGhhdFJldHVybnNGYWxzZT1uKCExKSxvLnRoYXRSZXR1cm5zVHJ1ZT1uKCEwKSxvLnRoYXRSZXR1cm5zTnVsbD1uKG51bGwpLG8udGhhdFJldHVybnNUaGlzPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXN9LG8udGhhdFJldHVybnNBcmd1bWVudD1mdW5jdGlvbihlKXtyZXR1cm4gZX0sZS5leHBvcnRzPW99LGZ1bmN0aW9uKGUsdCxuKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBvKGUsdCxuLG8saSxhLGwscyl7aWYocih0KSwhZSl7dmFyIHU7aWYodm9pZCAwPT09dCl1PW5ldyBFcnJvcihcIk1pbmlmaWVkIGV4Y2VwdGlvbiBvY2N1cnJlZDsgdXNlIHRoZSBub24tbWluaWZpZWQgZGV2IGVudmlyb25tZW50IGZvciB0aGUgZnVsbCBlcnJvciBtZXNzYWdlIGFuZCBhZGRpdGlvbmFsIGhlbHBmdWwgd2FybmluZ3MuXCIpO2Vsc2V7dmFyIGM9W24sbyxpLGEsbCxzXSxmPTA7dT1uZXcgRXJyb3IodC5yZXBsYWNlKC8lcy9nLGZ1bmN0aW9uKCl7cmV0dXJuIGNbZisrXX0pKSx1Lm5hbWU9XCJJbnZhcmlhbnQgVmlvbGF0aW9uXCJ9dGhyb3cgdS5mcmFtZXNUb1BvcD0xLHV9fXZhciByPWZ1bmN0aW9uKGUpe307ZS5leHBvcnRzPW99LGZ1bmN0aW9uKGUsdCxuKXsoZnVuY3Rpb24odCl7KGZ1bmN0aW9uKCl7dmFyIG4sbyxyLGksYSxsO1widW5kZWZpbmVkXCIhPXR5cGVvZiBwZXJmb3JtYW5jZSYmbnVsbCE9PXBlcmZvcm1hbmNlJiZwZXJmb3JtYW5jZS5ub3c/ZS5leHBvcnRzPWZ1bmN0aW9uKCl7cmV0dXJuIHBlcmZvcm1hbmNlLm5vdygpfTpcInVuZGVmaW5lZFwiIT10eXBlb2YgdCYmbnVsbCE9PXQmJnQuaHJ0aW1lPyhlLmV4cG9ydHM9ZnVuY3Rpb24oKXtyZXR1cm4obigpLWEpLzFlNn0sbz10LmhydGltZSxuPWZ1bmN0aW9uKCl7dmFyIGU7cmV0dXJuIGU9bygpLDFlOSplWzBdK2VbMV19LGk9bigpLGw9MWU5KnQudXB0aW1lKCksYT1pLWwpOkRhdGUubm93PyhlLmV4cG9ydHM9ZnVuY3Rpb24oKXtyZXR1cm4gRGF0ZS5ub3coKS1yfSxyPURhdGUubm93KCkpOihlLmV4cG9ydHM9ZnVuY3Rpb24oKXtyZXR1cm4obmV3IERhdGUpLmdldFRpbWUoKS1yfSxyPShuZXcgRGF0ZSkuZ2V0VGltZSgpKX0pLmNhbGwodGhpcyl9KS5jYWxsKHQsbigxMCkpfSxmdW5jdGlvbihlLHQsbil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbyhlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2U6e2RlZmF1bHQ6ZX19ZnVuY3Rpb24gcihlLHQpe2lmKCEoZSBpbnN0YW5jZW9mIHQpKXRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIil9ZnVuY3Rpb24gaShlLHQpe2lmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIHQmJm51bGwhPT10KXRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiK3R5cGVvZiB0KTtlLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKHQmJnQucHJvdG90eXBlLHtjb25zdHJ1Y3Rvcjp7dmFsdWU6ZSxlbnVtZXJhYmxlOiExLHdyaXRhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMH19KSx0JiYoT2JqZWN0LnNldFByb3RvdHlwZU9mP09iamVjdC5zZXRQcm90b3R5cGVPZihlLHQpOmUuX19wcm90b19fPXQpfXQuX19lc01vZHVsZT0hMDt2YXIgYT1PYmplY3QuYXNzaWdufHxmdW5jdGlvbihlKXtmb3IodmFyIHQ9MTt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKXt2YXIgbj1hcmd1bWVudHNbdF07Zm9yKHZhciBvIGluIG4pT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG4sbykmJihlW29dPW5bb10pfXJldHVybiBlfSxsPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gZShlLHQpe2Zvcih2YXIgbj0wO248dC5sZW5ndGg7bisrKXt2YXIgbz10W25dO28uZW51bWVyYWJsZT1vLmVudW1lcmFibGV8fCExLG8uY29uZmlndXJhYmxlPSEwLFwidmFsdWVcImluIG8mJihvLndyaXRhYmxlPSEwKSxPYmplY3QuZGVmaW5lUHJvcGVydHkoZSxvLmtleSxvKX19cmV0dXJuIGZ1bmN0aW9uKHQsbixvKXtyZXR1cm4gbiYmZSh0LnByb3RvdHlwZSxuKSxvJiZlKHQsbyksdH19KCkscz1uKDYpLHU9byhzKSxjPW4oMyksZj1vKGMpLHA9big4KSxkPW8ocCksaD1uKDQpLHk9byhoKSx2PW4oNSksbT1vKHYpLGI9big3KSxTPW8oYiksZz1uKDEpLHc9byhnKSxQPW4oMiksVD1vKFApLGs9MWUzLzYwLE89ZnVuY3Rpb24oZSl7ZnVuY3Rpb24gdChuKXt2YXIgbz10aGlzO3IodGhpcyx0KSxlLmNhbGwodGhpcyxuKSx0aGlzLndhc0FuaW1hdGluZz0hMSx0aGlzLmFuaW1hdGlvbklEPW51bGwsdGhpcy5wcmV2VGltZT0wLHRoaXMuYWNjdW11bGF0ZWRUaW1lPTAsdGhpcy51bnJlYWRQcm9wU3R5bGU9bnVsbCx0aGlzLmNsZWFyVW5yZWFkUHJvcFN0eWxlPWZ1bmN0aW9uKGUpe3ZhciB0PSExLG49by5zdGF0ZSxyPW4uY3VycmVudFN0eWxlLGk9bi5jdXJyZW50VmVsb2NpdHksbD1uLmxhc3RJZGVhbFN0eWxlLHM9bi5sYXN0SWRlYWxWZWxvY2l0eTtmb3IodmFyIHUgaW4gZSlpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZSx1KSl7dmFyIGM9ZVt1XTtcIm51bWJlclwiPT10eXBlb2YgYyYmKHR8fCh0PSEwLHI9YSh7fSxyKSxpPWEoe30saSksbD1hKHt9LGwpLHM9YSh7fSxzKSksclt1XT1jLGlbdV09MCxsW3VdPWMsc1t1XT0wKX10JiZvLnNldFN0YXRlKHtjdXJyZW50U3R5bGU6cixjdXJyZW50VmVsb2NpdHk6aSxsYXN0SWRlYWxTdHlsZTpsLGxhc3RJZGVhbFZlbG9jaXR5OnN9KX0sdGhpcy5zdGFydEFuaW1hdGlvbklmTmVjZXNzYXJ5PWZ1bmN0aW9uKCl7by5hbmltYXRpb25JRD1tLmRlZmF1bHQoZnVuY3Rpb24oZSl7dmFyIHQ9by5wcm9wcy5zdHlsZTtpZihTLmRlZmF1bHQoby5zdGF0ZS5jdXJyZW50U3R5bGUsdCxvLnN0YXRlLmN1cnJlbnRWZWxvY2l0eSkpcmV0dXJuIG8ud2FzQW5pbWF0aW5nJiZvLnByb3BzLm9uUmVzdCYmby5wcm9wcy5vblJlc3QoKSxvLmFuaW1hdGlvbklEPW51bGwsby53YXNBbmltYXRpbmc9ITEsdm9pZChvLmFjY3VtdWxhdGVkVGltZT0wKTtvLndhc0FuaW1hdGluZz0hMDt2YXIgbj1lfHx5LmRlZmF1bHQoKSxyPW4tby5wcmV2VGltZTtpZihvLnByZXZUaW1lPW4sby5hY2N1bXVsYXRlZFRpbWU9by5hY2N1bXVsYXRlZFRpbWUrcixvLmFjY3VtdWxhdGVkVGltZT4xMCprJiYoby5hY2N1bXVsYXRlZFRpbWU9MCksMD09PW8uYWNjdW11bGF0ZWRUaW1lKXJldHVybiBvLmFuaW1hdGlvbklEPW51bGwsdm9pZCBvLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKTt2YXIgaT0oby5hY2N1bXVsYXRlZFRpbWUtTWF0aC5mbG9vcihvLmFjY3VtdWxhdGVkVGltZS9rKSprKS9rLGE9TWF0aC5mbG9vcihvLmFjY3VtdWxhdGVkVGltZS9rKSxsPXt9LHM9e30sdT17fSxjPXt9O2Zvcih2YXIgZiBpbiB0KWlmKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0LGYpKXt2YXIgcD10W2ZdO2lmKFwibnVtYmVyXCI9PXR5cGVvZiBwKXVbZl09cCxjW2ZdPTAsbFtmXT1wLHNbZl09MDtlbHNle2Zvcih2YXIgaD1vLnN0YXRlLmxhc3RJZGVhbFN0eWxlW2ZdLHY9by5zdGF0ZS5sYXN0SWRlYWxWZWxvY2l0eVtmXSxtPTA7bTxhO20rKyl7dmFyIGI9ZC5kZWZhdWx0KGsvMWUzLGgsdixwLnZhbCxwLnN0aWZmbmVzcyxwLmRhbXBpbmcscC5wcmVjaXNpb24pO2g9YlswXSx2PWJbMV19dmFyIGc9ZC5kZWZhdWx0KGsvMWUzLGgsdixwLnZhbCxwLnN0aWZmbmVzcyxwLmRhbXBpbmcscC5wcmVjaXNpb24pLHc9Z1swXSxQPWdbMV07dVtmXT1oKyh3LWgpKmksY1tmXT12KyhQLXYpKmksbFtmXT1oLHNbZl09dn19by5hbmltYXRpb25JRD1udWxsLG8uYWNjdW11bGF0ZWRUaW1lLT1hKmssby5zZXRTdGF0ZSh7Y3VycmVudFN0eWxlOnUsY3VycmVudFZlbG9jaXR5OmMsbGFzdElkZWFsU3R5bGU6bCxsYXN0SWRlYWxWZWxvY2l0eTpzfSksby51bnJlYWRQcm9wU3R5bGU9bnVsbCxvLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKX0pfSx0aGlzLnN0YXRlPXRoaXMuZGVmYXVsdFN0YXRlKCl9cmV0dXJuIGkodCxlKSxsKHQsbnVsbCxbe2tleTpcInByb3BUeXBlc1wiLHZhbHVlOntkZWZhdWx0U3R5bGU6VC5kZWZhdWx0Lm9iamVjdE9mKFQuZGVmYXVsdC5udW1iZXIpLHN0eWxlOlQuZGVmYXVsdC5vYmplY3RPZihULmRlZmF1bHQub25lT2ZUeXBlKFtULmRlZmF1bHQubnVtYmVyLFQuZGVmYXVsdC5vYmplY3RdKSkuaXNSZXF1aXJlZCxjaGlsZHJlbjpULmRlZmF1bHQuZnVuYy5pc1JlcXVpcmVkLG9uUmVzdDpULmRlZmF1bHQuZnVuY30sZW51bWVyYWJsZTohMH1dKSx0LnByb3RvdHlwZS5kZWZhdWx0U3RhdGU9ZnVuY3Rpb24oKXt2YXIgZT10aGlzLnByb3BzLHQ9ZS5kZWZhdWx0U3R5bGUsbj1lLnN0eWxlLG89dHx8Zi5kZWZhdWx0KG4pLHI9dS5kZWZhdWx0KG8pO3JldHVybntjdXJyZW50U3R5bGU6byxjdXJyZW50VmVsb2NpdHk6cixsYXN0SWRlYWxTdHlsZTpvLGxhc3RJZGVhbFZlbG9jaXR5OnJ9fSx0LnByb3RvdHlwZS5jb21wb25lbnREaWRNb3VudD1mdW5jdGlvbigpe3RoaXMucHJldlRpbWU9eS5kZWZhdWx0KCksdGhpcy5zdGFydEFuaW1hdGlvbklmTmVjZXNzYXJ5KCl9LHQucHJvdG90eXBlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHM9ZnVuY3Rpb24oZSl7bnVsbCE9dGhpcy51bnJlYWRQcm9wU3R5bGUmJnRoaXMuY2xlYXJVbnJlYWRQcm9wU3R5bGUodGhpcy51bnJlYWRQcm9wU3R5bGUpLHRoaXMudW5yZWFkUHJvcFN0eWxlPWUuc3R5bGUsbnVsbD09dGhpcy5hbmltYXRpb25JRCYmKHRoaXMucHJldlRpbWU9eS5kZWZhdWx0KCksdGhpcy5zdGFydEFuaW1hdGlvbklmTmVjZXNzYXJ5KCkpfSx0LnByb3RvdHlwZS5jb21wb25lbnRXaWxsVW5tb3VudD1mdW5jdGlvbigpe251bGwhPXRoaXMuYW5pbWF0aW9uSUQmJihtLmRlZmF1bHQuY2FuY2VsKHRoaXMuYW5pbWF0aW9uSUQpLHRoaXMuYW5pbWF0aW9uSUQ9bnVsbCl9LHQucHJvdG90eXBlLnJlbmRlcj1mdW5jdGlvbigpe3ZhciBlPXRoaXMucHJvcHMuY2hpbGRyZW4odGhpcy5zdGF0ZS5jdXJyZW50U3R5bGUpO3JldHVybiBlJiZ3LmRlZmF1bHQuQ2hpbGRyZW4ub25seShlKX0sdH0ody5kZWZhdWx0LkNvbXBvbmVudCk7dC5kZWZhdWx0PU8sZS5leHBvcnRzPXQuZGVmYXVsdH0sZnVuY3Rpb24oZSx0LG4pe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG8oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fWZ1bmN0aW9uIHIoZSx0KXtpZighKGUgaW5zdGFuY2VvZiB0KSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpfWZ1bmN0aW9uIGkoZSx0KXtpZihcImZ1bmN0aW9uXCIhPXR5cGVvZiB0JiZudWxsIT09dCl0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCBcIit0eXBlb2YgdCk7ZS5wcm90b3R5cGU9T2JqZWN0LmNyZWF0ZSh0JiZ0LnByb3RvdHlwZSx7Y29uc3RydWN0b3I6e3ZhbHVlOmUsZW51bWVyYWJsZTohMSx3cml0YWJsZTohMCxjb25maWd1cmFibGU6ITB9fSksdCYmKE9iamVjdC5zZXRQcm90b3R5cGVPZj9PYmplY3Quc2V0UHJvdG90eXBlT2YoZSx0KTplLl9fcHJvdG9fXz10KX1mdW5jdGlvbiBhKGUsdCxuKXtmb3IodmFyIG89MDtvPGUubGVuZ3RoO28rKylpZighZy5kZWZhdWx0KGVbb10sdFtvXSxuW29dKSlyZXR1cm4hMTtyZXR1cm4hMH10Ll9fZXNNb2R1bGU9ITA7dmFyIGw9T2JqZWN0LmFzc2lnbnx8ZnVuY3Rpb24oZSl7Zm9yKHZhciB0PTE7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyl7dmFyIG49YXJndW1lbnRzW3RdO2Zvcih2YXIgbyBpbiBuKU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChuLG8pJiYoZVtvXT1uW29dKX1yZXR1cm4gZX0scz1mdW5jdGlvbigpe2Z1bmN0aW9uIGUoZSx0KXtmb3IodmFyIG49MDtuPHQubGVuZ3RoO24rKyl7dmFyIG89dFtuXTtvLmVudW1lcmFibGU9by5lbnVtZXJhYmxlfHwhMSxvLmNvbmZpZ3VyYWJsZT0hMCxcInZhbHVlXCJpbiBvJiYoby53cml0YWJsZT0hMCksT2JqZWN0LmRlZmluZVByb3BlcnR5KGUsby5rZXksbyl9fXJldHVybiBmdW5jdGlvbih0LG4sbyl7cmV0dXJuIG4mJmUodC5wcm90b3R5cGUsbiksbyYmZSh0LG8pLHR9fSgpLHU9big2KSxjPW8odSksZj1uKDMpLHA9byhmKSxkPW4oOCksaD1vKGQpLHk9big0KSx2PW8oeSksbT1uKDUpLGI9byhtKSxTPW4oNyksZz1vKFMpLHc9bigxKSxQPW8odyksVD1uKDIpLGs9byhUKSxPPTFlMy82MCxNPWZ1bmN0aW9uKGUpe2Z1bmN0aW9uIHQobil7dmFyIG89dGhpcztyKHRoaXMsdCksZS5jYWxsKHRoaXMsbiksdGhpcy5hbmltYXRpb25JRD1udWxsLHRoaXMucHJldlRpbWU9MCx0aGlzLmFjY3VtdWxhdGVkVGltZT0wLHRoaXMudW5yZWFkUHJvcFN0eWxlcz1udWxsLHRoaXMuY2xlYXJVbnJlYWRQcm9wU3R5bGU9ZnVuY3Rpb24oZSl7Zm9yKHZhciB0PW8uc3RhdGUsbj10LmN1cnJlbnRTdHlsZXMscj10LmN1cnJlbnRWZWxvY2l0aWVzLGk9dC5sYXN0SWRlYWxTdHlsZXMsYT10Lmxhc3RJZGVhbFZlbG9jaXRpZXMscz0hMSx1PTA7dTxlLmxlbmd0aDt1Kyspe3ZhciBjPWVbdV0sZj0hMTtmb3IodmFyIHAgaW4gYylpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYyxwKSl7dmFyIGQ9Y1twXTtcIm51bWJlclwiPT10eXBlb2YgZCYmKGZ8fChmPSEwLHM9ITAsblt1XT1sKHt9LG5bdV0pLHJbdV09bCh7fSxyW3VdKSxpW3VdPWwoe30saVt1XSksYVt1XT1sKHt9LGFbdV0pKSxuW3VdW3BdPWQsclt1XVtwXT0wLFxuaVt1XVtwXT1kLGFbdV1bcF09MCl9fXMmJm8uc2V0U3RhdGUoe2N1cnJlbnRTdHlsZXM6bixjdXJyZW50VmVsb2NpdGllczpyLGxhc3RJZGVhbFN0eWxlczppLGxhc3RJZGVhbFZlbG9jaXRpZXM6YX0pfSx0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3Nhcnk9ZnVuY3Rpb24oKXtvLmFuaW1hdGlvbklEPWIuZGVmYXVsdChmdW5jdGlvbihlKXt2YXIgdD1vLnByb3BzLnN0eWxlcyhvLnN0YXRlLmxhc3RJZGVhbFN0eWxlcyk7aWYoYShvLnN0YXRlLmN1cnJlbnRTdHlsZXMsdCxvLnN0YXRlLmN1cnJlbnRWZWxvY2l0aWVzKSlyZXR1cm4gby5hbmltYXRpb25JRD1udWxsLHZvaWQoby5hY2N1bXVsYXRlZFRpbWU9MCk7dmFyIG49ZXx8di5kZWZhdWx0KCkscj1uLW8ucHJldlRpbWU7aWYoby5wcmV2VGltZT1uLG8uYWNjdW11bGF0ZWRUaW1lPW8uYWNjdW11bGF0ZWRUaW1lK3Isby5hY2N1bXVsYXRlZFRpbWU+MTAqTyYmKG8uYWNjdW11bGF0ZWRUaW1lPTApLDA9PT1vLmFjY3VtdWxhdGVkVGltZSlyZXR1cm4gby5hbmltYXRpb25JRD1udWxsLHZvaWQgby5zdGFydEFuaW1hdGlvbklmTmVjZXNzYXJ5KCk7Zm9yKHZhciBpPShvLmFjY3VtdWxhdGVkVGltZS1NYXRoLmZsb29yKG8uYWNjdW11bGF0ZWRUaW1lL08pKk8pL08sbD1NYXRoLmZsb29yKG8uYWNjdW11bGF0ZWRUaW1lL08pLHM9W10sdT1bXSxjPVtdLGY9W10scD0wO3A8dC5sZW5ndGg7cCsrKXt2YXIgZD10W3BdLHk9e30sbT17fSxiPXt9LFM9e307Zm9yKHZhciBnIGluIGQpaWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGQsZykpe3ZhciB3PWRbZ107aWYoXCJudW1iZXJcIj09dHlwZW9mIHcpeVtnXT13LG1bZ109MCxiW2ddPXcsU1tnXT0wO2Vsc2V7Zm9yKHZhciBQPW8uc3RhdGUubGFzdElkZWFsU3R5bGVzW3BdW2ddLFQ9by5zdGF0ZS5sYXN0SWRlYWxWZWxvY2l0aWVzW3BdW2ddLGs9MDtrPGw7aysrKXt2YXIgTT1oLmRlZmF1bHQoTy8xZTMsUCxULHcudmFsLHcuc3RpZmZuZXNzLHcuZGFtcGluZyx3LnByZWNpc2lvbik7UD1NWzBdLFQ9TVsxXX12YXIgeD1oLmRlZmF1bHQoTy8xZTMsUCxULHcudmFsLHcuc3RpZmZuZXNzLHcuZGFtcGluZyx3LnByZWNpc2lvbiksST14WzBdLEQ9eFsxXTt5W2ddPVArKEktUCkqaSxtW2ddPVQrKEQtVCkqaSxiW2ddPVAsU1tnXT1UfX1jW3BdPXksZltwXT1tLHNbcF09Yix1W3BdPVN9by5hbmltYXRpb25JRD1udWxsLG8uYWNjdW11bGF0ZWRUaW1lLT1sKk8sby5zZXRTdGF0ZSh7Y3VycmVudFN0eWxlczpjLGN1cnJlbnRWZWxvY2l0aWVzOmYsbGFzdElkZWFsU3R5bGVzOnMsbGFzdElkZWFsVmVsb2NpdGllczp1fSksby51bnJlYWRQcm9wU3R5bGVzPW51bGwsby5zdGFydEFuaW1hdGlvbklmTmVjZXNzYXJ5KCl9KX0sdGhpcy5zdGF0ZT10aGlzLmRlZmF1bHRTdGF0ZSgpfXJldHVybiBpKHQsZSkscyh0LG51bGwsW3trZXk6XCJwcm9wVHlwZXNcIix2YWx1ZTp7ZGVmYXVsdFN0eWxlczprLmRlZmF1bHQuYXJyYXlPZihrLmRlZmF1bHQub2JqZWN0T2Yoay5kZWZhdWx0Lm51bWJlcikpLHN0eWxlczprLmRlZmF1bHQuZnVuYy5pc1JlcXVpcmVkLGNoaWxkcmVuOmsuZGVmYXVsdC5mdW5jLmlzUmVxdWlyZWR9LGVudW1lcmFibGU6ITB9XSksdC5wcm90b3R5cGUuZGVmYXVsdFN0YXRlPWZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5wcm9wcyx0PWUuZGVmYXVsdFN0eWxlcyxuPWUuc3R5bGVzLG89dHx8bigpLm1hcChwLmRlZmF1bHQpLHI9by5tYXAoZnVuY3Rpb24oZSl7cmV0dXJuIGMuZGVmYXVsdChlKX0pO3JldHVybntjdXJyZW50U3R5bGVzOm8sY3VycmVudFZlbG9jaXRpZXM6cixsYXN0SWRlYWxTdHlsZXM6byxsYXN0SWRlYWxWZWxvY2l0aWVzOnJ9fSx0LnByb3RvdHlwZS5jb21wb25lbnREaWRNb3VudD1mdW5jdGlvbigpe3RoaXMucHJldlRpbWU9di5kZWZhdWx0KCksdGhpcy5zdGFydEFuaW1hdGlvbklmTmVjZXNzYXJ5KCl9LHQucHJvdG90eXBlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHM9ZnVuY3Rpb24oZSl7bnVsbCE9dGhpcy51bnJlYWRQcm9wU3R5bGVzJiZ0aGlzLmNsZWFyVW5yZWFkUHJvcFN0eWxlKHRoaXMudW5yZWFkUHJvcFN0eWxlcyksdGhpcy51bnJlYWRQcm9wU3R5bGVzPWUuc3R5bGVzKHRoaXMuc3RhdGUubGFzdElkZWFsU3R5bGVzKSxudWxsPT10aGlzLmFuaW1hdGlvbklEJiYodGhpcy5wcmV2VGltZT12LmRlZmF1bHQoKSx0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKSl9LHQucHJvdG90eXBlLmNvbXBvbmVudFdpbGxVbm1vdW50PWZ1bmN0aW9uKCl7bnVsbCE9dGhpcy5hbmltYXRpb25JRCYmKGIuZGVmYXVsdC5jYW5jZWwodGhpcy5hbmltYXRpb25JRCksdGhpcy5hbmltYXRpb25JRD1udWxsKX0sdC5wcm90b3R5cGUucmVuZGVyPWZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5wcm9wcy5jaGlsZHJlbih0aGlzLnN0YXRlLmN1cnJlbnRTdHlsZXMpO3JldHVybiBlJiZQLmRlZmF1bHQuQ2hpbGRyZW4ub25seShlKX0sdH0oUC5kZWZhdWx0LkNvbXBvbmVudCk7dC5kZWZhdWx0PU0sZS5leHBvcnRzPXQuZGVmYXVsdH0sZnVuY3Rpb24oZSx0LG4pe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG8oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fWZ1bmN0aW9uIHIoZSx0KXtpZighKGUgaW5zdGFuY2VvZiB0KSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpfWZ1bmN0aW9uIGkoZSx0KXtpZihcImZ1bmN0aW9uXCIhPXR5cGVvZiB0JiZudWxsIT09dCl0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCBcIit0eXBlb2YgdCk7ZS5wcm90b3R5cGU9T2JqZWN0LmNyZWF0ZSh0JiZ0LnByb3RvdHlwZSx7Y29uc3RydWN0b3I6e3ZhbHVlOmUsZW51bWVyYWJsZTohMSx3cml0YWJsZTohMCxjb25maWd1cmFibGU6ITB9fSksdCYmKE9iamVjdC5zZXRQcm90b3R5cGVPZj9PYmplY3Quc2V0UHJvdG90eXBlT2YoZSx0KTplLl9fcHJvdG9fXz10KX1mdW5jdGlvbiBhKGUsdCxuKXt2YXIgbz10O3JldHVybiBudWxsPT1vP2UubWFwKGZ1bmN0aW9uKGUsdCl7cmV0dXJue2tleTplLmtleSxkYXRhOmUuZGF0YSxzdHlsZTpuW3RdfX0pOmUubWFwKGZ1bmN0aW9uKGUsdCl7Zm9yKHZhciByPTA7cjxvLmxlbmd0aDtyKyspaWYob1tyXS5rZXk9PT1lLmtleSlyZXR1cm57a2V5Om9bcl0ua2V5LGRhdGE6b1tyXS5kYXRhLHN0eWxlOm5bdF19O3JldHVybntrZXk6ZS5rZXksZGF0YTplLmRhdGEsc3R5bGU6blt0XX19KX1mdW5jdGlvbiBsKGUsdCxuLG8pe2lmKG8ubGVuZ3RoIT09dC5sZW5ndGgpcmV0dXJuITE7Zm9yKHZhciByPTA7cjxvLmxlbmd0aDtyKyspaWYob1tyXS5rZXkhPT10W3JdLmtleSlyZXR1cm4hMTtmb3IodmFyIHI9MDtyPG8ubGVuZ3RoO3IrKylpZighay5kZWZhdWx0KGVbcl0sdFtyXS5zdHlsZSxuW3JdKSlyZXR1cm4hMTtyZXR1cm4hMH1mdW5jdGlvbiBzKGUsdCxuLG8scixpLGEsbCxzKXtmb3IodmFyIHU9Yi5kZWZhdWx0KG8scixmdW5jdGlvbihlLG8pe3ZhciByPXQobyk7cmV0dXJuIG51bGw9PXI/KG4oe2tleTpvLmtleSxkYXRhOm8uZGF0YX0pLG51bGwpOmsuZGVmYXVsdChpW2VdLHIsYVtlXSk/KG4oe2tleTpvLmtleSxkYXRhOm8uZGF0YX0pLG51bGwpOntrZXk6by5rZXksZGF0YTpvLmRhdGEsc3R5bGU6cn19KSxjPVtdLGY9W10sZD1bXSxoPVtdLHk9MDt5PHUubGVuZ3RoO3krKyl7Zm9yKHZhciB2PXVbeV0sbT1udWxsLFM9MDtTPG8ubGVuZ3RoO1MrKylpZihvW1NdLmtleT09PXYua2V5KXttPVM7YnJlYWt9aWYobnVsbD09bSl7dmFyIGc9ZSh2KTtjW3ldPWcsZFt5XT1nO3ZhciB3PXAuZGVmYXVsdCh2LnN0eWxlKTtmW3ldPXcsaFt5XT13fWVsc2UgY1t5XT1pW21dLGRbeV09bFttXSxmW3ldPWFbbV0saFt5XT1zW21dfXJldHVyblt1LGMsZixkLGhdfXQuX19lc01vZHVsZT0hMDt2YXIgdT1PYmplY3QuYXNzaWdufHxmdW5jdGlvbihlKXtmb3IodmFyIHQ9MTt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKXt2YXIgbj1hcmd1bWVudHNbdF07Zm9yKHZhciBvIGluIG4pT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG4sbykmJihlW29dPW5bb10pfXJldHVybiBlfSxjPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gZShlLHQpe2Zvcih2YXIgbj0wO248dC5sZW5ndGg7bisrKXt2YXIgbz10W25dO28uZW51bWVyYWJsZT1vLmVudW1lcmFibGV8fCExLG8uY29uZmlndXJhYmxlPSEwLFwidmFsdWVcImluIG8mJihvLndyaXRhYmxlPSEwKSxPYmplY3QuZGVmaW5lUHJvcGVydHkoZSxvLmtleSxvKX19cmV0dXJuIGZ1bmN0aW9uKHQsbixvKXtyZXR1cm4gbiYmZSh0LnByb3RvdHlwZSxuKSxvJiZlKHQsbyksdH19KCksZj1uKDYpLHA9byhmKSxkPW4oMyksaD1vKGQpLHk9big4KSx2PW8oeSksbT1uKDI3KSxiPW8obSksUz1uKDQpLGc9byhTKSx3PW4oNSksUD1vKHcpLFQ9big3KSxrPW8oVCksTz1uKDEpLE09byhPKSx4PW4oMiksST1vKHgpLEQ9MWUzLzYwLF89ZnVuY3Rpb24oZSl7ZnVuY3Rpb24gdChuKXt2YXIgbz10aGlzO3IodGhpcyx0KSxlLmNhbGwodGhpcyxuKSx0aGlzLnVubW91bnRpbmc9ITEsdGhpcy5hbmltYXRpb25JRD1udWxsLHRoaXMucHJldlRpbWU9MCx0aGlzLmFjY3VtdWxhdGVkVGltZT0wLHRoaXMudW5yZWFkUHJvcFN0eWxlcz1udWxsLHRoaXMuY2xlYXJVbnJlYWRQcm9wU3R5bGU9ZnVuY3Rpb24oZSl7Zm9yKHZhciB0PXMoby5wcm9wcy53aWxsRW50ZXIsby5wcm9wcy53aWxsTGVhdmUsby5wcm9wcy5kaWRMZWF2ZSxvLnN0YXRlLm1lcmdlZFByb3BzU3R5bGVzLGUsby5zdGF0ZS5jdXJyZW50U3R5bGVzLG8uc3RhdGUuY3VycmVudFZlbG9jaXRpZXMsby5zdGF0ZS5sYXN0SWRlYWxTdHlsZXMsby5zdGF0ZS5sYXN0SWRlYWxWZWxvY2l0aWVzKSxuPXRbMF0scj10WzFdLGk9dFsyXSxhPXRbM10sbD10WzRdLGM9MDtjPGUubGVuZ3RoO2MrKyl7dmFyIGY9ZVtjXS5zdHlsZSxwPSExO2Zvcih2YXIgZCBpbiBmKWlmKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChmLGQpKXt2YXIgaD1mW2RdO1wibnVtYmVyXCI9PXR5cGVvZiBoJiYocHx8KHA9ITAscltjXT11KHt9LHJbY10pLGlbY109dSh7fSxpW2NdKSxhW2NdPXUoe30sYVtjXSksbFtjXT11KHt9LGxbY10pLG5bY109e2tleTpuW2NdLmtleSxkYXRhOm5bY10uZGF0YSxzdHlsZTp1KHt9LG5bY10uc3R5bGUpfSkscltjXVtkXT1oLGlbY11bZF09MCxhW2NdW2RdPWgsbFtjXVtkXT0wLG5bY10uc3R5bGVbZF09aCl9fW8uc2V0U3RhdGUoe2N1cnJlbnRTdHlsZXM6cixjdXJyZW50VmVsb2NpdGllczppLG1lcmdlZFByb3BzU3R5bGVzOm4sbGFzdElkZWFsU3R5bGVzOmEsbGFzdElkZWFsVmVsb2NpdGllczpsfSl9LHRoaXMuc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeT1mdW5jdGlvbigpe28udW5tb3VudGluZ3x8KG8uYW5pbWF0aW9uSUQ9UC5kZWZhdWx0KGZ1bmN0aW9uKGUpe2lmKCFvLnVubW91bnRpbmcpe3ZhciB0PW8ucHJvcHMuc3R5bGVzLG49XCJmdW5jdGlvblwiPT10eXBlb2YgdD90KGEoby5zdGF0ZS5tZXJnZWRQcm9wc1N0eWxlcyxvLnVucmVhZFByb3BTdHlsZXMsby5zdGF0ZS5sYXN0SWRlYWxTdHlsZXMpKTp0O2lmKGwoby5zdGF0ZS5jdXJyZW50U3R5bGVzLG4sby5zdGF0ZS5jdXJyZW50VmVsb2NpdGllcyxvLnN0YXRlLm1lcmdlZFByb3BzU3R5bGVzKSlyZXR1cm4gby5hbmltYXRpb25JRD1udWxsLHZvaWQoby5hY2N1bXVsYXRlZFRpbWU9MCk7dmFyIHI9ZXx8Zy5kZWZhdWx0KCksaT1yLW8ucHJldlRpbWU7aWYoby5wcmV2VGltZT1yLG8uYWNjdW11bGF0ZWRUaW1lPW8uYWNjdW11bGF0ZWRUaW1lK2ksby5hY2N1bXVsYXRlZFRpbWU+MTAqRCYmKG8uYWNjdW11bGF0ZWRUaW1lPTApLDA9PT1vLmFjY3VtdWxhdGVkVGltZSlyZXR1cm4gby5hbmltYXRpb25JRD1udWxsLHZvaWQgby5zdGFydEFuaW1hdGlvbklmTmVjZXNzYXJ5KCk7Zm9yKHZhciB1PShvLmFjY3VtdWxhdGVkVGltZS1NYXRoLmZsb29yKG8uYWNjdW11bGF0ZWRUaW1lL0QpKkQpL0QsYz1NYXRoLmZsb29yKG8uYWNjdW11bGF0ZWRUaW1lL0QpLGY9cyhvLnByb3BzLndpbGxFbnRlcixvLnByb3BzLndpbGxMZWF2ZSxvLnByb3BzLmRpZExlYXZlLG8uc3RhdGUubWVyZ2VkUHJvcHNTdHlsZXMsbixvLnN0YXRlLmN1cnJlbnRTdHlsZXMsby5zdGF0ZS5jdXJyZW50VmVsb2NpdGllcyxvLnN0YXRlLmxhc3RJZGVhbFN0eWxlcyxvLnN0YXRlLmxhc3RJZGVhbFZlbG9jaXRpZXMpLHA9ZlswXSxkPWZbMV0saD1mWzJdLHk9ZlszXSxtPWZbNF0sYj0wO2I8cC5sZW5ndGg7YisrKXt2YXIgUz1wW2JdLnN0eWxlLHc9e30sUD17fSxUPXt9LGs9e307Zm9yKHZhciBPIGluIFMpaWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKFMsTykpe3ZhciBNPVNbT107aWYoXCJudW1iZXJcIj09dHlwZW9mIE0pd1tPXT1NLFBbT109MCxUW09dPU0sa1tPXT0wO2Vsc2V7Zm9yKHZhciB4PXlbYl1bT10sST1tW2JdW09dLF89MDtfPGM7XysrKXt2YXIgaj12LmRlZmF1bHQoRC8xZTMseCxJLE0udmFsLE0uc3RpZmZuZXNzLE0uZGFtcGluZyxNLnByZWNpc2lvbik7eD1qWzBdLEk9alsxXX12YXIgQz12LmRlZmF1bHQoRC8xZTMseCxJLE0udmFsLE0uc3RpZmZuZXNzLE0uZGFtcGluZyxNLnByZWNpc2lvbiksej1DWzBdLEU9Q1sxXTt3W09dPXgrKHoteCkqdSxQW09dPUkrKEUtSSkqdSxUW09dPXgsa1tPXT1JfX15W2JdPVQsbVtiXT1rLGRbYl09dyxoW2JdPVB9by5hbmltYXRpb25JRD1udWxsLG8uYWNjdW11bGF0ZWRUaW1lLT1jKkQsby5zZXRTdGF0ZSh7Y3VycmVudFN0eWxlczpkLGN1cnJlbnRWZWxvY2l0aWVzOmgsbGFzdElkZWFsU3R5bGVzOnksbGFzdElkZWFsVmVsb2NpdGllczptLG1lcmdlZFByb3BzU3R5bGVzOnB9KSxvLnVucmVhZFByb3BTdHlsZXM9bnVsbCxvLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKX19KSl9LHRoaXMuc3RhdGU9dGhpcy5kZWZhdWx0U3RhdGUoKX1yZXR1cm4gaSh0LGUpLGModCxudWxsLFt7a2V5OlwicHJvcFR5cGVzXCIsdmFsdWU6e2RlZmF1bHRTdHlsZXM6SS5kZWZhdWx0LmFycmF5T2YoSS5kZWZhdWx0LnNoYXBlKHtrZXk6SS5kZWZhdWx0LnN0cmluZy5pc1JlcXVpcmVkLGRhdGE6SS5kZWZhdWx0LmFueSxzdHlsZTpJLmRlZmF1bHQub2JqZWN0T2YoSS5kZWZhdWx0Lm51bWJlcikuaXNSZXF1aXJlZH0pKSxzdHlsZXM6SS5kZWZhdWx0Lm9uZU9mVHlwZShbSS5kZWZhdWx0LmZ1bmMsSS5kZWZhdWx0LmFycmF5T2YoSS5kZWZhdWx0LnNoYXBlKHtrZXk6SS5kZWZhdWx0LnN0cmluZy5pc1JlcXVpcmVkLGRhdGE6SS5kZWZhdWx0LmFueSxzdHlsZTpJLmRlZmF1bHQub2JqZWN0T2YoSS5kZWZhdWx0Lm9uZU9mVHlwZShbSS5kZWZhdWx0Lm51bWJlcixJLmRlZmF1bHQub2JqZWN0XSkpLmlzUmVxdWlyZWR9KSldKS5pc1JlcXVpcmVkLGNoaWxkcmVuOkkuZGVmYXVsdC5mdW5jLmlzUmVxdWlyZWQsd2lsbEVudGVyOkkuZGVmYXVsdC5mdW5jLHdpbGxMZWF2ZTpJLmRlZmF1bHQuZnVuYyxkaWRMZWF2ZTpJLmRlZmF1bHQuZnVuY30sZW51bWVyYWJsZTohMH0se2tleTpcImRlZmF1bHRQcm9wc1wiLHZhbHVlOnt3aWxsRW50ZXI6ZnVuY3Rpb24oZSl7cmV0dXJuIGguZGVmYXVsdChlLnN0eWxlKX0sd2lsbExlYXZlOmZ1bmN0aW9uKCl7cmV0dXJuIG51bGx9LGRpZExlYXZlOmZ1bmN0aW9uKCl7fX0sZW51bWVyYWJsZTohMH1dKSx0LnByb3RvdHlwZS5kZWZhdWx0U3RhdGU9ZnVuY3Rpb24oKXt2YXIgZT10aGlzLnByb3BzLHQ9ZS5kZWZhdWx0U3R5bGVzLG49ZS5zdHlsZXMsbz1lLndpbGxFbnRlcixyPWUud2lsbExlYXZlLGk9ZS5kaWRMZWF2ZSxhPVwiZnVuY3Rpb25cIj09dHlwZW9mIG4/bih0KTpuLGw9dm9pZCAwO2w9bnVsbD09dD9hOnQubWFwKGZ1bmN0aW9uKGUpe2Zvcih2YXIgdD0wO3Q8YS5sZW5ndGg7dCsrKWlmKGFbdF0ua2V5PT09ZS5rZXkpcmV0dXJuIGFbdF07cmV0dXJuIGV9KTt2YXIgdT1udWxsPT10P2EubWFwKGZ1bmN0aW9uKGUpe3JldHVybiBoLmRlZmF1bHQoZS5zdHlsZSl9KTp0Lm1hcChmdW5jdGlvbihlKXtyZXR1cm4gaC5kZWZhdWx0KGUuc3R5bGUpfSksYz1udWxsPT10P2EubWFwKGZ1bmN0aW9uKGUpe3JldHVybiBwLmRlZmF1bHQoZS5zdHlsZSl9KTp0Lm1hcChmdW5jdGlvbihlKXtyZXR1cm4gcC5kZWZhdWx0KGUuc3R5bGUpfSksZj1zKG8scixpLGwsYSx1LGMsdSxjKSxkPWZbMF0seT1mWzFdLHY9ZlsyXSxtPWZbM10sYj1mWzRdO3JldHVybntjdXJyZW50U3R5bGVzOnksY3VycmVudFZlbG9jaXRpZXM6dixsYXN0SWRlYWxTdHlsZXM6bSxsYXN0SWRlYWxWZWxvY2l0aWVzOmIsbWVyZ2VkUHJvcHNTdHlsZXM6ZH19LHQucHJvdG90eXBlLmNvbXBvbmVudERpZE1vdW50PWZ1bmN0aW9uKCl7dGhpcy5wcmV2VGltZT1nLmRlZmF1bHQoKSx0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKX0sdC5wcm90b3R5cGUuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcz1mdW5jdGlvbihlKXt0aGlzLnVucmVhZFByb3BTdHlsZXMmJnRoaXMuY2xlYXJVbnJlYWRQcm9wU3R5bGUodGhpcy51bnJlYWRQcm9wU3R5bGVzKTt2YXIgdD1lLnN0eWxlcztcImZ1bmN0aW9uXCI9PXR5cGVvZiB0P3RoaXMudW5yZWFkUHJvcFN0eWxlcz10KGEodGhpcy5zdGF0ZS5tZXJnZWRQcm9wc1N0eWxlcyx0aGlzLnVucmVhZFByb3BTdHlsZXMsdGhpcy5zdGF0ZS5sYXN0SWRlYWxTdHlsZXMpKTp0aGlzLnVucmVhZFByb3BTdHlsZXM9dCxudWxsPT10aGlzLmFuaW1hdGlvbklEJiYodGhpcy5wcmV2VGltZT1nLmRlZmF1bHQoKSx0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKSl9LHQucHJvdG90eXBlLmNvbXBvbmVudFdpbGxVbm1vdW50PWZ1bmN0aW9uKCl7dGhpcy51bm1vdW50aW5nPSEwLG51bGwhPXRoaXMuYW5pbWF0aW9uSUQmJihQLmRlZmF1bHQuY2FuY2VsKHRoaXMuYW5pbWF0aW9uSUQpLHRoaXMuYW5pbWF0aW9uSUQ9bnVsbCl9LHQucHJvdG90eXBlLnJlbmRlcj1mdW5jdGlvbigpe3ZhciBlPWEodGhpcy5zdGF0ZS5tZXJnZWRQcm9wc1N0eWxlcyx0aGlzLnVucmVhZFByb3BTdHlsZXMsdGhpcy5zdGF0ZS5jdXJyZW50U3R5bGVzKSx0PXRoaXMucHJvcHMuY2hpbGRyZW4oZSk7cmV0dXJuIHQmJk0uZGVmYXVsdC5DaGlsZHJlbi5vbmx5KHQpfSx0fShNLmRlZmF1bHQuQ29tcG9uZW50KTt0LmRlZmF1bHQ9XyxlLmV4cG9ydHM9dC5kZWZhdWx0fSxmdW5jdGlvbihlLHQpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG4oZSx0LG4pe2Zvcih2YXIgbz17fSxyPTA7cjxlLmxlbmd0aDtyKyspb1tlW3JdLmtleV09cjtmb3IodmFyIGk9e30scj0wO3I8dC5sZW5ndGg7cisrKWlbdFtyXS5rZXldPXI7Zm9yKHZhciBhPVtdLHI9MDtyPHQubGVuZ3RoO3IrKylhW3JdPXRbcl07Zm9yKHZhciByPTA7cjxlLmxlbmd0aDtyKyspaWYoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChpLGVbcl0ua2V5KSl7dmFyIGw9bihyLGVbcl0pO251bGwhPWwmJmEucHVzaChsKX1yZXR1cm4gYS5zb3J0KGZ1bmN0aW9uKGUsbil7dmFyIHI9aVtlLmtleV0sYT1pW24ua2V5XSxsPW9bZS5rZXldLHM9b1tuLmtleV07aWYobnVsbCE9ciYmbnVsbCE9YSlyZXR1cm4gaVtlLmtleV0taVtuLmtleV07aWYobnVsbCE9bCYmbnVsbCE9cylyZXR1cm4gb1tlLmtleV0tb1tuLmtleV07aWYobnVsbCE9cil7Zm9yKHZhciB1PTA7dTx0Lmxlbmd0aDt1Kyspe3ZhciBjPXRbdV0ua2V5O2lmKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLGMpKXtpZihyPGlbY10mJnM+b1tjXSlyZXR1cm4tMTtpZihyPmlbY10mJnM8b1tjXSlyZXR1cm4gMX19cmV0dXJuIDF9Zm9yKHZhciB1PTA7dTx0Lmxlbmd0aDt1Kyspe3ZhciBjPXRbdV0ua2V5O2lmKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLGMpKXtpZihhPGlbY10mJmw+b1tjXSlyZXR1cm4gMTtpZihhPmlbY10mJmw8b1tjXSlyZXR1cm4tMX19cmV0dXJuLTF9KX10Ll9fZXNNb2R1bGU9ITAsdC5kZWZhdWx0PW4sZS5leHBvcnRzPXQuZGVmYXVsdH0sZnVuY3Rpb24oZSx0LG4pe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG8oKXt9dC5fX2VzTW9kdWxlPSEwLHQuZGVmYXVsdD1vO2UuZXhwb3J0cz10LmRlZmF1bHR9LGZ1bmN0aW9uKGUsdCxuKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBvKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX1mdW5jdGlvbiByKGUsdCl7cmV0dXJuIGkoe30scyx0LHt2YWw6ZX0pfXQuX19lc01vZHVsZT0hMDt2YXIgaT1PYmplY3QuYXNzaWdufHxmdW5jdGlvbihlKXtmb3IodmFyIHQ9MTt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKXt2YXIgbj1hcmd1bWVudHNbdF07Zm9yKHZhciBvIGluIG4pT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG4sbykmJihlW29dPW5bb10pfXJldHVybiBlfTt0LmRlZmF1bHQ9cjt2YXIgYT1uKDExKSxsPW8oYSkscz1pKHt9LGwuZGVmYXVsdC5ub1dvYmJsZSx7cHJlY2lzaW9uOi4wMX0pO2UuZXhwb3J0cz10LmRlZmF1bHR9LGZ1bmN0aW9uKGUsdCxuKXtmdW5jdGlvbiBvKGUsdCl7Zm9yKHZhciBuPTA7bjxlLmxlbmd0aDtuKyspe3ZhciBvPWVbbl0scj1kW28uaWRdO2lmKHIpe3IucmVmcysrO2Zvcih2YXIgaT0wO2k8ci5wYXJ0cy5sZW5ndGg7aSsrKXIucGFydHNbaV0oby5wYXJ0c1tpXSk7Zm9yKDtpPG8ucGFydHMubGVuZ3RoO2krKylyLnBhcnRzLnB1c2godShvLnBhcnRzW2ldLHQpKX1lbHNle2Zvcih2YXIgYT1bXSxpPTA7aTxvLnBhcnRzLmxlbmd0aDtpKyspYS5wdXNoKHUoby5wYXJ0c1tpXSx0KSk7ZFtvLmlkXT17aWQ6by5pZCxyZWZzOjEscGFydHM6YX19fX1mdW5jdGlvbiByKGUpe2Zvcih2YXIgdD1bXSxuPXt9LG89MDtvPGUubGVuZ3RoO28rKyl7dmFyIHI9ZVtvXSxpPXJbMF0sYT1yWzFdLGw9clsyXSxzPXJbM10sdT17Y3NzOmEsbWVkaWE6bCxzb3VyY2VNYXA6c307bltpXT9uW2ldLnBhcnRzLnB1c2godSk6dC5wdXNoKG5baV09e2lkOmkscGFydHM6W3VdfSl9cmV0dXJuIHR9ZnVuY3Rpb24gaShlLHQpe3ZhciBuPXYoKSxvPVNbUy5sZW5ndGgtMV07aWYoXCJ0b3BcIj09PWUuaW5zZXJ0QXQpbz9vLm5leHRTaWJsaW5nP24uaW5zZXJ0QmVmb3JlKHQsby5uZXh0U2libGluZyk6bi5hcHBlbmRDaGlsZCh0KTpuLmluc2VydEJlZm9yZSh0LG4uZmlyc3RDaGlsZCksUy5wdXNoKHQpO2Vsc2V7aWYoXCJib3R0b21cIiE9PWUuaW5zZXJ0QXQpdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB2YWx1ZSBmb3IgcGFyYW1ldGVyICdpbnNlcnRBdCcuIE11c3QgYmUgJ3RvcCcgb3IgJ2JvdHRvbScuXCIpO24uYXBwZW5kQ2hpbGQodCl9fWZ1bmN0aW9uIGEoZSl7ZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGUpO3ZhciB0PVMuaW5kZXhPZihlKTt0Pj0wJiZTLnNwbGljZSh0LDEpfWZ1bmN0aW9uIGwoZSl7dmFyIHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO3JldHVybiB0LnR5cGU9XCJ0ZXh0L2Nzc1wiLGkoZSx0KSx0fWZ1bmN0aW9uIHMoZSl7dmFyIHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImxpbmtcIik7cmV0dXJuIHQucmVsPVwic3R5bGVzaGVldFwiLGkoZSx0KSx0fWZ1bmN0aW9uIHUoZSx0KXt2YXIgbixvLHI7aWYodC5zaW5nbGV0b24pe3ZhciBpPWIrKztuPW18fChtPWwodCkpLG89Yy5iaW5kKG51bGwsbixpLCExKSxyPWMuYmluZChudWxsLG4saSwhMCl9ZWxzZSBlLnNvdXJjZU1hcCYmXCJmdW5jdGlvblwiPT10eXBlb2YgVVJMJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBVUkwuY3JlYXRlT2JqZWN0VVJMJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBVUkwucmV2b2tlT2JqZWN0VVJMJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBCbG9iJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBidG9hPyhuPXModCksbz1wLmJpbmQobnVsbCxuKSxyPWZ1bmN0aW9uKCl7YShuKSxuLmhyZWYmJlVSTC5yZXZva2VPYmplY3RVUkwobi5ocmVmKX0pOihuPWwodCksbz1mLmJpbmQobnVsbCxuKSxyPWZ1bmN0aW9uKCl7YShuKX0pO3JldHVybiBvKGUpLGZ1bmN0aW9uKHQpe2lmKHQpe2lmKHQuY3NzPT09ZS5jc3MmJnQubWVkaWE9PT1lLm1lZGlhJiZ0LnNvdXJjZU1hcD09PWUuc291cmNlTWFwKXJldHVybjtvKGU9dCl9ZWxzZSByKCl9fWZ1bmN0aW9uIGMoZSx0LG4sbyl7dmFyIHI9bj9cIlwiOm8uY3NzO2lmKGUuc3R5bGVTaGVldCllLnN0eWxlU2hlZXQuY3NzVGV4dD1nKHQscik7ZWxzZXt2YXIgaT1kb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShyKSxhPWUuY2hpbGROb2RlczthW3RdJiZlLnJlbW92ZUNoaWxkKGFbdF0pLGEubGVuZ3RoP2UuaW5zZXJ0QmVmb3JlKGksYVt0XSk6ZS5hcHBlbmRDaGlsZChpKX19ZnVuY3Rpb24gZihlLHQpe3ZhciBuPXQuY3NzLG89dC5tZWRpYTtpZihvJiZlLnNldEF0dHJpYnV0ZShcIm1lZGlhXCIsbyksZS5zdHlsZVNoZWV0KWUuc3R5bGVTaGVldC5jc3NUZXh0PW47ZWxzZXtmb3IoO2UuZmlyc3RDaGlsZDspZS5yZW1vdmVDaGlsZChlLmZpcnN0Q2hpbGQpO2UuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobikpfX1mdW5jdGlvbiBwKGUsdCl7dmFyIG49dC5jc3Msbz10LnNvdXJjZU1hcDtvJiYobis9XCJcXG4vKiMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247YmFzZTY0LFwiK2J0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KG8pKSkpK1wiICovXCIpO3ZhciByPW5ldyBCbG9iKFtuXSx7dHlwZTpcInRleHQvY3NzXCJ9KSxpPWUuaHJlZjtlLmhyZWY9VVJMLmNyZWF0ZU9iamVjdFVSTChyKSxpJiZVUkwucmV2b2tlT2JqZWN0VVJMKGkpfXZhciBkPXt9LGg9ZnVuY3Rpb24oZSl7dmFyIHQ7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuXCJ1bmRlZmluZWRcIj09dHlwZW9mIHQmJih0PWUuYXBwbHkodGhpcyxhcmd1bWVudHMpKSx0fX0seT1oKGZ1bmN0aW9uKCl7cmV0dXJuL21zaWUgWzYtOV1cXGIvLnRlc3Qod2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKSl9KSx2PWgoZnVuY3Rpb24oKXtyZXR1cm4gZG9jdW1lbnQuaGVhZHx8ZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJoZWFkXCIpWzBdfSksbT1udWxsLGI9MCxTPVtdO2UuZXhwb3J0cz1mdW5jdGlvbihlLHQpe3Q9dHx8e30sXCJ1bmRlZmluZWRcIj09dHlwZW9mIHQuc2luZ2xldG9uJiYodC5zaW5nbGV0b249eSgpKSxcInVuZGVmaW5lZFwiPT10eXBlb2YgdC5pbnNlcnRBdCYmKHQuaW5zZXJ0QXQ9XCJib3R0b21cIik7dmFyIG49cihlKTtyZXR1cm4gbyhuLHQpLGZ1bmN0aW9uKGUpe2Zvcih2YXIgaT1bXSxhPTA7YTxuLmxlbmd0aDthKyspe3ZhciBsPW5bYV0scz1kW2wuaWRdO3MucmVmcy0tLGkucHVzaChzKX1pZihlKXt2YXIgdT1yKGUpO28odSx0KX1mb3IodmFyIGE9MDthPGkubGVuZ3RoO2ErKyl7dmFyIHM9aVthXTtpZigwPT09cy5yZWZzKXtmb3IodmFyIGM9MDtjPHMucGFydHMubGVuZ3RoO2MrKylzLnBhcnRzW2NdKCk7ZGVsZXRlIGRbcy5pZF19fX19O3ZhciBnPWZ1bmN0aW9uKCl7dmFyIGU9W107cmV0dXJuIGZ1bmN0aW9uKHQsbil7cmV0dXJuIGVbdF09bixlLmZpbHRlcihCb29sZWFuKS5qb2luKFwiXFxuXCIpfX0oKX0sZnVuY3Rpb24oZSx0LG4pe3ZhciBvPW4oMTYpO1wic3RyaW5nXCI9PXR5cGVvZiBvJiYobz1bW2UuaWQsbyxcIlwiXV0pO24oMzApKG8se30pO28ubG9jYWxzJiYoZS5leHBvcnRzPW8ubG9jYWxzKX1dKX0pOyIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfU3RvcmUgPSByZXF1aXJlKCcuL1N0b3JlJyk7XG5cbnZhciBfU3RvcmUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU3RvcmUpO1xuXG52YXIgX0dyaWRCdWlsZGVyID0gcmVxdWlyZSgnLi9HcmlkQnVpbGRlcicpO1xuXG52YXIgX0dyaWRCdWlsZGVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0dyaWRCdWlsZGVyKTtcblxuLyoqXG4gKiBBdXRvbWF0aWMgbGF5b3V0IGZvciBwcmVzZW50aW5nIGRyYWdnYWJsZSBjYXJkcyB0byB1c2Vycy4gVXNlZCBmb3IgdXNlciBhbmQgYWRtaW4gZGFzaGJvYXJkLlxuICovXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIFB5ZGlvID0gcmVxdWlyZSgncHlkaW8nKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgncmVhY3QtZ3JpZC1sYXlvdXQnKTtcblxudmFyIFJlc3BvbnNpdmUgPSBfcmVxdWlyZS5SZXNwb25zaXZlO1xudmFyIFdpZHRoUHJvdmlkZXIgPSBfcmVxdWlyZS5XaWR0aFByb3ZpZGVyO1xuXG52YXIgX1B5ZGlvJHJlcXVpcmVMaWIgPSBQeWRpby5yZXF1aXJlTGliKCdib290Jyk7XG5cbnZhciBQeWRpb0NvbnRleHRDb25zdW1lciA9IF9QeWRpbyRyZXF1aXJlTGliLlB5ZGlvQ29udGV4dENvbnN1bWVyO1xudmFyIENhcmRzR3JpZCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ0NhcmRzR3JpZCcsXG5cbiAgICAvKipcbiAgICAgKiBTYXZlIGxheW91dHMgaW4gdGhlIHVzZXJzIHByZWZlcmVuY2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gYWxsTGF5b3V0cyBSZXNwb25zaXZlIGxheW91dHMgcGFzc2VkIGZvciBzYXZpbmdcbiAgICAgKi9cbiAgICBzYXZlRnVsbExheW91dHM6IGZ1bmN0aW9uIHNhdmVGdWxsTGF5b3V0cyhhbGxMYXlvdXRzKSB7XG4gICAgICAgIHZhciBzYXZlZFByZWYgPSB0aGlzLnByb3BzLnN0b3JlLmdldFVzZXJQcmVmZXJlbmNlKCdMYXlvdXQnKTtcbiAgICAgICAgLy8gQ29tcGFyZSBKU09OIHZlcnNpb25zIHRvIGF2b2lkIHNhdmluZyB1bm5lY2Vzc2FyeSBjaGFuZ2VzXG4gICAgICAgIGlmIChzYXZlZFByZWYgJiYgdGhpcy5wcmV2aW91c0xheW91dCAmJiB0aGlzLnByZXZpb3VzTGF5b3V0ID09IEpTT04uc3RyaW5naWZ5KGFsbExheW91dHMpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wcmV2aW91c0xheW91dCA9IEpTT04uc3RyaW5naWZ5KGFsbExheW91dHMpO1xuICAgICAgICB0aGlzLnByb3BzLnN0b3JlLnNhdmVVc2VyUHJlZmVyZW5jZSgnTGF5b3V0JywgYWxsTGF5b3V0cyk7XG4gICAgfSxcblxuICAgIG9uTGF5b3V0Q2hhbmdlOiBmdW5jdGlvbiBvbkxheW91dENoYW5nZShjdXJyZW50TGF5b3V0LCBhbGxMYXlvdXRzKSB7XG4gICAgICAgIGlmICh0aGlzLl9ibG9ja0xheW91dFNhdmUpIHJldHVybjtcbiAgICAgICAgdGhpcy5zYXZlRnVsbExheW91dHMoYWxsTGF5b3V0cyk7XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50OiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5zdG9yZS5zdG9wT2JzZXJ2aW5nKFwiY2FyZHNcIiwgdGhpcy5fc3RvcmVPYnNlcnZlcik7XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHM6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzICYmIG5leHRQcm9wcy5lZGl0TW9kZSAhPT0gdGhpcy5wcm9wcy5lZGl0TW9kZSkge1xuICAgICAgICAgICAgT2JqZWN0LmtleXModGhpcy5yZWZzKS5mb3JFYWNoKChmdW5jdGlvbiAoaykge1xuICAgICAgICAgICAgICAgIHRoaXMucmVmc1trXS50b2dnbGVFZGl0TW9kZShuZXh0UHJvcHMuZWRpdE1vZGUpO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgc2hvdWxkQ29tcG9uZW50VXBkYXRlOiBmdW5jdGlvbiBzaG91bGRDb21wb25lbnRVcGRhdGUobmV4dFByb3BzLCBuZXh0U3RhdGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZvcmNlVXBkYXRlIHx8IGZhbHNlO1xuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgdGhpcy5fc3RvcmVPYnNlcnZlciA9IChmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICAgICAgdGhpcy5fZm9yY2VVcGRhdGUgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgY2FyZHM6IHRoaXMucHJvcHMuc3RvcmUuZ2V0Q2FyZHMoKVxuICAgICAgICAgICAgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF90aGlzLl9mb3JjZVVwZGF0ZSA9IGZhbHNlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMucHJvcHMuc3RvcmUub2JzZXJ2ZShcImNhcmRzXCIsIHRoaXMuX3N0b3JlT2JzZXJ2ZXIpO1xuICAgICAgICByZXR1cm4geyBjYXJkczogdGhpcy5wcm9wcy5zdG9yZS5nZXRDYXJkcygpIH07XG4gICAgfSxcblxuICAgIHJlbW92ZUNhcmQ6IGZ1bmN0aW9uIHJlbW92ZUNhcmQoaXRlbUtleSkge1xuICAgICAgICB0aGlzLnByb3BzLnJlbW92ZUNhcmQoaXRlbUtleSk7XG4gICAgfSxcblxuICAgIGJ1aWxkQ2FyZHM6IGZ1bmN0aW9uIGJ1aWxkQ2FyZHMoY2FyZHMpIHtcblxuICAgICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgICB2YXIgbGF5b3V0cyA9IHsgbGc6IFtdLCBtZDogW10sIHNtOiBbXSwgeHM6IFtdLCB4eHM6IFtdIH07XG4gICAgICAgIHZhciBpdGVtcyA9IFtdO1xuICAgICAgICB2YXIgYWRkaXRpb25hbE5hbWVzcGFjZXMgPSBbXTtcbiAgICAgICAgdmFyIHJhbmQgPSBNYXRoLnJhbmRvbSgpO1xuICAgICAgICB2YXIgc2F2ZWRMYXlvdXRzID0gdGhpcy5wcm9wcy5zdG9yZS5nZXRVc2VyUHJlZmVyZW5jZSgnTGF5b3V0Jyk7XG4gICAgICAgIHZhciBidWlsZExheW91dCA9IGZ1bmN0aW9uIGJ1aWxkTGF5b3V0KGNsYXNzT2JqZWN0LCBpdGVtS2V5LCBpdGVtLCB4LCB5KSB7XG4gICAgICAgICAgICB2YXIgbGF5b3V0ID0gY2xhc3NPYmplY3QuZ2V0R3JpZExheW91dCh4LCB5KTtcbiAgICAgICAgICAgIGxheW91dFsnaGFuZGxlJ10gPSAnaDQnO1xuICAgICAgICAgICAgaWYgKGl0ZW1bJ2dyaWRIYW5kbGUnXSkge1xuICAgICAgICAgICAgICAgIGxheW91dFsnaGFuZGxlJ10gPSBpdGVtWydncmlkSGFuZGxlJ107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsYXlvdXRbJ2knXSA9IGl0ZW1LZXk7XG4gICAgICAgICAgICByZXR1cm4gbGF5b3V0O1xuICAgICAgICB9O1xuICAgICAgICBjYXJkcy5tYXAoKGZ1bmN0aW9uIChpdGVtKSB7XG5cbiAgICAgICAgICAgIHZhciBwYXJ0cyA9IGl0ZW0uY29tcG9uZW50Q2xhc3Muc3BsaXQoXCIuXCIpO1xuICAgICAgICAgICAgdmFyIGNsYXNzTlMgPSBwYXJ0c1swXTtcbiAgICAgICAgICAgIHZhciBjbGFzc05hbWUgPSBwYXJ0c1sxXTtcbiAgICAgICAgICAgIHZhciBjbGFzc09iamVjdDtcbiAgICAgICAgICAgIGlmIChnbG9iYWxbY2xhc3NOU10gJiYgZ2xvYmFsW2NsYXNzTlNdW2NsYXNzTmFtZV0pIHtcbiAgICAgICAgICAgICAgICBjbGFzc09iamVjdCA9IGdsb2JhbFtjbGFzc05TXVtjbGFzc05hbWVdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoIWdsb2JhbFtjbGFzc05TXSkge1xuICAgICAgICAgICAgICAgICAgICBhZGRpdGlvbmFsTmFtZXNwYWNlcy5wdXNoKGNsYXNzTlMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgcHJvcHMgPSBfZXh0ZW5kcyh7fSwgaXRlbS5wcm9wcyk7XG4gICAgICAgICAgICB2YXIgaXRlbUtleSA9IHByb3BzWydrZXknXSA9IGl0ZW1bJ2lkJ10gfHwgJ2l0ZW1fJyArIGluZGV4O1xuICAgICAgICAgICAgcHJvcHMucmVmID0gaXRlbUtleTtcbiAgICAgICAgICAgIHByb3BzLnB5ZGlvID0gdGhpcy5wcm9wcy5weWRpbztcbiAgICAgICAgICAgIHByb3BzLm9uQ2xvc2VBY3Rpb24gPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlQ2FyZChpdGVtS2V5KTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgICAgICBwcm9wcy5wcmVmZXJlbmNlc1Byb3ZpZGVyID0gdGhpcy5wcm9wcy5zdG9yZTtcbiAgICAgICAgICAgIHZhciBkZWZhdWx0WCA9IDAsXG4gICAgICAgICAgICAgICAgZGVmYXVsdFkgPSAwO1xuICAgICAgICAgICAgaWYgKGl0ZW0uZGVmYXVsdFBvc2l0aW9uKSB7XG4gICAgICAgICAgICAgICAgZGVmYXVsdFggPSBpdGVtLmRlZmF1bHRQb3NpdGlvbi54O1xuICAgICAgICAgICAgICAgIGRlZmF1bHRZID0gaXRlbS5kZWZhdWx0UG9zaXRpb24ueTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBkZWZhdWx0TGF5b3V0ID0gYnVpbGRMYXlvdXQoY2xhc3NPYmplY3QsIGl0ZW1LZXksIGl0ZW0sIGRlZmF1bHRYLCBkZWZhdWx0WSk7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGJyZWFrcG9pbnQgaW4gbGF5b3V0cykge1xuICAgICAgICAgICAgICAgIGlmICghbGF5b3V0cy5oYXNPd25Qcm9wZXJ0eShicmVha3BvaW50KSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgdmFyIGJyZWFrTGF5b3V0ID0gbGF5b3V0c1ticmVha3BvaW50XTtcbiAgICAgICAgICAgICAgICAvLyBGaW5kIGNvcnJlc3BvbmRpbmcgZWxlbWVudCBpbiBwcmVmZXJlbmNlXG4gICAgICAgICAgICAgICAgdmFyIGV4aXN0aW5nO1xuICAgICAgICAgICAgICAgIGlmIChzYXZlZExheW91dHMgJiYgc2F2ZWRMYXlvdXRzW2JyZWFrcG9pbnRdKSB7XG4gICAgICAgICAgICAgICAgICAgIHNhdmVkTGF5b3V0c1ticmVha3BvaW50XS5tYXAoZnVuY3Rpb24gKGdyaWREYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ3JpZERhdGFbJ2knXSA9PSBpdGVtS2V5ICYmIGdyaWREYXRhWydoJ10gPT0gZGVmYXVsdExheW91dFsnaCddKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcgPSBncmlkRGF0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICAgICAgICAgICAgICBicmVha0xheW91dC5wdXNoKGV4aXN0aW5nKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGl0ZW0uZGVmYXVsdExheW91dHMgJiYgaXRlbS5kZWZhdWx0TGF5b3V0c1ticmVha3BvaW50XSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgY3J0TGF5b3V0ID0gYnVpbGRMYXlvdXQoY2xhc3NPYmplY3QsIGl0ZW1LZXksIGl0ZW0sIGl0ZW0uZGVmYXVsdExheW91dHNbYnJlYWtwb2ludF0ueCwgaXRlbS5kZWZhdWx0TGF5b3V0c1ticmVha3BvaW50XS55KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtMYXlvdXQucHVzaChjcnRMYXlvdXQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrTGF5b3V0LnB1c2goZGVmYXVsdExheW91dCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgICAgIGl0ZW1zLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChjbGFzc09iamVjdCwgcHJvcHMpKTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgaWYgKGFkZGl0aW9uYWxOYW1lc3BhY2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5fYmxvY2tMYXlvdXRTYXZlID0gdHJ1ZTtcbiAgICAgICAgICAgIFJlc291cmNlc01hbmFnZXIubG9hZENsYXNzZXNBbmRBcHBseShhZGRpdGlvbmFsTmFtZXNwYWNlcywgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgYWRkaXRpb25hbE5hbWVzcGFjZXNMb2FkZWQ6IGFkZGl0aW9uYWxOYW1lc3BhY2VzIH0sIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2Jsb2NrTGF5b3V0U2F2ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgY2FyZHM6IGl0ZW1zLCBsYXlvdXRzOiBsYXlvdXRzIH07XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX2J1aWxkQ2FyZHMgPSB0aGlzLmJ1aWxkQ2FyZHModGhpcy5zdGF0ZS5jYXJkcyk7XG5cbiAgICAgICAgdmFyIGNhcmRzID0gX2J1aWxkQ2FyZHMuY2FyZHM7XG4gICAgICAgIHZhciBsYXlvdXRzID0gX2J1aWxkQ2FyZHMubGF5b3V0cztcblxuICAgICAgICB2YXIgUmVzcG9uc2l2ZUdyaWRMYXlvdXQgPSBXaWR0aFByb3ZpZGVyKFJlc3BvbnNpdmUpO1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgIFJlc3BvbnNpdmVHcmlkTGF5b3V0LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogJ2Rhc2hib2FyZC1sYXlvdXQnLFxuICAgICAgICAgICAgICAgIGNvbHM6IHRoaXMucHJvcHMuY29scyB8fCB7IGxnOiAxMCwgbWQ6IDgsIHNtOiA4LCB4czogNCwgeHhzOiAyIH0sXG4gICAgICAgICAgICAgICAgbGF5b3V0czogbGF5b3V0cyxcbiAgICAgICAgICAgICAgICByb3dIZWlnaHQ6IDUsXG4gICAgICAgICAgICAgICAgb25MYXlvdXRDaGFuZ2U6IHRoaXMub25MYXlvdXRDaGFuZ2UsXG4gICAgICAgICAgICAgICAgaXNEcmFnZ2FibGU6ICF0aGlzLnByb3BzLmRpc2FibGVEcmFnLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB0aGlzLnByb3BzLnN0eWxlLFxuICAgICAgICAgICAgICAgIGF1dG9TaXplOiBmYWxzZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNhcmRzXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcblxudmFyIER5bmFtaWNHcmlkID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnRHluYW1pY0dyaWQnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHN0b3JlTmFtZXNwYWNlOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgICAgIGJ1aWxkZXJOYW1lc3BhY2VzOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXksXG4gICAgICAgIGRlZmF1bHRDYXJkczogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuICAgICAgICBweWRpbzogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW8pLFxuICAgICAgICBkaXNhYmxlRHJhZzogUmVhY3QuUHJvcFR5cGVzLmJvb2xcbiAgICB9LFxuXG4gICAgcmVtb3ZlQ2FyZDogZnVuY3Rpb24gcmVtb3ZlQ2FyZChjYXJkSWQpIHtcblxuICAgICAgICB0aGlzLnN0YXRlLnN0b3JlLnJlbW92ZUNhcmQoY2FyZElkKTtcbiAgICB9LFxuXG4gICAgYWRkQ2FyZDogZnVuY3Rpb24gYWRkQ2FyZChjYXJkRGVmaW5pdGlvbikge1xuXG4gICAgICAgIHRoaXMuc3RhdGUuc3RvcmUuYWRkQ2FyZChjYXJkRGVmaW5pdGlvbik7XG4gICAgfSxcblxuICAgIHJlc2V0Q2FyZHNBbmRMYXlvdXQ6IGZ1bmN0aW9uIHJlc2V0Q2FyZHNBbmRMYXlvdXQoKSB7XG4gICAgICAgIHRoaXMuc3RhdGUuc3RvcmUuc2F2ZVVzZXJQcmVmZXJlbmNlKCdMYXlvdXQnLCBudWxsKTtcbiAgICAgICAgdGhpcy5zdGF0ZS5zdG9yZS5zZXRDYXJkcyh0aGlzLnByb3BzLmRlZmF1bHRDYXJkcyk7XG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICB2YXIgc3RvcmUgPSBuZXcgX1N0b3JlMlsnZGVmYXVsdCddKHRoaXMucHJvcHMuc3RvcmVOYW1lc3BhY2UsIHRoaXMucHJvcHMuZGVmYXVsdENhcmRzLCB0aGlzLnByb3BzLnB5ZGlvKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGVkaXRNb2RlOiBmYWxzZSxcbiAgICAgICAgICAgIHN0b3JlOiBzdG9yZVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICB0b2dnbGVFZGl0TW9kZTogZnVuY3Rpb24gdG9nZ2xlRWRpdE1vZGUoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlZGl0TW9kZTogIXRoaXMuc3RhdGUuZWRpdE1vZGUgfSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICB2YXIgbW9uaXRvcldpZGdldEVkaXRpbmcgPSAoZnVuY3Rpb24gKHN0YXR1cykge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHdpZGdldEVkaXRpbmc6IHN0YXR1cyB9KTtcbiAgICAgICAgfSkuYmluZCh0aGlzKTtcblxuICAgICAgICB2YXIgYnVpbGRlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuYnVpbGRlck5hbWVzcGFjZXMgJiYgdGhpcy5zdGF0ZS5lZGl0TW9kZSkge1xuICAgICAgICAgICAgYnVpbGRlciA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoX0dyaWRCdWlsZGVyMlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAnYWRtaW4taGVscGVyLXBhbmVsJyxcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2VzOiB0aGlzLnByb3BzLmJ1aWxkZXJOYW1lc3BhY2VzLFxuICAgICAgICAgICAgICAgIG9uQ3JlYXRlQ2FyZDogdGhpcy5hZGRDYXJkLFxuICAgICAgICAgICAgICAgIG9uUmVzZXRMYXlvdXQ6IHRoaXMucmVzZXRDYXJkc0FuZExheW91dCxcbiAgICAgICAgICAgICAgICBvbkVkaXRTdGF0dXNDaGFuZ2U6IG1vbml0b3JXaWRnZXRFZGl0aW5nLFxuICAgICAgICAgICAgICAgIGdldE1lc3NhZ2U6IGZ1bmN0aW9uIChpZCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbnMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyAnYWp4cF9hZG1pbicgOiBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIucHJvcHMuZ2V0TWVzc2FnZShpZCwgbnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcm9wU3R5bGUgPSB0aGlzLnByb3BzLnN0eWxlIHx8IHt9O1xuICAgICAgICB2YXIgcmdsU3R5bGUgPSB0aGlzLnByb3BzLnJnbFN0eWxlIHx8IHt9O1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgeyBzdHlsZTogX2V4dGVuZHMoe30sIHRoaXMucHJvcHMuc3R5bGUsIHsgd2lkdGg6ICcxMDAlJywgZmxleDogJzEnIH0pLCBjbGFzc05hbWU6IHRoaXMuc3RhdGUuZWRpdE1vZGUgPyBcImJ1aWxkZXItb3BlblwiIDogXCJcIiB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IHBvc2l0aW9uOiAnYWJzb2x1dGUnLCBib3R0b206IDMwLCByaWdodDogMTgsIHpJbmRleDogMTEgfSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWF0ZXJpYWxVSS5GbG9hdGluZ0FjdGlvbkJ1dHRvbiwge1xuICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJ2hvbWUuNDknKSxcbiAgICAgICAgICAgICAgICAgICAgb25DbGljazogdGhpcy50b2dnbGVFZGl0TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogdGhpcy5zdGF0ZS5lZGl0TW9kZSA/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/IFwiIHJvdGF0aW5nXCIgOiBcIlwiKSxcbiAgICAgICAgICAgICAgICAgICAgb25DbGljazogdGhpcy5wcm9wcy5yZWxvYWRcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmFkZGl0aW9uYWxBY3Rpb25zXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfVXRpbHMgPSByZXF1aXJlKCcuL1V0aWxzJyk7XG5cbnZhciBfVXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXRpbHMpO1xuXG52YXIgX01lbnVJdGVtc0NvbnN1bWVyID0gcmVxdWlyZSgnLi9NZW51SXRlbXNDb25zdW1lcicpO1xuXG52YXIgX01lbnVJdGVtc0NvbnN1bWVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX01lbnVJdGVtc0NvbnN1bWVyKTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcbnZhciBSZWFjdERPTSA9IHJlcXVpcmUoJ3JlYWN0LWRvbScpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgTWVudSA9IF9yZXF1aXJlLk1lbnU7XG5cbnZhciBDb250cm9sbGVyID0gcmVxdWlyZSgncHlkaW8vbW9kZWwvY29udHJvbGxlcicpO1xuXG52YXIgQnV0dG9uTWVudSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ0J1dHRvbk1lbnUnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIGJ1dHRvblRpdGxlOiBSZWFjdC5Qcm9wVHlwZXMub25lT2ZUeXBlKFtSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLCBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0XSkuaXNSZXF1aXJlZCxcbiAgICAgICAgbWVudUl0ZW1zOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXkuaXNSZXF1aXJlZCxcbiAgICAgICAgY2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICByYWlzZWQ6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBkaXJlY3Rpb246IFJlYWN0LlByb3BUeXBlcy5vbmVPZihbJ2xlZnQnLCAncmlnaHQnXSlcbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9wZW5PbkV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLnB5ZGlvLm9ic2VydmUodGhpcy5wcm9wcy5vcGVuT25FdmVudCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF90aGlzLnNob3dNZW51KCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHsgc2hvd01lbnU6IGZhbHNlIH07XG4gICAgfSxcblxuICAgIHNob3dNZW51OiBmdW5jdGlvbiBzaG93TWVudShldmVudCkge1xuICAgICAgICB2YXIgYW5jaG9yID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgIGFuY2hvciA9IGV2ZW50LmN1cnJlbnRUYXJnZXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbmNob3IgPSB0aGlzLl9idXR0b25ET007XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzaG93TWVudTogdHJ1ZSxcbiAgICAgICAgICAgIGFuY2hvcjogYW5jaG9yXG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBtZW51Q2xpY2tlZDogZnVuY3Rpb24gbWVudUNsaWNrZWQoZXZlbnQsIGluZGV4LCBvYmplY3QpIHtcbiAgICAgICAgLy9vYmplY3QucGF5bG9hZCgpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2hvd01lbnU6IGZhbHNlIH0pO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIGxhYmVsID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICB0aGlzLnByb3BzLmJ1dHRvblRpdGxlLFxuICAgICAgICAgICAgJyAnLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudCgnc3BhbicsIHsgY2xhc3NOYW1lOiAnaWNvbi1jYXJldC1kb3duJyB9KVxuICAgICAgICApO1xuICAgICAgICB2YXIgYnV0dG9uID0gdW5kZWZpbmVkO1xuICAgICAgICB2YXIgcHJvcHMgPSB7XG4gICAgICAgICAgICBwcmltYXJ5OiB0aGlzLnByb3BzLnByaW1hcnksXG4gICAgICAgICAgICBzZWNvbmRhcnk6IHRoaXMucHJvcHMuc2Vjb25kYXJ5LFxuICAgICAgICAgICAgZGlzYWJsZWQ6IHRoaXMucHJvcHMuZGlzYWJlbGQsXG4gICAgICAgICAgICBsYWJlbDogbGFiZWwsXG4gICAgICAgICAgICBvblRvdWNoVGFwOiB0aGlzLnNob3dNZW51LFxuICAgICAgICAgICAgb25DbGljazogZnVuY3Rpb24gb25DbGljayhlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHZhciBtZW51SXRlbXMgPSB0aGlzLnByb3BzLm1lbnVJdGVtcztcbiAgICAgICAgdmFyIF9zdGF0ZSA9IHRoaXMuc3RhdGU7XG4gICAgICAgIHZhciBzaG93TWVudSA9IF9zdGF0ZS5zaG93TWVudTtcbiAgICAgICAgdmFyIGFuY2hvciA9IF9zdGF0ZS5hbmNob3I7XG5cbiAgICAgICAgaWYgKG1lbnVJdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLnJhaXNlZCkge1xuICAgICAgICAgICAgICAgIGJ1dHRvbiA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWF0ZXJpYWxVSS5SYWlzZWRCdXR0b24sIF9leHRlbmRzKHt9LCBwcm9wcywgeyBzdHlsZTogdGhpcy5wcm9wcy5idXR0b25TdHlsZSwgbGFiZWxTdHlsZTogdGhpcy5wcm9wcy5idXR0b25MYWJlbFN0eWxlLCByZWY6IGZ1bmN0aW9uIChiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpczIuX2J1dHRvbkRPTSA9IFJlYWN0RE9NLmZpbmRET01Ob2RlKGIpO1xuICAgICAgICAgICAgICAgICAgICB9IH0pKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYnV0dG9uID0gUmVhY3QuY3JlYXRlRWxlbWVudChNYXRlcmlhbFVJLkZsYXRCdXR0b24sIF9leHRlbmRzKHt9LCBwcm9wcywgeyBzdHlsZTogdGhpcy5wcm9wcy5idXR0b25TdHlsZSwgbGFiZWxTdHlsZTogdGhpcy5wcm9wcy5idXR0b25MYWJlbFN0eWxlLCByZWY6IGZ1bmN0aW9uIChiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpczIuX2J1dHRvbkRPTSA9IFJlYWN0RE9NLmZpbmRET01Ob2RlKGIpO1xuICAgICAgICAgICAgICAgICAgICB9IH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgIHsgaWQ6IHRoaXMucHJvcHMuaWQsIGNsYXNzTmFtZTogdGhpcy5wcm9wcy5jbGFzc05hbWUgfSxcbiAgICAgICAgICAgIGJ1dHRvbixcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgTWF0ZXJpYWxVSS5Qb3BvdmVyLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAnbWVudVBvcG92ZXInLFxuICAgICAgICAgICAgICAgICAgICBvcGVuOiBzaG93TWVudSxcbiAgICAgICAgICAgICAgICAgICAgYW5jaG9yRWw6IGFuY2hvcixcbiAgICAgICAgICAgICAgICAgICAgYW5jaG9yT3JpZ2luOiB7IGhvcml6b250YWw6IHRoaXMucHJvcHMuZGlyZWN0aW9uIHx8ICdsZWZ0JywgdmVydGljYWw6ICdib3R0b20nIH0sXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldE9yaWdpbjogeyBob3Jpem9udGFsOiB0aGlzLnByb3BzLmRpcmVjdGlvbiB8fCAnbGVmdCcsIHZlcnRpY2FsOiAndG9wJyB9LFxuICAgICAgICAgICAgICAgICAgICBvblJlcXVlc3RDbG9zZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMyLnNldFN0YXRlKHsgc2hvd01lbnU6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogeyBtYXJnaW5Ub3A6IDEgfSxcbiAgICAgICAgICAgICAgICAgICAgdXNlTGF5ZXJGb3JDbGlja0F3YXk6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBfVXRpbHMyWydkZWZhdWx0J10uaXRlbXNUb01lbnUobWVudUl0ZW1zLCB0aGlzLm1lbnVDbGlja2VkKVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cblxufSk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IF9NZW51SXRlbXNDb25zdW1lcjJbJ2RlZmF1bHQnXShCdXR0b25NZW51KTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfcHlkaW9Nb2RlbENvbnRleHRNZW51ID0gcmVxdWlyZSgncHlkaW8vbW9kZWwvY29udGV4dC1tZW51Jyk7XG5cbnZhciBfcHlkaW9Nb2RlbENvbnRleHRNZW51MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3B5ZGlvTW9kZWxDb250ZXh0TWVudSk7XG5cbnZhciBfVXRpbHMgPSByZXF1aXJlKCcuL1V0aWxzJyk7XG5cbnZhciBfVXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXRpbHMpO1xuXG52YXIgX1BvcHVwTWVudSA9IHJlcXVpcmUoJy4vUG9wdXBNZW51Jyk7XG5cbnZhciBfUG9wdXBNZW51MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1BvcHVwTWVudSk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBDb21wb25lbnQgPSBfcmVxdWlyZS5Db21wb25lbnQ7XG5cbnZhciBkaW1zID0ge1xuICAgIE1FTlVfSVRFTV9IRUlHSFQ6IDMyLCAvLzQ4IGlmIG5vdCBkaXNwbGF5OmNvbXBhY3RcbiAgICBNRU5VX1NFUF9IRUlHSFQ6IDE2LFxuICAgIE1FTlVfVkVSVElDQUxfUEFERElORzogOCxcbiAgICBNRU5VX1dJRFRIOiAyNTAsXG4gICAgT0ZGU0VUX1ZFUlRJQ0FMOiA4LFxuICAgIE9GRlNFVF9IT1JJWk9OVEFMOiA4XG59O1xuXG52YXIgQ29udGV4dE1lbnUgPSAoZnVuY3Rpb24gKF9Db21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoQ29udGV4dE1lbnUsIF9Db21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gQ29udGV4dE1lbnUoKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDb250ZXh0TWVudSk7XG5cbiAgICAgICAgX0NvbXBvbmVudC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIENvbnRleHRNZW51LnByb3RvdHlwZS5tb2RlbE9wZW4gPSBmdW5jdGlvbiBtb2RlbE9wZW4obm9kZSkge1xuICAgICAgICB2YXIgcG9zaXRpb24gPSBfcHlkaW9Nb2RlbENvbnRleHRNZW51MlsnZGVmYXVsdCddLmdldEluc3RhbmNlKCkuZ2V0UG9zaXRpb24oKTtcbiAgICAgICAgdmFyIGl0ZW1zID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAobm9kZSkge1xuICAgICAgICAgICAgdmFyIGRtID0gcHlkaW8uZ2V0Q29udGV4dEhvbGRlcigpO1xuICAgICAgICAgICAgaWYgKGRtLmdldFNlbGVjdGVkTm9kZXMoKS5pbmRleE9mKG5vZGUpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3Blbk1lbnUoJ3NlbGVjdGlvbkNvbnRleHQnLCBwb3NpdGlvbik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHB5ZGlvLm9ic2VydmVPbmNlKFwiYWN0aW9uc19yZWZyZXNoZWRcIiwgKGZ1bmN0aW9uIChkYXRhTW9kZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVuTWVudSgnc2VsZWN0aW9uQ29udGV4dCcsIHBvc2l0aW9uKTtcbiAgICAgICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgICAgICBkbS5zZXRTZWxlY3RlZE5vZGVzKFtub2RlXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm9wZW5NZW51KCdnZW5lcmljQ29udGV4dCcsIHBvc2l0aW9uKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBDb250ZXh0TWVudS5wcm90b3R5cGUub3Blbk1lbnUgPSBmdW5jdGlvbiBvcGVuTWVudShjb250ZXh0LCBwb3NpdGlvbikge1xuICAgICAgICB2YXIgaXRlbXMgPSB0aGlzLmNvbXB1dGVNZW51SXRlbXMoY29udGV4dCk7XG4gICAgICAgIHRoaXMuX2l0ZW1zID0gaXRlbXM7XG4gICAgICAgIHZhciBtb2JpbGUgPSB0aGlzLnByb3BzLnB5ZGlvLlVJLk1PQklMRV9FWFRFTlNJT05TO1xuICAgICAgICBpZiAoIW1vYmlsZSkge1xuICAgICAgICAgICAgcG9zaXRpb24gPSB0aGlzLmNvbXB1dGVWaXNpYmxlUG9zaXRpb24ocG9zaXRpb24sIGl0ZW1zKTtcbiAgICAgICAgICAgIHRoaXMucmVmc1snbWVudSddLnNob3dNZW51KHtcbiAgICAgICAgICAgICAgICB0b3A6IHBvc2l0aW9uLnksXG4gICAgICAgICAgICAgICAgbGVmdDogcG9zaXRpb24ueFxuICAgICAgICAgICAgfSwgaXRlbXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5yZWZzWydtZW51J10uc2hvd01lbnUoe1xuICAgICAgICAgICAgICAgIGJvdHRvbTogMCxcbiAgICAgICAgICAgICAgICBsZWZ0OiAwLFxuICAgICAgICAgICAgICAgIHJpZ2h0OiAwLFxuICAgICAgICAgICAgICAgIGhlaWdodDogMjAwLFxuICAgICAgICAgICAgICAgIHpJbmRleDogMTAwMDAsXG4gICAgICAgICAgICAgICAgb3ZlcmZsb3dZOiAnYXV0bydcbiAgICAgICAgICAgIH0sIGl0ZW1zKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBDb250ZXh0TWVudS5wcm90b3R5cGUuY29tcHV0ZU1lbnVJdGVtcyA9IGZ1bmN0aW9uIGNvbXB1dGVNZW51SXRlbXMoY29udGV4dCkge1xuICAgICAgICB2YXIgYWN0aW9ucyA9IHRoaXMucHJvcHMucHlkaW8uQ29udHJvbGxlci5nZXRDb250ZXh0QWN0aW9ucyhjb250ZXh0LCBbJ2lubGluZScsICdpbmZvX3BhbmVsJywgJ2luZm9fcGFuZWxfc2hhcmUnXSk7XG4gICAgICAgIHJldHVybiBfVXRpbHMyWydkZWZhdWx0J10ucHlkaW9BY3Rpb25zVG9JdGVtcyhhY3Rpb25zKTtcbiAgICB9O1xuXG4gICAgQ29udGV4dE1lbnUucHJvdG90eXBlLmNvbXB1dGVWaXNpYmxlUG9zaXRpb24gPSBmdW5jdGlvbiBjb21wdXRlVmlzaWJsZVBvc2l0aW9uKHBvc2l0aW9uLCBpdGVtcykge1xuICAgICAgICB2YXIgbWVudUhlaWdodCA9IGRpbXMuTUVOVV9WRVJUSUNBTF9QQURESU5HICogMjtcbiAgICAgICAgaXRlbXMubWFwKGZ1bmN0aW9uIChpdCkge1xuICAgICAgICAgICAgaWYgKGl0LnNlcGFyYXRvcikgbWVudUhlaWdodCArPSBkaW1zLk1FTlVfU0VQX0hFSUdIVDtlbHNlIG1lbnVIZWlnaHQgKz0gZGltcy5NRU5VX0lURU1fSEVJR0hUO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIG1lbnVXaWR0aCA9IGRpbXMuTUVOVV9XSURUSDtcbiAgICAgICAgdmFyIHdpbmRvd1cgPSBNYXRoLm1heChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgsIHdpbmRvdy5pbm5lcldpZHRoIHx8IDApO1xuICAgICAgICB2YXIgd2luZG93SCA9IE1hdGgubWF4KGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQsIHdpbmRvdy5pbm5lckhlaWdodCB8fCAwKTtcbiAgICAgICAgaWYgKHBvc2l0aW9uLnggKyBtZW51V2lkdGggPiB3aW5kb3dXKSB7XG4gICAgICAgICAgICBwb3NpdGlvbi54ID0gTWF0aC5tYXgocG9zaXRpb24ueCAtIG1lbnVXaWR0aCwgMTApIC0gZGltcy5PRkZTRVRfSE9SSVpPTlRBTDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBvc2l0aW9uLnggKz0gZGltcy5PRkZTRVRfSE9SSVpPTlRBTDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zaXRpb24ueSArIG1lbnVIZWlnaHQgPiB3aW5kb3dIKSB7XG4gICAgICAgICAgICBwb3NpdGlvbi55ID0gTWF0aC5tYXgocG9zaXRpb24ueSAtIG1lbnVIZWlnaHQsIDEwKSAtIGRpbXMuT0ZGU0VUX1ZFUlRJQ0FMO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcG9zaXRpb24ueSArPSBkaW1zLk9GRlNFVF9WRVJUSUNBTDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcG9zaXRpb247XG4gICAgfTtcblxuICAgIENvbnRleHRNZW51LnByb3RvdHlwZS5jb21wb25lbnREaWRNb3VudCA9IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB0aGlzLl9tb2RlbE9wZW4gPSB0aGlzLm1vZGVsT3Blbi5iaW5kKHRoaXMpO1xuICAgICAgICBfcHlkaW9Nb2RlbENvbnRleHRNZW51MlsnZGVmYXVsdCddLmdldEluc3RhbmNlKCkub2JzZXJ2ZShcIm9wZW5cIiwgdGhpcy5fbW9kZWxPcGVuKTtcbiAgICB9O1xuXG4gICAgQ29udGV4dE1lbnUucHJvdG90eXBlLmNvbXBvbmVudFdpbGxVbm1vdW50ID0gZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIF9weWRpb01vZGVsQ29udGV4dE1lbnUyWydkZWZhdWx0J10uZ2V0SW5zdGFuY2UoKS5zdG9wT2JzZXJ2aW5nKFwib3BlblwiLCB0aGlzLl9tb2RlbE9wZW4pO1xuICAgIH07XG5cbiAgICBDb250ZXh0TWVudS5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgbW9iaWxlID0gdGhpcy5wcm9wcy5weWRpby5VSS5NT0JJTEVfRVhURU5TSU9OUztcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX1BvcHVwTWVudTJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgcmVmOiAnbWVudScsXG4gICAgICAgICAgICBtZW51SXRlbXM6IHRoaXMuX2l0ZW1zIHx8IFtdLFxuICAgICAgICAgICAgb25NZW51Q2xvc2VkOiB0aGlzLnByb3BzLm9uTWVudUNsb3NlZCxcbiAgICAgICAgICAgIG1lbnVQcm9wczogbW9iaWxlID8geyB3aWR0aDogNjAwLCBhdXRvV2lkdGg6IGZhbHNlLCBkZXNrdG9wOiBmYWxzZSB9IDoge30sXG4gICAgICAgICAgICB6RGVwdGg6IG1vYmlsZSA/IDIgOiAxXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICByZXR1cm4gQ29udGV4dE1lbnU7XG59KShDb21wb25lbnQpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBDb250ZXh0TWVudTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfVXRpbHMgPSByZXF1aXJlKCcuL1V0aWxzJyk7XG5cbnZhciBfVXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXRpbHMpO1xuXG52YXIgX01lbnVJdGVtc0NvbnN1bWVyID0gcmVxdWlyZSgnLi9NZW51SXRlbXNDb25zdW1lcicpO1xuXG52YXIgX01lbnVJdGVtc0NvbnN1bWVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX01lbnVJdGVtc0NvbnN1bWVyKTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIEljb25CdXR0b24gPSBfcmVxdWlyZS5JY29uQnV0dG9uO1xudmFyIFBvcG92ZXIgPSBfcmVxdWlyZS5Qb3BvdmVyO1xuXG52YXIgSWNvbkJ1dHRvbk1lbnUgPSAoZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoSWNvbkJ1dHRvbk1lbnUsIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gSWNvbkJ1dHRvbk1lbnUocHJvcHMsIGNvbnRleHQpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEljb25CdXR0b25NZW51KTtcblxuICAgICAgICBfUmVhY3QkQ29tcG9uZW50LmNhbGwodGhpcywgcHJvcHMsIGNvbnRleHQpO1xuICAgICAgICB0aGlzLnN0YXRlID0geyBzaG93TWVudTogZmFsc2UgfTtcbiAgICB9XG5cbiAgICBJY29uQnV0dG9uTWVudS5wcm90b3R5cGUuc2hvd01lbnUgPSBmdW5jdGlvbiBzaG93TWVudShldmVudCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNob3dNZW51OiB0cnVlLFxuICAgICAgICAgICAgYW5jaG9yOiBldmVudC5jdXJyZW50VGFyZ2V0XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBJY29uQnV0dG9uTWVudS5wcm90b3R5cGUuY2xvc2VNZW51ID0gZnVuY3Rpb24gY2xvc2VNZW51KGV2ZW50LCBpbmRleCwgbWVudUl0ZW0pIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dNZW51OiBmYWxzZSB9KTtcbiAgICB9O1xuXG4gICAgSWNvbkJ1dHRvbk1lbnUucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiBcInRvb2xiYXJzLWJ1dHRvbi1tZW51IFwiICsgKHRoaXMucHJvcHMuY2xhc3NOYW1lID8gdGhpcy5wcm9wcy5jbGFzc05hbWUgOiAnJykgfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoSWNvbkJ1dHRvbiwge1xuICAgICAgICAgICAgICAgIHJlZjogJ21lbnVCdXR0b24nLFxuICAgICAgICAgICAgICAgIHRvb2x0aXA6IHRoaXMucHJvcHMuYnV0dG9uVGl0bGUsXG4gICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogdGhpcy5wcm9wcy5idXR0b25DbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogdGhpcy5zaG93TWVudS5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIGljb25TdHlsZTogdGhpcy5wcm9wcy5idXR0b25TdHlsZVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFBvcG92ZXIsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBvcGVuOiB0aGlzLnN0YXRlLnNob3dNZW51LFxuICAgICAgICAgICAgICAgICAgICBhbmNob3JFbDogdGhpcy5zdGF0ZS5hbmNob3IsXG4gICAgICAgICAgICAgICAgICAgIGFuY2hvck9yaWdpbjogeyBob3Jpem9udGFsOiB0aGlzLnByb3BzLnBvcG92ZXJEaXJlY3Rpb24gfHwgJ3JpZ2h0JywgdmVydGljYWw6IHRoaXMucHJvcHMucG9wb3ZlclRhcmdldFBvc2l0aW9uIHx8ICdib3R0b20nIH0sXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldE9yaWdpbjogeyBob3Jpem9udGFsOiB0aGlzLnByb3BzLnBvcG92ZXJEaXJlY3Rpb24gfHwgJ3JpZ2h0JywgdmVydGljYWw6ICd0b3AnIH0sXG4gICAgICAgICAgICAgICAgICAgIG9uUmVxdWVzdENsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IHNob3dNZW51OiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgdXNlTGF5ZXJGb3JDbGlja0F3YXk6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBfVXRpbHMyWydkZWZhdWx0J10uaXRlbXNUb01lbnUodGhpcy5wcm9wcy5tZW51SXRlbXMsIHRoaXMuY2xvc2VNZW51LmJpbmQodGhpcyksIGZhbHNlLCB0aGlzLnByb3BzLm1lbnVQcm9wcyB8fCB1bmRlZmluZWQpXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBJY29uQnV0dG9uTWVudTtcbn0pKFJlYWN0LkNvbXBvbmVudCk7XG5cbkljb25CdXR0b25NZW51LnByb3BUeXBlcyA9IHtcbiAgICBidXR0b25UaXRsZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgIGJ1dHRvbkNsYXNzTmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgIGNsYXNzTmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICBwb3BvdmVyRGlyZWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMub25lT2YoWydyaWdodCcsICdsZWZ0J10pLFxuICAgIHBvcG92ZXJQb3NpdGlvbjogUmVhY3QuUHJvcFR5cGVzLm9uZU9mKFsndG9wJywgJ2JvdHRvbSddKSxcbiAgICBtZW51UHJvcHM6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgbWVudUl0ZW1zOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXkuaXNSZXF1aXJlZFxufTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gX01lbnVJdGVtc0NvbnN1bWVyMlsnZGVmYXVsdCddKEljb25CdXR0b25NZW51KTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgSWNvbkJ1dHRvbiA9IF9yZXF1aXJlLkljb25CdXR0b247XG52YXIgUG9wb3ZlciA9IF9yZXF1aXJlLlBvcG92ZXI7XG5cbnZhciBJY29uQnV0dG9uUG9wb3ZlciA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhJY29uQnV0dG9uUG9wb3ZlciwgX1JlYWN0JENvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBJY29uQnV0dG9uUG9wb3Zlcihwcm9wcywgY29udGV4dCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgSWNvbkJ1dHRvblBvcG92ZXIpO1xuXG4gICAgICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IHNob3dQb3BvdmVyOiBmYWxzZSB9O1xuICAgIH1cblxuICAgIEljb25CdXR0b25Qb3BvdmVyLnByb3RvdHlwZS5zaG93UG9wb3ZlciA9IGZ1bmN0aW9uIHNob3dQb3BvdmVyKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2hvd1BvcG92ZXI6IHRydWUsXG4gICAgICAgICAgICBhbmNob3I6IGV2ZW50LmN1cnJlbnRUYXJnZXRcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIEljb25CdXR0b25Qb3BvdmVyLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICB7IGNsYXNzTmFtZTogXCJ0b29sYmFycy1idXR0b24tbWVudSBcIiArICh0aGlzLnByb3BzLmNsYXNzTmFtZSA/IHRoaXMucHJvcHMuY2xhc3NOYW1lIDogJycpIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEljb25CdXR0b24sIHtcbiAgICAgICAgICAgICAgICByZWY6ICdtZW51QnV0dG9uJyxcbiAgICAgICAgICAgICAgICB0b29sdGlwOiB0aGlzLnByb3BzLmJ1dHRvblRpdGxlLFxuICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU6IHRoaXMucHJvcHMuYnV0dG9uQ2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IHRoaXMuc2hvd1BvcG92ZXIuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBpY29uU3R5bGU6IHRoaXMucHJvcHMuYnV0dG9uU3R5bGVcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBQb3BvdmVyLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgb3BlbjogdGhpcy5zdGF0ZS5zaG93UG9wb3ZlcixcbiAgICAgICAgICAgICAgICAgICAgYW5jaG9yRWw6IHRoaXMuc3RhdGUuYW5jaG9yLFxuICAgICAgICAgICAgICAgICAgICBhbmNob3JPcmlnaW46IHsgaG9yaXpvbnRhbDogdGhpcy5wcm9wcy5kaXJlY3Rpb24gfHwgJ3JpZ2h0JywgdmVydGljYWw6ICdib3R0b20nIH0sXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldE9yaWdpbjogeyBob3Jpem9udGFsOiB0aGlzLnByb3BzLmRpcmVjdGlvbiB8fCAncmlnaHQnLCB2ZXJ0aWNhbDogJ3RvcCcgfSxcbiAgICAgICAgICAgICAgICAgICAgb25SZXF1ZXN0Q2xvc2U6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgc2hvd1BvcG92ZXI6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB1c2VMYXllckZvckNsaWNrQXdheTogZmFsc2VcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMucG9wb3ZlckNvbnRlbnRcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEljb25CdXR0b25Qb3BvdmVyO1xufSkoUmVhY3QuQ29tcG9uZW50KTtcblxuSWNvbkJ1dHRvblBvcG92ZXIucHJvcFR5cGVzID0ge1xuICAgIGJ1dHRvblRpdGxlOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgYnV0dG9uQ2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgY2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIGRpcmVjdGlvbjogUmVhY3QuUHJvcFR5cGVzLm9uZU9mKFsncmlnaHQnLCAnbGVmdCddKSxcbiAgICBwb3BvdmVyQ29udGVudDogUmVhY3QuUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkXG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBJY29uQnV0dG9uUG9wb3Zlcjtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfVXRpbHMgPSByZXF1aXJlKCcuL1V0aWxzJyk7XG5cbnZhciBfVXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXRpbHMpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIENvbnRyb2xsZXIgPSByZXF1aXJlKCdweWRpby9tb2RlbC9jb250cm9sbGVyJyk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IGZ1bmN0aW9uIChDb21wb25lbnQpIHtcbiAgICB2YXIgV3JhcHBlZCA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgICAgICBfaW5oZXJpdHMoV3JhcHBlZCwgX1JlYWN0JENvbXBvbmVudCk7XG5cbiAgICAgICAgZnVuY3Rpb24gV3JhcHBlZChwcm9wcywgY29udGV4dCkge1xuICAgICAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFdyYXBwZWQpO1xuXG4gICAgICAgICAgICBfUmVhY3QkQ29tcG9uZW50LmNhbGwodGhpcywgcHJvcHMsIGNvbnRleHQpO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgICAgICBtZW51SXRlbXM6IHRoaXMucHJvcHMubWVudUl0ZW1zIHx8IFtdXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgV3JhcHBlZC5wcm90b3R5cGUuY29tcG9uZW50RGlkTW91bnQgPSBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmNvbnRyb2xsZXIgJiYgIXRoaXMucHJvcHMubWVudUl0ZW1zKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb2JzZXJ2ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhY3Rpb25zID0gX3RoaXMucHJvcHMuY29udHJvbGxlci5nZXRDb250ZXh0QWN0aW9ucygnZ2VuZXJpY0NvbnRleHQnLCBudWxsLCBfdGhpcy5wcm9wcy50b29sYmFycyk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBtZW51SXRlbXMgPSBfVXRpbHMyWydkZWZhdWx0J10ucHlkaW9BY3Rpb25zVG9JdGVtcyhhY3Rpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBtZW51SXRlbXM6IG1lbnVJdGVtcyB9KTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmNvbnRyb2xsZXIgPT09IHRoaXMucHJvcHMucHlkaW8uQ29udHJvbGxlcikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnB5ZGlvLm9ic2VydmUoXCJhY3Rpb25zX3JlZnJlc2hlZFwiLCB0aGlzLl9vYnNlcnZlcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5jb250cm9sbGVyLm9ic2VydmUoXCJhY3Rpb25zX3JlZnJlc2hlZFwiLCB0aGlzLl9vYnNlcnZlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX29ic2VydmVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgV3JhcHBlZC5wcm90b3R5cGUuY29tcG9uZW50V2lsbFVubW91bnQgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vYnNlcnZlcikge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmNvbnRyb2xsZXIgPT09IHRoaXMucHJvcHMucHlkaW8uQ29udHJvbGxlcikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnB5ZGlvLnN0b3BPYnNlcnZpbmcoXCJhY3Rpb25zX3JlZnJlc2hlZFwiLCB0aGlzLl9vYnNlcnZlcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5jb250cm9sbGVyLnN0b3BPYnNlcnZpbmcoXCJhY3Rpb25zX3JlZnJlc2hlZFwiLCB0aGlzLl9vYnNlcnZlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIFdyYXBwZWQucHJvdG90eXBlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykge1xuICAgICAgICAgICAgaWYgKG5leHRQcm9wcy5tZW51SXRlbXMgJiYgbmV4dFByb3BzLm1lbnVJdGVtcyAhPT0gdGhpcy5wcm9wcy5tZW51SXRlbXMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgbWVudUl0ZW1zOiBuZXh0UHJvcHMubWVudUl0ZW1zIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIFdyYXBwZWQucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KENvbXBvbmVudCwgX2V4dGVuZHMoe30sIHRoaXMucHJvcHMsIHsgbWVudUl0ZW1zOiB0aGlzLnN0YXRlLm1lbnVJdGVtcyB9KSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIFdyYXBwZWQ7XG4gICAgfSkoUmVhY3QuQ29tcG9uZW50KTtcblxuICAgIFdyYXBwZWQucHJvcFR5cGVzID0ge1xuICAgICAgICBtZW51SXRlbXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcbiAgICAgICAgdG9vbGJhcnM6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcbiAgICAgICAgY29udHJvbGxlcjogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoQ29udHJvbGxlciksXG4gICAgICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbylcbiAgICB9O1xuXG4gICAgcmV0dXJuIFdyYXBwZWQ7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfVXRpbHMgPSByZXF1aXJlKCcuL1V0aWxzJyk7XG5cbnZhciBfVXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXRpbHMpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIFJlYWN0RE9NID0gcmVxdWlyZSgncmVhY3QtZG9tJyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBNZW51ID0gX3JlcXVpcmUuTWVudTtcbnZhciBQYXBlciA9IF9yZXF1aXJlLlBhcGVyO1xuZXhwb3J0c1snZGVmYXVsdCddID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnUG9wdXBNZW51JyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBtZW51SXRlbXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheS5pc1JlcXVpcmVkLFxuICAgICAgICBvbkV4dGVybmFsQ2xpY2tDaGVja0VsZW1lbnRzOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgY2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICBzdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgb25NZW51Q2xvc2VkOiBSZWFjdC5Qcm9wVHlwZXMuZnVuY1xuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHsgc2hvd01lbnU6IGZhbHNlLCBtZW51SXRlbXM6IHRoaXMucHJvcHMubWVudUl0ZW1zIH07XG4gICAgfSxcbiAgICBzaG93TWVudTogZnVuY3Rpb24gc2hvd01lbnUoKSB7XG4gICAgICAgIHZhciBzdHlsZSA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMCB8fCBhcmd1bWVudHNbMF0gPT09IHVuZGVmaW5lZCA/IG51bGwgOiBhcmd1bWVudHNbMF07XG4gICAgICAgIHZhciBtZW51SXRlbXMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyBudWxsIDogYXJndW1lbnRzWzFdO1xuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2hvd01lbnU6IHRydWUsXG4gICAgICAgICAgICBzdHlsZTogc3R5bGUsXG4gICAgICAgICAgICBtZW51SXRlbXM6IG1lbnVJdGVtcyA/IG1lbnVJdGVtcyA6IHRoaXMuc3RhdGUubWVudUl0ZW1zXG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgaGlkZU1lbnU6IGZ1bmN0aW9uIGhpZGVNZW51KGV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93TWVudTogZmFsc2UgfSk7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5vbk1lbnVDbG9zZWQpIHRoaXMucHJvcHMub25NZW51Q2xvc2VkKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gRmlyZWZveCB0cmlnZ2VyIGEgY2xpY2sgZXZlbnQgd2hlbiB5b3UgbW91c2UgdXAgb24gY29udGV4dG1lbnUgZXZlbnRcbiAgICAgICAgaWYgKHR5cGVvZiBldmVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgZXZlbnQuYnV0dG9uID09PSAyICYmIGV2ZW50LnR5cGUgIT09ICdjb250ZXh0bWVudScpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbm9kZSA9IFJlYWN0RE9NLmZpbmRET01Ob2RlKHRoaXMucmVmcy5tZW51Q29udGFpbmVyKTtcbiAgICAgICAgaWYgKG5vZGUuY29udGFpbnMoZXZlbnQudGFyZ2V0KSB8fCBub2RlID09PSBldmVudC50YXJnZXQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93TWVudTogZmFsc2UgfSk7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uTWVudUNsb3NlZCkgdGhpcy5wcm9wcy5vbk1lbnVDbG9zZWQoKTtcbiAgICB9LFxuICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgdGhpcy5fb2JzZXJ2ZXIgPSB0aGlzLmhpZGVNZW51O1xuICAgIH0sXG4gICAgY29tcG9uZW50V2lsbFVubW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX29ic2VydmVyLCBmYWxzZSk7XG4gICAgfSxcbiAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykge1xuICAgICAgICBpZiAobmV4dFByb3BzLm1lbnVJdGVtcykge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IG1lbnVJdGVtczogbmV4dFByb3BzLm1lbnVJdGVtcyB9KTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgY29tcG9uZW50RGlkVXBkYXRlOiBmdW5jdGlvbiBjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzLCBuZXh0UHJvcHMpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2hvd01lbnUpIHtcbiAgICAgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fb2JzZXJ2ZXIsIGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fb2JzZXJ2ZXIsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBtZW51Q2xpY2tlZDogZnVuY3Rpb24gbWVudUNsaWNrZWQoZXZlbnQsIGluZGV4LCBtZW51SXRlbSkge1xuICAgICAgICB0aGlzLmhpZGVNZW51KCk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuXG4gICAgICAgIHZhciBzdHlsZSA9IHRoaXMuc3RhdGUuc3R5bGUgfHwge307XG4gICAgICAgIHN0eWxlID0gX2V4dGVuZHMoe30sIHN0eWxlLCB7IHpJbmRleDogMTAwMCB9KTtcbiAgICAgICAgdmFyIG1lbnUgPSBfVXRpbHMyWydkZWZhdWx0J10uaXRlbXNUb01lbnUodGhpcy5zdGF0ZS5tZW51SXRlbXMsIHRoaXMubWVudUNsaWNrZWQsIGZhbHNlLCBfZXh0ZW5kcyh7IGRlc2t0b3A6IHRydWUsIGRpc3BsYXk6ICdyaWdodCcsIHdpZHRoOiAyNTAgfSwgdGhpcy5wcm9wcy5tZW51UHJvcHMpKTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2hvd01lbnUpIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFBhcGVyLFxuICAgICAgICAgICAgICAgIHsgekRlcHRoOiB0aGlzLnByb3BzLnpEZXB0aCB8fCAxLCByZWY6ICdtZW51Q29udGFpbmVyJywgY2xhc3NOYW1lOiAnbWVudS1wb3NpdGlvbmVyJywgc3R5bGU6IHN0eWxlIH0sXG4gICAgICAgICAgICAgICAgbWVudVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG59KTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9VdGlscyA9IHJlcXVpcmUoJy4vVXRpbHMnKTtcblxudmFyIF9VdGlsczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9VdGlscyk7XG5cbnZhciBfSWNvbkJ1dHRvbk1lbnUgPSByZXF1aXJlKCcuL0ljb25CdXR0b25NZW51Jyk7XG5cbnZhciBfSWNvbkJ1dHRvbk1lbnUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfSWNvbkJ1dHRvbk1lbnUpO1xuXG52YXIgX0J1dHRvbk1lbnUgPSByZXF1aXJlKCcuL0J1dHRvbk1lbnUnKTtcblxudmFyIF9CdXR0b25NZW51MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0J1dHRvbk1lbnUpO1xuXG52YXIgX0ljb25CdXR0b25Qb3BvdmVyID0gcmVxdWlyZSgnLi9JY29uQnV0dG9uUG9wb3ZlcicpO1xuXG52YXIgX0ljb25CdXR0b25Qb3BvdmVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0ljb25CdXR0b25Qb3BvdmVyKTtcblxuKGZ1bmN0aW9uIChnbG9iYWwpIHtcbiAgICBleHBvcnRzWydkZWZhdWx0J10gPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgICAgIGRpc3BsYXlOYW1lOiAnVG9vbGJhcicsXG5cbiAgICAgICAgcHJvcFR5cGVzOiB7XG4gICAgICAgICAgICB0b29sYmFyczogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuICAgICAgICAgICAgZ3JvdXBPdGhlckxpc3Q6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcbiAgICAgICAgICAgIHJlbmRlcmluZ1R5cGU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgICAgICBjb250cm9sbGVyOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihDb250cm9sbGVyKSxcbiAgICAgICAgICAgIHRvb2xiYXJTdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgICAgIGJ1dHRvblN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0XG4gICAgICAgIH0sXG5cbiAgICAgICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICAgICAgdGhpcy5fb2JzZXJ2ZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc01vdW50ZWQoKSkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgICAgICBncm91cHM6IHRoaXMucHJvcHMuY29udHJvbGxlci5nZXRUb29sYmFyc0FjdGlvbnModGhpcy5wcm9wcy50b29sYmFycywgdGhpcy5wcm9wcy5ncm91cE90aGVyTGlzdClcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5jb250cm9sbGVyID09PSBweWRpby5Db250cm9sbGVyKSB7XG4gICAgICAgICAgICAgICAgcHlkaW8ub2JzZXJ2ZShcImFjdGlvbnNfcmVmcmVzaGVkXCIsIHRoaXMuX29ic2VydmVyKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5jb250cm9sbGVyLm9ic2VydmUoXCJhY3Rpb25zX3JlZnJlc2hlZFwiLCB0aGlzLl9vYnNlcnZlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgY29tcG9uZW50V2lsbFVubW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuY29udHJvbGxlciA9PT0gcHlkaW8uQ29udHJvbGxlcikge1xuICAgICAgICAgICAgICAgIHB5ZGlvLnN0b3BPYnNlcnZpbmcoXCJhY3Rpb25zX3JlZnJlc2hlZFwiLCB0aGlzLl9vYnNlcnZlcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuY29udHJvbGxlci5zdG9wT2JzZXJ2aW5nKFwiYWN0aW9uc19yZWZyZXNoZWRcIiwgdGhpcy5fb2JzZXJ2ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHM6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7XG4gICAgICAgICAgICBpZiAobmV4dFByb3BzLnRvb2xiYXJzICE9PSB0aGlzLnByb3BzLnRvb2xiYXJzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwczogdGhpcy5wcm9wcy5jb250cm9sbGVyLmdldFRvb2xiYXJzQWN0aW9ucyhuZXh0UHJvcHMudG9vbGJhcnMsIG5leHRQcm9wcy5ncm91cE90aGVyTGlzdClcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZ3JvdXBzOiB0aGlzLnByb3BzLmNvbnRyb2xsZXIuZ2V0VG9vbGJhcnNBY3Rpb25zKHRoaXMucHJvcHMudG9vbGJhcnMsIHRoaXMucHJvcHMuZ3JvdXBPdGhlckxpc3QpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuXG4gICAgICAgIGdldERlZmF1bHRQcm9wczogZnVuY3Rpb24gZ2V0RGVmYXVsdFByb3BzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyOiBnbG9iYWwucHlkaW8uQ29udHJvbGxlcixcbiAgICAgICAgICAgICAgICByZW5kZXJpbmdUeXBlOiAnYnV0dG9uJyxcbiAgICAgICAgICAgICAgICBncm91cE90aGVyTGlzdDogW11cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sXG5cbiAgICAgICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgICAgICB2YXIgZ3JvdXBzID0gdGhpcy5zdGF0ZS5ncm91cHM7XG4gICAgICAgICAgICB2YXIgYWN0aW9ucyA9IFtdO1xuICAgICAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHM7XG4gICAgICAgICAgICB2YXIgdG9vbGJhcnMgPSBfcHJvcHMudG9vbGJhcnM7XG4gICAgICAgICAgICB2YXIgcmVuZGVyaW5nVHlwZSA9IF9wcm9wcy5yZW5kZXJpbmdUeXBlO1xuICAgICAgICAgICAgdmFyIGdyb3VwT3RoZXJMaXN0ID0gX3Byb3BzLmdyb3VwT3RoZXJMaXN0O1xuICAgICAgICAgICAgdmFyIGJ1dHRvblN0eWxlID0gX3Byb3BzLmJ1dHRvblN0eWxlO1xuICAgICAgICAgICAgdmFyIHRvb2x0aXBQb3NpdGlvbiA9IF9wcm9wcy50b29sdGlwUG9zaXRpb247XG4gICAgICAgICAgICB2YXIgY29udHJvbGxlciA9IF9wcm9wcy5jb250cm9sbGVyO1xuXG4gICAgICAgICAgICB2YXIgYWxsVG9vbGJhcnMgPSBbXS5jb25jYXQodG9vbGJhcnMpO1xuICAgICAgICAgICAgaWYgKGdyb3VwT3RoZXJMaXN0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGFsbFRvb2xiYXJzID0gYWxsVG9vbGJhcnMuY29uY2F0KFsnTU9SRV9BQ1RJT04nXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhbGxUb29sYmFycy5tYXAoZnVuY3Rpb24gKGJhck5hbWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWdyb3Vwcy5oYXMoYmFyTmFtZSkpIHJldHVybjtcbiAgICAgICAgICAgICAgICBncm91cHMuZ2V0KGJhck5hbWUpLm1hcChmdW5jdGlvbiAoYWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhY3Rpb24uZGVueSkgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbWVudUl0ZW1zID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcG9wb3ZlckNvbnRlbnQgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZW51VGl0bGUgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZW51SWNvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFjdGlvbk5hbWUgPSBhY3Rpb24ub3B0aW9ucy5uYW1lO1xuXG4gICAgICAgICAgICAgICAgICAgIG1lbnVUaXRsZSA9IGFjdGlvbi5vcHRpb25zLnRleHQ7XG4gICAgICAgICAgICAgICAgICAgIG1lbnVJY29uID0gYWN0aW9uLm9wdGlvbnMuaWNvbl9jbGFzcztcblxuICAgICAgICAgICAgICAgICAgICBpZiAoYmFyTmFtZSA9PT0gJ01PUkVfQUNUSU9OJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3ViSXRlbXMgPSBhY3Rpb24uc3ViTWVudUl0ZW1zLmR5bmFtaWNJdGVtcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXRlbXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJJdGVtcy5tYXAoZnVuY3Rpb24gKG9iaikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob2JqLnNlcGFyYXRvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMucHVzaChvYmopO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG9iai5hY3Rpb25JZCAmJiAhb2JqLmFjdGlvbklkLmRlbnkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zLnB1c2gob2JqLmFjdGlvbklkLmdldE1lbnVEYXRhKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVudUl0ZW1zID0gX1V0aWxzMlsnZGVmYXVsdCddLnB5ZGlvQWN0aW9uc1RvSXRlbXMoaXRlbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhY3Rpb24uc3ViTWVudUl0ZW1zLnN0YXRpY0l0ZW1zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZW51SXRlbXMgPSBfVXRpbHMyWydkZWZhdWx0J10ucHlkaW9BY3Rpb25zVG9JdGVtcyhhY3Rpb24uc3ViTWVudUl0ZW1zLnN0YXRpY0l0ZW1zKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhY3Rpb24uc3ViTWVudUl0ZW1zLmR5bmFtaWNCdWlsZGVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZW51SXRlbXMgPSBfVXRpbHMyWydkZWZhdWx0J10ucHlkaW9BY3Rpb25zVG9JdGVtcyhhY3Rpb24uc3ViTWVudUl0ZW1zLmR5bmFtaWNCdWlsZGVyKGNvbnRyb2xsZXIpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhY3Rpb24uc3ViTWVudUl0ZW1zLnBvcG92ZXJDb250ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwb3BvdmVyQ29udGVudCA9IGFjdGlvbi5zdWJNZW51SXRlbXMucG9wb3ZlckNvbnRlbnQ7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7fVxuICAgICAgICAgICAgICAgICAgICB2YXIgaWQgPSAnYWN0aW9uLScgKyBhY3Rpb24ub3B0aW9ucy5uYW1lO1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVuZGVyaW5nVHlwZSA9PT0gJ2J1dHRvbi1pY29uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVudVRpdGxlID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdidXR0b24taWNvbicgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KCdzcGFuJywgeyBjbGFzc05hbWU6IFwiYnV0dG9uLWljb24taWNvbiBcIiArIG1lbnVJY29uIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdidXR0b24taWNvbi1sYWJlbCcgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVudVRpdGxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAobWVudUl0ZW1zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVuZGVyaW5nVHlwZSA9PT0gJ2J1dHRvbicgfHwgcmVuZGVyaW5nVHlwZSA9PT0gJ2J1dHRvbi1pY29uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbnMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KF9CdXR0b25NZW51MlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleTogYWN0aW9uTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBpZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9uVGl0bGU6IG1lbnVUaXRsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVudUl0ZW1zOiBtZW51SXRlbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbkxhYmVsU3R5bGU6IGJ1dHRvblN0eWxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb25zLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChfSWNvbkJ1dHRvbk1lbnUyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5OiBhY3Rpb25OYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbk1lbnVDbGlja2VkOiBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QucGF5bG9hZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25DbGFzc05hbWU6IG1lbnVJY29uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25UaXRsZTogbWVudVRpdGxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW51SXRlbXM6IG1lbnVJdGVtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9uU3R5bGU6IGJ1dHRvblN0eWxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBvcG92ZXJDb250ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb25zLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChfSWNvbkJ1dHRvblBvcG92ZXIyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IGFjdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBpZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25DbGFzc05hbWU6IG1lbnVJY29uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvblRpdGxlOiBtZW51VGl0bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9uU3R5bGU6IGJ1dHRvblN0eWxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcG92ZXJDb250ZW50OiBwb3BvdmVyQ29udGVudFxuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNsaWNrID0gZnVuY3Rpb24gY2xpY2soc3ludGhFdmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbi5hcHBseSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZW5kZXJpbmdUeXBlID09PSAnYnV0dG9uLWljb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9ucy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoUmVhY3RNVUkuRmxhdEJ1dHRvbiwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IGFjdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IGNsaWNrLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogbWVudVRpdGxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbFN0eWxlOiBidXR0b25TdHlsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVuZGVyaW5nVHlwZSA9PT0gJ2J1dHRvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb25zLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChNYXRlcmlhbFVJLkZsYXRCdXR0b24sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5OiBhY3Rpb25OYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiBjbGljayxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IG1lbnVUaXRsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxTdHlsZTogYnV0dG9uU3R5bGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbnMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KE1hdGVyaWFsVUkuSWNvbkJ1dHRvbiwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IGFjdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU6IG1lbnVJY29uICsgJyAnICsgaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljb25TdHlsZTogYnV0dG9uU3R5bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IGNsaWNrLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiBtZW51VGl0bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbjogdG9vbHRpcFBvc2l0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHZhciBjTmFtZSA9IHRoaXMucHJvcHMuY2xhc3NOYW1lID8gdGhpcy5wcm9wcy5jbGFzc05hbWUgOiAnJztcbiAgICAgICAgICAgIGNOYW1lICs9ICcgJyArICd0b29sYmFyJztcbiAgICAgICAgICAgIGlmICghYWN0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjTmFtZSArPSAnIGVtcHR5LXRvb2xiYXInO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IGNOYW1lLCBzdHlsZTogdGhpcy5wcm9wcy50b29sYmFyU3R5bGUsIGlkOiB0aGlzLnByb3BzLmlkIH0sXG4gICAgICAgICAgICAgICAgYWN0aW9uc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgfSk7XG59KSh3aW5kb3cpO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIERpdmlkZXIgPSBfcmVxdWlyZS5EaXZpZGVyO1xudmFyIE1lbnUgPSBfcmVxdWlyZS5NZW51O1xudmFyIE1lbnVJdGVtID0gX3JlcXVpcmUuTWVudUl0ZW07XG52YXIgRm9udEljb24gPSBfcmVxdWlyZS5Gb250SWNvbjtcblxuZnVuY3Rpb24gcHlkaW9BY3Rpb25zVG9JdGVtcygpIHtcbiAgICB2YXIgYWN0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMCB8fCBhcmd1bWVudHNbMF0gPT09IHVuZGVmaW5lZCA/IFtdIDogYXJndW1lbnRzWzBdO1xuXG4gICAgdmFyIGl0ZW1zID0gW107XG4gICAgdmFyIGxhc3RJc1NlcGFyYXRvciA9IGZhbHNlO1xuICAgIGFjdGlvbnMubWFwKChmdW5jdGlvbiAoYWN0aW9uLCBpbmRleCkge1xuICAgICAgICBpZiAoYWN0aW9uLnNlcGFyYXRvcikge1xuICAgICAgICAgICAgaWYgKGxhc3RJc1NlcGFyYXRvcikgcmV0dXJuO1xuICAgICAgICAgICAgaXRlbXMucHVzaChhY3Rpb24pO1xuICAgICAgICAgICAgbGFzdElzU2VwYXJhdG9yID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsYXN0SXNTZXBhcmF0b3IgPSBmYWxzZTtcbiAgICAgICAgdmFyIGxhYmVsID0gYWN0aW9uLnJhd19uYW1lID8gYWN0aW9uLnJhd19uYW1lIDogYWN0aW9uLm5hbWU7XG4gICAgICAgIHZhciBpY29uQ2xhc3MgPSBhY3Rpb24uaWNvbl9jbGFzcztcbiAgICAgICAgdmFyIHBheWxvYWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChhY3Rpb24uc3ViTWVudSkge1xuICAgICAgICAgICAgdmFyIHN1Ykl0ZW1zID0gYWN0aW9uLnN1Yk1lbnVCZWZvcmVTaG93ID8gcHlkaW9BY3Rpb25zVG9JdGVtcyhhY3Rpb24uc3ViTWVudUJlZm9yZVNob3coKSkgOiBhY3Rpb24uc3ViTWVudTtcbiAgICAgICAgICAgIGl0ZW1zLnB1c2goe1xuICAgICAgICAgICAgICAgIHRleHQ6IGxhYmVsLFxuICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU6IGljb25DbGFzcyxcbiAgICAgICAgICAgICAgICBzdWJJdGVtczogc3ViSXRlbXNcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgICAgICAgICAgdGV4dDogbGFiZWwsXG4gICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogaWNvbkNsYXNzLFxuICAgICAgICAgICAgICAgIHBheWxvYWQ6IGFjdGlvbi5jYWxsYmFja1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICBpZiAobGFzdElzU2VwYXJhdG9yKSB7XG4gICAgICAgIGl0ZW1zID0gaXRlbXMuc2xpY2UoMCwgaXRlbXMubGVuZ3RoIC0gMSk7XG4gICAgfVxuICAgIGlmIChpdGVtcy5sZW5ndGggJiYgaXRlbXNbMF0gJiYgaXRlbXNbMF0uc2VwYXJhdG9yKSB7XG4gICAgICAgIGl0ZW1zLnNoaWZ0KCk7XG4gICAgfVxuICAgIHJldHVybiBpdGVtcztcbn1cblxuZnVuY3Rpb24gaXRlbXNUb01lbnUoaXRlbXMsIGNsb3NlTWVudUNhbGxiYWNrKSB7XG4gICAgdmFyIHN1Ykl0ZW1zT25seSA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMiB8fCBhcmd1bWVudHNbMl0gPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogYXJndW1lbnRzWzJdO1xuICAgIHZhciBtZW51UHJvcHMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDMgfHwgYXJndW1lbnRzWzNdID09PSB1bmRlZmluZWQgPyB7fSA6IGFyZ3VtZW50c1szXTtcblxuICAgIG1lbnVQcm9wcyA9IF9leHRlbmRzKHtcbiAgICAgICAgZGlzcGxheTogJ25vcm1hbCcsXG4gICAgICAgIHdpZHRoOiAyMTYsXG4gICAgICAgIGRlc2t0b3A6IHRydWUsXG4gICAgICAgIGF1dG9XaWR0aDogZmFsc2VcbiAgICB9LCBtZW51UHJvcHMpO1xuXG4gICAgdmFyIG1lbnVJdGVtcyA9IGl0ZW1zLm1hcChmdW5jdGlvbiAoaXRlbSwgaW5kZXgpIHtcblxuICAgICAgICBpZiAoaXRlbS5zZXBhcmF0b3IpIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KERpdmlkZXIsIHsga2V5OiBcImRpdmlkZXJcIiArIGluZGV4IH0pO1xuXG4gICAgICAgIHZhciBzdWJJdGVtcyA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHBheWxvYWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChpdGVtLnN1Ykl0ZW1zKSB7XG4gICAgICAgICAgICBzdWJJdGVtcyA9IGl0ZW1zVG9NZW51KGl0ZW0uc3ViSXRlbXMsIGNsb3NlTWVudUNhbGxiYWNrLCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIGlmIChpdGVtLnBheWxvYWQpIHtcbiAgICAgICAgICAgIHBheWxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaXRlbS5wYXlsb2FkKCk7XG4gICAgICAgICAgICAgICAgY2xvc2VNZW51Q2FsbGJhY2soKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbGVmdEljb24gPSB1bmRlZmluZWQsXG4gICAgICAgICAgICByaWdodEljb24gPSB1bmRlZmluZWQ7XG4gICAgICAgIHZhciBpY29uQ2xhc3NOYW1lID0gaXRlbS5pY29uQ2xhc3NOYW1lO3ZhciBpbnNldCA9IGZhbHNlO1xuICAgICAgICBpZiAoaWNvbkNsYXNzTmFtZSA9PT0gJ19fSU5TRVRfXycpIHtcbiAgICAgICAgICAgIGljb25DbGFzc05hbWUgPSAnJztcbiAgICAgICAgICAgIGluc2V0ID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtZW51UHJvcHMuZGlzcGxheSA9PT0gJ25vcm1hbCcpIHtcbiAgICAgICAgICAgIGxlZnRJY29uID0gaWNvbkNsYXNzTmFtZSA/IFJlYWN0LmNyZWF0ZUVsZW1lbnQoRm9udEljb24sIHsgY2xhc3NOYW1lOiBpdGVtLmljb25DbGFzc05hbWUgKyAnIG1lbnUtaWNvbnMnLCBzdHlsZTogeyBmb250U2l6ZTogMTYsIHBhZGRpbmc6IDUgfSB9KSA6IG51bGw7XG4gICAgICAgIH0gZWxzZSBpZiAobWVudVByb3BzLmRpc3BsYXkgPT09ICdyaWdodCcpIHtcbiAgICAgICAgICAgIHJpZ2h0SWNvbiA9IGljb25DbGFzc05hbWUgPyBSZWFjdC5jcmVhdGVFbGVtZW50KEZvbnRJY29uLCB7IGNsYXNzTmFtZTogaXRlbS5pY29uQ2xhc3NOYW1lICsgJyBtZW51LWljb25zJywgc3R5bGU6IHsgZm9udFNpemU6IDE2LCBwYWRkaW5nOiA1IH0gfSkgOiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJpZ2h0SWNvbiA9IHN1Ykl0ZW1zICYmIHN1Ykl0ZW1zLmxlbmd0aCA/IFJlYWN0LmNyZWF0ZUVsZW1lbnQoRm9udEljb24sIHsgY2xhc3NOYW1lOiAnbWRpIG1kaS1tZW51LXJpZ2h0IG1lbnUtaWNvbnMnIH0pIDogcmlnaHRJY29uO1xuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KE1lbnVJdGVtLCB7XG4gICAgICAgICAgICBrZXk6IGl0ZW0udGV4dCxcbiAgICAgICAgICAgIHByaW1hcnlUZXh0OiBpdGVtLnRleHQsXG4gICAgICAgICAgICBpbnNldENoaWxkcmVuOiBpbnNldCxcbiAgICAgICAgICAgIGxlZnRJY29uOiBsZWZ0SWNvbixcbiAgICAgICAgICAgIHJpZ2h0SWNvbjogcmlnaHRJY29uLFxuICAgICAgICAgICAgb25Ub3VjaFRhcDogcGF5bG9hZCxcbiAgICAgICAgICAgIG1lbnVJdGVtczogc3ViSXRlbXNcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpZiAoc3ViSXRlbXNPbmx5KSB7XG4gICAgICAgIHJldHVybiBtZW51SXRlbXM7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICBNZW51LFxuICAgICAgICAgICAgbWVudVByb3BzLFxuICAgICAgICAgICAgbWVudUl0ZW1zXG4gICAgICAgICk7XG4gICAgfVxufVxuXG5leHBvcnRzWydkZWZhdWx0J10gPSB7IHB5ZGlvQWN0aW9uc1RvSXRlbXM6IHB5ZGlvQWN0aW9uc1RvSXRlbXMsIGl0ZW1zVG9NZW51OiBpdGVtc1RvTWVudSB9O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBDb21wb25lbnQgPSBfcmVxdWlyZS5Db21wb25lbnQ7XG52YXIgUHJvcFR5cGVzID0gX3JlcXVpcmUuUHJvcFR5cGVzO1xuXG52YXIgX3JlcXVpcmUyID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIFRleHRGaWVsZCA9IF9yZXF1aXJlMi5UZXh0RmllbGQ7XG52YXIgRmxhdEJ1dHRvbiA9IF9yZXF1aXJlMi5GbGF0QnV0dG9uO1xuXG52YXIgX3JlcXVpcmUkcmVxdWlyZUxpYiA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgUHlkaW9Db250ZXh0Q29uc3VtZXIgPSBfcmVxdWlyZSRyZXF1aXJlTGliLlB5ZGlvQ29udGV4dENvbnN1bWVyO1xuXG4vKipcbiAqIFNpbXBsZSBmb3JtIGZvciBjcmVhdGluZyBhIHRlYW1cbiAqL1xuXG52YXIgVGVhbUNyZWF0aW9uRm9ybSA9IChmdW5jdGlvbiAoX0NvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhUZWFtQ3JlYXRpb25Gb3JtLCBfQ29tcG9uZW50KTtcblxuICAgIFRlYW1DcmVhdGlvbkZvcm0udXBkYXRlVGVhbVVzZXJzID0gZnVuY3Rpb24gdXBkYXRlVGVhbVVzZXJzKHRlYW0sIG9wZXJhdGlvbiwgdXNlcnMsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciB0ZWFtSWQgPSB0ZWFtLmlkLnJlcGxhY2UoJy9BSlhQX1RFQU0vJywgJycpO1xuICAgICAgICB2YXIgY2xlYXJVc2VyQ2FjaGUgPSBmdW5jdGlvbiBjbGVhclVzZXJDYWNoZSh1SWQpIHtcbiAgICAgICAgICAgIE1ldGFDYWNoZVNlcnZpY2UuZ2V0SW5zdGFuY2UoKS5kZWxldGVLZXkoJ3VzZXJfcHVibGljX2RhdGEtcmljaCcsIHVJZCk7XG4gICAgICAgIH07XG4gICAgICAgIGlmIChvcGVyYXRpb24gPT09ICdhZGQnKSB7XG4gICAgICAgICAgICB1c2Vycy5mb3JFYWNoKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICAgICAgICAgICAgdmFyIHVzZXJJZCA9IHVzZXIuZ2V0SWQgPyB1c2VyLmdldElkKCkgOiB1c2VyLmlkO1xuICAgICAgICAgICAgICAgIFB5ZGlvVXNlcnMuQ2xpZW50LmFkZFVzZXJUb1RlYW0odGVhbUlkLCB1c2VySWQsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICBjbGVhclVzZXJDYWNoZSh1c2VySWQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAob3BlcmF0aW9uID09PSAnZGVsZXRlJykge1xuICAgICAgICAgICAgdXNlcnMuZm9yRWFjaChmdW5jdGlvbiAodXNlcikge1xuICAgICAgICAgICAgICAgIHZhciB1c2VySWQgPSB1c2VyLmdldElkID8gdXNlci5nZXRJZCgpIDogdXNlci5pZDtcbiAgICAgICAgICAgICAgICBQeWRpb1VzZXJzLkNsaWVudC5yZW1vdmVVc2VyRnJvbVRlYW0odGVhbUlkLCB1c2VySWQsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICBjbGVhclVzZXJDYWNoZSh1c2VySWQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAob3BlcmF0aW9uID09PSAnY3JlYXRlJykge1xuICAgICAgICAgICAgUHlkaW9Vc2Vycy5DbGllbnQuc2F2ZVNlbGVjdGlvbkFzVGVhbSh0ZWFtSWQsIHVzZXJzLCBjYWxsYmFjayk7XG4gICAgICAgICAgICB1c2Vycy5mb3JFYWNoKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJVc2VyQ2FjaGUodXNlci5nZXRJZCA/IHVzZXIuZ2V0SWQoKSA6IHVzZXIuaWQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gVGVhbUNyZWF0aW9uRm9ybShwcm9wcywgY29udGV4dCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVGVhbUNyZWF0aW9uRm9ybSk7XG5cbiAgICAgICAgX0NvbXBvbmVudC5jYWxsKHRoaXMsIHByb3BzLCBjb250ZXh0KTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHsgdmFsdWU6ICcnIH07XG4gICAgfVxuXG4gICAgVGVhbUNyZWF0aW9uRm9ybS5wcm90b3R5cGUub25DaGFuZ2UgPSBmdW5jdGlvbiBvbkNoYW5nZShlLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgdmFsdWU6IHZhbHVlIH0pO1xuICAgIH07XG5cbiAgICBUZWFtQ3JlYXRpb25Gb3JtLnByb3RvdHlwZS5zdWJtaXRDcmVhdGlvbkZvcm0gPSBmdW5jdGlvbiBzdWJtaXRDcmVhdGlvbkZvcm0oKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuc3RhdGUudmFsdWU7XG4gICAgICAgIFRlYW1DcmVhdGlvbkZvcm0udXBkYXRlVGVhbVVzZXJzKHsgaWQ6IHZhbHVlIH0sICdjcmVhdGUnLCBbXSwgdGhpcy5wcm9wcy5vblRlYW1DcmVhdGVkKTtcbiAgICB9O1xuXG4gICAgVGVhbUNyZWF0aW9uRm9ybS5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgZ2V0TWVzc2FnZSA9IHRoaXMucHJvcHMuZ2V0TWVzc2FnZTtcblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgeyBzdHlsZTogeyBwYWRkaW5nOiAyMCB9IH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgZ2V0TWVzc2FnZSg1OTEpXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChUZXh0RmllbGQsIHsgZmxvYXRpbmdMYWJlbFRleHQ6IGdldE1lc3NhZ2UoNTc4KSwgdmFsdWU6IHRoaXMuc3RhdGUudmFsdWUsIG9uQ2hhbmdlOiB0aGlzLm9uQ2hhbmdlLmJpbmQodGhpcyksIGZ1bGxXaWR0aDogdHJ1ZSB9KSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyB0ZXh0QWxpZ246ICdyaWdodCcsIHBhZGRpbmdUb3A6IDEwIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChGbGF0QnV0dG9uLCB7IGxhYmVsOiBnZXRNZXNzYWdlKDQ5KSwgb25Ub3VjaFRhcDogdGhpcy5wcm9wcy5vbkNhbmNlbC5iaW5kKHRoaXMpIH0pLFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEZsYXRCdXR0b24sIHsgbGFiZWw6IGdldE1lc3NhZ2UoNTc5KSwgc2Vjb25kYXJ5OiB0cnVlLCBvblRvdWNoVGFwOiB0aGlzLnN1Ym1pdENyZWF0aW9uRm9ybS5iaW5kKHRoaXMpIH0pXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH07XG5cbiAgICByZXR1cm4gVGVhbUNyZWF0aW9uRm9ybTtcbn0pKENvbXBvbmVudCk7XG5cblRlYW1DcmVhdGlvbkZvcm0ucHJvcFR5cGVzID0ge1xuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIHRyaWdnZXJlZCBhZnRlciB0ZWFtIGNyZWF0aW9uIHN1Y2NlZWRlZFxuICAgICAqL1xuICAgIG9uVGVhbUNyZWF0ZWQ6IFByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsXG4gICAgLyoqXG4gICAgICogUmVxdWVzdCBtb2RhbCBjbG9zZVxuICAgICAqL1xuICAgIG9uQ2FuY2VsOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkXG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBUZWFtQ3JlYXRpb25Gb3JtID0gUHlkaW9Db250ZXh0Q29uc3VtZXIoVGVhbUNyZWF0aW9uRm9ybSk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFRlYW1DcmVhdGlvbkZvcm07XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG52YXIgX2FkZHJlc3Nib29rQWRkcmVzc0Jvb2sgPSByZXF1aXJlKCcuL2FkZHJlc3Nib29rL0FkZHJlc3NCb29rJyk7XG5cbnZhciBfYWRkcmVzc2Jvb2tBZGRyZXNzQm9vazIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hZGRyZXNzYm9va0FkZHJlc3NCb29rKTtcblxudmFyIF9yZXF1aXJlJHJlcXVpcmVMaWIgPSByZXF1aXJlKCdweWRpby9odHRwL3Jlc291cmNlcy1tYW5hZ2VyJykucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgQXN5bmNDb21wb25lbnQgPSBfcmVxdWlyZSRyZXF1aXJlTGliLkFzeW5jQ29tcG9uZW50O1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgVGV4dEZpZWxkID0gX3JlcXVpcmUuVGV4dEZpZWxkO1xudmFyIEF1dG9Db21wbGV0ZSA9IF9yZXF1aXJlLkF1dG9Db21wbGV0ZTtcbnZhciBSZWZyZXNoSW5kaWNhdG9yID0gX3JlcXVpcmUuUmVmcmVzaEluZGljYXRvcjtcbnZhciBJY29uQnV0dG9uID0gX3JlcXVpcmUuSWNvbkJ1dHRvbjtcbnZhciBQb3BvdmVyID0gX3JlcXVpcmUuUG9wb3ZlcjtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcbnZhciBGdW5jVXRpbHMgPSByZXF1aXJlKCdweWRpby91dGlsL2Z1bmMnKTtcblxuLyoqXG4gKiBSZWFkeSB0byB1c2UgYXV0b2NvbXBsZXRlIGZpZWxkIHRoYXQgd2lsbCBsb2FkIHVzZXJzL2dyb3Vwcy9yb2xlcyBmcm9tXG4gKiB0aGUgc2VydmVyICh1c2luZyB1c2VyX2xpc3RfYXV0aG9yaXplZF91c2VycyBBUEkpLlxuICogVXNlZCBmb3Igc2hhcmluZywgYWRkcmVzc2Jvb2tzLCBzZW5kIGVtYWlsLCBldGMuXG4gKlxuICogQ2FuIGFsc28gb3BlbiBhIFwic2VsZWN0b3Itc3R5bGVcIiBhZHJlc3MgYm9vay5cbiAqL1xudmFyIFVzZXJzTG9hZGVyID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnVXNlcnNMb2FkZXInLFxuXG4gICAgcHJvcFR5cGVzOiB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1ldGhvZCBjYWxsZWQgdG8gcmVuZGVyIGEgY29tbXBvbmVudCwgdGFraW5nIGEgVXNlck9iamVjdCBhcyBpbnB1dFxuICAgICAgICAgKi9cbiAgICAgICAgcmVuZGVyU3VnZ2VzdGlvbjogUmVhY3QuUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIENhbGxiYWNrIHdoZW4gYSB2YWx1ZSBpcyBmaW5hbGx5IHNlbGVjdGVkXG4gICAgICAgICAqL1xuICAgICAgICBvblZhbHVlU2VsZWN0ZWQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGbG9hdGluZyBMYWJlbCBUZXh0IGRpc3BsYXllZCBvbiB0aGUgZmllbGRcbiAgICAgICAgICovXG4gICAgICAgIGZpZWxkTGFiZWw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFycmF5IG9mIHZhbHVlcyB0byBpZ25vcmVcbiAgICAgICAgICovXG4gICAgICAgIGV4Y2x1ZGVzOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXkuaXNSZXF1aXJlZCxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERpc3BsYXkgb25seSB1c2Vycywgbm8gZ3JvdXBzIG5vciByb2xlc1xuICAgICAgICAgKi9cbiAgICAgICAgdXNlcnNPbmx5OiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERpc3BsYXkgdXNlcnMgZnJvbSBsb2NhbCBkaXJlY3RvcnkgYW5kL29yIGZyb20gcmVtb3RlLlxuICAgICAgICAgKi9cbiAgICAgICAgdXNlcnNGcm9tOiBSZWFjdC5Qcm9wVHlwZXMub25lT2YoWydsb2NhbCcsICdyZW1vdGUnLCAnYW55J10pLFxuICAgICAgICAvKipcbiAgICAgICAgICogRG8gbm90IHByb3Bvc2UgYSBcIkNyZWF0ZSB1c2VyXCIgb3B0aW9uXG4gICAgICAgICAqL1xuICAgICAgICBleGlzdGluZ09ubHk6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICAvKipcbiAgICAgICAgICogQWxsb3cgZnJlZSB0eXBpbmdcbiAgICAgICAgICovXG4gICAgICAgIGZyZWVWYWx1ZUFsbG93ZWQ6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICAvKipcbiAgICAgICAgICogV2lsbCBiZSBwYXNzZWQgdG8gdGhlIHJvb3QgY29tcG9uZW50XG4gICAgICAgICAqL1xuICAgICAgICBjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmdcbiAgICB9LFxuXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiBnZXRJbml0aWFsU3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBkYXRhU291cmNlOiBbXSxcbiAgICAgICAgICAgIGxvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgICAgc2VhcmNoVGV4dDogJycsXG4gICAgICAgICAgICBtaW5DaGFyczogcGFyc2VJbnQoZ2xvYmFsLnB5ZGlvLmdldFBsdWdpbkNvbmZpZ3MoXCJjb3JlLmNvbmZcIikuZ2V0KFwiVVNFUlNfTElTVF9DT01QTEVURV9NSU5fQ0hBUlNcIikpXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIExvYWRzIHZhbHVlcyBmcm9tIHNlcnZlclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dCBDdXJyZW50bHkgc2VhcmNoZWQgdGV4dFxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIENhbGxlZCB3aXRoIHRoZSB2YWx1ZXNcbiAgICAgKi9cbiAgICBzdWdnZXN0aW9uTG9hZGVyOiBmdW5jdGlvbiBzdWdnZXN0aW9uTG9hZGVyKGlucHV0LCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgZXhjbHVkZXMgPSB0aGlzLnByb3BzLmV4Y2x1ZGVzO1xuICAgICAgICB2YXIgZGlzYWxsb3dUZW1wb3JhcnkgPSB0aGlzLnByb3BzLmV4aXN0aW5nT25seSAmJiAhdGhpcy5wcm9wcy5mcmVlVmFsdWVBbGxvd2VkO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgbG9hZGluZzogdGhpcy5zdGF0ZS5sb2FkaW5nICsgMSB9KTtcbiAgICAgICAgUHlkaW9Vc2Vycy5DbGllbnQuYXV0aG9yaXplZFVzZXJzU3RhcnRpbmdXaXRoKGlucHV0LCAoZnVuY3Rpb24gKHVzZXJzKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgbG9hZGluZzogdGhpcy5zdGF0ZS5sb2FkaW5nIC0gMSB9KTtcbiAgICAgICAgICAgIGlmIChkaXNhbGxvd1RlbXBvcmFyeSkge1xuICAgICAgICAgICAgICAgIHVzZXJzID0gdXNlcnMuZmlsdGVyKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAhdXNlci5nZXRUZW1wb3JhcnkoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChleGNsdWRlcyAmJiBleGNsdWRlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB1c2VycyA9IHVzZXJzLmZpbHRlcihmdW5jdGlvbiAodXNlcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXhjbHVkZXMuaW5kZXhPZih1c2VyLmdldElkKCkpID09IC0xO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FsbGJhY2sodXNlcnMpO1xuICAgICAgICB9KS5iaW5kKHRoaXMpLCB0aGlzLnByb3BzLnVzZXJzT25seSwgdGhpcy5wcm9wcy5leGlzdGluZ09ubHkpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDYWxsZWQgd2hlbiB0aGUgZmllbGQgaXMgdXBkYXRlZFxuICAgICAqIEBwYXJhbSB2YWx1ZVxuICAgICAqL1xuICAgIHRleHRGaWVsZFVwZGF0ZTogZnVuY3Rpb24gdGV4dEZpZWxkVXBkYXRlKHZhbHVlKSB7XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlYXJjaFRleHQ6IHZhbHVlIH0pO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5taW5DaGFycyAmJiB2YWx1ZSAmJiB2YWx1ZS5sZW5ndGggPCB0aGlzLnN0YXRlLm1pbkNoYXJzKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sb2FkQnVmZmVyZWQodmFsdWUsIDM1MCk7XG4gICAgfSxcblxuICAgIGdldFBlbmRpbmdTZWFyY2hUZXh0OiBmdW5jdGlvbiBnZXRQZW5kaW5nU2VhcmNoVGV4dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGUuc2VhcmNoVGV4dCB8fCBmYWxzZTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRGVib3VuY2VkIGNhbGwgZm9yIHJlbmRlcmluZyBzZWFyY2hcbiAgICAgKiBAcGFyYW0gdmFsdWUge3N0cmluZ31cbiAgICAgKiBAcGFyYW0gdGltZW91dCB7aW50fVxuICAgICAqL1xuICAgIGxvYWRCdWZmZXJlZDogZnVuY3Rpb24gbG9hZEJ1ZmZlcmVkKHZhbHVlLCB0aW1lb3V0KSB7XG5cbiAgICAgICAgaWYgKCF2YWx1ZSAmJiB0aGlzLl9lbXB0eVZhbHVlTGlzdCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGRhdGFTb3VyY2U6IHRoaXMuX2VtcHR5VmFsdWVMaXN0IH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIEZ1bmNVdGlscy5idWZmZXJDYWxsYmFjaygncmVtb3RlX3VzZXJzX3NlYXJjaCcsIHRpbWVvdXQsIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgbG9hZGluZzogdHJ1ZSB9KTtcbiAgICAgICAgICAgIHRoaXMuc3VnZ2VzdGlvbkxvYWRlcih2YWx1ZSwgKGZ1bmN0aW9uICh1c2Vycykge1xuICAgICAgICAgICAgICAgIHZhciBjcnRWYWx1ZUZvdW5kID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IHVzZXJzLm1hcCgoZnVuY3Rpb24gKHVzZXJPYmplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbXBvbmVudCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICBNYXRlcmlhbFVJLk1lbnVJdGVtLFxuICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMucmVuZGVyU3VnZ2VzdGlvbih1c2VyT2JqZWN0KVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdXNlck9iamVjdDogdXNlck9iamVjdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IHVzZXJPYmplY3QuZ2V0RXh0ZW5kZWRMYWJlbCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGNvbXBvbmVudFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZW1wdHlWYWx1ZUxpc3QgPSB2YWx1ZXM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBkYXRhU291cmNlOiB2YWx1ZXMsIGxvYWRpbmc6IGZhbHNlIH0pO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDYWxsZWQgd2hlbiB1c2VyIHNlbGVjdHMgYSB2YWx1ZSBmcm9tIHRoZSBsaXN0XG4gICAgICogQHBhcmFtIHZhbHVlXG4gICAgICogQHBhcmFtIGluZGV4XG4gICAgICovXG4gICAgb25Db21wbGV0ZXJSZXF1ZXN0OiBmdW5jdGlvbiBvbkNvbXBsZXRlclJlcXVlc3QodmFsdWUsIGluZGV4KSB7XG5cbiAgICAgICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZS5kYXRhU291cmNlLm1hcChmdW5jdGlvbiAoZW50cnkpIHtcbiAgICAgICAgICAgICAgICBpZiAoZW50cnkudGV4dCA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBlbnRyeTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSAmJiAhdmFsdWUudXNlck9iamVjdCAmJiB0aGlzLnByb3BzLmZyZWVWYWx1ZUFsbG93ZWQpIHtcbiAgICAgICAgICAgICAgICB2YXIgZmFrZSA9IG5ldyBQeWRpb1VzZXJzLlVzZXIodmFsdWUsIHZhbHVlLCAndXNlcicsIG51bGwsIG51bGwsIHRydWUpO1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMub25WYWx1ZVNlbGVjdGVkKGZha2UpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWFyY2hUZXh0OiAnJywgZGF0YVNvdXJjZTogW10gfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh2YWx1ZSAmJiB2YWx1ZS51c2VyT2JqZWN0KSB7XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0gdmFsdWUudXNlck9iamVjdDtcbiAgICAgICAgICAgIGlmIChvYmplY3QuZ2V0VGVtcG9yYXJ5KCkpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5mcmVlVmFsdWVBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMub25WYWx1ZVNlbGVjdGVkKG9iamVjdCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNyZWF0ZVVzZXI6IG9iamVjdC5nZXRMYWJlbCgpIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vblZhbHVlU2VsZWN0ZWQob2JqZWN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWFyY2hUZXh0OiAnJywgZGF0YVNvdXJjZTogW10gfSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVHJpZ2dlcnMgb25WYWx1ZVNlbGVjdGVkIHByb3BzIGNhbGxiYWNrXG4gICAgICogQHBhcmFtIHtQeWRpby5Vc2VyfSBuZXdVc2VyXG4gICAgICovXG4gICAgb25Vc2VyQ3JlYXRlZDogZnVuY3Rpb24gb25Vc2VyQ3JlYXRlZChuZXdVc2VyKSB7XG4gICAgICAgIHRoaXMucHJvcHMub25WYWx1ZVNlbGVjdGVkKG5ld1VzZXIpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgY3JlYXRlVXNlcjogbnVsbCB9KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ2xvc2UgdXNlciBjcmVhdGlvbiBmb3JtXG4gICAgICovXG4gICAgb25DcmVhdGlvbkNhbmNlbGxlZDogZnVuY3Rpb24gb25DcmVhdGlvbkNhbmNlbGxlZCgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNyZWF0ZVVzZXI6IG51bGwgfSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIE9wZW4gYWRkcmVzcyBib29rIGluc2lkZSBhIFBvcG92ZXJcbiAgICAgKiBAcGFyYW0gZXZlbnRcbiAgICAgKi9cbiAgICBvcGVuQWRkcmVzc0Jvb2s6IGZ1bmN0aW9uIG9wZW5BZGRyZXNzQm9vayhldmVudCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGFkZHJlc3NCb29rT3BlbjogdHJ1ZSxcbiAgICAgICAgICAgIGFkZHJlc3NCb29rQW5jaG9yOiBldmVudC5jdXJyZW50VGFyZ2V0XG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDbG9zZSBhZGRyZXNzIGJvb2sgcG9wb3ZlclxuICAgICAqL1xuICAgIGNsb3NlQWRkcmVzc0Jvb2s6IGZ1bmN0aW9uIGNsb3NlQWRkcmVzc0Jvb2soKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBhZGRyZXNzQm9va09wZW46IGZhbHNlIH0pO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyZWQgd2hlbiB1c2VyIGNsaWNrcyBvbiBhbiBlbnRyeSBmcm9tIGFkcmVzcyBib29rLlxuICAgICAqIEBwYXJhbSBpdGVtXG4gICAgICovXG4gICAgb25BZGRyZXNzQm9va0l0ZW1TZWxlY3RlZDogZnVuY3Rpb24gb25BZGRyZXNzQm9va0l0ZW1TZWxlY3RlZChpdGVtKSB7XG4gICAgICAgIHRoaXMucHJvcHMub25WYWx1ZVNlbGVjdGVkKGl0ZW0pO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB2YXIgX3N0YXRlID0gdGhpcy5zdGF0ZTtcbiAgICAgICAgdmFyIGRhdGFTb3VyY2UgPSBfc3RhdGUuZGF0YVNvdXJjZTtcbiAgICAgICAgdmFyIGNyZWF0ZVVzZXIgPSBfc3RhdGUuY3JlYXRlVXNlcjtcblxuICAgICAgICB2YXIgY29udGFpbmVyU3R5bGUgPSB7IHBvc2l0aW9uOiAncmVsYXRpdmUnLCBvdmVyZmxvdzogJ3Zpc2libGUnIH07XG5cbiAgICAgICAgLypcbiAgICAgICAgaWYoY3JlYXRlVXNlcil7XG4gICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPXtjb250YWluZXJTdHlsZX0+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9e3twb3NpdGlvbjogJ2Fic29sdXRlJywgdG9wOiA3MywgbGVmdDogMCwgcmlnaHQ6IDAsIHpJbmRleDogMTB9fT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxBc3luY0NvbXBvbmVudFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZT17XCJQeWRpb0Zvcm1cIn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnROYW1lPXtcIlVzZXJDcmVhdGlvbkZvcm1cIn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3VXNlck5hbWU9e3RoaXMuc3RhdGUuY3JlYXRlVXNlcn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvblVzZXJDcmVhdGVkPXt0aGlzLm9uVXNlckNyZWF0ZWR9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DYW5jZWw9e3RoaXMub25DcmVhdGlvbkNhbmNlbGxlZH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBweWRpbz17dGhpcy5wcm9wcy5weWRpb31cbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgKTtcbiAgICAgICAgIH1cbiAgICAgICAgKi9cblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgeyBzdHlsZTogY29udGFpbmVyU3R5bGUsIHJlZjogZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLl9wb3BvdmVyQW5jaG9yID0gZWw7XG4gICAgICAgICAgICAgICAgfSB9LFxuICAgICAgICAgICAgIWNyZWF0ZVVzZXIgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChBdXRvQ29tcGxldGUsIHtcbiAgICAgICAgICAgICAgICBmaWx0ZXI6IE1hdGVyaWFsVUkuQXV0b0NvbXBsZXRlLm5vRmlsdGVyLFxuICAgICAgICAgICAgICAgIGRhdGFTb3VyY2U6IGRhdGFTb3VyY2UsXG4gICAgICAgICAgICAgICAgc2VhcmNoVGV4dDogdGhpcy5zdGF0ZS5zZWFyY2hUZXh0LFxuICAgICAgICAgICAgICAgIG9uVXBkYXRlSW5wdXQ6IHRoaXMudGV4dEZpZWxkVXBkYXRlLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogdGhpcy5wcm9wcy5jbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgb3Blbk9uRm9jdXM6IHRydWUsXG4gICAgICAgICAgICAgICAgZmxvYXRpbmdMYWJlbFRleHQ6IHRoaXMucHJvcHMuZmllbGRMYWJlbCxcbiAgICAgICAgICAgICAgICB1bmRlcmxpbmVTaG93OiAhdGhpcy5wcm9wcy51bmRlcmxpbmVIaWRlLFxuICAgICAgICAgICAgICAgIGZ1bGxXaWR0aDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvbk5ld1JlcXVlc3Q6IHRoaXMub25Db21wbGV0ZXJSZXF1ZXN0LFxuICAgICAgICAgICAgICAgIGxpc3RTdHlsZTogeyBtYXhIZWlnaHQ6IDM1MCwgb3ZlcmZsb3dZOiAnYXV0bycgfSxcbiAgICAgICAgICAgICAgICBvbkZvY3VzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmxvYWRCdWZmZXJlZChfdGhpcy5zdGF0ZS5zZWFyY2hUZXh0LCAxMDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgY3JlYXRlVXNlciAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFRleHRGaWVsZCwge1xuICAgICAgICAgICAgICAgIGZsb2F0aW5nTGFiZWxUZXh0OiB0aGlzLnByb3BzLmZpZWxkTGFiZWwsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGdsb2JhbC5weWRpby5NZXNzYWdlSGFzaFs0ODVdICsgJyAoJyArIHRoaXMuc3RhdGUuY3JlYXRlVXNlciArICcpJyxcbiAgICAgICAgICAgICAgICBkaXNhYmxlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBmdWxsV2lkdGg6IHRydWUsXG4gICAgICAgICAgICAgICAgdW5kZXJsaW5lU2hvdzogIXRoaXMucHJvcHMudW5kZXJsaW5lSGlkZVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAhY3JlYXRlVXNlciAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgcG9zaXRpb246ICdhYnNvbHV0ZScsIHJpZ2h0OiA0LCBib3R0b206IDE0LCBoZWlnaHQ6IDIwLCB3aWR0aDogMjAgfSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoUmVmcmVzaEluZGljYXRvciwge1xuICAgICAgICAgICAgICAgICAgICBzaXplOiAyMCxcbiAgICAgICAgICAgICAgICAgICAgbGVmdDogMCxcbiAgICAgICAgICAgICAgICAgICAgdG9wOiAwLFxuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6IHRoaXMuc3RhdGUubG9hZGluZyA/ICdsb2FkaW5nJyA6ICdoaWRlJ1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgdGhpcy5wcm9wcy5zaG93QWRkcmVzc0Jvb2sgJiYgIWNyZWF0ZVVzZXIgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChfYWRkcmVzc2Jvb2tBZGRyZXNzQm9vazJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgIG1vZGU6ICdwb3BvdmVyJyxcbiAgICAgICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpbyxcbiAgICAgICAgICAgICAgICBsb2FkZXJTdHlsZTogeyB3aWR0aDogMzIwLCBoZWlnaHQ6IDQyMCB9LFxuICAgICAgICAgICAgICAgIG9uSXRlbVNlbGVjdGVkOiB0aGlzLm9uQWRkcmVzc0Jvb2tJdGVtU2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgdXNlcnNGcm9tOiB0aGlzLnByb3BzLnVzZXJzRnJvbSxcbiAgICAgICAgICAgICAgICBkaXNhYmxlU2VhcmNoOiB0cnVlXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgUG9wb3ZlcixcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG9wZW46IGNyZWF0ZVVzZXIsXG4gICAgICAgICAgICAgICAgICAgIGFuY2hvckVsOiB0aGlzLl9wb3BvdmVyQW5jaG9yLFxuICAgICAgICAgICAgICAgICAgICBhbmNob3JPcmlnaW46IHsgaG9yaXpvbnRhbDogJ2xlZnQnLCB2ZXJ0aWNhbDogJ2JvdHRvbScgfSxcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0T3JpZ2luOiB7IGhvcml6b250YWw6ICdsZWZ0JywgdmVydGljYWw6ICd0b3AnIH0sXG4gICAgICAgICAgICAgICAgICAgIG9uUmVxdWVzdENsb3NlOiB0aGlzLm9uQ3JlYXRpb25DYW5jZWxsZWQsXG4gICAgICAgICAgICAgICAgICAgIGNhbkF1dG9Qb3NpdGlvbjogZmFsc2VcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNyZWF0ZVVzZXIgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChBc3luY0NvbXBvbmVudCwge1xuICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2U6IFwiUHlkaW9Gb3JtXCIsXG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6IFwiVXNlckNyZWF0aW9uRm9ybVwiLFxuXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7IHdpZHRoOiAzNTAsIGhlaWdodDogMzIwIH0sXG4gICAgICAgICAgICAgICAgICAgIG5ld1VzZXJOYW1lOiB0aGlzLnN0YXRlLmNyZWF0ZVVzZXIsXG4gICAgICAgICAgICAgICAgICAgIG9uVXNlckNyZWF0ZWQ6IHRoaXMub25Vc2VyQ3JlYXRlZCxcbiAgICAgICAgICAgICAgICAgICAgb25DYW5jZWw6IHRoaXMub25DcmVhdGlvbkNhbmNlbGxlZCxcbiAgICAgICAgICAgICAgICAgICAgcHlkaW86IHRoaXMucHJvcHMucHlkaW9cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cblxufSk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFVzZXJzTG9hZGVyO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG52YXIgX05lc3RlZExpc3RJdGVtID0gcmVxdWlyZSgnLi9OZXN0ZWRMaXN0SXRlbScpO1xuXG52YXIgX05lc3RlZExpc3RJdGVtMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX05lc3RlZExpc3RJdGVtKTtcblxudmFyIF9Vc2Vyc0xpc3QgPSByZXF1aXJlKCcuL1VzZXJzTGlzdCcpO1xuXG52YXIgX1VzZXJzTGlzdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Vc2Vyc0xpc3QpO1xuXG52YXIgX1JpZ2h0UGFuZWxDYXJkID0gcmVxdWlyZSgnLi9SaWdodFBhbmVsQ2FyZCcpO1xuXG52YXIgX1JpZ2h0UGFuZWxDYXJkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1JpZ2h0UGFuZWxDYXJkKTtcblxudmFyIF9TZWFyY2hQYW5lbCA9IHJlcXVpcmUoJy4vU2VhcmNoUGFuZWwnKTtcblxudmFyIF9TZWFyY2hQYW5lbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TZWFyY2hQYW5lbCk7XG5cbnZhciBfTG9hZGVycyA9IHJlcXVpcmUoJy4vTG9hZGVycycpO1xuXG52YXIgX0xvYWRlcnMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTG9hZGVycyk7XG5cbnZhciBfVGVhbUNyZWF0aW9uRm9ybSA9IHJlcXVpcmUoJy4uL1RlYW1DcmVhdGlvbkZvcm0nKTtcblxudmFyIF9UZWFtQ3JlYXRpb25Gb3JtMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1RlYW1DcmVhdGlvbkZvcm0pO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIFB5ZGlvID0gcmVxdWlyZSgncHlkaW8nKTtcblxudmFyIF9QeWRpbyRyZXF1aXJlTGliID0gUHlkaW8ucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgQXN5bmNDb21wb25lbnQgPSBfUHlkaW8kcmVxdWlyZUxpYi5Bc3luY0NvbXBvbmVudDtcbnZhciBQeWRpb0NvbnRleHRDb25zdW1lciA9IF9QeWRpbyRyZXF1aXJlTGliLlB5ZGlvQ29udGV4dENvbnN1bWVyO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgUG9wb3ZlciA9IF9yZXF1aXJlLlBvcG92ZXI7XG52YXIgSWNvbkJ1dHRvbiA9IF9yZXF1aXJlLkljb25CdXR0b247XG5cbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKCdtYXRlcmlhbC11aS9zdHlsZXMnKTtcblxudmFyIG11aVRoZW1lYWJsZSA9IF9yZXF1aXJlMi5tdWlUaGVtZWFibGU7XG52YXIgY29sb3JzID0gX3JlcXVpcmUyLmNvbG9ycztcblxuLyoqXG4gKiBIaWdoIGxldmVsIGNvbXBvbmVudCB0byBicm93c2UgdXNlcnMsIGdyb3VwcyBhbmQgdGVhbXMsIGVpdGhlciBpbiBhIGxhcmdlIGZvcm1hdCAobW9kZT0nYm9vaycpIG9yIGEgbW9yZSBjb21wYWN0XG4gKiBmb3JtYXQgKG1vZGU9J3NlbGVjdG9yJ3wncG9wb3ZlcicpLlxuICogQWRkcmVzcyBib29rIGFsbG93cyB0byBjcmVhdGUgZXh0ZXJuYWwgdXNlcnMsIHRlYW1zLCBhbmQgYWxzbyB0byBicm93c2UgdHJ1c3RlZCBzZXJ2ZXIgZGlyZWN0b3JpZXMgaWYgRmVkZXJhdGVkIFNoYXJpbmdcbiAqIGlzIGFjdGl2ZS5cbiAqL1xudmFyIEFkZHJlc3NCb29rID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnQWRkcmVzc0Jvb2snLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNYWluIGluc3RhbmNlIG9mIHB5ZGlvXG4gICAgICAgICAqL1xuICAgICAgICBweWRpbzogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW8pLFxuICAgICAgICAvKipcbiAgICAgICAgICogRGlzcGxheSBtb2RlLCBlaXRoZXIgbGFyZ2UgKGJvb2spIG9yIHNtYWxsIHBpY2tlciAoJ3NlbGVjdG9yJywgJ3BvcG92ZXInKS5cbiAgICAgICAgICovXG4gICAgICAgIG1vZGU6IFJlYWN0LlByb3BUeXBlcy5vbmVPZihbJ2Jvb2snLCAnc2VsZWN0b3InLCAncG9wb3ZlciddKS5pc1JlcXVpcmVkLFxuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGJhY2sgdHJpZ2dlcmVkIGluICdzZWxlY3RvcicgbW9kZSB3aGVuZXZlciBhbiBpdGVtIGlzIGNsaWNrZWQuXG4gICAgICAgICAqL1xuICAgICAgICBvbkl0ZW1TZWxlY3RlZDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEaXNwbGF5IHVzZXJzIG9ubHksIG5vIHRlYW1zIG9yIGdyb3Vwc1xuICAgICAgICAgKi9cbiAgICAgICAgdXNlcnNPbmx5OiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIENob29zZSB2YXJpb3VzIHVzZXIgc291cmNlcywgZWl0aGVyIHRoZSBsb2NhbCBkaXJlY3Rvcnkgb3IgcmVtb3RlICggPSB0cnVzdGVkICkgc2VydmVycy5cbiAgICAgICAgICovXG4gICAgICAgIHVzZXJzRnJvbTogUmVhY3QuUHJvcFR5cGVzLm9uZU9mKFsnbG9jYWwnLCAncmVtb3RlJywgJ2FueSddKSxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERpc2FibGUgdGhlIHNlYXJjaCBlbmdpbmVcbiAgICAgICAgICovXG4gICAgICAgIGRpc2FibGVTZWFyY2g6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlbWUgb2JqZWN0IHBhc3NlZCBieSBtdWlUaGVtZWFibGUoKSB3cmFwcGVyXG4gICAgICAgICAqL1xuICAgICAgICBtdWlUaGVtZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdpbGwgYmUgcGFzc2VkIHRvIHRoZSBQb3BvdmVyIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgcG9wb3ZlclN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICAvKipcbiAgICAgICAgICogVXNlZCBhcyBhIGJ1dHRvbiB0byBvcGVuIHRoZSBzZWxlY3RvciBpbiBhIHBvcG92ZXJcbiAgICAgICAgICovXG4gICAgICAgIHBvcG92ZXJCdXR0b246IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaWxsIGJlIHBhc3NlZCB0byB0aGUgUG9wb3ZlciBjb250YWluZXIgb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBwb3BvdmVyQ29udGFpbmVyU3R5bGU6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaWxsIGJlIHBhc3NlZCB0byB0aGUgUG9wb3ZlciBJY29uIEJ1dHRvbi5cbiAgICAgICAgICovXG4gICAgICAgIHBvcG92ZXJJY29uQnV0dG9uU3R5bGU6IFJlYWN0LlByb3BUeXBlcy5vYmplY3RcbiAgICB9LFxuXG4gICAgZ2V0RGVmYXVsdFByb3BzOiBmdW5jdGlvbiBnZXREZWZhdWx0UHJvcHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBtb2RlOiAnYm9vaycsXG4gICAgICAgICAgICB1c2Vyc09ubHk6IGZhbHNlLFxuICAgICAgICAgICAgdXNlcnNGcm9tOiAnYW55JyxcbiAgICAgICAgICAgIHRlYW1zT25seTogZmFsc2UsXG4gICAgICAgICAgICBkaXNhYmxlU2VhcmNoOiBmYWxzZVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcztcbiAgICAgICAgdmFyIHB5ZGlvID0gX3Byb3BzLnB5ZGlvO1xuICAgICAgICB2YXIgbW9kZSA9IF9wcm9wcy5tb2RlO1xuICAgICAgICB2YXIgdXNlcnNPbmx5ID0gX3Byb3BzLnVzZXJzT25seTtcbiAgICAgICAgdmFyIHVzZXJzRnJvbSA9IF9wcm9wcy51c2Vyc0Zyb207XG4gICAgICAgIHZhciB0ZWFtc09ubHkgPSBfcHJvcHMudGVhbXNPbmx5O1xuICAgICAgICB2YXIgZGlzYWJsZVNlYXJjaCA9IF9wcm9wcy5kaXNhYmxlU2VhcmNoO1xuXG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gZnVuY3Rpb24gZ2V0TWVzc2FnZShpZCkge1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLnByb3BzLmdldE1lc3NhZ2UoaWQsICcnKTtcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIGNvbmZDb25maWdzID0gcHlkaW8uZ2V0UGx1Z2luQ29uZmlncygnY29yZS5jb25mJyk7XG5cbiAgICAgICAgdmFyIHJvb3QgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0ZWFtc09ubHkpIHtcbiAgICAgICAgICAgIHJvb3QgPSB7XG4gICAgICAgICAgICAgICAgaWQ6ICd0ZWFtcycsXG4gICAgICAgICAgICAgICAgbGFiZWw6IGdldE1lc3NhZ2UoNTY4KSxcbiAgICAgICAgICAgICAgICBjaGlsZHJlbkxvYWRlcjogX0xvYWRlcnMyWydkZWZhdWx0J10ubG9hZFRlYW1zLFxuICAgICAgICAgICAgICAgIF9wYXJlbnQ6IG51bGwsXG4gICAgICAgICAgICAgICAgX25vdFNlbGVjdGFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgYWN0aW9uczoge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGVhbXMnLFxuICAgICAgICAgICAgICAgICAgICBjcmVhdGU6ICcrICcgKyBnZXRNZXNzYWdlKDU2OSksXG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZTogZ2V0TWVzc2FnZSg1NzApLFxuICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZTogdHJ1ZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHJvb3Q6IHJvb3QsXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRJdGVtOiByb290LFxuICAgICAgICAgICAgICAgIGxvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHJpZ2h0UGFuZUl0ZW06IG51bGxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICByb290ID0ge1xuICAgICAgICAgICAgaWQ6ICdyb290JyxcbiAgICAgICAgICAgIGxhYmVsOiBnZXRNZXNzYWdlKDU5MiksXG4gICAgICAgICAgICB0eXBlOiAncm9vdCcsXG4gICAgICAgICAgICBjb2xsZWN0aW9uczogW11cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHVzZXJzRnJvbSAhPT0gJ3JlbW90ZScpIHtcbiAgICAgICAgICAgIGlmIChjb25mQ29uZmlncy5nZXQoJ1VTRVJfQ1JFQVRFX1VTRVJTJykpIHtcbiAgICAgICAgICAgICAgICByb290LmNvbGxlY3Rpb25zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBpZDogJ2V4dCcsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBnZXRNZXNzYWdlKDU5MyksXG4gICAgICAgICAgICAgICAgICAgIC8vaWNvbjonbWRpIG1kaS1hY2NvdW50LW5ldHdvcmsnLFxuICAgICAgICAgICAgICAgICAgICBpdGVtc0xvYWRlcjogX0xvYWRlcnMyWydkZWZhdWx0J10ubG9hZEV4dGVybmFsVXNlcnMsXG4gICAgICAgICAgICAgICAgICAgIF9wYXJlbnQ6IHJvb3QsXG4gICAgICAgICAgICAgICAgICAgIF9ub3RTZWxlY3RhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhY3Rpb25zOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAndXNlcnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlOiAnKyAnICsgZ2V0TWVzc2FnZSg0ODQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlOiBnZXRNZXNzYWdlKDU4MiksXG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZTogdHJ1ZVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXVzZXJzT25seSkge1xuICAgICAgICAgICAgICAgIHJvb3QuY29sbGVjdGlvbnMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGlkOiAndGVhbXMnLFxuICAgICAgICAgICAgICAgICAgICBsYWJlbDogZ2V0TWVzc2FnZSg1NjgpLFxuICAgICAgICAgICAgICAgICAgICAvL2ljb246ICdtZGkgbWRpLWFjY291bnQtbXVsdGlwbGUnLFxuICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbkxvYWRlcjogX0xvYWRlcnMyWydkZWZhdWx0J10ubG9hZFRlYW1zLFxuICAgICAgICAgICAgICAgICAgICBfcGFyZW50OiByb290LFxuICAgICAgICAgICAgICAgICAgICBfbm90U2VsZWN0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3RlYW1zJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZTogJysgJyArIGdldE1lc3NhZ2UoNTY5KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZTogZ2V0TWVzc2FnZSg1NzApLFxuICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGU6IHRydWVcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNvbmZDb25maWdzLmdldCgnQUxMT1dfQ1JPU1NVU0VSU19TSEFSSU5HJykpIHtcbiAgICAgICAgICAgICAgICB2YXIgZ3JvdXBPclVzZXJzID0gY29uZkNvbmZpZ3MuZ2V0KCdBRERSRVNTQk9PS19HUk9VUF9PUl9VU0VSUycpO1xuICAgICAgICAgICAgICAgIGlmIChncm91cE9yVXNlcnMgJiYgZ3JvdXBPclVzZXJzLmdyb3VwX3N3aXRjaF92YWx1ZSkgZ3JvdXBPclVzZXJzID0gZ3JvdXBPclVzZXJzLmdyb3VwX3N3aXRjaF92YWx1ZTtlbHNlIGdyb3VwT3JVc2VycyA9ICdib3RoJztcblxuICAgICAgICAgICAgICAgIGlmIChncm91cE9yVXNlcnMgPT09ICdzZWFyY2gnKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghZGlzYWJsZVNlYXJjaCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcm9vdC5jb2xsZWN0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZDogJ3NlYXJjaCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGdldE1lc3NhZ2UoNTgzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2ljb246J21kaSBtZGktYWNjb3VudC1zZWFyY2gnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdzZWFyY2gnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wYXJlbnQ6IHJvb3QsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX25vdFNlbGVjdGFibGU6IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcm9vdC5jb2xsZWN0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkOiAnQUpYUF9HUlBfLycsXG4gICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogZ2V0TWVzc2FnZSg1ODQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgLy9pY29uOidtZGkgbWRpLWFjY291bnQtYm94JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuTG9hZGVyOiBncm91cE9yVXNlcnMgPT09ICdib3RoJyB8fCBncm91cE9yVXNlcnMgPT09ICdncm91cHMnID8gX0xvYWRlcnMyWydkZWZhdWx0J10ubG9hZEdyb3VwcyA6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtc0xvYWRlcjogZ3JvdXBPclVzZXJzID09PSAnYm90aCcgfHwgZ3JvdXBPclVzZXJzID09PSAndXNlcnMnID8gX0xvYWRlcnMyWydkZWZhdWx0J10ubG9hZEdyb3VwVXNlcnMgOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgX3BhcmVudDogcm9vdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIF9ub3RTZWxlY3RhYmxlOiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBvY3NSZW1vdGVzID0gcHlkaW8uZ2V0UGx1Z2luQ29uZmlncygnY29yZS5vY3MnKS5nZXQoJ1RSVVNURURfU0VSVkVSUycpO1xuICAgICAgICBpZiAob2NzUmVtb3RlcyAmJiAhdXNlcnNPbmx5ICYmIHVzZXJzRnJvbSAhPT0gJ2xvY2FsJykge1xuICAgICAgICAgICAgdmFyIHJlbW90ZXMgPSBKU09OLnBhcnNlKG9jc1JlbW90ZXMpO1xuICAgICAgICAgICAgdmFyIHJlbW90ZXNOb2RlcyA9IHtcbiAgICAgICAgICAgICAgICBpZDogJ3JlbW90ZXMnLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBnZXRNZXNzYWdlKDU5NCksXG4gICAgICAgICAgICAgICAgLy9pY29uOidtZGkgbWRpLXNlcnZlcicsXG4gICAgICAgICAgICAgICAgY29sbGVjdGlvbnM6IFtdLFxuICAgICAgICAgICAgICAgIF9wYXJlbnQ6IHJvb3QsXG4gICAgICAgICAgICAgICAgX25vdFNlbGVjdGFibGU6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBmb3IgKHZhciBrIGluIHJlbW90ZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXJlbW90ZXMuaGFzT3duUHJvcGVydHkoaykpIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIHJlbW90ZXNOb2Rlcy5jb2xsZWN0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6IGssXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiByZW1vdGVzW2tdLFxuICAgICAgICAgICAgICAgICAgICBpY29uOiAnbWRpIG1kaS1zZXJ2ZXItbmV0d29yaycsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdyZW1vdGUnLFxuICAgICAgICAgICAgICAgICAgICBfcGFyZW50OiByZW1vdGVzTm9kZXMsXG4gICAgICAgICAgICAgICAgICAgIF9ub3RTZWxlY3RhYmxlOiB0cnVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVtb3Rlc05vZGVzLmNvbGxlY3Rpb25zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJvb3QuY29sbGVjdGlvbnMucHVzaChyZW1vdGVzTm9kZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJvb3Q6IHJvb3QsXG4gICAgICAgICAgICBzZWxlY3RlZEl0ZW06IG1vZGUgPT09ICdzZWxlY3RvcicgPyByb290IDogcm9vdC5jb2xsZWN0aW9uc1swXSxcbiAgICAgICAgICAgIGxvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgICAgcmlnaHRQYW5lSXRlbTogbnVsbFxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtICYmIHRoaXMub25Gb2xkZXJDbGlja2VkKHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtKTtcbiAgICB9LFxuXG4gICAgb25Gb2xkZXJDbGlja2VkOiBmdW5jdGlvbiBvbkZvbGRlckNsaWNrZWQoaXRlbSkge1xuICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICB2YXIgY2FsbGJhY2sgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBhcmd1bWVudHNbMV07XG5cbiAgICAgICAgLy8gU3BlY2lhbCBjYXNlIGZvciB0ZWFtc1xuICAgICAgICBpZiAoaXRlbS50eXBlID09PSAnZ3JvdXAnICYmIGl0ZW0uaWQuaW5kZXhPZignL0FKWFBfVEVBTS8nKSA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5vblVzZXJMaXN0SXRlbUNsaWNrZWQoaXRlbSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGxvYWRpbmc6IHRydWUgfSk7XG5cbiAgICAgICAgX0xvYWRlcnMyWydkZWZhdWx0J10uY2hpbGRyZW5Bc1Byb21pc2UoaXRlbSwgZmFsc2UpLnRoZW4oZnVuY3Rpb24gKGNoaWxkcmVuKSB7XG4gICAgICAgICAgICBfTG9hZGVyczJbJ2RlZmF1bHQnXS5jaGlsZHJlbkFzUHJvbWlzZShpdGVtLCB0cnVlKS50aGVuKGZ1bmN0aW9uIChjaGlsZHJlbikge1xuICAgICAgICAgICAgICAgIF90aGlzMi5zZXRTdGF0ZSh7IHNlbGVjdGVkSXRlbTogaXRlbSwgbG9hZGluZzogZmFsc2UgfSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBvblVzZXJMaXN0SXRlbUNsaWNrZWQ6IGZ1bmN0aW9uIG9uVXNlckxpc3RJdGVtQ2xpY2tlZChpdGVtKSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uSXRlbVNlbGVjdGVkKSB7XG4gICAgICAgICAgICB2YXIgdU9iamVjdCA9IG5ldyBQeWRpb1VzZXJzLlVzZXIoaXRlbS5pZCwgaXRlbS5sYWJlbCwgaXRlbS50eXBlLCBpdGVtLmdyb3VwLCBpdGVtLmF2YXRhciwgaXRlbS50ZW1wb3JhcnksIGl0ZW0uZXh0ZXJuYWwpO1xuICAgICAgICAgICAgaWYgKGl0ZW0udHJ1c3RlZF9zZXJ2ZXJfaWQpIHtcbiAgICAgICAgICAgICAgICB1T2JqZWN0LnRydXN0ZWRTZXJ2ZXJJZCA9IGl0ZW0udHJ1c3RlZF9zZXJ2ZXJfaWQ7XG4gICAgICAgICAgICAgICAgdU9iamVjdC50cnVzdGVkU2VydmVyTGFiZWwgPSBpdGVtLnRydXN0ZWRfc2VydmVyX2xhYmVsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkl0ZW1TZWxlY3RlZCh1T2JqZWN0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyByaWdodFBhbmVJdGVtOiBpdGVtIH0pO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIG9uQ3JlYXRlQWN0aW9uOiBmdW5jdGlvbiBvbkNyZWF0ZUFjdGlvbihpdGVtKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjcmVhdGVEaWFsb2dJdGVtOiBpdGVtIH0pO1xuICAgIH0sXG5cbiAgICBjbG9zZUNyZWF0ZURpYWxvZ0FuZFJlbG9hZDogZnVuY3Rpb24gY2xvc2VDcmVhdGVEaWFsb2dBbmRSZWxvYWQoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjcmVhdGVEaWFsb2dJdGVtOiBudWxsIH0pO1xuICAgICAgICB0aGlzLnJlbG9hZEN1cnJlbnROb2RlKCk7XG4gICAgfSxcblxuICAgIG9uQ2FyZFVwZGF0ZUFjdGlvbjogZnVuY3Rpb24gb25DYXJkVXBkYXRlQWN0aW9uKGl0ZW0pIHtcbiAgICAgICAgaWYgKGl0ZW0uX3BhcmVudCAmJiBpdGVtLl9wYXJlbnQgPT09IHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtKSB7XG4gICAgICAgICAgICB0aGlzLnJlbG9hZEN1cnJlbnROb2RlKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgb25EZWxldGVBY3Rpb246IGZ1bmN0aW9uIG9uRGVsZXRlQWN0aW9uKHBhcmVudEl0ZW0sIHNlbGVjdGlvbikge1xuICAgICAgICBpZiAoIWNvbmZpcm0odGhpcy5wcm9wcy5nZXRNZXNzYWdlKDI3OCkpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3dpdGNoIChwYXJlbnRJdGVtLmFjdGlvbnMudHlwZSkge1xuICAgICAgICAgICAgY2FzZSAndXNlcnMnOlxuICAgICAgICAgICAgICAgIHNlbGVjdGlvbi5mb3JFYWNoKChmdW5jdGlvbiAodXNlcikge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5yaWdodFBhbmVJdGVtID09PSB1c2VyKSB0aGlzLnNldFN0YXRlKHsgcmlnaHRQYW5lSXRlbTogbnVsbCB9KTtcbiAgICAgICAgICAgICAgICAgICAgUHlkaW9Vc2Vycy5DbGllbnQuZGVsZXRlVXNlcih1c2VyLmlkLCB0aGlzLnJlbG9hZEN1cnJlbnROb2RlLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAndGVhbXMnOlxuICAgICAgICAgICAgICAgIHNlbGVjdGlvbi5mb3JFYWNoKChmdW5jdGlvbiAodGVhbSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5yaWdodFBhbmVJdGVtID09PSB0ZWFtKSB0aGlzLnNldFN0YXRlKHsgcmlnaHRQYW5lSXRlbTogbnVsbCB9KTtcbiAgICAgICAgICAgICAgICAgICAgUHlkaW9Vc2Vycy5DbGllbnQuZGVsZXRlVGVhbSh0ZWFtLmlkLnJlcGxhY2UoJy9BSlhQX1RFQU0vJywgJycpLCB0aGlzLnJlbG9hZEN1cnJlbnROb2RlLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAndGVhbSc6XG4gICAgICAgICAgICAgICAgX1RlYW1DcmVhdGlvbkZvcm0yWydkZWZhdWx0J10udXBkYXRlVGVhbVVzZXJzKHBhcmVudEl0ZW0sICdkZWxldGUnLCBzZWxlY3Rpb24sIHRoaXMucmVsb2FkQ3VycmVudE5vZGUuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIG9wZW5Qb3BvdmVyOiBmdW5jdGlvbiBvcGVuUG9wb3ZlcihldmVudCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHBvcG92ZXJPcGVuOiB0cnVlLFxuICAgICAgICAgICAgcG9wb3ZlckFuY2hvcjogZXZlbnQuY3VycmVudFRhcmdldFxuICAgICAgICB9KTtcbiAgICB9LFxuXG4gICAgY2xvc2VQb3BvdmVyOiBmdW5jdGlvbiBjbG9zZVBvcG92ZXIoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBwb3BvdmVyT3BlbjogZmFsc2UgfSk7XG4gICAgfSxcblxuICAgIHJlbG9hZEN1cnJlbnROb2RlOiBmdW5jdGlvbiByZWxvYWRDdXJyZW50Tm9kZSgpIHtcbiAgICAgICAgdmFyIF90aGlzMyA9IHRoaXM7XG5cbiAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0ubGVhZkxvYWRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5jb2xsZWN0aW9uc0xvYWRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLm9uRm9sZGVyQ2xpY2tlZCh0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKF90aGlzMy5zdGF0ZS5yaWdodFBhbmVJdGVtKSB7XG4gICAgICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJQYW5lSWQgPSBfdGhpczMuc3RhdGUucmlnaHRQYW5lSXRlbS5pZDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZvdW5kSXRlbSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsZWFmcyA9IF90aGlzMy5zdGF0ZS5zZWxlY3RlZEl0ZW0ubGVhZnMgfHwgW107XG4gICAgICAgICAgICAgICAgICAgIHZhciBjb2xsZWN0aW9ucyA9IF90aGlzMy5zdGF0ZS5zZWxlY3RlZEl0ZW0uY29sbGVjdGlvbnMgfHwgW107XG4gICAgICAgICAgICAgICAgICAgIFtdLmNvbmNhdChsZWFmcywgY29sbGVjdGlvbnMpLmZvckVhY2goZnVuY3Rpb24gKGxlYWYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsZWFmLmlkID09PSByUGFuZUlkKSBmb3VuZEl0ZW0gPSBsZWFmO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMzLnNldFN0YXRlKHsgcmlnaHRQYW5lSXRlbTogZm91bmRJdGVtIH0pO1xuICAgICAgICAgICAgICAgIH0pKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICByZWxvYWRDdXJyZW50QXRQYWdlOiBmdW5jdGlvbiByZWxvYWRDdXJyZW50QXRQYWdlKGxldHRlck9yUmFuZ2UpIHtcbiAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0ubGVhZkxvYWRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5jb2xsZWN0aW9uc0xvYWRlZCA9IGZhbHNlO1xuICAgICAgICBpZiAobGV0dGVyT3JSYW5nZSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtLmN1cnJlbnRQYXJhbXMgPSBudWxsO1xuICAgICAgICB9IGVsc2UgaWYgKGxldHRlck9yUmFuZ2UuaW5kZXhPZignLScpICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0ucmFuZ2UgPSBsZXR0ZXJPclJhbmdlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0ucmFuZ2UgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0uY3VycmVudFBhcmFtcyA9IHsgYWxwaGFfcGFnZXM6ICd0cnVlJywgdmFsdWU6IGxldHRlck9yUmFuZ2UgfTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9uRm9sZGVyQ2xpY2tlZCh0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbSk7XG4gICAgfSxcblxuICAgIHJlbG9hZEN1cnJlbnRXaXRoU2VhcmNoOiBmdW5jdGlvbiByZWxvYWRDdXJyZW50V2l0aFNlYXJjaCh2YWx1ZSkge1xuICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLnJlbG9hZEN1cnJlbnRBdFBhZ2UoLTEpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtLmxlYWZMb2FkZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0uY29sbGVjdGlvbnNMb2FkZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0uY3VycmVudFBhcmFtcyA9IHsgaGFzX3NlYXJjaDogdHJ1ZSwgdmFsdWU6IHZhbHVlLCBleGlzdGluZ19vbmx5OiB0cnVlIH07XG4gICAgICAgIHRoaXMub25Gb2xkZXJDbGlja2VkKHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpczQgPSB0aGlzO1xuXG4gICAgICAgIHZhciBfcHJvcHMyID0gdGhpcy5wcm9wcztcbiAgICAgICAgdmFyIG1vZGUgPSBfcHJvcHMyLm1vZGU7XG4gICAgICAgIHZhciBtdWlUaGVtZSA9IF9wcm9wczIubXVpVGhlbWU7XG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gX3Byb3BzMi5nZXRNZXNzYWdlO1xuXG4gICAgICAgIGlmIChtb2RlID09PSAncG9wb3ZlcicpIHtcblxuICAgICAgICAgICAgdmFyIHBvcG92ZXJTdHlsZSA9IHRoaXMucHJvcHMucG9wb3ZlclN0eWxlIHx8IHt9O1xuICAgICAgICAgICAgdmFyIHBvcG92ZXJDb250YWluZXJTdHlsZSA9IHRoaXMucHJvcHMucG9wb3ZlckNvbnRhaW5lclN0eWxlIHx8IHt9O1xuICAgICAgICAgICAgdmFyIGljb25CdXR0b25TdHlsZSA9IHRoaXMucHJvcHMucG9wb3Zlckljb25CdXR0b25TdHlsZSB8fCB7fTtcbiAgICAgICAgICAgIHZhciBpY29uQnV0dG9uID0gUmVhY3QuY3JlYXRlRWxlbWVudChJY29uQnV0dG9uLCB7XG4gICAgICAgICAgICAgICAgc3R5bGU6IF9leHRlbmRzKHsgcG9zaXRpb246ICdhYnNvbHV0ZScsIHBhZGRpbmc6IDE1LCB6SW5kZXg6IDEwMCwgcmlnaHQ6IDAsIHRvcDogMjUsIGRpc3BsYXk6IHRoaXMuc3RhdGUubG9hZGluZyA/ICdub25lJyA6ICdpbml0aWFsJyB9LCBpY29uQnV0dG9uU3R5bGUpLFxuICAgICAgICAgICAgICAgIGljb25TdHlsZTogeyBmb250U2l6ZTogMTksIGNvbG9yOiAncmdiYSgwLDAsMCwwLjYpJyB9LFxuICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU6ICdtZGkgbWRpLWJvb2stb3Blbi12YXJpYW50JyxcbiAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiB0aGlzLm9wZW5Qb3BvdmVyXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLnBvcG92ZXJCdXR0b24pIHtcbiAgICAgICAgICAgICAgICBpY29uQnV0dG9uID0gUmVhY3QuY3JlYXRlRWxlbWVudCh0aGlzLnByb3BzLnBvcG92ZXJCdXR0b24udHlwZSwgX2V4dGVuZHMoe30sIHRoaXMucHJvcHMucG9wb3ZlckJ1dHRvbi5wcm9wcywgeyBvblRvdWNoVGFwOiB0aGlzLm9wZW5Qb3BvdmVyIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgIGljb25CdXR0b24sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgUG9wb3ZlcixcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3BlbjogdGhpcy5zdGF0ZS5wb3BvdmVyT3BlbixcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvckVsOiB0aGlzLnN0YXRlLnBvcG92ZXJBbmNob3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JPcmlnaW46IHsgaG9yaXpvbnRhbDogJ3JpZ2h0JywgdmVydGljYWw6ICd0b3AnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRPcmlnaW46IHsgaG9yaXpvbnRhbDogJ2xlZnQnLCB2ZXJ0aWNhbDogJ3RvcCcgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uUmVxdWVzdENsb3NlOiB0aGlzLmNsb3NlUG9wb3ZlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiBfZXh0ZW5kcyh7IG1hcmdpbkxlZnQ6IDIwIH0sIHBvcG92ZXJTdHlsZSksXG4gICAgICAgICAgICAgICAgICAgICAgICB6RGVwdGg6IDJcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogX2V4dGVuZHMoeyB3aWR0aDogMzIwLCBoZWlnaHQ6IDQyMCB9LCBwb3BvdmVyQ29udGFpbmVyU3R5bGUpIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEFkZHJlc3NCb29rLCBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcywgeyBtb2RlOiAnc2VsZWN0b3InIH0pKVxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBfc3RhdGUgPSB0aGlzLnN0YXRlO1xuICAgICAgICB2YXIgc2VsZWN0ZWRJdGVtID0gX3N0YXRlLnNlbGVjdGVkSXRlbTtcbiAgICAgICAgdmFyIHJvb3QgPSBfc3RhdGUucm9vdDtcbiAgICAgICAgdmFyIHJpZ2h0UGFuZUl0ZW0gPSBfc3RhdGUucmlnaHRQYW5lSXRlbTtcbiAgICAgICAgdmFyIGNyZWF0ZURpYWxvZ0l0ZW0gPSBfc3RhdGUuY3JlYXRlRGlhbG9nSXRlbTtcblxuICAgICAgICB2YXIgbGVmdENvbHVtblN0eWxlID0ge1xuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBjb2xvcnMuZ3JleTEwMCxcbiAgICAgICAgICAgIHdpZHRoOiAyNTYsXG4gICAgICAgICAgICBvdmVyZmxvd1k6ICdhdXRvJyxcbiAgICAgICAgICAgIG92ZXJmbG93WDogJ2hpZGRlbidcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIGNlbnRlckNvbXBvbmVudCA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHJpZ2h0UGFuZWwgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICBsZWZ0UGFuZWwgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKHNlbGVjdGVkSXRlbS5pZCA9PT0gJ3NlYXJjaCcpIHtcblxuICAgICAgICAgICAgY2VudGVyQ29tcG9uZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudChfU2VhcmNoUGFuZWwyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICBpdGVtOiBzZWxlY3RlZEl0ZW0sXG4gICAgICAgICAgICAgICAgdGl0bGU6IGdldE1lc3NhZ2UoNTgzLCAnJyksXG4gICAgICAgICAgICAgICAgc2VhcmNoTGFiZWw6IGdldE1lc3NhZ2UoNTk1LCAnJyksXG4gICAgICAgICAgICAgICAgb25JdGVtQ2xpY2tlZDogdGhpcy5vblVzZXJMaXN0SXRlbUNsaWNrZWQsXG4gICAgICAgICAgICAgICAgb25Gb2xkZXJDbGlja2VkOiB0aGlzLm9uRm9sZGVyQ2xpY2tlZCxcbiAgICAgICAgICAgICAgICBtb2RlOiBtb2RlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZEl0ZW0udHlwZSA9PT0gJ3JlbW90ZScpIHtcblxuICAgICAgICAgICAgY2VudGVyQ29tcG9uZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudChfU2VhcmNoUGFuZWwyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICBpdGVtOiBzZWxlY3RlZEl0ZW0sXG4gICAgICAgICAgICAgICAgcGFyYW1zOiB7IHRydXN0ZWRfc2VydmVyX2lkOiBzZWxlY3RlZEl0ZW0uaWQgfSxcbiAgICAgICAgICAgICAgICBzZWFyY2hMYWJlbDogZ2V0TWVzc2FnZSg1OTUsICcnKSxcbiAgICAgICAgICAgICAgICB0aXRsZTogZ2V0TWVzc2FnZSg1OTYsICcnKS5yZXBsYWNlKCclcycsIHNlbGVjdGVkSXRlbS5sYWJlbCksXG4gICAgICAgICAgICAgICAgb25JdGVtQ2xpY2tlZDogdGhpcy5vblVzZXJMaXN0SXRlbUNsaWNrZWQsXG4gICAgICAgICAgICAgICAgb25Gb2xkZXJDbGlja2VkOiB0aGlzLm9uRm9sZGVyQ2xpY2tlZCxcbiAgICAgICAgICAgICAgICBtb2RlOiBtb2RlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgdmFyIGVtcHR5U3RhdGVQcmltYXJ5ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdmFyIGVtcHR5U3RhdGVTZWNvbmRhcnkgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB2YXIgb3RoZXJQcm9wcyA9IHt9O1xuICAgICAgICAgICAgaWYgKHNlbGVjdGVkSXRlbS5pZCA9PT0gJ3RlYW1zJykge1xuICAgICAgICAgICAgICAgIGVtcHR5U3RhdGVQcmltYXJ5ID0gZ2V0TWVzc2FnZSg1NzEsICcnKTtcbiAgICAgICAgICAgICAgICBlbXB0eVN0YXRlU2Vjb25kYXJ5ID0gZ2V0TWVzc2FnZSg1NzIsICcnKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc2VsZWN0ZWRJdGVtLmlkID09PSAnZXh0Jykge1xuICAgICAgICAgICAgICAgIGVtcHR5U3RhdGVQcmltYXJ5ID0gZ2V0TWVzc2FnZSg1ODUsICcnKTtcbiAgICAgICAgICAgICAgICBlbXB0eVN0YXRlU2Vjb25kYXJ5ID0gZ2V0TWVzc2FnZSg1ODYsICcnKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc2VsZWN0ZWRJdGVtLmlkLmluZGV4T2YoJ0FKWFBfR1JQXy8nKSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIG90aGVyUHJvcHMgPSB7XG4gICAgICAgICAgICAgICAgICAgIHNob3dTdWJoZWFkZXJzOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBwYWdpbmF0b3JUeXBlOiAhKHNlbGVjdGVkSXRlbS5jdXJyZW50UGFyYW1zICYmIHNlbGVjdGVkSXRlbS5jdXJyZW50UGFyYW1zLmhhc19zZWFyY2gpICYmICdhbHBoYScsXG4gICAgICAgICAgICAgICAgICAgIHBhZ2luYXRvckNhbGxiYWNrOiB0aGlzLnJlbG9hZEN1cnJlbnRBdFBhZ2UuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICAgICAgZW5hYmxlU2VhcmNoOiAhdGhpcy5wcm9wcy5kaXNhYmxlU2VhcmNoLFxuICAgICAgICAgICAgICAgICAgICBzZWFyY2hMYWJlbDogZ2V0TWVzc2FnZSg1OTUsICcnKSxcbiAgICAgICAgICAgICAgICAgICAgb25TZWFyY2g6IHRoaXMucmVsb2FkQ3VycmVudFdpdGhTZWFyY2guYmluZCh0aGlzKVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNlbnRlckNvbXBvbmVudCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoX1VzZXJzTGlzdDJbJ2RlZmF1bHQnXSwgX2V4dGVuZHMoe1xuICAgICAgICAgICAgICAgIGl0ZW06IHNlbGVjdGVkSXRlbSxcbiAgICAgICAgICAgICAgICBvbkl0ZW1DbGlja2VkOiB0aGlzLm9uVXNlckxpc3RJdGVtQ2xpY2tlZCxcbiAgICAgICAgICAgICAgICBvbkZvbGRlckNsaWNrZWQ6IHRoaXMub25Gb2xkZXJDbGlja2VkLFxuICAgICAgICAgICAgICAgIG9uQ3JlYXRlQWN0aW9uOiB0aGlzLm9uQ3JlYXRlQWN0aW9uLFxuICAgICAgICAgICAgICAgIG9uRGVsZXRlQWN0aW9uOiB0aGlzLm9uRGVsZXRlQWN0aW9uLFxuICAgICAgICAgICAgICAgIGxvYWRpbmc6IHRoaXMuc3RhdGUubG9hZGluZyxcbiAgICAgICAgICAgICAgICBtb2RlOiBtb2RlLFxuICAgICAgICAgICAgICAgIGVtcHR5U3RhdGVQcmltYXJ5VGV4dDogZW1wdHlTdGF0ZVByaW1hcnksXG4gICAgICAgICAgICAgICAgZW1wdHlTdGF0ZVNlY29uZGFyeVRleHQ6IGVtcHR5U3RhdGVTZWNvbmRhcnksXG4gICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogdGhpcy5zdGF0ZS5yaWdodFBhbmVJdGVtID8gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpczQuc2V0U3RhdGUoeyByaWdodFBhbmVJdGVtOiBudWxsIH0pO1xuICAgICAgICAgICAgICAgIH0gOiBudWxsXG4gICAgICAgICAgICB9LCBvdGhlclByb3BzKSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJpZ2h0UGFuZWxTdHlsZSA9IF9leHRlbmRzKHt9LCBsZWZ0Q29sdW1uU3R5bGUsIHsgdHJhbnNmb3JtT3JpZ2luOiAncmlnaHQnLCBiYWNrZ3JvdW5kQ29sb3I6ICd3aGl0ZScgfSk7XG4gICAgICAgIGlmICghcmlnaHRQYW5lSXRlbSkge1xuICAgICAgICAgICAgcmlnaHRQYW5lbFN0eWxlID0gX2V4dGVuZHMoe30sIHJpZ2h0UGFuZWxTdHlsZSwgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKDI1NnB4KScsIHdpZHRoOiAwIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJpZ2h0UGFuZWwgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9SaWdodFBhbmVsQ2FyZDJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgcHlkaW86IHRoaXMucHJvcHMucHlkaW8sXG4gICAgICAgICAgICBvblJlcXVlc3RDbG9zZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF90aGlzNC5zZXRTdGF0ZSh7IHJpZ2h0UGFuZUl0ZW06IG51bGwgfSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3R5bGU6IHJpZ2h0UGFuZWxTdHlsZSxcbiAgICAgICAgICAgIG9uQ3JlYXRlQWN0aW9uOiB0aGlzLm9uQ3JlYXRlQWN0aW9uLFxuICAgICAgICAgICAgb25EZWxldGVBY3Rpb246IHRoaXMub25EZWxldGVBY3Rpb24sXG4gICAgICAgICAgICBvblVwZGF0ZUFjdGlvbjogdGhpcy5vbkNhcmRVcGRhdGVBY3Rpb24sXG4gICAgICAgICAgICBpdGVtOiByaWdodFBhbmVJdGVtIH0pO1xuICAgICAgICBpZiAobW9kZSA9PT0gJ2Jvb2snKSB7XG4gICAgICAgICAgICBsZWZ0UGFuZWwgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIE1hdGVyaWFsVUkuUGFwZXIsXG4gICAgICAgICAgICAgICAgeyB6RGVwdGg6IDAsIHN0eWxlOiBfZXh0ZW5kcyh7fSwgbGVmdENvbHVtblN0eWxlLCB7IHpJbmRleDogMiB9KSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgIE1hdGVyaWFsVUkuTGlzdCxcbiAgICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgcm9vdC5jb2xsZWN0aW9ucy5tYXAoKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChfTmVzdGVkTGlzdEl0ZW0yWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IGUuaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHNlbGVjdGVkSXRlbS5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXN0ZWRMZXZlbDogMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnRyeTogZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiB0aGlzLm9uRm9sZGVyQ2xpY2tlZFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pLmJpbmQodGhpcykpXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBkaWFsb2dUaXRsZSA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGRpYWxvZ0NvbnRlbnQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChjcmVhdGVEaWFsb2dJdGVtKSB7XG4gICAgICAgICAgICBpZiAoY3JlYXRlRGlhbG9nSXRlbS5hY3Rpb25zLnR5cGUgPT09ICd1c2VycycpIHtcbiAgICAgICAgICAgICAgICBkaWFsb2dUaXRsZSA9IGdldE1lc3NhZ2UoNDg0LCAnJyk7XG4gICAgICAgICAgICAgICAgZGlhbG9nQ29udGVudCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IGhlaWdodDogNTAwIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChBc3luY0NvbXBvbmVudCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlOiAnUHlkaW9Gb3JtJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICdVc2VyQ3JlYXRpb25Gb3JtJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHpEZXB0aDogMCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7IGhlaWdodDogNTAwIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdVc2VyTmFtZTogXCJcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uVXNlckNyZWF0ZWQ6IHRoaXMuY2xvc2VDcmVhdGVEaWFsb2dBbmRSZWxvYWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNhbmNlbDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzNC5zZXRTdGF0ZSh7IGNyZWF0ZURpYWxvZ0l0ZW06IG51bGwgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgcHlkaW86IHRoaXMucHJvcHMucHlkaW9cbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjcmVhdGVEaWFsb2dJdGVtLmFjdGlvbnMudHlwZSA9PT0gJ3RlYW1zJykge1xuICAgICAgICAgICAgICAgIGRpYWxvZ1RpdGxlID0gZ2V0TWVzc2FnZSg1NjksICcnKTtcbiAgICAgICAgICAgICAgICBkaWFsb2dDb250ZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudChfVGVhbUNyZWF0aW9uRm9ybTJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgICAgICBvblRlYW1DcmVhdGVkOiB0aGlzLmNsb3NlQ3JlYXRlRGlhbG9nQW5kUmVsb2FkLFxuICAgICAgICAgICAgICAgICAgICBvbkNhbmNlbDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXM0LnNldFN0YXRlKHsgY3JlYXRlRGlhbG9nSXRlbTogbnVsbCB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjcmVhdGVEaWFsb2dJdGVtLmFjdGlvbnMudHlwZSA9PT0gJ3RlYW0nKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlbGVjdFVzZXIgPSBmdW5jdGlvbiBzZWxlY3RVc2VyKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICAgICAgX1RlYW1DcmVhdGlvbkZvcm0yWydkZWZhdWx0J10udXBkYXRlVGVhbVVzZXJzKGNyZWF0ZURpYWxvZ0l0ZW0sICdhZGQnLCBbaXRlbV0sIF90aGlzNC5yZWxvYWRDdXJyZW50Tm9kZS5iaW5kKF90aGlzNCkpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgZGlhbG9nVGl0bGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIGRpYWxvZ0NvbnRlbnQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KEFkZHJlc3NCb29rLCB7XG4gICAgICAgICAgICAgICAgICAgIHB5ZGlvOiB0aGlzLnByb3BzLnB5ZGlvLFxuICAgICAgICAgICAgICAgICAgICBtb2RlOiAnc2VsZWN0b3InLFxuICAgICAgICAgICAgICAgICAgICB1c2Vyc09ubHk6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVTZWFyY2g6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIG9uSXRlbVNlbGVjdGVkOiBzZWxlY3RVc2VyXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc3R5bGUgPSB0aGlzLnByb3BzLnN0eWxlIHx8IHt9O1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgeyBzdHlsZTogX2V4dGVuZHMoeyBkaXNwbGF5OiAnZmxleCcsIGhlaWdodDogbW9kZSA9PT0gJ3NlbGVjdG9yJyA/IDQyMCA6IDQ1MCB9LCBzdHlsZSkgfSxcbiAgICAgICAgICAgIGxlZnRQYW5lbCxcbiAgICAgICAgICAgIGNlbnRlckNvbXBvbmVudCxcbiAgICAgICAgICAgIHJpZ2h0UGFuZWwsXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIE1hdGVyaWFsVUkuRGlhbG9nLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGVudFN0eWxlOiB7IHdpZHRoOiAzODAsIG1pbldpZHRoOiAzODAsIG1heFdpZHRoOiAzODAsIHBhZGRpbmc6IDAgfSxcbiAgICAgICAgICAgICAgICAgICAgYm9keVN0eWxlOiB7IHBhZGRpbmc6IDAgfSxcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgcGFkZGluZzogMjAgfSB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nVGl0bGVcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uczogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgbW9kYWw6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBvcGVuOiBjcmVhdGVEaWFsb2dJdGVtID8gdHJ1ZSA6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBvblJlcXVlc3RDbG9zZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXM0LnNldFN0YXRlKHsgY3JlYXRlRGlhbG9nSXRlbTogbnVsbCB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZGlhbG9nQ29udGVudFxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cblxufSk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEFkZHJlc3NCb29rID0gUHlkaW9Db250ZXh0Q29uc3VtZXIoQWRkcmVzc0Jvb2spO1xuZXhwb3J0c1snZGVmYXVsdCddID0gQWRkcmVzc0Jvb2sgPSBtdWlUaGVtZWFibGUoKShBZGRyZXNzQm9vayk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBBZGRyZXNzQm9vaztcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX21hdGVyaWFsVWlTdHlsZXMgPSByZXF1aXJlKCdtYXRlcmlhbC11aS9zdHlsZXMnKTtcblxudmFyIF9weWRpbyA9IHJlcXVpcmUoJ3B5ZGlvJyk7XG5cbnZhciBfcHlkaW8yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcHlkaW8pO1xuXG52YXIgX21hdGVyaWFsVWkgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG4vKipcbiAqIEFscGhhYmV0IGFuZCBwYWdlcyBnZW5lcmF0b3IgdG8gZ2l2ZSBhIGZpcnN0LWxldHRlci1iYXNlZCBwYWdpbmF0aW9uXG4gKi9cblxudmFyIF9QeWRpbyRyZXF1aXJlTGliID0gX3B5ZGlvMlsnZGVmYXVsdCddLnJlcXVpcmVMaWIoJ2Jvb3QnKTtcblxudmFyIFB5ZGlvQ29udGV4dENvbnN1bWVyID0gX1B5ZGlvJHJlcXVpcmVMaWIuUHlkaW9Db250ZXh0Q29uc3VtZXI7XG5cbnZhciBBbHBoYVBhZ2luYXRvciA9IChmdW5jdGlvbiAoX0NvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhBbHBoYVBhZ2luYXRvciwgX0NvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBBbHBoYVBhZ2luYXRvcigpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEFscGhhUGFnaW5hdG9yKTtcblxuICAgICAgICBfQ29tcG9uZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgQWxwaGFQYWdpbmF0b3IucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcblxuICAgICAgICB2YXIgbGV0dGVycyA9ICdhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODknLnNwbGl0KCcnKTtcbiAgICAgICAgbGV0dGVycyA9IFstMV0uY29uY2F0KGxldHRlcnMpO1xuICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcztcbiAgICAgICAgdmFyIGl0ZW0gPSBfcHJvcHMuaXRlbTtcbiAgICAgICAgdmFyIHBhZ2luYXRvckNhbGxiYWNrID0gX3Byb3BzLnBhZ2luYXRvckNhbGxiYWNrO1xuICAgICAgICB2YXIgc3R5bGUgPSBfcHJvcHMuc3R5bGU7XG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gX3Byb3BzLmdldE1lc3NhZ2U7XG5cbiAgICAgICAgdmFyIHBhZ2luYXRvciA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGl0ZW0ucGFnaW5hdGlvbikge1xuICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2l0ZW0kcGFnaW5hdGlvbiA9IGl0ZW0ucGFnaW5hdGlvbjtcbiAgICAgICAgICAgICAgICB2YXIgc3RhcnQgPSBfaXRlbSRwYWdpbmF0aW9uLnN0YXJ0O1xuICAgICAgICAgICAgICAgIHZhciBlbmQgPSBfaXRlbSRwYWdpbmF0aW9uLmVuZDtcbiAgICAgICAgICAgICAgICB2YXIgbWF4ID0gX2l0ZW0kcGFnaW5hdGlvbi5tYXg7XG4gICAgICAgICAgICAgICAgdmFyIGludGVydmFsID0gX2l0ZW0kcGFnaW5hdGlvbi5pbnRlcnZhbDtcblxuICAgICAgICAgICAgICAgIHZhciB0b3RhbF9wYWdlcyA9IE1hdGguY2VpbChtYXggLyBpbnRlcnZhbCk7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnJlbnQgPSBNYXRoLmNlaWwoc3RhcnQgLyBpbnRlcnZhbCk7XG4gICAgICAgICAgICAgICAgdmFyIHBhZ2VzID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0b3RhbF9wYWdlczsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhZ2VzLnB1c2goaSk7XG4gICAgICAgICAgICAgICAgfXBhZ2luYXRvciA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgIF9tYXRlcmlhbFVpLlNlbGVjdEZpZWxkLFxuICAgICAgICAgICAgICAgICAgICB7IGZsb2F0aW5nTGFiZWxUZXh0OiBnZXRNZXNzYWdlKDMzMSksIHN0eWxlOiB7IHdpZHRoOiA2MCB9LCBmdWxsV2lkdGg6IHRydWUsIHZhbHVlOiBjdXJyZW50LCBvbkNoYW5nZTogZnVuY3Rpb24gKGUsIGksIHYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdpbmF0b3JDYWxsYmFjayh2ICogaW50ZXJ2YWwgKyAnLScgKyAodiArIDEpICogaW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSB9LFxuICAgICAgICAgICAgICAgICAgICBwYWdlcy5tYXAoZnVuY3Rpb24gKHApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KF9tYXRlcmlhbFVpLk1lbnVJdGVtLCB7IHZhbHVlOiBwLCBrZXk6IHAsIHByaW1hcnlUZXh0OiBwICsgMSB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjdXJyZW50UGFnZSA9IGl0ZW0uY3VycmVudFBhcmFtcyAmJiBpdGVtLmN1cnJlbnRQYXJhbXMuYWxwaGFfcGFnZXMgJiYgaXRlbS5jdXJyZW50UGFyYW1zLnZhbHVlIHx8IC0xO1xuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiBfZXh0ZW5kcyh7fSwgc3R5bGUsIHsgZGlzcGxheTogJ2ZsZXgnLCBwYWRkaW5nUmlnaHQ6IDgsIGFsaWduSXRlbXM6ICdjZW50ZXInIH0pIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgZmxleDogMSB9IH0sXG4gICAgICAgICAgICAgICAgZ2V0TWVzc2FnZSgyNDksICcnKVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIHBhZ2luYXRvcixcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgX21hdGVyaWFsVWkuU2VsZWN0RmllbGQsXG4gICAgICAgICAgICAgICAgeyBmbG9hdGluZ0xhYmVsVGV4dDogZ2V0TWVzc2FnZSg2MjUpLCBzdHlsZTogeyB3aWR0aDogNjAsIG1hcmdpbkxlZnQ6IDIwIH0sIGZ1bGxXaWR0aDogdHJ1ZSwgdmFsdWU6IGN1cnJlbnRQYWdlLCBvbkNoYW5nZTogZnVuY3Rpb24gKGUsIGksIHYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2luYXRvckNhbGxiYWNrKHYpO1xuICAgICAgICAgICAgICAgICAgICB9IH0sXG4gICAgICAgICAgICAgICAgbGV0dGVycy5tYXAoZnVuY3Rpb24gKGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX21hdGVyaWFsVWkuTWVudUl0ZW0sIHsgdmFsdWU6IGwsIGtleTogbCwgcHJpbWFyeVRleHQ6IGwgPT09IC0xID8gZ2V0TWVzc2FnZSg1OTcsICcnKSA6IGwgfSk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEFscGhhUGFnaW5hdG9yO1xufSkoX3JlYWN0LkNvbXBvbmVudCk7XG5cbkFscGhhUGFnaW5hdG9yLnByb3BUeXBlcyA9IHtcbiAgICAvKipcbiAgICAgKiBDdXJyZW50bHkgc2VsZWN0ZWQgSXRlbVxuICAgICAqL1xuICAgIGl0ZW06IF9yZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgIC8qKlxuICAgICAqIFdoZW4gYSBsZXR0ZXIgaXMgY2xpY2tlZCwgZnVuY3Rpb24obGV0dGVyKVxuICAgICAqL1xuICAgIHBhZ2luYXRvckNhbGxiYWNrOiBfcmVhY3QuUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICAvKipcbiAgICAgKiBNYWluIGluc3RhbmNlIG9mIHB5ZGlvXG4gICAgICovXG4gICAgcHlkaW86IF9yZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihfcHlkaW8yWydkZWZhdWx0J10pLFxuICAgIC8qKlxuICAgICAqIERpc3BsYXkgbW9kZSwgZWl0aGVyIGxhcmdlIChib29rKSBvciBzbWFsbCBwaWNrZXIgKCdzZWxlY3RvcicsICdwb3BvdmVyJykuXG4gICAgICovXG4gICAgbW9kZTogX3JlYWN0LlByb3BUeXBlcy5vbmVPZihbJ2Jvb2snLCAnc2VsZWN0b3InLCAncG9wb3ZlciddKS5pc1JlcXVpcmVkXG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBBbHBoYVBhZ2luYXRvciA9IFB5ZGlvQ29udGV4dENvbnN1bWVyKEFscGhhUGFnaW5hdG9yKTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEFscGhhUGFnaW5hdG9yID0gX21hdGVyaWFsVWlTdHlsZXMubXVpVGhlbWVhYmxlKCkoQWxwaGFQYWdpbmF0b3IpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBBbHBoYVBhZ2luYXRvcjtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG52YXIgTG9hZGVycyA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTG9hZGVycygpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIExvYWRlcnMpO1xuICAgIH1cblxuICAgIExvYWRlcnMuY2hpbGRyZW5Bc1Byb21pc2UgPSBmdW5jdGlvbiBjaGlsZHJlbkFzUHJvbWlzZShpdGVtKSB7XG4gICAgICAgIHZhciBsZWFmID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiBhcmd1bWVudHNbMV07XG4gICAgICAgIHZhciBjaGlsZHJlbkxvYWRlciA9IGl0ZW0uY2hpbGRyZW5Mb2FkZXI7XG4gICAgICAgIHZhciBpdGVtc0xvYWRlciA9IGl0ZW0uaXRlbXNMb2FkZXI7XG4gICAgICAgIHZhciBsZWFmTG9hZGVkID0gaXRlbS5sZWFmTG9hZGVkO1xuICAgICAgICB2YXIgY29sbGVjdGlvbnNMb2FkZWQgPSBpdGVtLmNvbGxlY3Rpb25zTG9hZGVkO1xuICAgICAgICB2YXIgbGVhZnMgPSBpdGVtLmxlYWZzO1xuICAgICAgICB2YXIgY29sbGVjdGlvbnMgPSBpdGVtLmNvbGxlY3Rpb25zO1xuXG4gICAgICAgIHZhciBsb2FkZXIgPSBsZWFmID8gaXRlbXNMb2FkZXIgOiBjaGlsZHJlbkxvYWRlcjtcbiAgICAgICAgdmFyIGxvYWRlZCA9IGxlYWYgPyBsZWFmTG9hZGVkIDogY29sbGVjdGlvbnNMb2FkZWQ7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICBpZiAoIWxvYWRlZCAmJiBsb2FkZXIpIHtcbiAgICAgICAgICAgICAgICBsb2FkZXIoaXRlbSwgZnVuY3Rpb24gKG5ld0NoaWxkcmVuKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsZWFmKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmxlYWZzID0gbmV3Q2hpbGRyZW47XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmxlYWZMb2FkZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS5jb2xsZWN0aW9ucyA9IG5ld0NoaWxkcmVuO1xuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS5jb2xsZWN0aW9uc0xvYWRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShuZXdDaGlsZHJlbik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciByZXMgPSAobGVhZiA/IGxlYWZzIDogY29sbGVjdGlvbnMpIHx8IFtdO1xuICAgICAgICAgICAgICAgIHJlc29sdmUocmVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIExvYWRlcnMubGlzdFVzZXJzID0gZnVuY3Rpb24gbGlzdFVzZXJzKHBhcmFtcywgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHBhcmVudCA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMiB8fCBhcmd1bWVudHNbMl0gPT09IHVuZGVmaW5lZCA/IG51bGwgOiBhcmd1bWVudHNbMl07XG5cbiAgICAgICAgdmFyIGJhc2VQYXJhbXMgPSB7IGdldF9hY3Rpb246ICd1c2VyX2xpc3RfYXV0aG9yaXplZF91c2VycycsIGZvcm1hdDogJ2pzb24nIH07XG4gICAgICAgIGJhc2VQYXJhbXMgPSBfZXh0ZW5kcyh7fSwgYmFzZVBhcmFtcywgcGFyYW1zKTtcbiAgICAgICAgdmFyIGNiID0gY2FsbGJhY2s7XG4gICAgICAgIGlmIChwYXJlbnQpIHtcbiAgICAgICAgICAgIGlmIChwYXJlbnQucmFuZ2UpIHtcbiAgICAgICAgICAgICAgICBiYXNlUGFyYW1zWydyYW5nZSddID0gcGFyZW50LnJhbmdlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2IgPSBmdW5jdGlvbiAoY2hpbGRyZW4pIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhjaGlsZHJlbi5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICAgICAgYy5fcGFyZW50ID0gcGFyZW50O3JldHVybiBjO1xuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgUHlkaW9BcGkuZ2V0Q2xpZW50KCkucmVxdWVzdChiYXNlUGFyYW1zLCBmdW5jdGlvbiAodHJhbnNwb3J0KSB7XG4gICAgICAgICAgICBjYih0cmFuc3BvcnQucmVzcG9uc2VKU09OKTtcbiAgICAgICAgICAgIHZhciBjUmFuZ2UgPSB0cmFuc3BvcnQucmVzcG9uc2VPYmplY3QuaGVhZGVycy5nZXQoJ0NvbnRlbnQtUmFuZ2UnKTtcbiAgICAgICAgICAgIHZhciBhUmFuZ2UgPSB0cmFuc3BvcnQucmVzcG9uc2VPYmplY3QuaGVhZGVycy5nZXQoJ0FjY2VwdC1SYW5nZScpO1xuICAgICAgICAgICAgaWYgKGNSYW5nZSAmJiBhUmFuZ2UgJiYgcGFyZW50KSB7XG4gICAgICAgICAgICAgICAgdmFyIF9hUmFuZ2Ukc3BsaXQgPSBhUmFuZ2Uuc3BsaXQoJyAnKTtcblxuICAgICAgICAgICAgICAgIHZhciB0eXBlID0gX2FSYW5nZSRzcGxpdFswXTtcbiAgICAgICAgICAgICAgICB2YXIgaW50ZXJ2YWwgPSBfYVJhbmdlJHNwbGl0WzFdO1xuXG4gICAgICAgICAgICAgICAgdmFyIF9jUmFuZ2Ukc3BsaXQgPSBjUmFuZ2Uuc3BsaXQoJy8nKTtcblxuICAgICAgICAgICAgICAgIHZhciByYW5nZSA9IF9jUmFuZ2Ukc3BsaXRbMF07XG4gICAgICAgICAgICAgICAgdmFyIG1heCA9IF9jUmFuZ2Ukc3BsaXRbMV07XG5cbiAgICAgICAgICAgICAgICB2YXIgX3JhbmdlJHNwbGl0ID0gcmFuZ2Uuc3BsaXQoJy0nKTtcblxuICAgICAgICAgICAgICAgIHZhciBzdGFydCA9IF9yYW5nZSRzcGxpdFswXTtcbiAgICAgICAgICAgICAgICB2YXIgZW5kID0gX3JhbmdlJHNwbGl0WzFdO1xuXG4gICAgICAgICAgICAgICAgcGFyZW50LnBhZ2luYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0OiBwYXJzZUludChzdGFydCksXG4gICAgICAgICAgICAgICAgICAgIGVuZDogcGFyc2VJbnQoZW5kKSxcbiAgICAgICAgICAgICAgICAgICAgbWF4OiBwYXJzZUludChtYXgpLFxuICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbDogcGFyc2VJbnQoaW50ZXJ2YWwpXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIExvYWRlcnMubG9hZFRlYW1zID0gZnVuY3Rpb24gbG9hZFRlYW1zKGVudHJ5LCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgd3JhcHBlZCA9IGZ1bmN0aW9uIHdyYXBwZWQoY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIGNoaWxkcmVuLm1hcChmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgICAgICAgICBjaGlsZC5pY29uID0gJ21kaSBtZGktYWNjb3VudC1tdWx0aXBsZSc7XG4gICAgICAgICAgICAgICAgY2hpbGQuaXRlbXNMb2FkZXIgPSBMb2FkZXJzLmxvYWRUZWFtVXNlcnM7XG4gICAgICAgICAgICAgICAgY2hpbGQuYWN0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3RlYW0nLFxuICAgICAgICAgICAgICAgICAgICBjcmVhdGU6ICc1NzMnLFxuICAgICAgICAgICAgICAgICAgICByZW1vdmU6ICc1NzQnLFxuICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZTogdHJ1ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgY2hpbGQuX25vdFNlbGVjdGFibGUgPSB0cnVlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjYWxsYmFjayhjaGlsZHJlbik7XG4gICAgICAgIH07XG4gICAgICAgIExvYWRlcnMubGlzdFVzZXJzKHsgZmlsdGVyX3ZhbHVlOiA4IH0sIHdyYXBwZWQsIGVudHJ5KTtcbiAgICB9O1xuXG4gICAgTG9hZGVycy5sb2FkR3JvdXBzID0gZnVuY3Rpb24gbG9hZEdyb3VwcyhlbnRyeSwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHdyYXBwZWQgPSBmdW5jdGlvbiB3cmFwcGVkKGNoaWxkcmVuKSB7XG4gICAgICAgICAgICBjaGlsZHJlbi5tYXAoZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgICAgICAgICAgY2hpbGQuaWNvbiA9ICdtZGkgbWRpLWFjY291bnQtbXVsdGlwbGUnO1xuICAgICAgICAgICAgICAgIGNoaWxkLmNoaWxkcmVuTG9hZGVyID0gZW50cnkuY2hpbGRyZW5Mb2FkZXIgPyBMb2FkZXJzLmxvYWRHcm91cHMgOiBudWxsO1xuICAgICAgICAgICAgICAgIGNoaWxkLml0ZW1zTG9hZGVyID0gZW50cnkuaXRlbXNMb2FkZXIgPyBMb2FkZXJzLmxvYWRHcm91cFVzZXJzIDogbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAoZW50cnkuY3VycmVudFBhcmFtcyAmJiBlbnRyeS5jdXJyZW50UGFyYW1zLmFscGhhX3BhZ2VzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoaWxkLmN1cnJlbnRQYXJhbXMgPSBfZXh0ZW5kcyh7fSwgZW50cnkuY3VycmVudFBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjYWxsYmFjayhjaGlsZHJlbik7XG4gICAgICAgIH07XG4gICAgICAgIHZhciBwYXRoID0gZW50cnkuaWQucmVwbGFjZSgnQUpYUF9HUlBfJywgJycpO1xuICAgICAgICB2YXIgcGFyYW1zID0geyBmaWx0ZXJfdmFsdWU6IDQsIGdyb3VwX3BhdGg6IHBhdGggfTtcbiAgICAgICAgaWYgKGVudHJ5LmN1cnJlbnRQYXJhbXMgJiYgIWVudHJ5LmN1cnJlbnRQYXJhbXMuYWxwaGFfcGFnZXMpIHtcbiAgICAgICAgICAgIHBhcmFtcyA9IF9leHRlbmRzKHt9LCBwYXJhbXMsIGVudHJ5LmN1cnJlbnRQYXJhbXMpO1xuICAgICAgICB9XG4gICAgICAgIExvYWRlcnMubGlzdFVzZXJzKHBhcmFtcywgd3JhcHBlZCwgZW50cnkpO1xuICAgIH07XG5cbiAgICBMb2FkZXJzLmxvYWRFeHRlcm5hbFVzZXJzID0gZnVuY3Rpb24gbG9hZEV4dGVybmFsVXNlcnMoZW50cnksIGNhbGxiYWNrKSB7XG4gICAgICAgIExvYWRlcnMubGlzdFVzZXJzKHsgZmlsdGVyX3ZhbHVlOiAyIH0sIGNhbGxiYWNrLCBlbnRyeSk7XG4gICAgfTtcblxuICAgIExvYWRlcnMubG9hZEdyb3VwVXNlcnMgPSBmdW5jdGlvbiBsb2FkR3JvdXBVc2VycyhlbnRyeSwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHBhdGggPSBlbnRyeS5pZC5yZXBsYWNlKCdBSlhQX0dSUF8nLCAnJyk7XG4gICAgICAgIHZhciBwYXJhbXMgPSB7IGZpbHRlcl92YWx1ZTogMSwgZ3JvdXBfcGF0aDogcGF0aCB9O1xuICAgICAgICBpZiAoZW50cnkuY3VycmVudFBhcmFtcykge1xuICAgICAgICAgICAgcGFyYW1zID0gX2V4dGVuZHMoe30sIHBhcmFtcywgZW50cnkuY3VycmVudFBhcmFtcyk7XG4gICAgICAgIH1cbiAgICAgICAgTG9hZGVycy5saXN0VXNlcnMocGFyYW1zLCBjYWxsYmFjaywgZW50cnkpO1xuICAgIH07XG5cbiAgICBMb2FkZXJzLmxvYWRUZWFtVXNlcnMgPSBmdW5jdGlvbiBsb2FkVGVhbVVzZXJzKGVudHJ5LCBjYWxsYmFjaykge1xuICAgICAgICBMb2FkZXJzLmxpc3RVc2Vycyh7IGZpbHRlcl92YWx1ZTogMywgZ3JvdXBfcGF0aDogZW50cnkuaWQgfSwgY2FsbGJhY2ssIGVudHJ5KTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIExvYWRlcnM7XG59KSgpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBMb2FkZXJzO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBDb21wb25lbnQgPSBfcmVxdWlyZS5Db21wb25lbnQ7XG52YXIgUHJvcFR5cGVzID0gX3JlcXVpcmUuUHJvcFR5cGVzO1xuXG4vKipcbiAqIExlZnQgcGFuZWwgb2YgdGhlIGFkZHJlc3MgYm9va1xuICogRGlzcGxheSB0cmVldmlldyBoaWVyYXJjaHkgb2YgdXNlcnMsIHRlYW1zLCBncm91cHMuXG4gKi9cblxudmFyIE5lc3RlZExpc3RJdGVtID0gKGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7XG4gICAgX2luaGVyaXRzKE5lc3RlZExpc3RJdGVtLCBfQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIE5lc3RlZExpc3RJdGVtKCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTmVzdGVkTGlzdEl0ZW0pO1xuXG4gICAgICAgIF9Db21wb25lbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VycyB0aGlzLnByb3BzLm9uVG91Y2hUYXBcbiAgICAgKi9cblxuICAgIE5lc3RlZExpc3RJdGVtLnByb3RvdHlwZS5vblRvdWNoVGFwID0gZnVuY3Rpb24gb25Ub3VjaFRhcCgpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblRvdWNoVGFwKHRoaXMucHJvcHMuZW50cnkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZWN1cnNpdmVseSBidWlsZCBvdGhlciBOZXN0ZWRMaXN0SXRlbVxuICAgICAqIEBwYXJhbSBkYXRhXG4gICAgICovXG5cbiAgICBOZXN0ZWRMaXN0SXRlbS5wcm90b3R5cGUuYnVpbGROZXN0ZWRJdGVtcyA9IGZ1bmN0aW9uIGJ1aWxkTmVzdGVkSXRlbXMoZGF0YSkge1xuICAgICAgICByZXR1cm4gZGF0YS5tYXAoKGZ1bmN0aW9uIChlbnRyeSkge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoTmVzdGVkTGlzdEl0ZW0sIHtcbiAgICAgICAgICAgICAgICBuZXN0ZWRMZXZlbDogdGhpcy5wcm9wcy5uZXN0ZWRMZXZlbCArIDEsXG4gICAgICAgICAgICAgICAgZW50cnk6IGVudHJ5LFxuICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IHRoaXMucHJvcHMub25Ub3VjaFRhcCxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZDogdGhpcy5wcm9wcy5zZWxlY3RlZFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgIH07XG5cbiAgICBOZXN0ZWRMaXN0SXRlbS5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3Byb3BzJGVudHJ5ID0gdGhpcy5wcm9wcy5lbnRyeTtcbiAgICAgICAgdmFyIGlkID0gX3Byb3BzJGVudHJ5LmlkO1xuICAgICAgICB2YXIgbGFiZWwgPSBfcHJvcHMkZW50cnkubGFiZWw7XG4gICAgICAgIHZhciBpY29uID0gX3Byb3BzJGVudHJ5Lmljb247XG4gICAgICAgIHZhciBzZWxlY3RlZCA9IF9wcm9wcyRlbnRyeS5zZWxlY3RlZDtcblxuICAgICAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLnByb3BzLmVudHJ5LmNvbGxlY3Rpb25zIHx8IFtdO1xuICAgICAgICB2YXIgbmVzdGVkID0gdGhpcy5idWlsZE5lc3RlZEl0ZW1zKGNoaWxkcmVuKTtcbiAgICAgICAgdmFyIGZvbnRJY29uID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoaWNvbikge1xuICAgICAgICAgICAgZm9udEljb24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KE1hdGVyaWFsVUkuRm9udEljb24sIHsgY2xhc3NOYW1lOiBpY29uIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KE1hdGVyaWFsVUkuTGlzdEl0ZW0sIHtcbiAgICAgICAgICAgIG5lc3RlZExldmVsOiB0aGlzLnByb3BzLm5lc3RlZExldmVsLFxuICAgICAgICAgICAga2V5OiBpZCxcbiAgICAgICAgICAgIHByaW1hcnlUZXh0OiBsYWJlbCxcbiAgICAgICAgICAgIG9uVG91Y2hUYXA6IHRoaXMub25Ub3VjaFRhcC5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgbmVzdGVkSXRlbXM6IG5lc3RlZCxcbiAgICAgICAgICAgIGluaXRpYWxseU9wZW46IHRydWUsXG4gICAgICAgICAgICBsZWZ0SWNvbjogZmFsc2UgJiYgZm9udEljb24sXG4gICAgICAgICAgICBpbm5lckRpdlN0eWxlOiB7IGZvbnRXZWlnaHQ6IHRoaXMucHJvcHMuc2VsZWN0ZWQgPT09IHRoaXMucHJvcHMuZW50cnkuaWQgPyA1MDAgOiA0MDAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIE5lc3RlZExpc3RJdGVtO1xufSkoQ29tcG9uZW50KTtcblxuTmVzdGVkTGlzdEl0ZW0ucHJvcFR5cGVzID0ge1xuICAgIC8qKlxuICAgICAqIEtlZXBzIHRyYWNrIG9mIHRoZSBjdXJyZW50IGRlcHRoIGxldmVsXG4gICAgICovXG4gICAgbmVzdGVkTGV2ZWw6IFByb3BUeXBlcy5udW1iZXIsXG4gICAgLyoqXG4gICAgICogQ3VycmVudGx5IHNlbGVjdGVkIG5vZGUgaWRcbiAgICAgKi9cbiAgICBzZWxlY3RlZDogUHJvcFR5cGVzLnN0cmluZyxcbiAgICAvKipcbiAgICAgKiBDYWxsYmFjayB0cmlnZ2VyZWQgd2hlbiBhbiBlbnRyeSBpcyBzZWxlY3RlZFxuICAgICAqL1xuICAgIG9uVG91Y2hUYXA6IFByb3BUeXBlcy5mdW5jXG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBOZXN0ZWRMaXN0SXRlbTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfVGVhbUNhcmQgPSByZXF1aXJlKCcuL1RlYW1DYXJkJyk7XG5cbnZhciBfVGVhbUNhcmQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVGVhbUNhcmQpO1xuXG52YXIgX1VzZXJDYXJkID0gcmVxdWlyZSgnLi9Vc2VyQ2FyZCcpO1xuXG52YXIgX1VzZXJDYXJkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1VzZXJDYXJkKTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIFBhcGVyID0gX3JlcXVpcmUuUGFwZXI7XG5cbi8qKlxuICogQ29udGFpbmVyIGZvciBVc2VyQ2FyZCBvciBUZWFtQ2FyZFxuICovXG5cbnZhciBSaWdodFBhbmVsQ2FyZCA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICBfaW5oZXJpdHMoUmlnaHRQYW5lbENhcmQsIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gIGZ1bmN0aW9uIFJpZ2h0UGFuZWxDYXJkKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBSaWdodFBhbmVsQ2FyZCk7XG5cbiAgICBfUmVhY3QkQ29tcG9uZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBSaWdodFBhbmVsQ2FyZC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuXG4gICAgdmFyIGNvbnRlbnQgPSB1bmRlZmluZWQ7XG4gICAgdmFyIGl0ZW0gPSB0aGlzLnByb3BzLml0ZW0gfHwge307XG4gICAgaWYgKGl0ZW0udHlwZSA9PT0gJ3VzZXInKSB7XG4gICAgICBjb250ZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudChfVXNlckNhcmQyWydkZWZhdWx0J10sIHRoaXMucHJvcHMpO1xuICAgIH0gZWxzZSBpZiAoaXRlbS50eXBlID09PSAnZ3JvdXAnICYmIGl0ZW0uaWQuaW5kZXhPZignL0FKWFBfVEVBTS8nKSA9PT0gMCkge1xuICAgICAgY29udGVudCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoX1RlYW1DYXJkMlsnZGVmYXVsdCddLCB0aGlzLnByb3BzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgIFBhcGVyLFxuICAgICAgeyB6RGVwdGg6IDIsIHN0eWxlOiBfZXh0ZW5kcyh7IHBvc2l0aW9uOiAncmVsYXRpdmUnIH0sIHRoaXMucHJvcHMuc3R5bGUpIH0sXG4gICAgICBjb250ZW50XG4gICAgKTtcbiAgfTtcblxuICByZXR1cm4gUmlnaHRQYW5lbENhcmQ7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5SaWdodFBhbmVsQ2FyZC5wcm9wVHlwZXMgPSB7XG4gIC8qKlxuICAgKiBQeWRpbyBpbnN0YW5jZVxuICAgKi9cbiAgcHlkaW86IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFB5ZGlvKSxcbiAgLyoqXG4gICAqIFNlbGVjdGVkIGl0ZW1cbiAgICovXG4gIGl0ZW06IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gIC8qKlxuICAgKiBBcHBsaWVzIHRvIHJvb3QgY29udGFpbmVyXG4gICAqL1xuICBzdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgLyoqXG4gICAqIEZvcndhcmRlZCB0byBjaGlsZFxuICAgKi9cbiAgb25SZXF1ZXN0Q2xvc2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAvKipcbiAgICogRm9yd2FyZGVkIHRvIGNoaWxkXG4gICAqL1xuICBvbkRlbGV0ZUFjdGlvbjogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gIC8qKlxuICAgKiBGb3J3YXJkZWQgdG8gY2hpbGRcbiAgICovXG4gIG9uVXBkYXRlQWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuY1xufTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gUmlnaHRQYW5lbENhcmQ7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIENvbXBvbmVudCA9IF9yZXF1aXJlLkNvbXBvbmVudDtcbnZhciBQcm9wVHlwZXMgPSBfcmVxdWlyZS5Qcm9wVHlwZXM7XG5cbi8qKlxuICogUmVhZHkgdG8gdXNlIEZvcm0gKyBSZXN1bHQgTGlzdCBmb3Igc2VhcmNoIHVzZXJzXG4gKi9cblxudmFyIFNlYXJjaEZvcm0gPSAoZnVuY3Rpb24gKF9Db21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoU2VhcmNoRm9ybSwgX0NvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBTZWFyY2hGb3JtKHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTZWFyY2hGb3JtKTtcblxuICAgICAgICBfQ29tcG9uZW50LmNhbGwodGhpcywgcHJvcHMuY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IHZhbHVlOiAnJyB9O1xuICAgIH1cblxuICAgIFNlYXJjaEZvcm0ucHJvdG90eXBlLnNlYXJjaCA9IGZ1bmN0aW9uIHNlYXJjaCgpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblNlYXJjaCh0aGlzLnN0YXRlLnZhbHVlKTtcbiAgICB9O1xuXG4gICAgU2VhcmNoRm9ybS5wcm90b3R5cGUub25DaGFuZ2UgPSBmdW5jdGlvbiBvbkNoYW5nZShldmVudCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHZhbHVlOiB2YWx1ZSB9KTtcbiAgICAgICAgRnVuY1V0aWxzLmJ1ZmZlckNhbGxiYWNrKCdzZWFyY2hfdXNlcnNfbGlzdCcsIDMwMCwgdGhpcy5zZWFyY2guYmluZCh0aGlzKSk7XG4gICAgfTtcblxuICAgIFNlYXJjaEZvcm0ucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgeyBzdHlsZTogX2V4dGVuZHMoeyBtaW5XaWR0aDogMzIwIH0sIHRoaXMucHJvcHMuc3R5bGUpIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KE1hdGVyaWFsVUkuVGV4dEZpZWxkLCB7XG4gICAgICAgICAgICAgICAgZnVsbFdpZHRoOiB0cnVlLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB0aGlzLnN0YXRlLnZhbHVlLFxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlOiB0aGlzLm9uQ2hhbmdlLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgaGludFRleHQ6IHRoaXMucHJvcHMuc2VhcmNoTGFiZWxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBTZWFyY2hGb3JtO1xufSkoQ29tcG9uZW50KTtcblxuU2VhcmNoRm9ybS5wcm9wVHlwZXMgPSB7XG4gICAgLyoqXG4gICAgICogTGFiZWwgZGlzcGxheWVkIGluIHRoZSBzZWFyY2ggZmllbGRcbiAgICAgKi9cbiAgICBzZWFyY2hMYWJlbDogUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIHRyaWdnZXJlZCB0byBzZWFyY2hcbiAgICAgKi9cbiAgICBvblNlYXJjaDogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICAvKipcbiAgICAgKiBXaWxsIGJlIGFwcGVuZGVkIHRvIHRoZSByb290IGVsZW1lbnRcbiAgICAgKi9cbiAgICBzdHlsZTogUHJvcFR5cGVzLm9iamVjdFxufTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gU2VhcmNoRm9ybTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfU2VhcmNoRm9ybSA9IHJlcXVpcmUoJy4vU2VhcmNoRm9ybScpO1xuXG52YXIgX1NlYXJjaEZvcm0yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2VhcmNoRm9ybSk7XG5cbnZhciBfVXNlcnNMaXN0ID0gcmVxdWlyZSgnLi9Vc2Vyc0xpc3QnKTtcblxudmFyIF9Vc2Vyc0xpc3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXNlcnNMaXN0KTtcblxudmFyIF9Mb2FkZXJzID0gcmVxdWlyZSgnLi9Mb2FkZXJzJyk7XG5cbnZhciBfTG9hZGVyczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Mb2FkZXJzKTtcblxuLyoqXG4gKiBSZWFkeSB0byB1c2UgRm9ybSArIFJlc3VsdCBMaXN0IGZvciBzZWFyY2ggdXNlcnNcbiAqL1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgQ29tcG9uZW50ID0gX3JlcXVpcmUuQ29tcG9uZW50O1xudmFyIFByb3BUeXBlcyA9IF9yZXF1aXJlLlByb3BUeXBlcztcblxudmFyIF9yZXF1aXJlJHJlcXVpcmVMaWIgPSByZXF1aXJlKCdweWRpbycpLnJlcXVpcmVMaWIoJ2Jvb3QnKTtcblxudmFyIFB5ZGlvQ29udGV4dENvbnN1bWVyID0gX3JlcXVpcmUkcmVxdWlyZUxpYi5QeWRpb0NvbnRleHRDb25zdW1lcjtcblxudmFyIFNlYXJjaFBhbmVsID0gKGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7XG4gICAgX2luaGVyaXRzKFNlYXJjaFBhbmVsLCBfQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIFNlYXJjaFBhbmVsKHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTZWFyY2hQYW5lbCk7XG5cbiAgICAgICAgX0NvbXBvbmVudC5jYWxsKHRoaXMsIHByb3BzLmNvbnRleHQpO1xuICAgICAgICB0aGlzLnN0YXRlID0geyBpdGVtczogW10gfTtcbiAgICB9XG5cbiAgICBTZWFyY2hQYW5lbC5wcm90b3R5cGUub25TZWFyY2ggPSBmdW5jdGlvbiBvblNlYXJjaCh2YWx1ZSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpdGVtczogW10gfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHBhcmFtcyA9IHsgdmFsdWU6IHZhbHVlLCBleGlzdGluZ19vbmx5OiAndHJ1ZScgfTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMucGFyYW1zKSB7XG4gICAgICAgICAgICBwYXJhbXMgPSBfZXh0ZW5kcyh7fSwgcGFyYW1zLCB0aGlzLnByb3BzLnBhcmFtcyk7XG4gICAgICAgIH1cbiAgICAgICAgX0xvYWRlcnMyWydkZWZhdWx0J10ubGlzdFVzZXJzKHBhcmFtcywgZnVuY3Rpb24gKGNoaWxkcmVuKSB7XG4gICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IGl0ZW1zOiBjaGlsZHJlbiB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIFNlYXJjaFBhbmVsLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgbW9kZSA9IF9wcm9wcy5tb2RlO1xuICAgICAgICB2YXIgaXRlbSA9IF9wcm9wcy5pdGVtO1xuICAgICAgICB2YXIgZ2V0TWVzc2FnZSA9IF9wcm9wcy5nZXRNZXNzYWdlO1xuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiB7IGZsZXg6IDEsIGRpc3BsYXk6ICdmbGV4JywgZmxleERpcmVjdGlvbjogJ2NvbHVtbicgfSB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IHBhZGRpbmc6IDEwLCBoZWlnaHQ6IDU2LCBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuc2VsZWN0ID8gYWN0aXZlVGJhckNvbG9yIDogJyNmYWZhZmEnLCBkaXNwbGF5OiAnZmxleCcsIGFsaWduSXRlbXM6ICdjZW50ZXInLCB0cmFuc2l0aW9uOiBET01VdGlscy5nZXRCZXppZXJzVHJhbnNpdGlvbigpIH0gfSxcbiAgICAgICAgICAgICAgICBtb2RlID09PSBcInNlbGVjdG9yXCIgJiYgaXRlbS5fcGFyZW50ICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWF0ZXJpYWxVSS5JY29uQnV0dG9uLCB7IGljb25DbGFzc05hbWU6ICdtZGkgbWRpLWNoZXZyb24tbGVmdCcsIG9uVG91Y2hUYXA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMi5wcm9wcy5vbkZvbGRlckNsaWNrZWQoaXRlbS5fcGFyZW50KTtcbiAgICAgICAgICAgICAgICAgICAgfSB9KSxcbiAgICAgICAgICAgICAgICBtb2RlID09PSAnYm9vaycgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgZm9udFNpemU6IDIwLCBjb2xvcjogJ3JnYmEoMCwwLDAsMC44NyknLCBmbGV4OiAxIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy50aXRsZVxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChfU2VhcmNoRm9ybTJbJ2RlZmF1bHQnXSwgeyBzdHlsZTogbW9kZSA9PT0gJ2Jvb2snID8geyBtaW5XaWR0aDogMzIwIH0gOiB7IGZsZXg6IDEgfSwgc2VhcmNoTGFiZWw6IHRoaXMucHJvcHMuc2VhcmNoTGFiZWwsIG9uU2VhcmNoOiB0aGlzLm9uU2VhcmNoLmJpbmQodGhpcykgfSlcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KF9Vc2Vyc0xpc3QyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICBtb2RlOiB0aGlzLnByb3BzLm1vZGUsXG4gICAgICAgICAgICAgICAgb25JdGVtQ2xpY2tlZDogdGhpcy5wcm9wcy5vbkl0ZW1DbGlja2VkLFxuICAgICAgICAgICAgICAgIGl0ZW06IHsgbGVhZnM6IHRoaXMuc3RhdGUuaXRlbXMgfSxcbiAgICAgICAgICAgICAgICBub1Rvb2xiYXI6IHRydWUsXG4gICAgICAgICAgICAgICAgZW1wdHlTdGF0ZVByaW1hcnlUZXh0OiBnZXRNZXNzYWdlKDU4NywgJycpLFxuICAgICAgICAgICAgICAgIGVtcHR5U3RhdGVTZWNvbmRhcnlUZXh0OiBnZXRNZXNzYWdlKDU4OCwgJycpXG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH07XG5cbiAgICByZXR1cm4gU2VhcmNoUGFuZWw7XG59KShDb21wb25lbnQpO1xuXG5TZWFyY2hQYW5lbC5wcm9wVHlwZXMgPSB7XG4gICAgLyoqXG4gICAgICogT3B0aW9uYWwgcGFyYW1ldGVycyBhZGRlZCB0byBsaXN0VXNlcnMoKSByZXF1ZXN0XG4gICAgICovXG4gICAgcGFyYW1zOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIC8qKlxuICAgICAqIExhYmVsIGRpc3BsYXllZCBpbiB0aGUgdG9vbGJhclxuICAgICAqL1xuICAgIHNlYXJjaExhYmVsOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIHRyaWdnZXJlZCB3aGVuIGEgc2VhcmNoIHJlc3VsdCBpcyBjbGlja2VkXG4gICAgICovXG4gICAgb25JdGVtQ2xpY2tlZDogUHJvcFR5cGVzLmZ1bmMsXG4gICAgLyoqXG4gICAgICogQ3VycmVudGx5IHNlbGVjdGVkIGl0ZW0sIHJlcXVpcmVkIGZvciBuYXZpZ2F0aW9uXG4gICAgICovXG4gICAgaXRlbTogUHJvcFR5cGVzLm9iamVjdCxcbiAgICAvKipcbiAgICAgKiBDYWxsYmFjayB0cmlnZ2VyZWQgaWYgdGhlIHJlc3VsdCBpcyBhIGNvbGxlY3Rpb25cbiAgICAgKi9cbiAgICBvbkZvbGRlckNsaWNrZWQ6IFByb3BUeXBlcy5mdW5jXG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBTZWFyY2hQYW5lbCA9IFB5ZGlvQ29udGV4dENvbnN1bWVyKFNlYXJjaFBhbmVsKTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFNlYXJjaFBhbmVsO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9Vc2Vyc0xpc3QgPSByZXF1aXJlKCcuL1VzZXJzTGlzdCcpO1xuXG52YXIgX1VzZXJzTGlzdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Vc2Vyc0xpc3QpO1xuXG52YXIgX0xvYWRlcnMgPSByZXF1aXJlKCcuL0xvYWRlcnMnKTtcblxudmFyIF9Mb2FkZXJzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0xvYWRlcnMpO1xuXG52YXIgX2F2YXRhckFjdGlvbnNQYW5lbCA9IHJlcXVpcmUoJy4uL2F2YXRhci9BY3Rpb25zUGFuZWwnKTtcblxudmFyIF9hdmF0YXJBY3Rpb25zUGFuZWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXZhdGFyQWN0aW9uc1BhbmVsKTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIFRleHRGaWVsZCA9IF9yZXF1aXJlLlRleHRGaWVsZDtcbnZhciBGbGF0QnV0dG9uID0gX3JlcXVpcmUuRmxhdEJ1dHRvbjtcbnZhciBDYXJkVGl0bGUgPSBfcmVxdWlyZS5DYXJkVGl0bGU7XG52YXIgRGl2aWRlciA9IF9yZXF1aXJlLkRpdmlkZXI7XG5cbnZhciBfcmVxdWlyZSRyZXF1aXJlTGliID0gcmVxdWlyZSgncHlkaW8nKS5yZXF1aXJlTGliKCdib290Jyk7XG5cbnZhciBQeWRpb0NvbnRleHRDb25zdW1lciA9IF9yZXF1aXJlJHJlcXVpcmVMaWIuUHlkaW9Db250ZXh0Q29uc3VtZXI7XG5cbi8qKlxuICogRGlzcGxheSBpbmZvIGFib3V0IGEgVGVhbSBpbnNpZGUgYSBwb3BvdmVyLWFibGUgY2FyZFxuICovXG5cbnZhciBUZWFtQ2FyZCA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhUZWFtQ2FyZCwgX1JlYWN0JENvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBUZWFtQ2FyZChwcm9wcywgY29udGV4dCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVGVhbUNhcmQpO1xuXG4gICAgICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IGxhYmVsOiB0aGlzLnByb3BzLml0ZW0ubGFiZWwgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2UgbG9hZGVyIHRvIGdldCB0ZWFtIHBhcnRpY2lwYW50c1xuICAgICAqIEBwYXJhbSBpdGVtXG4gICAgICovXG5cbiAgICBUZWFtQ2FyZC5wcm90b3R5cGUubG9hZE1lbWJlcnMgPSBmdW5jdGlvbiBsb2FkTWVtYmVycyhpdGVtKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGxvYWRpbmc6IHRydWUgfSk7XG4gICAgICAgIF9Mb2FkZXJzMlsnZGVmYXVsdCddLmNoaWxkcmVuQXNQcm9taXNlKGl0ZW0sIGZhbHNlKS50aGVuKGZ1bmN0aW9uIChjaGlsZHJlbikge1xuICAgICAgICAgICAgX0xvYWRlcnMyWydkZWZhdWx0J10uY2hpbGRyZW5Bc1Byb21pc2UoaXRlbSwgdHJ1ZSkudGhlbihmdW5jdGlvbiAoY2hpbGRyZW4pIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IG1lbWJlcnM6IGl0ZW0ubGVhZnMsIGxvYWRpbmc6IGZhbHNlIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBUZWFtQ2FyZC5wcm90b3R5cGUuY29tcG9uZW50V2lsbE1vdW50ID0gZnVuY3Rpb24gY29tcG9uZW50V2lsbE1vdW50KCkge1xuICAgICAgICB0aGlzLmxvYWRNZW1iZXJzKHRoaXMucHJvcHMuaXRlbSk7XG4gICAgfTtcblxuICAgIFRlYW1DYXJkLnByb3RvdHlwZS5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzID0gZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHtcbiAgICAgICAgdGhpcy5sb2FkTWVtYmVycyhuZXh0UHJvcHMuaXRlbSk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBsYWJlbDogbmV4dFByb3BzLml0ZW0ubGFiZWwgfSk7XG4gICAgfTtcblxuICAgIFRlYW1DYXJkLnByb3RvdHlwZS5vbkxhYmVsQ2hhbmdlID0gZnVuY3Rpb24gb25MYWJlbENoYW5nZShlLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgbGFiZWw6IHZhbHVlIH0pO1xuICAgIH07XG5cbiAgICBUZWFtQ2FyZC5wcm90b3R5cGUudXBkYXRlTGFiZWwgPSBmdW5jdGlvbiB1cGRhdGVMYWJlbCgpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUubGFiZWwgIT09IHRoaXMucHJvcHMuaXRlbS5sYWJlbCkge1xuICAgICAgICAgICAgUHlkaW9Vc2Vycy5DbGllbnQudXBkYXRlVGVhbUxhYmVsKHRoaXMucHJvcHMuaXRlbS5pZC5yZXBsYWNlKCcvQUpYUF9URUFNLycsICcnKSwgdGhpcy5zdGF0ZS5sYWJlbCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF90aGlzMi5wcm9wcy5vblVwZGF0ZUFjdGlvbihfdGhpczIucHJvcHMuaXRlbSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZWRpdE1vZGU6IGZhbHNlIH0pO1xuICAgIH07XG5cbiAgICBUZWFtQ2FyZC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3RoaXMzID0gdGhpcztcblxuICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcztcbiAgICAgICAgdmFyIGl0ZW0gPSBfcHJvcHMuaXRlbTtcbiAgICAgICAgdmFyIG9uRGVsZXRlQWN0aW9uID0gX3Byb3BzLm9uRGVsZXRlQWN0aW9uO1xuICAgICAgICB2YXIgb25DcmVhdGVBY3Rpb24gPSBfcHJvcHMub25DcmVhdGVBY3Rpb247XG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gX3Byb3BzLmdldE1lc3NhZ2U7XG5cbiAgICAgICAgdmFyIGVkaXRQcm9wcyA9IHtcbiAgICAgICAgICAgIHRlYW06IGl0ZW0sXG4gICAgICAgICAgICB1c2VyRWRpdGFibGU6IHRydWUsXG4gICAgICAgICAgICBvbkRlbGV0ZUFjdGlvbjogZnVuY3Rpb24gb25EZWxldGVBY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMzLnByb3BzLm9uRGVsZXRlQWN0aW9uKGl0ZW0uX3BhcmVudCwgW2l0ZW1dKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvbkVkaXRBY3Rpb246IGZ1bmN0aW9uIG9uRWRpdEFjdGlvbigpIHtcbiAgICAgICAgICAgICAgICBfdGhpczMuc2V0U3RhdGUoeyBlZGl0TW9kZTogIV90aGlzMy5zdGF0ZS5lZGl0TW9kZSB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZWxvYWRBY3Rpb246IGZ1bmN0aW9uIHJlbG9hZEFjdGlvbigpIHtcbiAgICAgICAgICAgICAgICBfdGhpczMucHJvcHMub25VcGRhdGVBY3Rpb24oaXRlbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIHRpdGxlID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0TW9kZSkge1xuICAgICAgICAgICAgdGl0bGUgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgZGlzcGxheTogJ2ZsZXgnLCBhbGlnbkl0ZW1zOiAnY2VudGVyJywgbWFyZ2luOiAxNiB9IH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChUZXh0RmllbGQsIHsgc3R5bGU6IHsgZmxleDogMSwgZm9udFNpemU6IDI0IH0sIGZ1bGxXaWR0aDogdHJ1ZSwgZGlzYWJsZWQ6IGZhbHNlLCB1bmRlcmxpbmVTaG93OiBmYWxzZSwgdmFsdWU6IHRoaXMuc3RhdGUubGFiZWwsIG9uQ2hhbmdlOiB0aGlzLm9uTGFiZWxDaGFuZ2UuYmluZCh0aGlzKSB9KSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEZsYXRCdXR0b24sIHsgc2Vjb25kYXJ5OiB0cnVlLCBsYWJlbDogZ2V0TWVzc2FnZSg0OCksIG9uVG91Y2hUYXA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMy51cGRhdGVMYWJlbCgpO1xuICAgICAgICAgICAgICAgICAgICB9IH0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGl0bGUgPSBSZWFjdC5jcmVhdGVFbGVtZW50KENhcmRUaXRsZSwgeyB0aXRsZTogdGhpcy5zdGF0ZS5sYWJlbCwgc3VidGl0bGU6IGl0ZW0ubGVhZnMgJiYgaXRlbS5sZWFmcy5sZW5ndGggPyBnZXRNZXNzYWdlKDU3NikucmVwbGFjZSgnJXMnLCBpdGVtLmxlYWZzLmxlbmd0aCkgOiBnZXRNZXNzYWdlKDU3NykgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX2F2YXRhckFjdGlvbnNQYW5lbDJbJ2RlZmF1bHQnXSwgX2V4dGVuZHMoe30sIHRoaXMucHJvcHMsIGVkaXRQcm9wcykpLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChEaXZpZGVyLCBudWxsKSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX1VzZXJzTGlzdDJbJ2RlZmF1bHQnXSwgeyBzdWJIZWFkZXI6IGdldE1lc3NhZ2UoNTc1KSwgb25JdGVtQ2xpY2tlZDogZnVuY3Rpb24gKCkge30sIGl0ZW06IGl0ZW0sIG1vZGU6ICdpbm5lcicsIG9uRGVsZXRlQWN0aW9uOiBvbkRlbGV0ZUFjdGlvbiB9KVxuICAgICAgICApO1xuICAgIH07XG5cbiAgICByZXR1cm4gVGVhbUNhcmQ7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5UZWFtQ2FyZC5wcm9wVHlwZXMgPSB7XG4gICAgLyoqXG4gICAgICogUHlkaW8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBweWRpbzogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW8pLFxuICAgIC8qKlxuICAgICAqIFRlYW0gZGF0YSBvYmplY3RcbiAgICAgKi9cbiAgICBpdGVtOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgIC8qKlxuICAgICAqIEFwcGxpZWQgdG8gcm9vdCBjb250YWluZXJcbiAgICAgKi9cbiAgICBzdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAvKipcbiAgICAgKiBDYWxsZWQgdG8gZGlzbWlzcyB0aGUgcG9wb3ZlclxuICAgICAqL1xuICAgIG9uUmVxdWVzdENsb3NlOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAvKipcbiAgICAgKiBEZWxldGUgY3VycmVudCB0ZWFtXG4gICAgICovXG4gICAgb25EZWxldGVBY3Rpb246IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSBjdXJyZW50IHRlYW1cbiAgICAgKi9cbiAgICBvblVwZGF0ZUFjdGlvbjogUmVhY3QuUHJvcFR5cGVzLmZ1bmNcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFRlYW1DYXJkID0gUHlkaW9Db250ZXh0Q29uc3VtZXIoVGVhbUNhcmQpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBUZWFtQ2FyZDtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfYXZhdGFyVXNlckF2YXRhciA9IHJlcXVpcmUoJy4uL2F2YXRhci9Vc2VyQXZhdGFyJyk7XG5cbnZhciBfYXZhdGFyVXNlckF2YXRhcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hdmF0YXJVc2VyQXZhdGFyKTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIF9yZXF1aXJlJHJlcXVpcmVMaWIgPSByZXF1aXJlKCdweWRpbycpLnJlcXVpcmVMaWIoJ2Jvb3QnKTtcblxudmFyIEFzeW5jQ29tcG9uZW50ID0gX3JlcXVpcmUkcmVxdWlyZUxpYi5Bc3luY0NvbXBvbmVudDtcblxuLyoqXG4gKiBDYXJkIHByZXNlbnRhdGlvbiBvZiBhIHVzZXIuIFJlbGllcyBvbiB0aGUgVXNlckF2YXRhciBvYmplY3QsXG4gKiBwbHVzIHRoZSBQeWRpb0Zvcm0uVXNlckNyZWF0aW9uRm9ybSB3aGVuIGluIGVkaXQgbW9kZS5cbiAqL1xuXG52YXIgVXNlckNhcmQgPSAoZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoVXNlckNhcmQsIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gVXNlckNhcmQocHJvcHMsIGNvbnRleHQpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFVzZXJDYXJkKTtcblxuICAgICAgICBfUmVhY3QkQ29tcG9uZW50LmNhbGwodGhpcywgcHJvcHMsIGNvbnRleHQpO1xuICAgICAgICB0aGlzLnN0YXRlID0geyBlZGl0Rm9ybTogZmFsc2UgfTtcbiAgICB9XG5cbiAgICBVc2VyQ2FyZC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciBpdGVtID0gdGhpcy5wcm9wcy5pdGVtO1xuXG4gICAgICAgIHZhciBlZGl0YWJsZVByb3BzID0ge30sXG4gICAgICAgICAgICBlZGl0Rm9ybSA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGl0ZW0uX3BhcmVudCAmJiBpdGVtLl9wYXJlbnQuaWQgPT09ICdleHQnKSB7XG4gICAgICAgICAgICBlZGl0YWJsZVByb3BzID0ge1xuICAgICAgICAgICAgICAgIHVzZXJFZGl0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvbkRlbGV0ZUFjdGlvbjogZnVuY3Rpb24gb25EZWxldGVBY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnByb3BzLm9uRGVsZXRlQWN0aW9uKGl0ZW0uX3BhcmVudCwgW2l0ZW1dKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIG9uRWRpdEFjdGlvbjogZnVuY3Rpb24gb25FZGl0QWN0aW9uKCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IGVkaXRGb3JtOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVsb2FkQWN0aW9uOiBmdW5jdGlvbiByZWxvYWRBY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnByb3BzLm9uVXBkYXRlQWN0aW9uKGl0ZW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0Rm9ybSkge1xuICAgICAgICAgICAgZWRpdEZvcm0gPSBSZWFjdC5jcmVhdGVFbGVtZW50KEFzeW5jQ29tcG9uZW50LCB7XG4gICAgICAgICAgICAgICAgbmFtZXNwYWNlOiAnUHlkaW9Gb3JtJyxcbiAgICAgICAgICAgICAgICBjb21wb25lbnROYW1lOiAnVXNlckNyZWF0aW9uRm9ybScsXG4gICAgICAgICAgICAgICAgcHlkaW86IHRoaXMucHJvcHMucHlkaW8sXG4gICAgICAgICAgICAgICAgekRlcHRoOiAwLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7IGhlaWdodDogNTAwIH0sXG4gICAgICAgICAgICAgICAgbmV3VXNlck5hbWU6IGl0ZW0uaWQsXG4gICAgICAgICAgICAgICAgZWRpdE1vZGU6IHRydWUsXG4gICAgICAgICAgICAgICAgdXNlckRhdGE6IGl0ZW0sXG4gICAgICAgICAgICAgICAgb25Vc2VyQ3JlYXRlZDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5wcm9wcy5vblVwZGF0ZUFjdGlvbihpdGVtKTtfdGhpcy5zZXRTdGF0ZSh7IGVkaXRGb3JtOiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIG9uQ2FuY2VsOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgZWRpdEZvcm06IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIF9hdmF0YXJVc2VyQXZhdGFyMlsnZGVmYXVsdCddLFxuICAgICAgICAgICAgICAgIF9leHRlbmRzKHtcbiAgICAgICAgICAgICAgICAgICAgdXNlcklkOiB0aGlzLnByb3BzLml0ZW0uaWQsXG4gICAgICAgICAgICAgICAgICAgIHJpY2hDYXJkOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpbyxcbiAgICAgICAgICAgICAgICAgICAgY2FyZFNpemU6IHRoaXMucHJvcHMuc3R5bGUud2lkdGhcbiAgICAgICAgICAgICAgICB9LCBlZGl0YWJsZVByb3BzKSxcbiAgICAgICAgICAgICAgICBlZGl0Rm9ybVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH07XG5cbiAgICByZXR1cm4gVXNlckNhcmQ7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5Vc2VyQ2FyZC5wcm9wVHlwZXMgPSB7XG4gICAgLyoqXG4gICAgICogUHlkaW8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBweWRpbzogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW8pLFxuICAgIC8qKlxuICAgICAqIFRlYW0gZGF0YSBvYmplY3RcbiAgICAgKi9cbiAgICBpdGVtOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgIC8qKlxuICAgICAqIEFwcGxpZWQgdG8gcm9vdCBjb250YWluZXJcbiAgICAgKi9cbiAgICBzdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAvKipcbiAgICAgKiBDYWxsZWQgdG8gZGlzbWlzcyB0aGUgcG9wb3ZlclxuICAgICAqL1xuICAgIG9uUmVxdWVzdENsb3NlOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAvKipcbiAgICAgKiBEZWxldGUgY3VycmVudCB0ZWFtXG4gICAgICovXG4gICAgb25EZWxldGVBY3Rpb246IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSBjdXJyZW50IHRlYW1cbiAgICAgKi9cbiAgICBvblVwZGF0ZUFjdGlvbjogUmVhY3QuUHJvcFR5cGVzLmZ1bmNcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFVzZXJDYXJkO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9hdmF0YXJVc2VyQXZhdGFyID0gcmVxdWlyZSgnLi4vYXZhdGFyL1VzZXJBdmF0YXInKTtcblxudmFyIF9hdmF0YXJVc2VyQXZhdGFyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2F2YXRhclVzZXJBdmF0YXIpO1xuXG52YXIgX3ZpZXdzRW1wdHlTdGF0ZVZpZXcgPSByZXF1aXJlKCcuLi8uLi92aWV3cy9FbXB0eVN0YXRlVmlldycpO1xuXG52YXIgX3ZpZXdzRW1wdHlTdGF0ZVZpZXcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdmlld3NFbXB0eVN0YXRlVmlldyk7XG5cbnZhciBfQWxwaGFQYWdpbmF0b3IgPSByZXF1aXJlKCcuL0FscGhhUGFnaW5hdG9yJyk7XG5cbnZhciBfQWxwaGFQYWdpbmF0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQWxwaGFQYWdpbmF0b3IpO1xuXG52YXIgX1NlYXJjaEZvcm0gPSByZXF1aXJlKCcuL1NlYXJjaEZvcm0nKTtcblxudmFyIF9TZWFyY2hGb3JtMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1NlYXJjaEZvcm0pO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgSWNvbkJ1dHRvbiA9IF9yZXF1aXJlLkljb25CdXR0b247XG52YXIgQ2hlY2tib3ggPSBfcmVxdWlyZS5DaGVja2JveDtcbnZhciBGbGF0QnV0dG9uID0gX3JlcXVpcmUuRmxhdEJ1dHRvbjtcbnZhciBSYWlzZWRCdXR0b24gPSBfcmVxdWlyZS5SYWlzZWRCdXR0b247XG52YXIgTGlzdEl0ZW0gPSBfcmVxdWlyZS5MaXN0SXRlbTtcbnZhciBGb250SWNvbiA9IF9yZXF1aXJlLkZvbnRJY29uO1xudmFyIEF2YXRhciA9IF9yZXF1aXJlLkF2YXRhcjtcbnZhciBEaXZpZGVyID0gX3JlcXVpcmUuRGl2aWRlcjtcbnZhciBTdWJoZWFkZXIgPSBfcmVxdWlyZS5TdWJoZWFkZXI7XG52YXIgTGlzdCA9IF9yZXF1aXJlLkxpc3Q7XG5cbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKCdtYXRlcmlhbC11aS9zdHlsZXMnKTtcblxudmFyIG11aVRoZW1lYWJsZSA9IF9yZXF1aXJlMi5tdWlUaGVtZWFibGU7XG5cbnZhciBfcmVxdWlyZSRyZXF1aXJlTGliID0gcmVxdWlyZSgncHlkaW8nKS5yZXF1aXJlTGliKCdib290Jyk7XG5cbnZhciBMb2FkZXIgPSBfcmVxdWlyZSRyZXF1aXJlTGliLkxvYWRlcjtcbnZhciBQeWRpb0NvbnRleHRDb25zdW1lciA9IF9yZXF1aXJlJHJlcXVpcmVMaWIuUHlkaW9Db250ZXh0Q29uc3VtZXI7XG5cbnZhciBVc2Vyc0xpc3QgPSAoZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoVXNlcnNMaXN0LCBfUmVhY3QkQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIFVzZXJzTGlzdChwcm9wcywgY29udGV4dCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVXNlcnNMaXN0KTtcblxuICAgICAgICBfUmVhY3QkQ29tcG9uZW50LmNhbGwodGhpcywgcHJvcHMsIGNvbnRleHQpO1xuICAgICAgICB0aGlzLnN0YXRlID0geyBzZWxlY3Q6IGZhbHNlLCBzZWxlY3Rpb246IFtdIH07XG4gICAgfVxuXG4gICAgVXNlcnNMaXN0LnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHM7XG4gICAgICAgIHZhciBpdGVtID0gX3Byb3BzLml0ZW07XG4gICAgICAgIHZhciBtb2RlID0gX3Byb3BzLm1vZGU7XG4gICAgICAgIHZhciBwYWdpbmF0b3JUeXBlID0gX3Byb3BzLnBhZ2luYXRvclR5cGU7XG4gICAgICAgIHZhciBsb2FkaW5nID0gX3Byb3BzLmxvYWRpbmc7XG4gICAgICAgIHZhciBlbmFibGVTZWFyY2ggPSBfcHJvcHMuZW5hYmxlU2VhcmNoO1xuICAgICAgICB2YXIgc2hvd1N1YmhlYWRlcnMgPSBfcHJvcHMuc2hvd1N1YmhlYWRlcnM7XG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gX3Byb3BzLmdldE1lc3NhZ2U7XG5cbiAgICAgICAgdmFyIGZvbGRlcnMgPSBpdGVtLmNvbGxlY3Rpb25zIHx8IFtdO1xuICAgICAgICB2YXIgbGVhZnMgPSBpdGVtLmxlYWZzIHx8IFtdO1xuICAgICAgICB2YXIgZm9sZGVyc1N1YkhlYWRlciA9IGZvbGRlcnMubGVuZ3RoICYmIChsZWFmcy5sZW5ndGggfHwgc2hvd1N1YmhlYWRlcnMpID8gW3sgc3ViaGVhZGVyOiBnZXRNZXNzYWdlKCc1MzInKSB9XSA6IFtdO1xuICAgICAgICB2YXIgdXNlcnNTdWJIZWFkZXIgPSBbXTtcbiAgICAgICAgaWYgKChzaG93U3ViaGVhZGVycyB8fCBwYWdpbmF0b3JUeXBlKSAmJiBsZWFmcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHVzZXJzU3ViSGVhZGVyID0gW3sgc3ViaGVhZGVyOiBwYWdpbmF0b3JUeXBlID8gUmVhY3QuY3JlYXRlRWxlbWVudChfQWxwaGFQYWdpbmF0b3IyWydkZWZhdWx0J10sIF9leHRlbmRzKHt9LCB0aGlzLnByb3BzLCB7IHN0eWxlOiB7IGxpbmVIZWlnaHQ6ICcyMHB4JywgcGFkZGluZzogJzE0cHggMCcgfSB9KSkgOiBnZXRNZXNzYWdlKCcyNDknKSB9XTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaXRlbXMgPSBbXS5jb25jYXQoZm9sZGVyc1N1YkhlYWRlciwgZm9sZGVycywgdXNlcnNTdWJIZWFkZXIsIGxlYWZzKTtcbiAgICAgICAgdmFyIHRvdGFsID0gaXRlbXMubGVuZ3RoO1xuICAgICAgICB2YXIgZWxlbWVudHMgPSBbXTtcbiAgICAgICAgdmFyIHRvZ2dsZVNlbGVjdCA9IGZ1bmN0aW9uIHRvZ2dsZVNlbGVjdCgpIHtcbiAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgc2VsZWN0OiAhX3RoaXMuc3RhdGUuc2VsZWN0LCBzZWxlY3Rpb246IFtdIH0pO1xuICAgICAgICB9O1xuICAgICAgICB2YXIgY3JlYXRlQWN0aW9uID0gZnVuY3Rpb24gY3JlYXRlQWN0aW9uKCkge1xuICAgICAgICAgICAgX3RoaXMucHJvcHMub25DcmVhdGVBY3Rpb24oaXRlbSk7XG4gICAgICAgIH07XG4gICAgICAgIHZhciBkZWxldGVBY3Rpb24gPSBmdW5jdGlvbiBkZWxldGVBY3Rpb24oKSB7XG4gICAgICAgICAgICBfdGhpcy5wcm9wcy5vbkRlbGV0ZUFjdGlvbihpdGVtLCBfdGhpcy5zdGF0ZS5zZWxlY3Rpb24pO190aGlzLnNldFN0YXRlKHsgc2VsZWN0OiBmYWxzZSwgc2VsZWN0aW9uOiBbXSB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgYWN0aXZlVGJhckNvbG9yID0gdGhpcy5wcm9wcy5tdWlUaGVtZS5wYWxldHRlLmFjY2VudDJDb2xvcjtcbiAgICAgICAgdmFyIHRvb2xiYXIgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiB7IHBhZGRpbmc6IDEwLCBoZWlnaHQ6IDU2LCBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuc3RhdGUuc2VsZWN0ID8gYWN0aXZlVGJhckNvbG9yIDogJyNmYWZhZmEnLCBkaXNwbGF5OiAnZmxleCcsIGFsaWduSXRlbXM6ICdjZW50ZXInLCB0cmFuc2l0aW9uOiBET01VdGlscy5nZXRCZXppZXJzVHJhbnNpdGlvbigpIH0gfSxcbiAgICAgICAgICAgIG1vZGUgPT09IFwic2VsZWN0b3JcIiAmJiBpdGVtLl9wYXJlbnQgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChJY29uQnV0dG9uLCB7IGljb25DbGFzc05hbWU6ICdtZGkgbWRpLWNoZXZyb24tbGVmdCcsIG9uVG91Y2hUYXA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMucHJvcHMub25Gb2xkZXJDbGlja2VkKGl0ZW0uX3BhcmVudCk7XG4gICAgICAgICAgICAgICAgfSB9KSxcbiAgICAgICAgICAgIG1vZGUgPT09ICdib29rJyAmJiB0b3RhbCA+IDAgJiYgaXRlbS5hY3Rpb25zICYmIGl0ZW0uYWN0aW9ucy5tdWx0aXBsZSAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KENoZWNrYm94LCB7IHN0eWxlOiB7IHdpZHRoOiAnaW5pdGlhbCcsIG1hcmdpbkxlZnQ6IHRoaXMuc3RhdGUuc2VsZWN0ID8gNyA6IDE0IH0sIGNoZWNrZWQ6IHRoaXMuc3RhdGUuc2VsZWN0LCBvbkNoZWNrOiB0b2dnbGVTZWxlY3QgfSksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgZmxleDogMSwgZm9udFNpemU6IDIwLCBjb2xvcjogdGhpcy5zdGF0ZS5zZWxlY3QgPyAnd2hpdGUnIDogJ3JnYmEoMCwwLDAsMC44NyknIH0gfSxcbiAgICAgICAgICAgICAgICBpdGVtLmxhYmVsXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgbW9kZSA9PT0gJ2Jvb2snICYmIGl0ZW0uYWN0aW9ucyAmJiBpdGVtLmFjdGlvbnMuY3JlYXRlICYmICF0aGlzLnN0YXRlLnNlbGVjdCAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KEZsYXRCdXR0b24sIHsgc2Vjb25kYXJ5OiB0cnVlLCBsYWJlbDogZ2V0TWVzc2FnZShpdGVtLmFjdGlvbnMuY3JlYXRlKSwgb25Ub3VjaFRhcDogY3JlYXRlQWN0aW9uIH0pLFxuICAgICAgICAgICAgbW9kZSA9PT0gJ2Jvb2snICYmIGl0ZW0uYWN0aW9ucyAmJiBpdGVtLmFjdGlvbnMucmVtb3ZlICYmIHRoaXMuc3RhdGUuc2VsZWN0ICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoUmFpc2VkQnV0dG9uLCB7IHNlY29uZGFyeTogdHJ1ZSwgbGFiZWw6IGdldE1lc3NhZ2UoaXRlbS5hY3Rpb25zLnJlbW92ZSksIGRpc2FibGVkOiAhdGhpcy5zdGF0ZS5zZWxlY3Rpb24ubGVuZ3RoLCBvblRvdWNoVGFwOiBkZWxldGVBY3Rpb24gfSksXG4gICAgICAgICAgICBlbmFibGVTZWFyY2ggJiYgUmVhY3QuY3JlYXRlRWxlbWVudChfU2VhcmNoRm9ybTJbJ2RlZmF1bHQnXSwgeyBzZWFyY2hMYWJlbDogdGhpcy5wcm9wcy5zZWFyY2hMYWJlbCwgb25TZWFyY2g6IHRoaXMucHJvcHMub25TZWFyY2gsIHN0eWxlOiB7IGZsZXg6IDEsIG1pbldpZHRoOiAyMDAgfSB9KVxuICAgICAgICApO1xuICAgICAgICAvLyBQQVJFTlQgTk9ERVxuICAgICAgICBpZiAoaXRlbS5fcGFyZW50ICYmIG1vZGUgPT09ICdib29rJyAmJiBpdGVtLl9wYXJlbnQuX3BhcmVudCkge1xuICAgICAgICAgICAgZWxlbWVudHMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KExpc3RJdGVtLCB7XG4gICAgICAgICAgICAgICAga2V5OiAnX19wYXJlbnRfXycsXG4gICAgICAgICAgICAgICAgcHJpbWFyeVRleHQ6IFwiLi5cIixcbiAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO190aGlzLnByb3BzLm9uRm9sZGVyQ2xpY2tlZChpdGVtLl9wYXJlbnQpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGVmdEF2YXRhcjogUmVhY3QuY3JlYXRlRWxlbWVudChBdmF0YXIsIHsgaWNvbjogUmVhY3QuY3JlYXRlRWxlbWVudChGb250SWNvbiwgeyBjbGFzc05hbWU6ICdtZGkgbWRpLWFycm93LXVwJyB9KSB9KVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgaWYgKHRvdGFsKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudHMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KERpdmlkZXIsIHsgaW5zZXQ6IHRydWUsIGtleTogJ3BhcmVudC1kaXZpZGVyJyB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSVRFTVNcbiAgICAgICAgaXRlbXMuZm9yRWFjaCgoZnVuY3Rpb24gKGl0ZW0sIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKGl0ZW0uc3ViaGVhZGVyKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudHMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICBTdWJoZWFkZXIsXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGl0ZW0uc3ViaGVhZGVyXG4gICAgICAgICAgICAgICAgKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGZvbnRJY29uID0gUmVhY3QuY3JlYXRlRWxlbWVudChfYXZhdGFyVXNlckF2YXRhcjJbJ2RlZmF1bHQnXSwgeyBhdmF0YXJTaXplOiAzNiwgcHlkaW86IHRoaXMucHJvcHMucHlkaW8gfHwgcHlkaW8sXG4gICAgICAgICAgICAgICAgdXNlcklkOiBpdGVtLmlkLFxuICAgICAgICAgICAgICAgIHVzZXJMYWJlbDogaXRlbS5sYWJlbCxcbiAgICAgICAgICAgICAgICBhdmF0YXI6IGl0ZW0uYXZhdGFyLFxuICAgICAgICAgICAgICAgIGljb246IGl0ZW0uaWNvbixcbiAgICAgICAgICAgICAgICBhdmF0YXJPbmx5OiB0cnVlLFxuICAgICAgICAgICAgICAgIHVzZURlZmF1bHRBdmF0YXI6IHRydWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIHJpZ2h0SWNvbkJ1dHRvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHZhciB0b3VjaFRhcCA9IGZ1bmN0aW9uIHRvdWNoVGFwKGUpIHtcbiAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO190aGlzMi5wcm9wcy5vbkl0ZW1DbGlja2VkKGl0ZW0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChmb2xkZXJzLmluZGV4T2YoaXRlbSkgPiAtMSAmJiB0aGlzLnByb3BzLm9uRm9sZGVyQ2xpY2tlZCkge1xuICAgICAgICAgICAgICAgIHRvdWNoVGFwID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtfdGhpczIucHJvcHMub25Gb2xkZXJDbGlja2VkKGl0ZW0pO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKG1vZGUgPT09ICdzZWxlY3RvcicgJiYgIWl0ZW0uX25vdFNlbGVjdGFibGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmlnaHRJY29uQnV0dG9uID0gUmVhY3QuY3JlYXRlRWxlbWVudChJY29uQnV0dG9uLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lOiBcIm1kaSBtZGktYWNjb3VudC1tdWx0aXBsZS1wbHVzXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiBcIlNlbGVjdCB0aGlzIGdyb3VwXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwUG9zaXRpb246ICdib3R0b20tbGVmdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMyLnByb3BzLm9uSXRlbUNsaWNrZWQoaXRlbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAobW9kZSA9PT0gJ2lubmVyJyAmJiB0aGlzLnByb3BzLm9uRGVsZXRlQWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmlnaHRJY29uQnV0dG9uID0gUmVhY3QuY3JlYXRlRWxlbWVudChJY29uQnV0dG9uLCB7XG4gICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU6IFwibWRpIG1kaS1kZWxldGVcIixcbiAgICAgICAgICAgICAgICAgICAgdG9vbHRpcDogZ2V0TWVzc2FnZSgyNTcpLFxuICAgICAgICAgICAgICAgICAgICB0b29sdGlwUG9zaXRpb246ICdib3R0b20tbGVmdCcsXG4gICAgICAgICAgICAgICAgICAgIGljb25TdHlsZTogeyBjb2xvcjogJ3JnYmEoMCwwLDAsMC4xMyknLCBob3ZlckNvbG9yOiAncmdiYSgwLDAsMCwwLjUzKScgfSxcbiAgICAgICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMyLnByb3BzLm9uRGVsZXRlQWN0aW9uKF90aGlzMi5wcm9wcy5pdGVtLCBbaXRlbV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgc2VsZWN0ID0gZnVuY3Rpb24gc2VsZWN0KGUsIGNoZWNrZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoY2hlY2tlZCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpczIuc2V0U3RhdGUoeyBzZWxlY3Rpb246IFtdLmNvbmNhdChfdGhpczIuc3RhdGUuc2VsZWN0aW9uLCBbaXRlbV0pIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzdGF0ZVNlbCA9IF90aGlzMi5zdGF0ZS5zZWxlY3Rpb247XG4gICAgICAgICAgICAgICAgICAgIHZhciBzZWxlY3Rpb24gPSBbXS5jb25jYXQoc3RhdGVTZWwuc2xpY2UoMCwgc3RhdGVTZWwuaW5kZXhPZihpdGVtKSksIHN0YXRlU2VsLnNsaWNlKHN0YXRlU2VsLmluZGV4T2YoaXRlbSkgKyAxKSk7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzMi5zZXRTdGF0ZSh7IHNlbGVjdGlvbjogc2VsZWN0aW9uIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBlbGVtZW50cy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoTGlzdEl0ZW0sIHtcbiAgICAgICAgICAgICAgICBrZXk6IGl0ZW0uaWQsXG4gICAgICAgICAgICAgICAgcHJpbWFyeVRleHQ6IGl0ZW0ubGFiZWwsXG4gICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogdG91Y2hUYXAsXG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ6IG1vZGUgPT09ICdpbm5lcicsXG4gICAgICAgICAgICAgICAgbGVmdEF2YXRhcjogIXRoaXMuc3RhdGUuc2VsZWN0ICYmIGZvbnRJY29uLFxuICAgICAgICAgICAgICAgIHJpZ2h0SWNvbkJ1dHRvbjogcmlnaHRJY29uQnV0dG9uLFxuICAgICAgICAgICAgICAgIGxlZnRDaGVja2JveDogdGhpcy5zdGF0ZS5zZWxlY3QgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChDaGVja2JveCwgeyBjaGVja2VkOiB0aGlzLnN0YXRlLnNlbGVjdGlvbi5pbmRleE9mKGl0ZW0pID4gLTEsIG9uQ2hlY2s6IHNlbGVjdCB9KVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgaWYgKG1vZGUgIT09ICdpbm5lcicgJiYgaW5kZXggPCB0b3RhbCAtIDEpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoRGl2aWRlciwgeyBpbnNldDogdHJ1ZSwga2V5OiBpdGVtLmlkICsgJy1kaXZpZGVyJyB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pLmJpbmQodGhpcykpO1xuXG4gICAgICAgIHZhciBlbXB0eVN0YXRlID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoIWVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgdmFyIGVtcHR5U3RhdGVQcm9wcyA9IHtcbiAgICAgICAgICAgICAgICBzdHlsZTogeyBiYWNrZ3JvdW5kQ29sb3I6ICdyZ2IoMjUwLCAyNTAsIDI1MCknIH0sXG4gICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogJ21kaSBtZGktYWNjb3VudC1vZmYnLFxuICAgICAgICAgICAgICAgIHByaW1hcnlUZXh0SWQ6IHRoaXMucHJvcHMuZW1wdHlTdGF0ZVByaW1hcnlUZXh0IHx8IGdldE1lc3NhZ2UoNjI5KSxcbiAgICAgICAgICAgICAgICBzZWNvbmRhcnlUZXh0SWQ6IG1vZGUgPT09ICdib29rJyA/IHRoaXMucHJvcHMuZW1wdHlTdGF0ZVNlY29uZGFyeVRleHQgfHwgbnVsbCA6IG51bGxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAobW9kZSA9PT0gJ2Jvb2snICYmIGl0ZW0uYWN0aW9ucyAmJiBpdGVtLmFjdGlvbnMuY3JlYXRlKSB7XG4gICAgICAgICAgICAgICAgZW1wdHlTdGF0ZVByb3BzID0gX2V4dGVuZHMoe30sIGVtcHR5U3RhdGVQcm9wcywge1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb25MYWJlbElkOiBnZXRNZXNzYWdlKGl0ZW0uYWN0aW9ucy5jcmVhdGUpLFxuICAgICAgICAgICAgICAgICAgICBhY3Rpb25DYWxsYmFjazogY3JlYXRlQWN0aW9uXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbXB0eVN0YXRlID0gUmVhY3QuY3JlYXRlRWxlbWVudChfdmlld3NFbXB0eVN0YXRlVmlldzJbJ2RlZmF1bHQnXSwgZW1wdHlTdGF0ZVByb3BzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiB7IGZsZXg6IDEsIGZsZXhEaXJlY3Rpb246ICdjb2x1bW4nLCBkaXNwbGF5OiAnZmxleCcgfSwgb25Ub3VjaFRhcDogdGhpcy5wcm9wcy5vblRvdWNoVGFwIH0sXG4gICAgICAgICAgICBtb2RlICE9PSAnaW5uZXInICYmIC8qKCFlbXB0eVN0YXRlIHx8IG1vZGUgIT09ICdib29rJykgJiYqLyF0aGlzLnByb3BzLm5vVG9vbGJhciAmJiB0b29sYmFyLFxuICAgICAgICAgICAgIWVtcHR5U3RhdGUgJiYgIWxvYWRpbmcgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBMaXN0LFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgZmxleDogMSwgb3ZlcmZsb3dZOiBtb2RlICE9PSAnaW5uZXInID8gJ2F1dG8nIDogJ2luaXRpYWwnIH0gfSxcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnN1YkhlYWRlciAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICBTdWJoZWFkZXIsXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuc3ViSGVhZGVyXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBlbGVtZW50c1xuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIGxvYWRpbmcgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChMb2FkZXIsIHsgc3R5bGU6IHsgZmxleDogMSB9IH0pLFxuICAgICAgICAgICAgIWxvYWRpbmcgJiYgZW1wdHlTdGF0ZVxuICAgICAgICApO1xuICAgIH07XG5cbiAgICByZXR1cm4gVXNlcnNMaXN0O1xufSkoUmVhY3QuQ29tcG9uZW50KTtcblxuVXNlcnNMaXN0LnByb3BUeXBlcyA9IHtcbiAgICBpdGVtOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgIG9uQ3JlYXRlQWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICBvbkRlbGV0ZUFjdGlvbjogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgb25JdGVtQ2xpY2tlZDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgb25Gb2xkZXJDbGlja2VkOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICBtb2RlOiBSZWFjdC5Qcm9wVHlwZXMub25lT2YoWydib29rJywgJ3NlbGVjdG9yJywgJ2lubmVyJ10pXG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBVc2Vyc0xpc3QgPSBQeWRpb0NvbnRleHRDb25zdW1lcihVc2Vyc0xpc3QpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gVXNlcnNMaXN0ID0gbXVpVGhlbWVhYmxlKCkoVXNlcnNMaXN0KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gVXNlcnNMaXN0O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9hZGRyZXNzYm9va0FkZHJlc3NCb29rID0gcmVxdWlyZSgnLi4vYWRkcmVzc2Jvb2svQWRkcmVzc0Jvb2snKTtcblxudmFyIF9hZGRyZXNzYm9va0FkZHJlc3NCb29rMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2FkZHJlc3Nib29rQWRkcmVzc0Jvb2spO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdweWRpby9odHRwL3VzZXJzLWFwaScpO1xuXG52YXIgVXNlcnNBcGkgPSBfcmVxdWlyZS5Vc2Vyc0FwaTtcblxudmFyIFJlc291cmNlc01hbmFnZXIgPSByZXF1aXJlKCdweWRpby9odHRwL3Jlc291cmNlcy1tYW5hZ2VyJyk7XG5cbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgSWNvbkJ1dHRvbiA9IF9yZXF1aXJlMi5JY29uQnV0dG9uO1xudmFyIFBvcG92ZXIgPSBfcmVxdWlyZTIuUG9wb3ZlcjtcblxudmFyIF9yZXF1aXJlMyA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpL3N0eWxlcycpO1xuXG52YXIgbXVpVGhlbWVhYmxlID0gX3JlcXVpcmUzLm11aVRoZW1lYWJsZTtcblxudmFyIF9yZXF1aXJlJHJlcXVpcmVMaWIgPSByZXF1aXJlKCdweWRpbycpLnJlcXVpcmVMaWIoJ2Jvb3QnKTtcblxudmFyIFB5ZGlvQ29udGV4dENvbnN1bWVyID0gX3JlcXVpcmUkcmVxdWlyZUxpYi5QeWRpb0NvbnRleHRDb25zdW1lcjtcbnZhciBBc3luY0NvbXBvbmVudCA9IF9yZXF1aXJlJHJlcXVpcmVMaWIuQXN5bmNDb21wb25lbnQ7XG5cbnZhciBBY3Rpb25zUGFuZWwgPSAoZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoQWN0aW9uc1BhbmVsLCBfUmVhY3QkQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIEFjdGlvbnNQYW5lbChwcm9wcywgY29udGV4dCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQWN0aW9uc1BhbmVsKTtcblxuICAgICAgICBfUmVhY3QkQ29tcG9uZW50LmNhbGwodGhpcywgcHJvcHMsIGNvbnRleHQpO1xuICAgICAgICB0aGlzLnN0YXRlID0geyBzaG93UGlja2VyOiBmYWxzZSwgcGlja2VyQW5jaG9yOiBudWxsLCBzaG93TWFpbGVyOiBmYWxzZSwgbWFpbGVyQW5jaG9yOiBudWxsIH07XG4gICAgfVxuXG4gICAgQWN0aW9uc1BhbmVsLnByb3RvdHlwZS5vblRlYW1TZWxlY3RlZCA9IGZ1bmN0aW9uIG9uVGVhbVNlbGVjdGVkKGl0ZW0pIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dQaWNrZXI6IGZhbHNlIH0pO1xuICAgICAgICBpZiAoaXRlbS5nZXRUeXBlKCkgPT09ICdncm91cCcgJiYgaXRlbS5nZXRJZCgpLmluZGV4T2YoJy9BSlhQX1RFQU0vJykgPT09IDApIHtcbiAgICAgICAgICAgIFVzZXJzQXBpLmFkZFVzZXJUb1RlYW0oaXRlbS5nZXRJZCgpLnJlcGxhY2UoJy9BSlhQX1RFQU0vJywgJycpLCB0aGlzLnByb3BzLnVzZXJJZCwgdGhpcy5wcm9wcy5yZWxvYWRBY3Rpb24pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIEFjdGlvbnNQYW5lbC5wcm90b3R5cGUub25Vc2VyU2VsZWN0ZWQgPSBmdW5jdGlvbiBvblVzZXJTZWxlY3RlZChpdGVtKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93UGlja2VyOiBmYWxzZSB9KTtcbiAgICAgICAgVXNlcnNBcGkuYWRkVXNlclRvVGVhbSh0aGlzLnByb3BzLnRlYW0uaWQsIGl0ZW0uZ2V0SWQoKSwgdGhpcy5wcm9wcy5yZWxvYWRBY3Rpb24pO1xuICAgIH07XG5cbiAgICBBY3Rpb25zUGFuZWwucHJvdG90eXBlLm9wZW5QaWNrZXIgPSBmdW5jdGlvbiBvcGVuUGlja2VyKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93UGlja2VyOiB0cnVlLCBwaWNrZXJBbmNob3I6IGV2ZW50LmN1cnJlbnRUYXJnZXQgfSk7XG4gICAgfTtcblxuICAgIEFjdGlvbnNQYW5lbC5wcm90b3R5cGUub3Blbk1haWxlciA9IGZ1bmN0aW9uIG9wZW5NYWlsZXIoZXZlbnQpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB2YXIgdGFyZ2V0ID0gZXZlbnQuY3VycmVudFRhcmdldDtcbiAgICAgICAgUmVzb3VyY2VzTWFuYWdlci5sb2FkQ2xhc3Nlc0FuZEFwcGx5KFsnUHlkaW9NYWlsZXInXSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBtYWlsZXJMaWJMb2FkZWQ6IHRydWUgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgc2hvd01haWxlcjogdHJ1ZSwgbWFpbGVyQW5jaG9yOiB0YXJnZXQgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIEFjdGlvbnNQYW5lbC5wcm90b3R5cGUuY29tcG9uZW50RGlkVXBkYXRlID0gZnVuY3Rpb24gY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wcywgcHJldlN0YXRlKSB7XG4gICAgICAgIGlmICghdGhpcy5wcm9wcy5sb2NrT25TdWJQb3BvdmVyT3BlbikgcmV0dXJuO1xuICAgICAgICBpZiAoKHRoaXMuc3RhdGUuc2hvd1BpY2tlciB8fCB0aGlzLnN0YXRlLnNob3dNYWlsZXIpICYmICEocHJldlN0YXRlLnNob3dQaWNrZXIgfHwgcHJldlN0YXRlLnNob3dNYWlsZXIpKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLmxvY2tPblN1YlBvcG92ZXJPcGVuKHRydWUpO1xuICAgICAgICB9IGVsc2UgaWYgKCEodGhpcy5zdGF0ZS5zaG93UGlja2VyIHx8IHRoaXMuc3RhdGUuc2hvd01haWxlcikgJiYgKHByZXZTdGF0ZS5zaG93UGlja2VyIHx8IHByZXZTdGF0ZS5zaG93TWFpbGVyKSkge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5sb2NrT25TdWJQb3BvdmVyT3BlbihmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgQWN0aW9uc1BhbmVsLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgZ2V0TWVzc2FnZSA9IF9wcm9wcy5nZXRNZXNzYWdlO1xuICAgICAgICB2YXIgbXVpVGhlbWUgPSBfcHJvcHMubXVpVGhlbWU7XG4gICAgICAgIHZhciB0ZWFtID0gX3Byb3BzLnRlYW07XG4gICAgICAgIHZhciB1c2VyID0gX3Byb3BzLnVzZXI7XG4gICAgICAgIHZhciB1c2VyRWRpdGFibGUgPSBfcHJvcHMudXNlckVkaXRhYmxlO1xuXG4gICAgICAgIHZhciBzdHlsZXMgPSB7XG4gICAgICAgICAgICBidXR0b246IHtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IG11aVRoZW1lLnBhbGV0dGUuYWNjZW50MkNvbG9yLFxuICAgICAgICAgICAgICAgIGJvcmRlclJhZGl1czogJzUwJScsXG4gICAgICAgICAgICAgICAgbWFyZ2luOiAnMCA0cHgnLFxuICAgICAgICAgICAgICAgIHdpZHRoOiA0NCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IDQ0LFxuICAgICAgICAgICAgICAgIHBhZGRpbmc6IDEwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaWNvbjoge1xuICAgICAgICAgICAgICAgIGNvbG9yOiAnd2hpdGUnXG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHZhciBtYWlsZXIgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICB1c2VybWFpbHMgPSB7fTtcbiAgICAgICAgdmFyIGFjdGlvbnMgPSBbXTtcbiAgICAgICAgaWYgKHVzZXIgJiYgdXNlci5oYXNFbWFpbCkge1xuICAgICAgICAgICAgYWN0aW9ucy5wdXNoKHsga2V5OiAnbWVzc2FnZScsIGxhYmVsOiBnZXRNZXNzYWdlKDU5OCksIGljb246ICdlbWFpbCcsIGNhbGxiYWNrOiB0aGlzLm9wZW5NYWlsZXIuYmluZCh0aGlzKSB9KTtcbiAgICAgICAgICAgIHVzZXJtYWlsc1t0aGlzLnByb3BzLnVzZXIuaWRdID0gUHlkaW9Vc2Vycy5Vc2VyLmZyb21PYmplY3QodGhpcy5wcm9wcy51c2VyKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGVhbSkge1xuICAgICAgICAgICAgYWN0aW9ucy5wdXNoKHsga2V5OiAndXNlcnMnLCBsYWJlbDogZ2V0TWVzc2FnZSg1OTkpLCBpY29uOiAnYWNjb3VudC1tdWx0aXBsZS1wbHVzJywgY2FsbGJhY2s6IHRoaXMub3BlblBpY2tlci5iaW5kKHRoaXMpIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWN0aW9ucy5wdXNoKHsga2V5OiAndGVhbXMnLCBsYWJlbDogZ2V0TWVzc2FnZSg1NzMpLCBpY29uOiAnYWNjb3VudC1tdWx0aXBsZS1wbHVzJywgY2FsbGJhY2s6IHRoaXMub3BlblBpY2tlci5iaW5kKHRoaXMpIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh1c2VyRWRpdGFibGUpIHtcbiAgICAgICAgICAgIGFjdGlvbnMucHVzaCh7IGtleTogJ2VkaXQnLCBsYWJlbDogdGhpcy5wcm9wcy50ZWFtID8gZ2V0TWVzc2FnZSg1ODApIDogZ2V0TWVzc2FnZSg2MDApLCBpY29uOiAncGVuY2lsJywgY2FsbGJhY2s6IHRoaXMucHJvcHMub25FZGl0QWN0aW9uIH0pO1xuICAgICAgICAgICAgYWN0aW9ucy5wdXNoKHsga2V5OiAnZGVsZXRlJywgbGFiZWw6IHRoaXMucHJvcHMudGVhbSA/IGdldE1lc3NhZ2UoNTcwKSA6IGdldE1lc3NhZ2UoNTgyKSwgaWNvbjogJ2RlbGV0ZScsIGNhbGxiYWNrOiB0aGlzLnByb3BzLm9uRGVsZXRlQWN0aW9uIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgc3R5bGU6IHsgdGV4dEFsaWduOiAnY2VudGVyJywgbWFyZ2luQm90dG9tOiAxNiB9IH0sXG4gICAgICAgICAgICBhY3Rpb25zLm1hcChmdW5jdGlvbiAoYSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KEljb25CdXR0b24sIHtcbiAgICAgICAgICAgICAgICAgICAga2V5OiBhLmtleSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHN0eWxlcy5idXR0b24sXG4gICAgICAgICAgICAgICAgICAgIGljb25TdHlsZTogc3R5bGVzLmljb24sXG4gICAgICAgICAgICAgICAgICAgIHRvb2x0aXA6IGEubGFiZWwsXG4gICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU6IFwibWRpIG1kaS1cIiArIGEuaWNvbixcbiAgICAgICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogYS5jYWxsYmFja1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFBvcG92ZXIsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBvcGVuOiB0aGlzLnN0YXRlLnNob3dQaWNrZXIsXG4gICAgICAgICAgICAgICAgICAgIGFuY2hvckVsOiB0aGlzLnN0YXRlLnBpY2tlckFuY2hvcixcbiAgICAgICAgICAgICAgICAgICAgYW5jaG9yT3JpZ2luOiB7IGhvcml6b250YWw6ICdyaWdodCcsIHZlcnRpY2FsOiAndG9wJyB9LFxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRPcmlnaW46IHsgaG9yaXpvbnRhbDogJ3JpZ2h0JywgdmVydGljYWw6ICd0b3AnIH0sXG4gICAgICAgICAgICAgICAgICAgIG9uUmVxdWVzdENsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpczIuc2V0U3RhdGUoeyBzaG93UGlja2VyOiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgdXNlTGF5ZXJGb3JDbGlja0F3YXk6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogeyB6SW5kZXg6IDIyMDAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgd2lkdGg6IDI1NiwgaGVpZ2h0OiAzMjAgfSB9LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KF9hZGRyZXNzYm9va0FkZHJlc3NCb29rMlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtb2RlOiAnc2VsZWN0b3InLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHlkaW86IHRoaXMucHJvcHMucHlkaW8sXG4gICAgICAgICAgICAgICAgICAgICAgICBsb2FkZXJTdHlsZTogeyB3aWR0aDogMzIwLCBoZWlnaHQ6IDQyMCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgb25JdGVtU2VsZWN0ZWQ6IHRoaXMucHJvcHMudGVhbSA/IHRoaXMub25Vc2VyU2VsZWN0ZWQuYmluZCh0aGlzKSA6IHRoaXMub25UZWFtU2VsZWN0ZWQuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRlYW1zT25seTogdGhpcy5wcm9wcy50ZWFtID8gZmFsc2UgOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlcnNPbmx5OiB0aGlzLnByb3BzLnRlYW0gPyB0cnVlIDogZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBQb3BvdmVyLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgb3BlbjogdGhpcy5zdGF0ZS5zaG93TWFpbGVyLFxuICAgICAgICAgICAgICAgICAgICBhbmNob3JFbDogdGhpcy5zdGF0ZS5tYWlsZXJBbmNob3IsXG4gICAgICAgICAgICAgICAgICAgIGFuY2hvck9yaWdpbjogeyBob3Jpem9udGFsOiAncmlnaHQnLCB2ZXJ0aWNhbDogJ3RvcCcgfSxcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0T3JpZ2luOiB7IGhvcml6b250YWw6ICdyaWdodCcsIHZlcnRpY2FsOiAndG9wJyB9LFxuICAgICAgICAgICAgICAgICAgICB1c2VMYXllckZvckNsaWNrQXdheTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7IHpJbmRleDogMjIwMCB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyB3aWR0aDogMjU2LCBoZWlnaHQ6IDMyMCB9IH0sXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUubWFpbGVyTGliTG9hZGVkICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoQXN5bmNDb21wb25lbnQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZTogJ1B5ZGlvTWFpbGVyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICdQYW5lJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHpEZXB0aDogMCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhbmVsVGl0bGU6IGdldE1lc3NhZ2UoNTk4KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHVuaXF1ZVVzZXJTdHlsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZXJzOiB1c2VybWFpbHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkRpc21pc3M6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpczIuc2V0U3RhdGUoeyBzaG93TWFpbGVyOiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkZpZWxkRm9jdXM6IHRoaXMucHJvcHMub3RoZXJQb3BvdmVyTW91c2VPdmVyXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH07XG5cbiAgICByZXR1cm4gQWN0aW9uc1BhbmVsO1xufSkoUmVhY3QuQ29tcG9uZW50KTtcblxuQWN0aW9uc1BhbmVsLnByb3BUeXBlcyA9IHtcblxuICAgIC8qKlxuICAgICAqIFVzZXIgZGF0YSwgcHJvcHMgbXVzdCBwYXNzIGF0IGxlYXN0IG9uZSBvZiAndXNlcicgb3IgJ3RlYW0nXG4gICAgICovXG4gICAgdXNlcjogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAvKipcbiAgICAgKiBUZWFtIGRhdGEsIHByb3BzIG11c3QgcGFzcyBhdCBsZWFzdCBvbmUgb2YgJ3VzZXInIG9yICd0ZWFtJ1xuICAgICAqL1xuICAgIHRlYW06IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICogRm9yIHVzZXJzLCB3aGV0aGVyIGl0IGlzIGVkaXRhYmxlIG9yIG5vdFxuICAgICAqL1xuICAgIHVzZXJFZGl0YWJsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdFxuXG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBBY3Rpb25zUGFuZWwgPSBQeWRpb0NvbnRleHRDb25zdW1lcihBY3Rpb25zUGFuZWwpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gQWN0aW9uc1BhbmVsID0gbXVpVGhlbWVhYmxlKCkoQWN0aW9uc1BhbmVsKTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gQWN0aW9uc1BhbmVsO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9hZGRyZXNzYm9va1VzZXJzTGlzdCA9IHJlcXVpcmUoJy4uL2FkZHJlc3Nib29rL1VzZXJzTGlzdCcpO1xuXG52YXIgX2FkZHJlc3Nib29rVXNlcnNMaXN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2FkZHJlc3Nib29rVXNlcnNMaXN0KTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIENvbXBvbmVudCA9IF9yZXF1aXJlLkNvbXBvbmVudDtcbnZhciBQcm9wVHlwZXMgPSBfcmVxdWlyZS5Qcm9wVHlwZXM7XG5cbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgRGl2aWRlciA9IF9yZXF1aXJlMi5EaXZpZGVyO1xuXG52YXIgX3JlcXVpcmUzID0gcmVxdWlyZSgncHlkaW8vaHR0cC91c2Vycy1hcGknKTtcblxudmFyIFVzZXJzQXBpID0gX3JlcXVpcmUzLlVzZXJzQXBpO1xuXG52YXIgX3JlcXVpcmUkcmVxdWlyZUxpYiA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgUHlkaW9Db250ZXh0Q29uc3VtZXIgPSBfcmVxdWlyZSRyZXF1aXJlTGliLlB5ZGlvQ29udGV4dENvbnN1bWVyO1xuXG4vKipcbiAqIERpc3BsYXkgaW5mb3JtYXRpb24gYWJvdXQgdXNlciBvciB0ZWFtIHJlbGF0aW9uc1xuICovXG5cbnZhciBHcmFwaFBhbmVsID0gKGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7XG4gICAgX2luaGVyaXRzKEdyYXBoUGFuZWwsIF9Db21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gR3JhcGhQYW5lbCgpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEdyYXBoUGFuZWwpO1xuXG4gICAgICAgIF9Db21wb25lbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBHcmFwaFBhbmVsLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgZ3JhcGggPSBfcHJvcHMuZ3JhcGg7XG4gICAgICAgIHZhciB1c2VyTGFiZWwgPSBfcHJvcHMudXNlckxhYmVsO1xuICAgICAgICB2YXIgcHlkaW8gPSBfcHJvcHMucHlkaW87XG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gX3Byb3BzLmdldE1lc3NhZ2U7XG5cbiAgICAgICAgdmFyIGVsZW1lbnRzID0gW107XG4gICAgICAgIGlmIChncmFwaC50ZWFtcyAmJiBncmFwaC50ZWFtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHZhciBvbkRlbGV0ZUFjdGlvbiA9IChmdW5jdGlvbiAocGFyZW50SXRlbSwgdGVhbSkge1xuICAgICAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgICAgICAgICBVc2Vyc0FwaS5yZW1vdmVVc2VyRnJvbVRlYW0odGVhbVswXS5pZCwgdGhpcy5wcm9wcy51c2VySWQsIGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UubWVzc2FnZSkgcHlkaW8uVUkuZGlzcGxheU1lc3NhZ2UoJ1NVQ0NFU1MnLCByZXNwb25zZS5tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMucHJvcHMucmVsb2FkQWN0aW9uKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgZWxlbWVudHMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsga2V5OiAndGVhbXMnIH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChEaXZpZGVyLCBudWxsKSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KF9hZGRyZXNzYm9va1VzZXJzTGlzdDJbJ2RlZmF1bHQnXSwgeyBzdWJIZWFkZXI6IGdldE1lc3NhZ2UoNTgxKS5yZXBsYWNlKCclcycsIGdyYXBoLnRlYW1zLmxlbmd0aCksIG9uSXRlbUNsaWNrZWQ6IGZ1bmN0aW9uICgpIHt9LCBpdGVtOiB7IGxlYWZzOiBncmFwaC50ZWFtcyB9LCBtb2RlOiAnaW5uZXInLCBvbkRlbGV0ZUFjdGlvbjogb25EZWxldGVBY3Rpb24gfSlcbiAgICAgICAgICAgICkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChncmFwaC5zb3VyY2UgJiYgT2JqZWN0LmtleXMoZ3JhcGguc291cmNlKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGVsZW1lbnRzLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGtleTogJ3NvdXJjZScgfSxcbiAgICAgICAgICAgICAgICBlbGVtZW50cy5sZW5ndGggPyBSZWFjdC5jcmVhdGVFbGVtZW50KERpdmlkZXIsIG51bGwpIDogbnVsbCxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyBwYWRkaW5nOiAxNiB9IH0sXG4gICAgICAgICAgICAgICAgICAgIGdldE1lc3NhZ2UoNjAxKS5yZXBsYWNlKCclMScsIHVzZXJMYWJlbCkucmVwbGFjZSgnJTInLCBPYmplY3Qua2V5cyhncmFwaC5zb3VyY2UpLmxlbmd0aClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZ3JhcGgudGFyZ2V0ICYmIE9iamVjdC5rZXlzKGdyYXBoLnRhcmdldCkubGVuZ3RoKSB7XG4gICAgICAgICAgICBlbGVtZW50cy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBrZXk6ICd0YXJnZXQnIH0sXG4gICAgICAgICAgICAgICAgZWxlbWVudHMubGVuZ3RoID8gUmVhY3QuY3JlYXRlRWxlbWVudChEaXZpZGVyLCBudWxsKSA6IG51bGwsXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgcGFkZGluZzogMTYgfSB9LFxuICAgICAgICAgICAgICAgICAgICBnZXRNZXNzYWdlKDYwMikucmVwbGFjZSgnJTEnLCB1c2VyTGFiZWwpLnJlcGxhY2UoJyUyJywgT2JqZWN0LmtleXMoZ3JhcGgudGFyZ2V0KS5sZW5ndGgpXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICBlbGVtZW50c1xuICAgICAgICApO1xuICAgIH07XG5cbiAgICByZXR1cm4gR3JhcGhQYW5lbDtcbn0pKENvbXBvbmVudCk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEdyYXBoUGFuZWwgPSBQeWRpb0NvbnRleHRDb25zdW1lcihHcmFwaFBhbmVsKTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEdyYXBoUGFuZWw7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX0dyYXBoUGFuZWwgPSByZXF1aXJlKCcuL0dyYXBoUGFuZWwnKTtcblxudmFyIF9HcmFwaFBhbmVsMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0dyYXBoUGFuZWwpO1xuXG52YXIgX0FjdGlvbnNQYW5lbCA9IHJlcXVpcmUoJy4vQWN0aW9uc1BhbmVsJyk7XG5cbnZhciBfQWN0aW9uc1BhbmVsMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0FjdGlvbnNQYW5lbCk7XG5cbnZhciBkZWJvdW5jZSA9IHJlcXVpcmUoJ2xvZGFzaC5kZWJvdW5jZScpO1xudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcbnZhciBDb2xvciA9IHJlcXVpcmUoJ2NvbG9yJyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBGb250SWNvbiA9IF9yZXF1aXJlLkZvbnRJY29uO1xudmFyIFBvcG92ZXIgPSBfcmVxdWlyZS5Qb3BvdmVyO1xudmFyIFBhcGVyID0gX3JlcXVpcmUuUGFwZXI7XG52YXIgQXZhdGFyID0gX3JlcXVpcmUuQXZhdGFyO1xudmFyIENhcmRUaXRsZSA9IF9yZXF1aXJlLkNhcmRUaXRsZTtcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpL3N0eWxlcycpO1xuXG52YXIgbXVpVGhlbWVhYmxlID0gX3JlcXVpcmUyLm11aVRoZW1lYWJsZTtcblxudmFyIE1ldGFDYWNoZVNlcnZpY2UgPSByZXF1aXJlKCdweWRpby9odHRwL21ldGEtY2FjaGUtc2VydmljZScpO1xudmFyIFB5ZGlvQXBpID0gcmVxdWlyZSgncHlkaW8vaHR0cC9hcGknKTtcblxuLyoqXG4gKiBHZW5lcmljIGNvbXBvbmVudCBmb3IgZGlzcGxheSBhIHVzZXIgYW5kIGhlciBhdmF0YXIgKGZpcnN0IGxldHRlcnMgb3IgcGhvdG8pXG4gKi9cblxudmFyIFVzZXJBdmF0YXIgPSAoZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoVXNlckF2YXRhciwgX1JlYWN0JENvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBVc2VyQXZhdGFyKHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBVc2VyQXZhdGFyKTtcblxuICAgICAgICBfUmVhY3QkQ29tcG9uZW50LmNhbGwodGhpcywgcHJvcHMsIGNvbnRleHQpO1xuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgdXNlcjogbnVsbCxcbiAgICAgICAgICAgIGF2YXRhcjogbnVsbCxcbiAgICAgICAgICAgIGdyYXBoOiBudWxsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgVXNlckF2YXRhci5wcm90b3R5cGUuY29tcG9uZW50RGlkTW91bnQgPSBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMucHlkaW8udXNlciAmJiB0aGlzLnByb3BzLnB5ZGlvLnVzZXIuaWQgPT09IHRoaXMucHJvcHMudXNlcklkKSB7XG4gICAgICAgICAgICB0aGlzLmxvYWRMb2NhbERhdGEoKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5fdXNlckxvZ2dlZE9icykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3VzZXJMb2dnZWRPYnMgPSB0aGlzLmxvYWRMb2NhbERhdGEuYmluZCh0aGlzKTtcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnB5ZGlvLm9ic2VydmUoJ3VzZXJfbG9nZ2VkJywgdGhpcy5fdXNlckxvZ2dlZE9icyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy51c2VyVHlwZSA9PT0gJ3VzZXInKSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlID0gTWV0YUNhY2hlU2VydmljZS5nZXRJbnN0YW5jZSgpO1xuICAgICAgICAgICAgdGhpcy5jYWNoZS5yZWdpc3Rlck1ldGFTdHJlYW0oJ3VzZXJfcHVibGljX2RhdGEnLCAnRVhQSVJBVElPTl9NQU5VQUxfVFJJR0dFUicpO1xuICAgICAgICAgICAgdGhpcy5jYWNoZS5yZWdpc3Rlck1ldGFTdHJlYW0oJ3VzZXJfcHVibGljX2RhdGEtcmljaCcsICdFWFBJUkFUSU9OX01BTlVBTF9UUklHR0VSJyk7XG4gICAgICAgICAgICB0aGlzLmxvYWRQdWJsaWNEYXRhKHRoaXMucHJvcHMudXNlcklkKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBVc2VyQXZhdGFyLnByb3RvdHlwZS5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzID0gZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHtcbiAgICAgICAgaWYgKCF0aGlzLnByb3BzLnVzZXJJZCB8fCB0aGlzLnByb3BzLnVzZXJJZCAhPT0gbmV4dFByb3BzLnVzZXJJZCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGxhYmVsOiBuZXh0UHJvcHMudXNlcklkIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnB5ZGlvICYmIHRoaXMucHJvcHMucHlkaW8udXNlciAmJiB0aGlzLnByb3BzLnB5ZGlvLnVzZXIuaWQgPT09IG5leHRQcm9wcy51c2VySWQpIHtcbiAgICAgICAgICAgIHRoaXMubG9hZExvY2FsRGF0YSgpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLl91c2VyTG9nZ2VkT2JzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdXNlckxvZ2dlZE9icyA9IHRoaXMubG9hZExvY2FsRGF0YS5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMucHlkaW8ub2JzZXJ2ZSgndXNlcl9sb2dnZWQnLCB0aGlzLl91c2VyTG9nZ2VkT2JzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl91c2VyTG9nZ2VkT2JzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5weWRpby5zdG9wT2JzZXJ2aW5nKCd1c2VyX2xvZ2dlZCcsIHRoaXMuX3VzZXJMb2dnZWRPYnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jYWNoZSA9IE1ldGFDYWNoZVNlcnZpY2UuZ2V0SW5zdGFuY2UoKTtcbiAgICAgICAgICAgIHRoaXMuY2FjaGUucmVnaXN0ZXJNZXRhU3RyZWFtKCd1c2VyX3B1YmxpY19kYXRhJywgJ0VYUElSQVRJT05fTUFOVUFMX1RSSUdHRVInKTtcbiAgICAgICAgICAgIHRoaXMuY2FjaGUucmVnaXN0ZXJNZXRhU3RyZWFtKCd1c2VyX3B1YmxpY19kYXRhLXJpY2gnLCAnRVhQSVJBVElPTl9NQU5VQUxfVFJJR0dFUicpO1xuICAgICAgICAgICAgdGhpcy5sb2FkUHVibGljRGF0YShuZXh0UHJvcHMudXNlcklkKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBVc2VyQXZhdGFyLnByb3RvdHlwZS5jb21wb25lbnRXaWxsVW5tb3VudCA9IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICBpZiAodGhpcy5fdXNlckxvZ2dlZE9icykge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5weWRpby5zdG9wT2JzZXJ2aW5nKCd1c2VyX2xvZ2dlZCcsIHRoaXMuX3VzZXJMb2dnZWRPYnMpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIFVzZXJBdmF0YXIucHJvdG90eXBlLmxvYWRMb2NhbERhdGEgPSBmdW5jdGlvbiBsb2FkTG9jYWxEYXRhKCkge1xuICAgICAgICB2YXIgcHlkaW8gPSB0aGlzLnByb3BzLnB5ZGlvO1xuXG4gICAgICAgIGlmICghcHlkaW8udXNlcikge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGxhYmVsOiAnJywgYXZhdGFyOiBudWxsIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciB1c2VyTmFtZSA9IHB5ZGlvLnVzZXIuZ2V0UHJlZmVyZW5jZSgnVVNFUl9ESVNQTEFZX05BTUUnKSB8fCBweWRpby51c2VyLmlkO1xuICAgICAgICB2YXIgYXZhdGFySWQgPSBweWRpby51c2VyLmdldFByZWZlcmVuY2UoJ2F2YXRhcicpO1xuICAgICAgICB2YXIgYXZhdGFyVXJsID0gUHlkaW9BcGkuZ2V0Q2xpZW50KCkuYnVpbGRVc2VyQXZhdGFyVXJsKHB5ZGlvLnVzZXIuaWQsIGF2YXRhcklkKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBsYWJlbDogdXNlck5hbWUsXG4gICAgICAgICAgICBhdmF0YXI6IGF2YXRhclVybFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFhdmF0YXJVcmwpIHtcbiAgICAgICAgICAgIHRoaXMubG9hZEZyb21FeHRlcm5hbFByb3ZpZGVyKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgVXNlckF2YXRhci5wcm90b3R5cGUubG9hZFB1YmxpY0RhdGEgPSBmdW5jdGlvbiBsb2FkUHVibGljRGF0YSh1c2VySWQpIHtcblxuICAgICAgICB2YXIgbmFtZXNwYWNlID0gdGhpcy5wcm9wcy5yaWNoQ2FyZCA/ICd1c2VyX3B1YmxpY19kYXRhLXJpY2gnIDogJ3VzZXJfcHVibGljX2RhdGEnO1xuICAgICAgICBpZiAodGhpcy5jYWNoZS5oYXNLZXkobmFtZXNwYWNlLCB1c2VySWQpKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHRoaXMuY2FjaGUuZ2V0QnlLZXkobmFtZXNwYWNlLCB1c2VySWQpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBQeWRpb0FwaS5nZXRDbGllbnQoKS5yZXF1ZXN0KHtcbiAgICAgICAgICAgIGdldF9hY3Rpb246ICd1c2VyX3B1YmxpY19kYXRhJyxcbiAgICAgICAgICAgIHVzZXJfaWQ6IHVzZXJJZCxcbiAgICAgICAgICAgIGdyYXBoOiB0aGlzLnByb3BzLnJpY2hDYXJkID8gJ3RydWUnIDogJ2ZhbHNlJ1xuICAgICAgICB9LCAoZnVuY3Rpb24gKHRyYW5zcG9ydCkge1xuICAgICAgICAgICAgdmFyIGRhdGEgPSB0cmFuc3BvcnQucmVzcG9uc2VKU09OO1xuICAgICAgICAgICAgaWYgKCFkYXRhIHx8IGRhdGEuZXJyb3IpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhY2hlLnNldEtleShuYW1lc3BhY2UsIHVzZXJJZCwge30pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB1c2VyID0gZGF0YS51c2VyO1xuICAgICAgICAgICAgdmFyIGdyYXBoID0gZGF0YS5ncmFwaDtcblxuICAgICAgICAgICAgdmFyIGF2YXRhclVybCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHZhciBhdmF0YXJJZCA9IHVzZXIuYXZhdGFyIHx8IG51bGw7XG4gICAgICAgICAgICB2YXIgbGFiZWwgPSB1c2VyLmxhYmVsIHx8IHVzZXJJZDtcbiAgICAgICAgICAgIGlmICghdXNlci5hdmF0YXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRGcm9tRXh0ZXJuYWxQcm92aWRlcigpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhdmF0YXJVcmwgPSBQeWRpb0FwaS5nZXRDbGllbnQoKS5idWlsZFVzZXJBdmF0YXJVcmwodXNlcklkLCBhdmF0YXJJZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmNhY2hlLnNldEtleShuYW1lc3BhY2UsIHVzZXJJZCwge1xuICAgICAgICAgICAgICAgIHVzZXI6IHVzZXIsXG4gICAgICAgICAgICAgICAgZ3JhcGg6IGdyYXBoLFxuICAgICAgICAgICAgICAgIGF2YXRhcjogYXZhdGFyVXJsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIHVzZXI6IHVzZXIsXG4gICAgICAgICAgICAgICAgZ3JhcGg6IGdyYXBoLFxuICAgICAgICAgICAgICAgIGF2YXRhcjogYXZhdGFyVXJsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgfTtcblxuICAgIFVzZXJBdmF0YXIucHJvdG90eXBlLmxvYWRGcm9tRXh0ZXJuYWxQcm92aWRlciA9IGZ1bmN0aW9uIGxvYWRGcm9tRXh0ZXJuYWxQcm92aWRlcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLnByb3BzLnB5ZGlvLmdldFBsdWdpbkNvbmZpZ3MoXCJhanhwX3BsdWdpbltAaWQ9J2FjdGlvbi5hdmF0YXInXVwiKS5nZXQoXCJBVkFUQVJfUFJPVklERVJcIikpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmFtZXNwYWNlID0gdGhpcy5wcm9wcy5yaWNoQ2FyZCA/ICd1c2VyX3B1YmxpY19kYXRhLXJpY2gnIDogJ3VzZXJfcHVibGljX2RhdGEnO1xuICAgICAgICBQeWRpb0FwaS5nZXRDbGllbnQoKS5yZXF1ZXN0KHtcbiAgICAgICAgICAgIGdldF9hY3Rpb246ICdnZXRfYXZhdGFyX3VybCcsXG4gICAgICAgICAgICB1c2VyaWQ6IHRoaXMucHJvcHMudXNlcklkXG4gICAgICAgIH0sIChmdW5jdGlvbiAodHJhbnNwb3J0KSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgYXZhdGFyOiB0cmFuc3BvcnQucmVzcG9uc2VUZXh0IH0pO1xuICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICB9O1xuXG4gICAgVXNlckF2YXRhci5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciBfc3RhdGUgPSB0aGlzLnN0YXRlO1xuICAgICAgICB2YXIgdXNlciA9IF9zdGF0ZS51c2VyO1xuICAgICAgICB2YXIgYXZhdGFyID0gX3N0YXRlLmF2YXRhcjtcbiAgICAgICAgdmFyIGdyYXBoID0gX3N0YXRlLmdyYXBoO1xuICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcztcbiAgICAgICAgdmFyIHB5ZGlvID0gX3Byb3BzLnB5ZGlvO1xuICAgICAgICB2YXIgdXNlcklkID0gX3Byb3BzLnVzZXJJZDtcbiAgICAgICAgdmFyIHVzZXJUeXBlID0gX3Byb3BzLnVzZXJUeXBlO1xuICAgICAgICB2YXIgaWNvbiA9IF9wcm9wcy5pY29uO1xuICAgICAgICB2YXIgc3R5bGUgPSBfcHJvcHMuc3R5bGU7XG4gICAgICAgIHZhciBsYWJlbFN0eWxlID0gX3Byb3BzLmxhYmVsU3R5bGU7XG4gICAgICAgIHZhciBhdmF0YXJTdHlsZSA9IF9wcm9wcy5hdmF0YXJTdHlsZTtcbiAgICAgICAgdmFyIGF2YXRhclNpemUgPSBfcHJvcHMuYXZhdGFyU2l6ZTtcbiAgICAgICAgdmFyIGNsYXNzTmFtZSA9IF9wcm9wcy5jbGFzc05hbWU7XG4gICAgICAgIHZhciBhdmF0YXJDbGFzc05hbWUgPSBfcHJvcHMuYXZhdGFyQ2xhc3NOYW1lO1xuICAgICAgICB2YXIgbGFiZWxDbGFzc05hbWUgPSBfcHJvcHMubGFiZWxDbGFzc05hbWU7XG4gICAgICAgIHZhciBkaXNwbGF5TGFiZWwgPSBfcHJvcHMuZGlzcGxheUxhYmVsO1xuICAgICAgICB2YXIgZGlzcGxheUF2YXRhciA9IF9wcm9wcy5kaXNwbGF5QXZhdGFyO1xuICAgICAgICB2YXIgdXNlRGVmYXVsdEF2YXRhciA9IF9wcm9wcy51c2VEZWZhdWx0QXZhdGFyO1xuICAgICAgICB2YXIgcmljaENhcmQgPSBfcHJvcHMucmljaENhcmQ7XG4gICAgICAgIHZhciBjYXJkU2l6ZSA9IF9wcm9wcy5jYXJkU2l6ZTtcbiAgICAgICAgdmFyIG11aVRoZW1lID0gX3Byb3BzLm11aVRoZW1lO1xuICAgICAgICB2YXIgbGFiZWwgPSB0aGlzLnN0YXRlLmxhYmVsO1xuXG4gICAgICAgIHZhciB1c2VyVHlwZUxhYmVsID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAodXNlcikge1xuICAgICAgICAgICAgbGFiZWwgPSB1c2VyLmxhYmVsO1xuICAgICAgICB9IGVsc2UgaWYgKCFsYWJlbCkge1xuICAgICAgICAgICAgbGFiZWwgPSB0aGlzLnByb3BzLnVzZXJMYWJlbCB8fCB0aGlzLnByb3BzLnVzZXJJZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBhdmF0YXJDb250ZW50ID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgYXZhdGFyQ29sb3IgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICBhdmF0YXJJY29uID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAocmljaENhcmQpIHtcbiAgICAgICAgICAgIGRpc3BsYXlBdmF0YXIgPSB1c2VEZWZhdWx0QXZhdGFyID0gZGlzcGxheUxhYmVsID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGlzcGxheUF2YXRhciAmJiAhYXZhdGFyICYmIGxhYmVsICYmICghZGlzcGxheUxhYmVsIHx8IHVzZURlZmF1bHRBdmF0YXIpKSB7XG4gICAgICAgICAgICB2YXIgYXZhdGFyc0NvbG9yID0gbXVpVGhlbWUucGFsZXR0ZS5hdmF0YXJzQ29sb3I7XG4gICAgICAgICAgICBpZiAodXNlclR5cGUgPT09ICdncm91cCcgfHwgdXNlclR5cGUgPT09ICd0ZWFtJyB8fCB1c2VySWQuaW5kZXhPZignQUpYUF9HUlBfLycpID09PSAwIHx8IHVzZXJJZC5pbmRleE9mKCcvQUpYUF9URUFNLycpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgYXZhdGFyc0NvbG9yID0gQ29sb3IoYXZhdGFyc0NvbG9yKS5kYXJrZW4oMC4yKS50b1N0cmluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGljb25DbGFzc05hbWUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBzd2l0Y2ggKHVzZXJUeXBlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnZ3JvdXAnOlxuICAgICAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lID0gJ21kaSBtZGktYWNjb3VudC1tdWx0aXBsZSc7XG4gICAgICAgICAgICAgICAgICAgIHVzZXJUeXBlTGFiZWwgPSAnMjg5JztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAndGVhbSc6XG4gICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWUgPSAnbWRpIG1kaS1hY2NvdW50LW11bHRpcGxlLW91dGxpbmUnO1xuICAgICAgICAgICAgICAgICAgICB1c2VyVHlwZUxhYmVsID0gJzYwMyc7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3JlbW90ZSc6XG4gICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWUgPSAnbWRpIG1kaS1hY2NvdW50LW5ldHdvcmsnO1xuICAgICAgICAgICAgICAgICAgICB1c2VyVHlwZUxhYmVsID0gJzYwNCc7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWUgPSAnbWRpIG1kaS1hY2NvdW50JztcbiAgICAgICAgICAgICAgICAgICAgdXNlclR5cGVMYWJlbCA9IHVzZXIgPyB1c2VyLmV4dGVybmFsID8gJzU4OScgOiAnNTkwJyA6ICcyODgnO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpY29uKSBpY29uQ2xhc3NOYW1lID0gaWNvbjtcbiAgICAgICAgICAgIGlmICh1c2VyVHlwZUxhYmVsKSB1c2VyVHlwZUxhYmVsID0gcHlkaW8uTWVzc2FnZUhhc2hbdXNlclR5cGVMYWJlbF07XG4gICAgICAgICAgICBpZiAocmljaENhcmQpIHtcbiAgICAgICAgICAgICAgICBhdmF0YXJJY29uID0gUmVhY3QuY3JlYXRlRWxlbWVudChGb250SWNvbiwgeyBjbGFzc05hbWU6IGljb25DbGFzc05hbWUsIHN0eWxlOiB7IGNvbG9yOiBhdmF0YXJzQ29sb3IgfSB9KTtcbiAgICAgICAgICAgICAgICBhdmF0YXJDb2xvciA9ICcjZjVmNWY1JztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXZhdGFyQ29sb3IgPSBhdmF0YXJzQ29sb3I7XG4gICAgICAgICAgICAgICAgaWYgKGljb25DbGFzc05hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgYXZhdGFySWNvbiA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoRm9udEljb24sIHsgY2xhc3NOYW1lOiBpY29uQ2xhc3NOYW1lIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGF2YXRhckNvbnRlbnQgPSBsYWJlbC5zcGxpdCgnICcpLm1hcChmdW5jdGlvbiAod29yZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdvcmRbMF07XG4gICAgICAgICAgICAgICAgICAgIH0pLmpvaW4oJycpLnN1YnN0cmluZygwLCAyKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF2YXRhckNvbnRlbnQubGVuZ3RoIDwgMikgYXZhdGFyQ29udGVudCA9IGxhYmVsLnN1YnN0cmluZygwLCAyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJlbG9hZEFjdGlvbiA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG9uRWRpdEFjdGlvbiA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG9uTW91c2VPdmVyID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgb25Nb3VzZU91dCA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHBvcG92ZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChyaWNoQ2FyZCkge1xuICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIGRpc3BsYXlBdmF0YXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHN0eWxlID0gX2V4dGVuZHMoe30sIHN0eWxlLCB7IGZsZXhEaXJlY3Rpb246ICdjb2x1bW4nIH0pO1xuICAgICAgICAgICAgICAgIGF2YXRhclNpemUgPSBjYXJkU2l6ZSA/IGNhcmRTaXplIDogJzEwMCUnO1xuICAgICAgICAgICAgICAgIGF2YXRhclN0eWxlID0geyBib3JkZXJSYWRpdXM6IDAgfTtcbiAgICAgICAgICAgICAgICB2YXIgbG9jYWxSZWxvYWQgPSBmdW5jdGlvbiBsb2NhbFJlbG9hZCgpIHtcbiAgICAgICAgICAgICAgICAgICAgTWV0YUNhY2hlU2VydmljZS5nZXRJbnN0YW5jZSgpLmRlbGV0ZUtleSgndXNlcl9wdWJsaWNfZGF0YS1yaWNoJywgX3RoaXMucHJvcHMudXNlcklkKTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMubG9hZFB1YmxpY0RhdGEoX3RoaXMucHJvcHMudXNlcklkKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlbG9hZEFjdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9jYWxSZWxvYWQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzLnByb3BzLnJlbG9hZEFjdGlvbikgX3RoaXMucHJvcHMucmVsb2FkQWN0aW9uKCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBvbkVkaXRBY3Rpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvY2FsUmVsb2FkKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfdGhpcy5wcm9wcy5vbkVkaXRBY3Rpb24pIF90aGlzLnByb3BzLm9uRWRpdEFjdGlvbigpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJvcHMucmljaE9uSG92ZXIpIHtcbiAgICAgICAgICAgIChmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBvbk1vdXNlT3V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIV90aGlzLmxvY2tlZEJ5U3ViUG9wb3Zlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBzaG93UG9wb3ZlcjogZmFsc2UgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG9uTW91c2VPdXQgPSBkZWJvdW5jZShvbk1vdXNlT3V0LCAzNTApO1xuICAgICAgICAgICAgICAgIG9uTW91c2VPdmVyID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBzaG93UG9wb3ZlcjogdHJ1ZSwgcG9wb3ZlckFuY2hvcjogZS5jdXJyZW50VGFyZ2V0IH0pO1xuICAgICAgICAgICAgICAgICAgICBvbk1vdXNlT3V0LmNhbmNlbCgpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdmFyIG9uTW91c2VPdmVySW5uZXIgPSBmdW5jdGlvbiBvbk1vdXNlT3ZlcklubmVyKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBzaG93UG9wb3ZlcjogdHJ1ZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgb25Nb3VzZU91dC5jYW5jZWwoKTtcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgdmFyIGxvY2tPblN1YlBvcG92ZXJPcGVuID0gZnVuY3Rpb24gbG9ja09uU3ViUG9wb3Zlck9wZW4oc3RhdHVzKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmxvY2tlZEJ5U3ViUG9wb3ZlciA9IHN0YXR1cztcbiAgICAgICAgICAgICAgICAgICAgb25Nb3VzZU92ZXJJbm5lcigpO1xuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICBwb3BvdmVyID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgUG9wb3ZlcixcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3BlbjogX3RoaXMuc3RhdGUuc2hvd1BvcG92ZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JFbDogX3RoaXMuc3RhdGUucG9wb3ZlckFuY2hvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uUmVxdWVzdENsb3NlOiBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlYXNvbiAhPT0gJ2NsaWNrQXdheScgfHwgIV90aGlzLmxvY2tlZEJ5U3ViUG9wb3Zlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IHNob3dQb3BvdmVyOiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yT3JpZ2luOiB7IGhvcml6b250YWw6IFwibGVmdFwiLCB2ZXJ0aWNhbDogXCJjZW50ZXJcIiB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0T3JpZ2luOiB7IGhvcml6b250YWw6IFwicmlnaHRcIiwgdmVydGljYWw6IFwiY2VudGVyXCIgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZUxheWVyRm9yQ2xpY2tBd2F5OiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgUGFwZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICB7IHpEZXB0aDogMiwgc3R5bGU6IHsgd2lkdGg6IDIyMCwgaGVpZ2h0OiAzMjAsIG92ZXJmbG93WTogJ2F1dG8nIH0sIG9uTW91c2VPdmVyOiBvbk1vdXNlT3ZlcklubmVyLCBvbk1vdXNlT3V0OiBvbk1vdXNlT3V0IH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFVzZXJBdmF0YXIsIF9leHRlbmRzKHt9LCBfdGhpcy5wcm9wcywgeyByaWNoQ2FyZDogdHJ1ZSwgcmljaE9uSG92ZXI6IGZhbHNlLCBjYXJkU2l6ZTogMjIwLCBsb2NrT25TdWJQb3BvdmVyT3BlbjogbG9ja09uU3ViUG9wb3Zlck9wZW4gfSkpXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBhdmF0YXJDb21wb25lbnQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgQXZhdGFyLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHNyYzogYXZhdGFyLFxuICAgICAgICAgICAgICAgIGljb246IGF2YXRhckljb24sXG4gICAgICAgICAgICAgICAgc2l6ZTogYXZhdGFyU2l6ZSxcbiAgICAgICAgICAgICAgICBzdHlsZTogdGhpcy5wcm9wcy5hdmF0YXJPbmx5ID8gdGhpcy5wcm9wcy5zdHlsZSA6IGF2YXRhclN0eWxlLFxuICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogYXZhdGFyQ29sb3JcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhdmF0YXJDb250ZW50XG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHRoaXMucHJvcHMuYXZhdGFyT25seSkge1xuICAgICAgICAgICAgcmV0dXJuIGF2YXRhckNvbXBvbmVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IGNsYXNzTmFtZTogY2xhc3NOYW1lLCBzdHlsZTogc3R5bGUsIG9uTW91c2VPdmVyOiBvbk1vdXNlT3Zlciwgb25Nb3VzZU91dDogb25Nb3VzZU91dCB9LFxuICAgICAgICAgICAgZGlzcGxheUF2YXRhciAmJiAoYXZhdGFyIHx8IGF2YXRhckNvbnRlbnQgfHwgYXZhdGFySWNvbikgJiYgYXZhdGFyQ29tcG9uZW50LFxuICAgICAgICAgICAgZGlzcGxheUxhYmVsICYmICFyaWNoQ2FyZCAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBsYWJlbENsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IGxhYmVsU3R5bGUgfSxcbiAgICAgICAgICAgICAgICBsYWJlbFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIGRpc3BsYXlMYWJlbCAmJiByaWNoQ2FyZCAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KENhcmRUaXRsZSwgeyBzdHlsZTogeyB0ZXh0QWxpZ246ICdjZW50ZXInIH0sIHRpdGxlOiBsYWJlbCwgc3VidGl0bGU6IHVzZXJUeXBlTGFiZWwgfSksXG4gICAgICAgICAgICByaWNoQ2FyZCAmJiB1c2VyICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX0FjdGlvbnNQYW5lbDJbJ2RlZmF1bHQnXSwgX2V4dGVuZHMoe30sIHRoaXMuc3RhdGUsIHRoaXMucHJvcHMsIHsgcmVsb2FkQWN0aW9uOiByZWxvYWRBY3Rpb24sIG9uRWRpdEFjdGlvbjogb25FZGl0QWN0aW9uIH0pKSxcbiAgICAgICAgICAgIGdyYXBoICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX0dyYXBoUGFuZWwyWydkZWZhdWx0J10sIF9leHRlbmRzKHsgZ3JhcGg6IGdyYXBoIH0sIHRoaXMucHJvcHMsIHsgdXNlckxhYmVsOiBsYWJlbCwgcmVsb2FkQWN0aW9uOiByZWxvYWRBY3Rpb24sIG9uRWRpdEFjdGlvbjogb25FZGl0QWN0aW9uIH0pKSxcbiAgICAgICAgICAgIHRoaXMucHJvcHMuY2hpbGRyZW4sXG4gICAgICAgICAgICBwb3BvdmVyXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBVc2VyQXZhdGFyO1xufSkoUmVhY3QuQ29tcG9uZW50KTtcblxuVXNlckF2YXRhci5wcm9wVHlwZXMgPSB7XG4gICAgLyoqXG4gICAgICogSWQgb2YgdGhlIHVzZXIgdG8gYmUgbG9hZGVkXG4gICAgICovXG4gICAgdXNlcklkOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgLyoqXG4gICAgICogUHlkaW8gaW5zdGFuY2VcbiAgICAgKi9cbiAgICBweWRpbzogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW8pLFxuICAgIC8qKlxuICAgICAqIExhYmVsIG9mIHRoZSB1c2VyLCBpZiB3ZSBhbHJlYWR5IGhhdmUgaXQgKG90aGVyd2lzZSB3aWxsIGJlIGxvYWRlZClcbiAgICAgKi9cbiAgICB1c2VyTGFiZWw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgLyoqXG4gICAgICogVHlwZSBvZiB1c2VyXG4gICAgICovXG4gICAgdXNlclR5cGU6IFJlYWN0LlByb3BUeXBlcy5vbmVPZihbJ3VzZXInLCAnZ3JvdXAnLCAncmVtb3RlJywgJ3RlYW0nXSksXG4gICAgLyoqXG4gICAgICogSWNvbiB0byBiZSBkaXNwbGF5ZWQgaW4gYXZhdGFyXG4gICAgICovXG4gICAgaWNvbjogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAvKipcbiAgICAgKiBEaXNwbGF5IGEgcmljaCBjYXJkIG9yIGEgc2ltcGxlIGF2YXRhcitsYWJlbCBjaGlwXG4gICAgICovXG4gICAgcmljaENhcmQ6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgIC8qKlxuICAgICAqIElmIG5vdCByaWNoLCBkaXNwbGF5IGEgcmljaCBjYXJkIGFzIHBvcG92ZXIgb24gbW91c2VvdmVyXG4gICAgICovXG4gICAgcmljaE9uSG92ZXI6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuXG4gICAgLyoqXG4gICAgICogQWRkIGVkaXQgYWN0aW9uIHRvIHRoZSBjYXJkXG4gICAgICovXG4gICAgdXNlckVkaXRhYmxlOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyZWQgYWZ0ZXIgc3VjY2Vzc2Z1bCBlZGl0aW9uXG4gICAgICovXG4gICAgb25FZGl0QWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyZWQgYWZ0ZXIgZGVsZXRpb25cbiAgICAgKi9cbiAgICBvbkRlbGV0ZUFjdGlvbjogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgLyoqXG4gICAgICogVHJpZ2dlcmVkIGlmIGEgcmVsb2FkIGlzIHJlcXVpcmVkXG4gICAgICovXG4gICAgcmVsb2FkQWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcblxuICAgIC8qKlxuICAgICAqIERpc3BsYXkgbGFiZWwgZWxlbWVudCBvciBub3RcbiAgICAgKi9cbiAgICBkaXNwbGF5TGFiZWw6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgIC8qKlxuICAgICAqIERpc3BsYXkgYXZhdGFyIGVsZW1lbnQgb3Igbm90XG4gICAgICovXG4gICAgZGlzcGxheUF2YXRhcjogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgLyoqXG4gICAgICogRGlzcGxheSBvbmx5IGF2YXRhclxuICAgICAqL1xuICAgIGF2YXRhck9ubHk6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgIC8qKlxuICAgICAqIFVzZSBkZWZhdWx0IGF2YXRhclxuICAgICAqL1xuICAgIHVzZURlZmF1bHRBdmF0YXI6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgIC8qKlxuICAgICAqIEF2YXRhciBzaXplLCA0MHB4IGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBhdmF0YXJTaXplOiBSZWFjdC5Qcm9wVHlwZXMubnVtYmVyLFxuXG4gICAgLyoqXG4gICAgICogQWRkIGNsYXNzIG5hbWUgdG8gcm9vdCBlbGVtZW50XG4gICAgICovXG4gICAgY2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIEFkZCBjbGFzcyBuYW1lIHRvIGxhYmVsIGVsZW1lbnRcbiAgICAgKi9cbiAgICBsYWJlbENsYXNzTmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAvKipcbiAgICAgKiBBZGQgY2xhc3MgbmFtZSB0byBhdmF0YXIgZWxlbWVudFxuICAgICAqL1xuICAgIGF2YXRhckNsYXNzTmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAvKipcbiAgICAgKiBBZGQgc3R5bGUgdG8gcm9vdCBlbGVtZW50XG4gICAgICovXG4gICAgc3R5bGU6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICogQWRkIHN0eWxlIHRvIGxhYmVsIGVsZW1lbnRcbiAgICAgKi9cbiAgICBsYWJlbFN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgIC8qKlxuICAgICAqIEFkZCBzdHlsZSB0byBhdmF0YXIgZWxlbWVudFxuICAgICAqL1xuICAgIGF2YXRhclN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0XG59O1xuXG5Vc2VyQXZhdGFyLmRlZmF1bHRQcm9wcyA9IHtcbiAgICBkaXNwbGF5TGFiZWw6IHRydWUsXG4gICAgZGlzcGxheUF2YXRhcjogdHJ1ZSxcbiAgICBhdmF0YXJTaXplOiA0MCxcbiAgICB1c2VyVHlwZTogJ3VzZXInLFxuICAgIGNsYXNzTmFtZTogJ3VzZXItYXZhdGFyLXdpZGdldCcsXG4gICAgYXZhdGFyQ2xhc3NOYW1lOiAndXNlci1hdmF0YXInLFxuICAgIGxhYmVsQ2xhc3NOYW1lOiAndXNlci1sYWJlbCdcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFVzZXJBdmF0YXIgPSBtdWlUaGVtZWFibGUoKShVc2VyQXZhdGFyKTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gVXNlckF2YXRhcjtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIEZ1bmNVdGlscyA9IHJlcXVpcmUoXCJweWRpby91dGlsL2Z1bmNcIik7XG52YXIgUmVzb3VyY2VzTWFuYWdlciA9IHJlcXVpcmUoXCJweWRpby9odHRwL3Jlc291cmNlcy1tYW5hZ2VyXCIpO1xuXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyogUkVBQ1QgRE5EIEdFTkVSSUMgQ09NUE9ORU5UU1xuIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG52YXIgVHlwZXMgPSB7XG4gICAgTk9ERV9QUk9WSURFUjogJ25vZGUnLFxuICAgIFNPUlRBQkxFX0xJU1RfSVRFTTogJ3NvcnRhYmxlLWxpc3QtaXRlbSdcbn07XG5cbi8qKlxuICogU3BlY2lmaWVzIHdoaWNoIHByb3BzIHRvIGluamVjdCBpbnRvIHlvdXIgY29tcG9uZW50LlxuICovXG5mdW5jdGlvbiBjb2xsZWN0KGNvbm5lY3QsIG1vbml0b3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBjb25uZWN0RHJhZ1NvdXJjZTogY29ubmVjdC5kcmFnU291cmNlKCksXG4gICAgICAgIGlzRHJhZ2dpbmc6IG1vbml0b3IuaXNEcmFnZ2luZygpXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gY29sbGVjdERyb3AoY29ubmVjdCwgbW9uaXRvcikge1xuICAgIHJldHVybiB7XG4gICAgICAgIGNvbm5lY3REcm9wVGFyZ2V0OiBjb25uZWN0LmRyb3BUYXJnZXQoKSxcbiAgICAgICAgY2FuRHJvcDogbW9uaXRvci5jYW5Ecm9wKCksXG4gICAgICAgIGlzT3ZlcjogbW9uaXRvci5pc092ZXIoKSxcbiAgICAgICAgaXNPdmVyQ3VycmVudDogbW9uaXRvci5pc092ZXIoeyBzaGFsbG93OiB0cnVlIH0pXG4gICAgfTtcbn1cblxudmFyIEROREFjdGlvblBhcmFtZXRlciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRE5EQWN0aW9uUGFyYW1ldGVyKHNvdXJjZSwgdGFyZ2V0LCBzdGVwKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBETkRBY3Rpb25QYXJhbWV0ZXIpO1xuXG4gICAgICAgIHRoaXMuX3NvdXJjZSA9IHNvdXJjZTtcbiAgICAgICAgdGhpcy5fdGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICB0aGlzLl9zdGVwID0gc3RlcDtcbiAgICB9XG5cbiAgICBETkRBY3Rpb25QYXJhbWV0ZXIucHJvdG90eXBlLmdldFNvdXJjZSA9IGZ1bmN0aW9uIGdldFNvdXJjZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZTtcbiAgICB9O1xuXG4gICAgRE5EQWN0aW9uUGFyYW1ldGVyLnByb3RvdHlwZS5nZXRUYXJnZXQgPSBmdW5jdGlvbiBnZXRUYXJnZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90YXJnZXQ7XG4gICAgfTtcblxuICAgIEROREFjdGlvblBhcmFtZXRlci5wcm90b3R5cGUuZ2V0U3RlcCA9IGZ1bmN0aW9uIGdldFN0ZXAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGVwO1xuICAgIH07XG5cbiAgICByZXR1cm4gRE5EQWN0aW9uUGFyYW1ldGVyO1xufSkoKTtcblxuRE5EQWN0aW9uUGFyYW1ldGVyLlNURVBfQkVHSU5fRFJBRyA9ICdiZWdpbkRyYWcnO1xuRE5EQWN0aW9uUGFyYW1ldGVyLlNURVBfRU5EX0RSQUcgPSAnZW5kRHJhZyc7XG5ETkRBY3Rpb25QYXJhbWV0ZXIuU1RFUF9DQU5fRFJPUCA9ICdjYW5Ecm9wJztcbkROREFjdGlvblBhcmFtZXRlci5TVEVQX0hPVkVSX0RST1AgPSAnaG92ZXInO1xuXG52YXIgYXBwbHlETkRBY3Rpb24gPSBmdW5jdGlvbiBhcHBseUROREFjdGlvbihzb3VyY2UsIHRhcmdldCwgc3RlcCkge1xuICAgIHZhciBDb250cm9sbGVyID0gd2luZG93LnB5ZGlvLkNvbnRyb2xsZXI7XG5cbiAgICB2YXIgZG5kID0gQ29udHJvbGxlci5kZWZhdWx0QWN0aW9ucy5nZXQoXCJkcmFnbmRyb3BcIik7XG4gICAgaWYgKGRuZCkge1xuICAgICAgICB2YXIgZG5kQWN0aW9uID0gQ29udHJvbGxlci5nZXRBY3Rpb25CeU5hbWUoZG5kKTtcbiAgICAgICAgZG5kQWN0aW9uLmVuYWJsZSgpO1xuICAgICAgICB2YXIgcGFyYW1zID0gbmV3IEROREFjdGlvblBhcmFtZXRlcihzb3VyY2UsIHRhcmdldCwgc3RlcCk7XG4gICAgICAgIHZhciBjaGVja01vZHVsZSA9IGRuZEFjdGlvbi5vcHRpb25zLmRyYWduZHJvcENoZWNrTW9kdWxlO1xuICAgICAgICBpZiAoc3RlcCA9PT0gRE5EQWN0aW9uUGFyYW1ldGVyLlNURVBfQ0FOX0RST1AgJiYgY2hlY2tNb2R1bGUpIHtcbiAgICAgICAgICAgIGlmICghRnVuY1V0aWxzLmdldEZ1bmN0aW9uQnlOYW1lKGNoZWNrTW9kdWxlLCB3aW5kb3cpKSB7XG4gICAgICAgICAgICAgICAgUmVzb3VyY2VzTWFuYWdlci5kZXRlY3RNb2R1bGVUb0xvYWRBbmRBcHBseShjaGVja01vZHVsZSwgZnVuY3Rpb24gKCkge30pO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGZpbmQgdGVzdCBtb2R1bGUsIHRyeWluZyB0byBsb2FkIGl0Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBGdW5jVXRpbHMuZXhlY3V0ZUZ1bmN0aW9uQnlOYW1lKGRuZEFjdGlvbi5vcHRpb25zLmRyYWduZHJvcENoZWNrTW9kdWxlLCB3aW5kb3csIENvbnRyb2xsZXIsIHBhcmFtcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkbmRBY3Rpb24uYXBwbHkocGFyYW1zKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gRE5EIEFjdGlvbnMgYXZhaWxhYmxlJyk7XG4gICAgfVxufTtcblxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiBSRUFDVCBETkQgRFJBRy9EUk9QIE5PREVTXG4gLyoqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxudmFyIG5vZGVEcmFnU291cmNlID0ge1xuICAgIGJlZ2luRHJhZzogZnVuY3Rpb24gYmVnaW5EcmFnKHByb3BzKSB7XG4gICAgICAgIC8vIFJldHVybiB0aGUgZGF0YSBkZXNjcmliaW5nIHRoZSBkcmFnZ2VkIGl0ZW1cbiAgICAgICAgcmV0dXJuIHsgbm9kZTogcHJvcHMubm9kZSB9O1xuICAgIH0sXG5cbiAgICBlbmREcmFnOiBmdW5jdGlvbiBlbmREcmFnKHByb3BzLCBtb25pdG9yLCBjb21wb25lbnQpIHtcbiAgICAgICAgaWYgKCFtb25pdG9yLmRpZERyb3AoKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciBpdGVtID0gbW9uaXRvci5nZXRJdGVtKCk7XG4gICAgICAgIHZhciBkcm9wUmVzdWx0ID0gbW9uaXRvci5nZXREcm9wUmVzdWx0KCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhcHBseUROREFjdGlvbihpdGVtLm5vZGUsIGRyb3BSZXN1bHQubm9kZSwgRE5EQWN0aW9uUGFyYW1ldGVyLlNURVBfRU5EX0RSQUcpO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgIH1cbn07XG5cbnZhciBub2RlRHJvcFRhcmdldCA9IHtcblxuICAgIGhvdmVyOiBmdW5jdGlvbiBob3Zlcihwcm9wcywgbW9uaXRvcikge30sXG5cbiAgICBjYW5Ecm9wOiBmdW5jdGlvbiBjYW5Ecm9wKHByb3BzLCBtb25pdG9yKSB7XG5cbiAgICAgICAgdmFyIHNvdXJjZSA9IG1vbml0b3IuZ2V0SXRlbSgpLm5vZGU7XG4gICAgICAgIHZhciB0YXJnZXQgPSBwcm9wcy5ub2RlO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhcHBseUROREFjdGlvbihzb3VyY2UsIHRhcmdldCwgRE5EQWN0aW9uUGFyYW1ldGVyLlNURVBfQ0FOX0RST1ApO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcblxuICAgIGRyb3A6IGZ1bmN0aW9uIGRyb3AocHJvcHMsIG1vbml0b3IpIHtcbiAgICAgICAgdmFyIGhhc0Ryb3BwZWRPbkNoaWxkID0gbW9uaXRvci5kaWREcm9wKCk7XG4gICAgICAgIGlmIChoYXNEcm9wcGVkT25DaGlsZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IG5vZGU6IHByb3BzLm5vZGUgfTtcbiAgICB9XG5cbn07XG5cbmV4cG9ydHMuVHlwZXMgPSBUeXBlcztcbmV4cG9ydHMuY29sbGVjdCA9IGNvbGxlY3Q7XG5leHBvcnRzLmNvbGxlY3REcm9wID0gY29sbGVjdERyb3A7XG5leHBvcnRzLm5vZGVEcmFnU291cmNlID0gbm9kZURyYWdTb3VyY2U7XG5leHBvcnRzLm5vZGVEcm9wVGFyZ2V0ID0gbm9kZURyb3BUYXJnZXQ7XG5leHBvcnRzLkROREFjdGlvblBhcmFtZXRlciA9IEROREFjdGlvblBhcmFtZXRlcjtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IHtcbiAgICBjb250ZXh0VHlwZXM6IHtcbiAgICAgICAgbWVzc2FnZXM6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgICAgIGdldE1lc3NhZ2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgfVxufTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1tcImRlZmF1bHRcIl07XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBDb21wb25lbnQgPSBfcmVxdWlyZS5Db21wb25lbnQ7XG52YXIgUHJvcFR5cGVzID0gX3JlcXVpcmUuUHJvcFR5cGVzO1xuXG52YXIgX3JlcXVpcmUyID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIEZsYXRCdXR0b24gPSBfcmVxdWlyZTIuRmxhdEJ1dHRvbjtcbnZhciBGb250SWNvbiA9IF9yZXF1aXJlMi5Gb250SWNvbjtcblxudmFyIF9yZXF1aXJlMyA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpL3N0eWxlcycpO1xuXG52YXIgbXVpVGhlbWVhYmxlID0gX3JlcXVpcmUzLm11aVRoZW1lYWJsZTtcblxudmFyIENvbG9yID0gcmVxdWlyZSgnY29sb3InKTtcbnZhciBQeWRpbyA9IHJlcXVpcmUoJ3B5ZGlvJyk7XG5cbnZhciBfUHlkaW8kcmVxdWlyZUxpYiA9IFB5ZGlvLnJlcXVpcmVMaWIoJ2Jvb3QnKTtcblxudmFyIFB5ZGlvQ29udGV4dENvbnN1bWVyID0gX1B5ZGlvJHJlcXVpcmVMaWIuUHlkaW9Db250ZXh0Q29uc3VtZXI7XG5cbnZhciBFbXB0eVN0YXRlVmlldyA9IChmdW5jdGlvbiAoX0NvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhFbXB0eVN0YXRlVmlldywgX0NvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBFbXB0eVN0YXRlVmlldyhwcm9wcywgY29udGV4dCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRW1wdHlTdGF0ZVZpZXcpO1xuXG4gICAgICAgIF9Db21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgfVxuXG4gICAgRW1wdHlTdGF0ZVZpZXcucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHM7XG4gICAgICAgIHZhciBzdHlsZSA9IF9wcm9wcy5zdHlsZTtcbiAgICAgICAgdmFyIGljb25DbGFzc05hbWUgPSBfcHJvcHMuaWNvbkNsYXNzTmFtZTtcbiAgICAgICAgdmFyIHByaW1hcnlUZXh0SWQgPSBfcHJvcHMucHJpbWFyeVRleHRJZDtcbiAgICAgICAgdmFyIHNlY29uZGFyeVRleHRJZCA9IF9wcm9wcy5zZWNvbmRhcnlUZXh0SWQ7XG4gICAgICAgIHZhciBhY3Rpb25MYWJlbElkID0gX3Byb3BzLmFjdGlvbkxhYmVsSWQ7XG4gICAgICAgIHZhciBhY3Rpb25DYWxsYmFjayA9IF9wcm9wcy5hY3Rpb25DYWxsYmFjaztcbiAgICAgICAgdmFyIGFjdGlvblN0eWxlID0gX3Byb3BzLmFjdGlvblN0eWxlO1xuICAgICAgICB2YXIgYWN0aW9uSWNvbkNsYXNzTmFtZSA9IF9wcm9wcy5hY3Rpb25JY29uQ2xhc3NOYW1lO1xuICAgICAgICB2YXIgZ2V0TWVzc2FnZSA9IF9wcm9wcy5nZXRNZXNzYWdlO1xuXG4gICAgICAgIHZhciBtYWluQ29sb3IgPSBDb2xvcih0aGlzLnByb3BzLm11aVRoZW1lLnBhbGV0dGUucHJpbWFyeTFDb2xvcik7XG5cbiAgICAgICAgdmFyIHN0eWxlcyA9IHtcbiAgICAgICAgICAgIGNvbnRhaW5lcjogX2V4dGVuZHMoe1xuICAgICAgICAgICAgICAgIGRpc3BsYXk6ICdmbGV4JyxcbiAgICAgICAgICAgICAgICBhbGlnbkl0ZW1zOiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICBqdXN0aWZ5Q29udGVudDogJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiAnMTAwJScsXG4gICAgICAgICAgICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgICAgICAgICAgICBmbGV4OiAxLFxuICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogbWFpbkNvbG9yLmxpZ2h0bmVzcyg5NykucmdiKCkudG9TdHJpbmcoKVxuICAgICAgICAgICAgfSwgc3R5bGUpLFxuICAgICAgICAgICAgY2VudGVyZWQ6IHtcbiAgICAgICAgICAgICAgICBtYXhXaWR0aDogMjgwLFxuICAgICAgICAgICAgICAgIHRleHRBbGlnbjogJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAgY29sb3I6IG1haW5Db2xvci5mYWRlKDAuNikudG9TdHJpbmcoKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGljb246IHtcbiAgICAgICAgICAgICAgICBmb250U2l6ZTogMTAwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcHJpbWFyeVRleHQ6IHtcbiAgICAgICAgICAgICAgICBmb250U2l6ZTogMTYsXG4gICAgICAgICAgICAgICAgZm9udFdlaWdodDogNTAwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2Vjb25kYXJ5VGV4dDoge1xuICAgICAgICAgICAgICAgIG1hcmdpblRvcDogMjAsXG4gICAgICAgICAgICAgICAgZm9udFNpemU6IDEzXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYnV0dG9uQ29udGFpbmVyOiB7XG4gICAgICAgICAgICAgICAgbWFyZ2luVG9wOiAxMDAsXG4gICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJ1dHRvblN0eWxlOiB7XG4gICAgICAgICAgICAgICAgY29sb3I6IHRoaXMucHJvcHMubXVpVGhlbWUucGFsZXR0ZS5hY2NlbnQyQ29sb3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdmFyIGJ1dHRvbkljb24gPSBhY3Rpb25JY29uQ2xhc3NOYW1lID8gUmVhY3QuY3JlYXRlRWxlbWVudChGb250SWNvbiwgeyBjbGFzc05hbWU6IGFjdGlvbkljb25DbGFzc05hbWUgfSkgOiBudWxsO1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgeyBzdHlsZTogc3R5bGVzLmNvbnRhaW5lciB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IHN0eWxlOiBzdHlsZXMuY2VudGVyZWQgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KCdkaXYnLCB7IGNsYXNzTmFtZTogaWNvbkNsYXNzTmFtZSwgc3R5bGU6IHN0eWxlcy5pY29uIH0pLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiBzdHlsZXMucHJpbWFyeVRleHQgfSxcbiAgICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZShwcmltYXJ5VGV4dElkKVxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgc2Vjb25kYXJ5VGV4dElkICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiBzdHlsZXMuc2Vjb25kYXJ5VGV4dCB9LFxuICAgICAgICAgICAgICAgICAgICBnZXRNZXNzYWdlKHNlY29uZGFyeVRleHRJZClcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIGFjdGlvbkxhYmVsSWQgJiYgYWN0aW9uQ2FsbGJhY2sgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IF9leHRlbmRzKHt9LCBzdHlsZXMuYnV0dG9uQ29udGFpbmVyLCBhY3Rpb25TdHlsZSkgfSxcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChGbGF0QnV0dG9uLCB7IHN0eWxlOiBzdHlsZXMuYnV0dG9uU3R5bGUsIGxhYmVsOiBnZXRNZXNzYWdlKGFjdGlvbkxhYmVsSWQpLCBvblRvdWNoVGFwOiBhY3Rpb25DYWxsYmFjaywgaWNvbjogYnV0dG9uSWNvbiB9KVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEVtcHR5U3RhdGVWaWV3O1xufSkoQ29tcG9uZW50KTtcblxuRW1wdHlTdGF0ZVZpZXcucHJvcFR5cGVzID0ge1xuXG4gICAgcHlkaW86IFByb3BUeXBlcy5pbnN0YW5jZU9mKFB5ZGlvKS5pc1JlcXVpcmVkLFxuICAgIGljb25DbGFzc05hbWU6IFByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICBwcmltYXJ5VGV4dElkOiBQcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG5cbiAgICBzZWNvbmRhcnlUZXh0SWQ6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgYWN0aW9uTGFiZWxJZDogUHJvcFR5cGVzLnN0cmluZyxcbiAgICBhY3Rpb25DYWxsYmFjazogUHJvcFR5cGVzLmZ1bmMsXG4gICAgYWN0aW9uU3R5bGU6IFByb3BUeXBlcy5vYmplY3QsXG5cbiAgICBzdHlsZTogUHJvcFR5cGVzLm9iamVjdCxcbiAgICBnZXRNZXNzYWdlOiBQcm9wVHlwZXMuZnVuY1xuXG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBFbXB0eVN0YXRlVmlldyA9IFB5ZGlvQ29udGV4dENvbnN1bWVyKEVtcHR5U3RhdGVWaWV3KTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEVtcHR5U3RhdGVWaWV3ID0gbXVpVGhlbWVhYmxlKCkoRW1wdHlTdGF0ZVZpZXcpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBFbXB0eVN0YXRlVmlldztcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKG9iaiwga2V5cykgeyB2YXIgdGFyZ2V0ID0ge307IGZvciAodmFyIGkgaW4gb2JqKSB7IGlmIChrZXlzLmluZGV4T2YoaSkgPj0gMCkgY29udGludWU7IGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgaSkpIGNvbnRpbnVlOyB0YXJnZXRbaV0gPSBvYmpbaV07IH0gcmV0dXJuIHRhcmdldDsgfVxuXG52YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7XG5cbnZhciBfbWF0ZXJpYWxVaSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBNb2RhbEFwcEJhciA9IGZ1bmN0aW9uIE1vZGFsQXBwQmFyKHByb3BzKSB7XG4gICAgdmFyIHN0eWxlID0gcHJvcHMuc3R5bGU7XG4gICAgdmFyIHRpdGxlU3R5bGUgPSBwcm9wcy50aXRsZVN0eWxlO1xuICAgIHZhciBpY29uU3R5bGVSaWdodCA9IHByb3BzLmljb25TdHlsZVJpZ2h0O1xuICAgIHZhciBpY29uU3R5bGVMZWZ0ID0gcHJvcHMuaWNvblN0eWxlTGVmdDtcblxuICAgIHZhciBvdGhlclByb3BzID0gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKHByb3BzLCBbJ3N0eWxlJywgJ3RpdGxlU3R5bGUnLCAnaWNvblN0eWxlUmlnaHQnLCAnaWNvblN0eWxlTGVmdCddKTtcblxuICAgIHZhciBzdHlsZXMgPSB7XG4gICAgICAgIHN0eWxlOiBfZXh0ZW5kcyh7XG4gICAgICAgICAgICBmbGV4U2hyaW5rOiAwXG4gICAgICAgIH0sIHN0eWxlKSxcbiAgICAgICAgdGl0bGVTdHlsZTogX2V4dGVuZHMoe1xuICAgICAgICAgICAgbGluZUhlaWdodDogJzU2cHgnLFxuICAgICAgICAgICAgaGVpZ2h0OiA1NixcbiAgICAgICAgICAgIG1hcmdpbkxlZnQ6IC04XG4gICAgICAgIH0sIHRpdGxlU3R5bGUpLFxuICAgICAgICBpY29uU3R5bGVSaWdodDogX2V4dGVuZHMoe1xuICAgICAgICAgICAgbWFyZ2luVG9wOiA0XG4gICAgICAgIH0sIGljb25TdHlsZVJpZ2h0KSxcbiAgICAgICAgaWNvblN0eWxlTGVmdDogX2V4dGVuZHMoe1xuICAgICAgICAgICAgbWFyZ2luVG9wOiA0XG4gICAgICAgIH0sIGljb25TdHlsZUxlZnQpXG4gICAgfTtcblxuICAgIHJldHVybiBfcmVhY3QyWydkZWZhdWx0J10uY3JlYXRlRWxlbWVudChfbWF0ZXJpYWxVaS5BcHBCYXIsIF9leHRlbmRzKHt9LCBvdGhlclByb3BzLCBzdHlsZXMpKTtcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IE1vZGFsQXBwQmFyO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4vKmJvcmRlclJhZGl1czogJzJweCAycHggMCAwJywqL1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4vKipcbiAqIFNlYXJjaCBpbnB1dCBidWlsZGluZyBhIHNldCBvZiBxdWVyeSBwYXJhbWV0ZXJzIGFuZCBjYWxsaW5nXG4gKiB0aGUgY2FsbGJhY2tzIHRvIGRpc3BsYXkgLyBoaWRlIHJlc3VsdHNcbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0c1snZGVmYXVsdCddID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnU2VhcmNoQm94JyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICAvLyBSZXF1aXJlZFxuICAgICAgICBwYXJhbWV0ZXJzOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICAgIHF1ZXJ5UGFyYW1ldGVyTmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgICAgICAvLyBPdGhlclxuICAgICAgICB0ZXh0TGFiZWw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIGRpc3BsYXlSZXN1bHRzOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgaGlkZVJlc3VsdHM6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBkaXNwbGF5UmVzdWx0c1N0YXRlOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgbGltaXQ6IFJlYWN0LlByb3BUeXBlcy5udW1iZXJcbiAgICB9LFxuXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiBnZXRJbml0aWFsU3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBkaXNwbGF5UmVzdWx0OiB0aGlzLnByb3BzLmRpc3BsYXlSZXN1bHRzU3RhdGUgPyB0cnVlIDogZmFsc2VcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgZ2V0RGVmYXVsdFByb3BzOiBmdW5jdGlvbiBnZXREZWZhdWx0UHJvcHMoKSB7XG4gICAgICAgIHZhciBkbSA9IG5ldyBQeWRpb0RhdGFNb2RlbCgpO1xuICAgICAgICBkbS5zZXRSb290Tm9kZShuZXcgQWp4cE5vZGUoKSk7XG4gICAgICAgIHJldHVybiB7IGRhdGFNb2RlbDogZG0gfTtcbiAgICB9LFxuXG4gICAgZGlzcGxheVJlc3VsdHNTdGF0ZTogZnVuY3Rpb24gZGlzcGxheVJlc3VsdHNTdGF0ZSgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBkaXNwbGF5UmVzdWx0OiB0cnVlXG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBoaWRlUmVzdWx0c1N0YXRlOiBmdW5jdGlvbiBoaWRlUmVzdWx0c1N0YXRlKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGRpc3BsYXlSZXN1bHQ6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnByb3BzLmhpZGVSZXN1bHRzKCk7XG4gICAgfSxcblxuICAgIG9uQ2xpY2tTZWFyY2g6IGZ1bmN0aW9uIG9uQ2xpY2tTZWFyY2goKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMucmVmcy5xdWVyeS5nZXRWYWx1ZSgpO1xuICAgICAgICB2YXIgZG0gPSB0aGlzLnByb3BzLmRhdGFNb2RlbDtcbiAgICAgICAgdmFyIHBhcmFtcyA9IHRoaXMucHJvcHMucGFyYW1ldGVycztcbiAgICAgICAgcGFyYW1zW3RoaXMucHJvcHMucXVlcnlQYXJhbWV0ZXJOYW1lXSA9IHZhbHVlO1xuICAgICAgICBwYXJhbXNbJ2xpbWl0J10gPSB0aGlzLnByb3BzLmxpbWl0IHx8IDEwMDtcbiAgICAgICAgZG0uZ2V0Um9vdE5vZGUoKS5zZXRDaGlsZHJlbihbXSk7XG4gICAgICAgIFB5ZGlvQXBpLmdldENsaWVudCgpLnJlcXVlc3QocGFyYW1zLCAoZnVuY3Rpb24gKHRyYW5zcG9ydCkge1xuICAgICAgICAgICAgdmFyIHJlbW90ZU5vZGVQcm92aWRlciA9IG5ldyBSZW1vdGVOb2RlUHJvdmlkZXIoe30pO1xuICAgICAgICAgICAgcmVtb3RlTm9kZVByb3ZpZGVyLnBhcnNlTm9kZXMoZG0uZ2V0Um9vdE5vZGUoKSwgdHJhbnNwb3J0KTtcbiAgICAgICAgICAgIGRtLmdldFJvb3ROb2RlKCkuc2V0TG9hZGVkKHRydWUpO1xuICAgICAgICAgICAgdGhpcy5kaXNwbGF5UmVzdWx0c1N0YXRlKCk7XG4gICAgICAgICAgICB0aGlzLnByb3BzLmRpc3BsYXlSZXN1bHRzKHZhbHVlLCBkbSk7XG4gICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgIH0sXG5cbiAgICBrZXlEb3duOiBmdW5jdGlvbiBrZXlEb3duKGV2ZW50KSB7XG4gICAgICAgIGlmIChldmVudC5rZXkgPT0gJ0VudGVyJykge1xuICAgICAgICAgICAgdGhpcy5vbkNsaWNrU2VhcmNoKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IGNsYXNzTmFtZTogdGhpcy5wcm9wcy5jbGFzc05hbWUgPyB0aGlzLnByb3BzLmNsYXNzTmFtZSA6ICcnIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgcGFkZGluZ1RvcDogMjIsIGZsb2F0OiAncmlnaHQnLCBvcGFjaXR5OiAwLjMgfSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoUmVhY3RNVUkuSWNvbkJ1dHRvbiwge1xuICAgICAgICAgICAgICAgICAgICByZWY6ICdidXR0b24nLFxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiB0aGlzLm9uQ2xpY2tTZWFyY2gsXG4gICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU6ICdpY29uLXNlYXJjaCcsXG4gICAgICAgICAgICAgICAgICAgIHRvb2x0aXA6ICdTZWFyY2gnXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnc2VhcmNoYm94LWlucHV0LWZpbGwnLCBzdHlsZTogeyB3aWR0aDogMjIwLCBmbG9hdDogJ3JpZ2h0JyB9IH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5UZXh0RmllbGQsIHsgcmVmOiAncXVlcnknLCBvbktleURvd246IHRoaXMua2V5RG93biwgZmxvYXRpbmdMYWJlbFRleHQ6IHRoaXMucHJvcHMudGV4dExhYmVsIH0pXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4vKipcbiAqIEdldCBpbmZvIGZyb20gUHlkaW8gY29udHJvbGxlciBhbiBidWlsZCBhblxuICogYWN0aW9uIGJhciB3aXRoIGFjdGl2ZSBhY3Rpb25zLlxuICogVEJDXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ1NpbXBsZVJlYWN0QWN0aW9uQmFyJyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBkYXRhTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFB5ZGlvRGF0YU1vZGVsKS5pc1JlcXVpcmVkLFxuICAgICAgICBub2RlOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihBanhwTm9kZSkuaXNSZXF1aXJlZCxcbiAgICAgICAgYWN0aW9uczogUmVhY3QuUHJvcFR5cGVzLmFycmF5XG4gICAgfSxcblxuICAgIGNsaWNrQWN0aW9uOiBmdW5jdGlvbiBjbGlja0FjdGlvbihldmVudCkge1xuICAgICAgICB2YXIgYWN0aW9uTmFtZSA9IGV2ZW50LmN1cnJlbnRUYXJnZXQuZ2V0QXR0cmlidXRlKFwiZGF0YS1hY3Rpb25cIik7XG4gICAgICAgIHRoaXMucHJvcHMuZGF0YU1vZGVsLnNldFNlbGVjdGVkTm9kZXMoW3RoaXMucHJvcHMubm9kZV0pO1xuICAgICAgICB2YXIgYSA9IHdpbmRvdy5weWRpby5Db250cm9sbGVyLmdldEFjdGlvbkJ5TmFtZShhY3Rpb25OYW1lKTtcbiAgICAgICAgYS5maXJlQ29udGV4dENoYW5nZSh0aGlzLnByb3BzLmRhdGFNb2RlbCwgdHJ1ZSwgd2luZG93LnB5ZGlvLnVzZXIpO1xuICAgICAgICAvL2EuZmlyZVNlbGVjdGlvbkNoYW5nZSh0aGlzLnByb3BzLmRhdGFNb2RlbCk7XG4gICAgICAgIGEuYXBwbHkoW3RoaXMucHJvcHMuZGF0YU1vZGVsXSk7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIGFjdGlvbnMgPSB0aGlzLnByb3BzLmFjdGlvbnMubWFwKChmdW5jdGlvbiAoYSkge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ2RpdicsIHtcbiAgICAgICAgICAgICAgICBrZXk6IGEub3B0aW9ucy5uYW1lLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogYS5vcHRpb25zLmljb25fY2xhc3MgKyAnIG1hdGVyaWFsLWxpc3QtYWN0aW9uLWlubGluZScgfHwgJycsXG4gICAgICAgICAgICAgICAgdGl0bGU6IGEub3B0aW9ucy50aXRsZSxcbiAgICAgICAgICAgICAgICAnZGF0YS1hY3Rpb24nOiBhLm9wdGlvbnMubmFtZSxcbiAgICAgICAgICAgICAgICBvbkNsaWNrOiB0aGlzLmNsaWNrQWN0aW9uIH0pO1xuICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgYWN0aW9uc1xuICAgICAgICApO1xuICAgIH1cbn0pO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxudmFyIF91dGlsRE5EID0gcmVxdWlyZSgnLi4vdXRpbC9ETkQnKTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIF9QeWRpbyRyZXF1aXJlTGliID0gUHlkaW8ucmVxdWlyZUxpYignaG9jJyk7XG5cbnZhciB3aXRoQ29udGV4dE1lbnUgPSBfUHlkaW8kcmVxdWlyZUxpYi53aXRoQ29udGV4dE1lbnU7XG5cbnZhciBDb250ZXh0TWVudVdyYXBwZXIgPSBmdW5jdGlvbiBDb250ZXh0TWVudVdyYXBwZXIocHJvcHMpIHtcbiAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudCgnZGl2JywgcHJvcHMpO1xufTtcbkNvbnRleHRNZW51V3JhcHBlciA9IHdpdGhDb250ZXh0TWVudShDb250ZXh0TWVudVdyYXBwZXIpO1xuXG4vKipcbiAqIFRyZWUgTm9kZVxuICovXG52YXIgU2ltcGxlVHJlZU5vZGUgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdTaW1wbGVUcmVlTm9kZScsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgY29sbGFwc2U6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBmb3JjZUV4cGFuZDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIGNoaWxkcmVuT25seTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIGRlcHRoOiBSZWFjdC5Qcm9wVHlwZXMubnVtYmVyLFxuICAgICAgICBvbk5vZGVTZWxlY3Q6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBub2RlOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihBanhwTm9kZSksXG4gICAgICAgIGRhdGFNb2RlbDogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW9EYXRhTW9kZWwpLFxuICAgICAgICBmb3JjZUxhYmVsOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICAvLyBPcHRpb25hbCBjdXJyZW50bHkgc2VsZWN0ZWQgZGV0ZWN0aW9uXG4gICAgICAgIG5vZGVJc1NlbGVjdGVkOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgLy8gT3B0aW9uYWwgY2hlY2tib3hlc1xuICAgICAgICBjaGVja2JveGVzOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXksXG4gICAgICAgIGNoZWNrYm94ZXNWYWx1ZXM6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgICAgIGNoZWNrYm94ZXNDb21wdXRlU3RhdHVzOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgb25DaGVja2JveENoZWNrOiBSZWFjdC5Qcm9wVHlwZXMuZnVuY1xuICAgIH0sXG5cbiAgICBnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uIGdldERlZmF1bHRQcm9wcygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbGxhcHNlOiBmYWxzZSxcbiAgICAgICAgICAgIGNoaWxkcmVuT25seTogZmFsc2UsXG4gICAgICAgICAgICBkZXB0aDogMCxcbiAgICAgICAgICAgIG9uTm9kZVNlbGVjdDogZnVuY3Rpb24gb25Ob2RlU2VsZWN0KG5vZGUpIHt9XG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGxpc3RlblRvTm9kZTogZnVuY3Rpb24gbGlzdGVuVG9Ob2RlKG5vZGUpIHtcbiAgICAgICAgdGhpcy5fY2hpbGRyZW5MaXN0ZW5lciA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNNb3VudGVkKCkpIHJldHVybjtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjaGlsZHJlbjogdGhpcy5fbm9kZVRvQ2hpbGRyZW4obm9kZSkgfSk7XG4gICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuX25vZGVMaXN0ZW5lciA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNNb3VudGVkKCkpIHJldHVybjtcbiAgICAgICAgICAgIHRoaXMuZm9yY2VVcGRhdGUoKTtcbiAgICAgICAgfSkuYmluZCh0aGlzKTtcbiAgICAgICAgbm9kZS5vYnNlcnZlKFwiY2hpbGRfYWRkZWRcIiwgdGhpcy5fY2hpbGRyZW5MaXN0ZW5lcik7XG4gICAgICAgIG5vZGUub2JzZXJ2ZShcImNoaWxkX3JlbW92ZWRcIiwgdGhpcy5fY2hpbGRyZW5MaXN0ZW5lcik7XG4gICAgICAgIG5vZGUub2JzZXJ2ZShcIm5vZGVfcmVwbGFjZWRcIiwgdGhpcy5fbm9kZUxpc3RlbmVyKTtcbiAgICB9LFxuXG4gICAgc3RvcExpc3RlbmluZzogZnVuY3Rpb24gc3RvcExpc3RlbmluZyhub2RlKSB7XG4gICAgICAgIG5vZGUuc3RvcE9ic2VydmluZyhcImNoaWxkX2FkZGVkXCIsIHRoaXMuX2NoaWxkcmVuTGlzdGVuZXIpO1xuICAgICAgICBub2RlLnN0b3BPYnNlcnZpbmcoXCJjaGlsZF9yZW1vdmVkXCIsIHRoaXMuX2NoaWxkcmVuTGlzdGVuZXIpO1xuICAgICAgICBub2RlLnN0b3BPYnNlcnZpbmcoXCJub2RlX3JlcGxhY2VkXCIsIHRoaXMuX25vZGVMaXN0ZW5lcik7XG4gICAgfSxcblxuICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgdGhpcy5saXN0ZW5Ub05vZGUodGhpcy5wcm9wcy5ub2RlKTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFVubW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICB0aGlzLnN0b3BMaXN0ZW5pbmcodGhpcy5wcm9wcy5ub2RlKTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wczogZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHtcbiAgICAgICAgdmFyIG9sZE5vZGUgPSB0aGlzLnByb3BzLm5vZGU7XG4gICAgICAgIHZhciBuZXdOb2RlID0gbmV4dFByb3BzLm5vZGU7XG4gICAgICAgIGlmIChuZXdOb2RlID09IG9sZE5vZGUgJiYgbmV3Tm9kZS5nZXRNZXRhZGF0YSgpLmdldChcInBhZ2luYXRpb25EYXRhXCIpKSB7XG4gICAgICAgICAgICB2YXIgcmVtYXBlZENoaWxkcmVuID0gdGhpcy5zdGF0ZS5jaGlsZHJlbi5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICBjLnNldFBhcmVudChuZXdOb2RlKTtyZXR1cm4gYztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIHJlbWFwZWRQYXRoZXMgPSB0aGlzLnN0YXRlLmNoaWxkcmVuLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgICAgIHJldHVybiBjLmdldFBhdGgoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIG5ld0NoaWxkcmVuID0gdGhpcy5fbm9kZVRvQ2hpbGRyZW4obmV3Tm9kZSk7XG4gICAgICAgICAgICBuZXdDaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uIChuYykge1xuICAgICAgICAgICAgICAgIGlmIChyZW1hcGVkUGF0aGVzLmluZGV4T2YobmMuZ2V0UGF0aCgpKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVtYXBlZENoaWxkcmVuLnB1c2gobmMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNoaWxkcmVuOiByZW1hcGVkQ2hpbGRyZW4gfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgY2hpbGRyZW46IHRoaXMuX25vZGVUb0NoaWxkcmVuKG5ld05vZGUpIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuZXdOb2RlICE9PSBvbGROb2RlKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3BMaXN0ZW5pbmcob2xkTm9kZSk7XG4gICAgICAgICAgICB0aGlzLmxpc3RlblRvTm9kZShuZXdOb2RlKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNob3dDaGlsZHJlbjogIXRoaXMucHJvcHMuY29sbGFwc2UgfHwgdGhpcy5wcm9wcy5mb3JjZUV4cGFuZCxcbiAgICAgICAgICAgIGNoaWxkcmVuOiB0aGlzLl9ub2RlVG9DaGlsZHJlbih0aGlzLnByb3BzLm5vZGUpXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIF9ub2RlVG9DaGlsZHJlbjogZnVuY3Rpb24gX25vZGVUb0NoaWxkcmVuKCkge1xuICAgICAgICB2YXIgY2hpbGRyZW4gPSBbXTtcbiAgICAgICAgdGhpcy5wcm9wcy5ub2RlLmdldENoaWxkcmVuKCkuZm9yRWFjaChmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgaWYgKCFjLmlzTGVhZigpIHx8IGMuZ2V0QWp4cE1pbWUoKSA9PT0gJ2FqeHBfYnJvd3NhYmxlX2FyY2hpdmUnKSBjaGlsZHJlbi5wdXNoKGMpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNoaWxkcmVuO1xuICAgIH0sXG5cbiAgICBvbk5vZGVTZWxlY3Q6IGZ1bmN0aW9uIG9uTm9kZVNlbGVjdChldikge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5vbk5vZGVTZWxlY3QpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMub25Ob2RlU2VsZWN0KHRoaXMucHJvcHMubm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSxcbiAgICBvbkNoaWxkRGlzcGxheVRvZ2dsZTogZnVuY3Rpb24gb25DaGlsZERpc3BsYXlUb2dnbGUoZXYpIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMubm9kZS5nZXRDaGlsZHJlbigpLnNpemUpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93Q2hpbGRyZW46ICF0aGlzLnN0YXRlLnNob3dDaGlsZHJlbiB9KTtcbiAgICAgICAgfVxuICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9LFxuICAgIG5vZGVJc1NlbGVjdGVkOiBmdW5jdGlvbiBub2RlSXNTZWxlY3RlZChuKSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm5vZGVJc1NlbGVjdGVkKSByZXR1cm4gdGhpcy5wcm9wcy5ub2RlSXNTZWxlY3RlZChuKTtlbHNlIHJldHVybiB0aGlzLnByb3BzLmRhdGFNb2RlbC5nZXRTZWxlY3RlZE5vZGVzKCkuaW5kZXhPZihuKSAhPT0gLTE7XG4gICAgfSxcbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcztcbiAgICAgICAgdmFyIG5vZGUgPSBfcHJvcHMubm9kZTtcbiAgICAgICAgdmFyIGNoaWxkcmVuT25seSA9IF9wcm9wcy5jaGlsZHJlbk9ubHk7XG4gICAgICAgIHZhciBjYW5Ecm9wID0gX3Byb3BzLmNhbkRyb3A7XG4gICAgICAgIHZhciBpc092ZXJDdXJyZW50ID0gX3Byb3BzLmlzT3ZlckN1cnJlbnQ7XG4gICAgICAgIHZhciBjaGVja2JveGVzID0gX3Byb3BzLmNoZWNrYm94ZXM7XG4gICAgICAgIHZhciBjaGVja2JveGVzQ29tcHV0ZVN0YXR1cyA9IF9wcm9wcy5jaGVja2JveGVzQ29tcHV0ZVN0YXR1cztcbiAgICAgICAgdmFyIGNoZWNrYm94ZXNWYWx1ZXMgPSBfcHJvcHMuY2hlY2tib3hlc1ZhbHVlcztcbiAgICAgICAgdmFyIG9uQ2hlY2tib3hDaGVjayA9IF9wcm9wcy5vbkNoZWNrYm94Q2hlY2s7XG4gICAgICAgIHZhciBkZXB0aCA9IF9wcm9wcy5kZXB0aDtcbiAgICAgICAgdmFyIGZvcmNlRXhwYW5kID0gX3Byb3BzLmZvcmNlRXhwYW5kO1xuICAgICAgICB2YXIgc2VsZWN0ZWRJdGVtU3R5bGUgPSBfcHJvcHMuc2VsZWN0ZWRJdGVtU3R5bGU7XG4gICAgICAgIHZhciBnZXRJdGVtU3R5bGUgPSBfcHJvcHMuZ2V0SXRlbVN0eWxlO1xuICAgICAgICB2YXIgZm9yY2VMYWJlbCA9IF9wcm9wcy5mb3JjZUxhYmVsO1xuXG4gICAgICAgIHZhciBoYXNGb2xkZXJDaGlsZHJlbnMgPSB0aGlzLnN0YXRlLmNoaWxkcmVuLmxlbmd0aCA/IHRydWUgOiBmYWxzZTtcbiAgICAgICAgdmFyIGhhc0NoaWxkcmVuO1xuICAgICAgICBpZiAoaGFzRm9sZGVyQ2hpbGRyZW5zKSB7XG4gICAgICAgICAgICBoYXNDaGlsZHJlbiA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgICAgIHsgb25DbGljazogdGhpcy5vbkNoaWxkRGlzcGxheVRvZ2dsZSB9LFxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuc2hvd0NoaWxkcmVuIHx8IGZvcmNlRXhwYW5kID8gUmVhY3QuY3JlYXRlRWxlbWVudCgnc3BhbicsIHsgY2xhc3NOYW1lOiAndHJlZS1pY29uIGljb24tYW5nbGUtZG93bicgfSkgOiBSZWFjdC5jcmVhdGVFbGVtZW50KCdzcGFuJywgeyBjbGFzc05hbWU6ICd0cmVlLWljb24gaWNvbi1hbmdsZS1yaWdodCcgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgY25hbWUgPSBcInRyZWUtaWNvbiBpY29uLWFuZ2xlLXJpZ2h0XCI7XG4gICAgICAgICAgICBpZiAobm9kZS5pc0xvYWRlZCgpKSB7XG4gICAgICAgICAgICAgICAgY25hbWUgKz0gXCIgbm8tZm9sZGVyLWNoaWxkcmVuXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYXNDaGlsZHJlbiA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCB7IGNsYXNzTmFtZTogY25hbWUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGlzU2VsZWN0ZWQgPSB0aGlzLm5vZGVJc1NlbGVjdGVkKG5vZGUpID8gJ211aS1tZW51LWl0ZW0gbXVpLWlzLXNlbGVjdGVkJyA6ICdtdWktbWVudS1pdGVtJztcbiAgICAgICAgdmFyIHNlbGZMYWJlbDtcbiAgICAgICAgaWYgKCFjaGlsZHJlbk9ubHkpIHtcbiAgICAgICAgICAgIGlmIChjYW5Ecm9wICYmIGlzT3ZlckN1cnJlbnQpIHtcbiAgICAgICAgICAgICAgICBpc1NlbGVjdGVkICs9ICcgZHJvcHBhYmxlLWFjdGl2ZSc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgYm94ZXM7XG4gICAgICAgICAgICBpZiAoY2hlY2tib3hlcykge1xuICAgICAgICAgICAgICAgIHZhciB2YWx1ZXMgPSB7fSxcbiAgICAgICAgICAgICAgICAgICAgaW5oZXJpdGVkID0gZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVkID0ge30sXG4gICAgICAgICAgICAgICAgICAgIGFkZGl0aW9uYWxDbGFzc05hbWUgPSAnJztcbiAgICAgICAgICAgICAgICBpZiAoY2hlY2tib3hlc0NvbXB1dGVTdGF0dXMpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0YXR1cyA9IGNoZWNrYm94ZXNDb21wdXRlU3RhdHVzKG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBzdGF0dXMuVkFMVUVTO1xuICAgICAgICAgICAgICAgICAgICBpbmhlcml0ZWQgPSBzdGF0dXMuSU5IRVJJVEVEO1xuICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZCA9IHN0YXR1cy5ESVNBQkxFRDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXR1cy5DTEFTU05BTUUpIGFkZGl0aW9uYWxDbGFzc05hbWUgPSAnICcgKyBzdGF0dXMuQ0xBU1NOQU1FO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hlY2tib3hlc1ZhbHVlcyAmJiBjaGVja2JveGVzVmFsdWVzW25vZGUuZ2V0UGF0aCgpXSkge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjaGVja2JveGVzVmFsdWVzW25vZGUuZ2V0UGF0aCgpXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlQ2xhc3NlcyA9IFtdO1xuICAgICAgICAgICAgICAgIGJveGVzID0gY2hlY2tib3hlcy5tYXAoKGZ1bmN0aW9uIChjKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzZWxlY3RlZCA9IHZhbHVlc1tjXSAhPT0gdW5kZWZpbmVkID8gdmFsdWVzW2NdIDogZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGljayA9IChmdW5jdGlvbiAoZXZlbnQsIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNoZWNrYm94Q2hlY2sobm9kZSwgYywgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9KS5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWQpIHZhbHVlQ2xhc3Nlcy5wdXNoKGMpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5DaGVja2JveCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogYyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleTogYyArIFwiLVwiICsgKHNlbGVjdGVkID8gXCJ0cnVlXCIgOiBcImZhbHNlXCIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tlZDogc2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNoZWNrOiBjbGljayxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVkOiBkaXNhYmxlZFtjXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJjYm94LVwiICsgY1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgICAgICBpc1NlbGVjdGVkICs9IGluaGVyaXRlZCA/IFwiIGluaGVyaXRlZCBcIiA6IFwiXCI7XG4gICAgICAgICAgICAgICAgaXNTZWxlY3RlZCArPSB2YWx1ZUNsYXNzZXMubGVuZ3RoID8gXCIgY2hlY2tib3gtdmFsdWVzLVwiICsgdmFsdWVDbGFzc2VzLmpvaW4oJy0nKSA6IFwiIGNoZWNrYm94LXZhbHVlcy1lbXB0eVwiO1xuICAgICAgICAgICAgICAgIGJveGVzID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiBcInRyZWUtY2hlY2tib3hlc1wiICsgYWRkaXRpb25hbENsYXNzTmFtZSB9LFxuICAgICAgICAgICAgICAgICAgICBib3hlc1xuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgaXRlbVN0eWxlID0geyBwYWRkaW5nTGVmdDogZGVwdGggKiAyMCB9O1xuICAgICAgICAgICAgaWYgKHRoaXMubm9kZUlzU2VsZWN0ZWQobm9kZSkgJiYgc2VsZWN0ZWRJdGVtU3R5bGUpIHtcbiAgICAgICAgICAgICAgICBpdGVtU3R5bGUgPSBfZXh0ZW5kcyh7fSwgaXRlbVN0eWxlLCBzZWxlY3RlZEl0ZW1TdHlsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZ2V0SXRlbVN0eWxlKSB7XG4gICAgICAgICAgICAgICAgaXRlbVN0eWxlID0gX2V4dGVuZHMoe30sIGl0ZW1TdHlsZSwgZ2V0SXRlbVN0eWxlKG5vZGUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBpY29uID0gJ21kaSBtZGktZm9sZGVyJztcbiAgICAgICAgICAgIHZhciBhanhwTWltZSA9IG5vZGUuZ2V0QWp4cE1pbWUoKTtcbiAgICAgICAgICAgIGlmIChhanhwTWltZSA9PT0gJ2FqeHBfYnJvd3NhYmxlX2FyY2hpdmUnKSB7XG4gICAgICAgICAgICAgICAgaWNvbiA9ICdtZGkgbWRpLWFyY2hpdmUnO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChhanhwTWltZSA9PT0gJ2FqeHBfcmVjeWNsZScpIHtcbiAgICAgICAgICAgICAgICBpY29uID0gJ21kaSBtZGktZGVsZXRlJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlbGZMYWJlbCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgQ29udGV4dE1lbnVXcmFwcGVyLFxuICAgICAgICAgICAgICAgIHsgbm9kZTogbm9kZSwgY2xhc3NOYW1lOiAndHJlZS1pdGVtICcgKyBpc1NlbGVjdGVkICsgKGJveGVzID8gJyBoYXMtY2hlY2tib3hlcycgOiAnJyksIHN0eWxlOiBpdGVtU3R5bGUgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICd0cmVlLWl0ZW0tbGFiZWwnLCBvbkNsaWNrOiB0aGlzLm9uTm9kZVNlbGVjdCwgdGl0bGU6IG5vZGUuZ2V0TGFiZWwoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICdkYXRhLWlkJzogbm9kZS5nZXRQYXRoKCkgfSxcbiAgICAgICAgICAgICAgICAgICAgaGFzQ2hpbGRyZW4sXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCB7IGNsYXNzTmFtZTogXCJ0cmVlLWljb24gXCIgKyBpY29uIH0pLFxuICAgICAgICAgICAgICAgICAgICBmb3JjZUxhYmVsID8gZm9yY2VMYWJlbCA6IG5vZGUuZ2V0TGFiZWwoKVxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgYm94ZXNcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY2hpbGRyZW4gPSBbXTtcbiAgICAgICAgdmFyIGNvbm5lY3RvciA9IGZ1bmN0aW9uIGNvbm5lY3RvcihpbnN0YW5jZSkge1xuICAgICAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgICAgICB9O1xuICAgICAgICB2YXIgZHJhZ2dhYmxlID0gZmFsc2U7XG4gICAgICAgIGlmICh3aW5kb3cuUmVhY3RETkQgJiYgdGhpcy5wcm9wcy5jb25uZWN0RHJvcFRhcmdldCAmJiB0aGlzLnByb3BzLmNvbm5lY3REcmFnU291cmNlKSB7XG4gICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBjb25uZWN0RHJhZ1NvdXJjZSA9IF90aGlzLnByb3BzLmNvbm5lY3REcmFnU291cmNlO1xuICAgICAgICAgICAgICAgIHZhciBjb25uZWN0RHJvcFRhcmdldCA9IF90aGlzLnByb3BzLmNvbm5lY3REcm9wVGFyZ2V0O1xuICAgICAgICAgICAgICAgIGNvbm5lY3RvciA9IGZ1bmN0aW9uIChpbnN0YW5jZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0RHJhZ1NvdXJjZShSZWFjdERPTS5maW5kRE9NTm9kZShpbnN0YW5jZSkpO1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0RHJvcFRhcmdldChSZWFjdERPTS5maW5kRE9NTm9kZShpbnN0YW5jZSkpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgZHJhZ2dhYmxlID0gdHJ1ZTtcbiAgICAgICAgICAgIH0pKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5zaG93Q2hpbGRyZW4gfHwgZm9yY2VFeHBhbmQpIHtcbiAgICAgICAgICAgIGNoaWxkcmVuID0gdGhpcy5zdGF0ZS5jaGlsZHJlbi5tYXAoKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAgICAgICAgIHZhciBwcm9wcyA9IF9leHRlbmRzKHt9LCB0aGlzLnByb3BzLCB7XG4gICAgICAgICAgICAgICAgICAgIGZvcmNlTGFiZWw6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuT25seTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGtleTogY2hpbGQuZ2V0UGF0aCgpLFxuICAgICAgICAgICAgICAgICAgICBub2RlOiBjaGlsZCxcbiAgICAgICAgICAgICAgICAgICAgZGVwdGg6IGRlcHRoICsgMVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KGRyYWdnYWJsZSA/IERyYWdEcm9wVHJlZU5vZGUgOiBTaW1wbGVUcmVlTm9kZSwgcHJvcHMpO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnbGknLFxuICAgICAgICAgICAgeyByZWY6IGNvbm5lY3RvciwgY2xhc3NOYW1lOiBcInRyZWVub2RlXCIgKyBub2RlLmdldFBhdGgoKS5yZXBsYWNlKC9cXC8vZywgJ18nKSB9LFxuICAgICAgICAgICAgc2VsZkxhYmVsLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAndWwnLFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgY2hpbGRyZW5cbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxudmFyIERyYWdEcm9wVHJlZU5vZGU7XG5pZiAod2luZG93LlJlYWN0RE5EKSB7XG4gICAgRHJhZ0Ryb3BUcmVlTm9kZSA9IFJlYWN0RE5ELmZsb3coUmVhY3RETkQuRHJhZ1NvdXJjZShfdXRpbERORC5UeXBlcy5OT0RFX1BST1ZJREVSLCBfdXRpbERORC5ub2RlRHJhZ1NvdXJjZSwgX3V0aWxETkQuY29sbGVjdCksIFJlYWN0RE5ELkRyb3BUYXJnZXQoX3V0aWxETkQuVHlwZXMuTk9ERV9QUk9WSURFUiwgX3V0aWxETkQubm9kZURyb3BUYXJnZXQsIF91dGlsRE5ELmNvbGxlY3REcm9wKSkoU2ltcGxlVHJlZU5vZGUpO1xufSBlbHNlIHtcbiAgICBEcmFnRHJvcFRyZWVOb2RlID0gU2ltcGxlVHJlZU5vZGU7XG59XG5cbi8qKlxuICogU2ltcGxlIG9wZW5hYmxlIC8gbG9hZGFibGUgdHJlZSB0YWtpbmcgQWp4cE5vZGUgYXMgaW5wdXRzXG4gKi9cbnZhciBETkRUcmVlVmlldyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ0RORFRyZWVWaWV3JyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBzaG93Um9vdDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIHJvb3RMYWJlbDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgb25Ob2RlU2VsZWN0OiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgbm9kZTogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoQWp4cE5vZGUpLmlzUmVxdWlyZWQsXG4gICAgICAgIGRhdGFNb2RlbDogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW9EYXRhTW9kZWwpLmlzUmVxdWlyZWQsXG4gICAgICAgIHNlbGVjdGFibGU6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBzZWxlY3RhYmxlTXVsdGlwbGU6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBpbml0aWFsU2VsZWN0aW9uTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcbiAgICAgICAgb25TZWxlY3Rpb25DaGFuZ2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBmb3JjZUV4cGFuZDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIC8vIE9wdGlvbmFsIGN1cnJlbnRseSBzZWxlY3RlZCBkZXRlY3Rpb25cbiAgICAgICAgbm9kZUlzU2VsZWN0ZWQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICAvLyBPcHRpb25hbCBjaGVja2JveGVzXG4gICAgICAgIGNoZWNrYm94ZXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcbiAgICAgICAgY2hlY2tib3hlc1ZhbHVlczogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgY2hlY2tib3hlc0NvbXB1dGVTdGF0dXM6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvbkNoZWNrYm94Q2hlY2s6IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgfSxcblxuICAgIGdldERlZmF1bHRQcm9wczogZnVuY3Rpb24gZ2V0RGVmYXVsdFByb3BzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2hvd1Jvb3Q6IHRydWUsXG4gICAgICAgICAgICBvbk5vZGVTZWxlY3Q6IHRoaXMub25Ob2RlU2VsZWN0XG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIG9uTm9kZVNlbGVjdDogZnVuY3Rpb24gb25Ob2RlU2VsZWN0KG5vZGUpIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25Ob2RlU2VsZWN0KSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uTm9kZVNlbGVjdChub2RlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuZGF0YU1vZGVsLnNldFNlbGVjdGVkTm9kZXMoW25vZGVdKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAndWwnLFxuICAgICAgICAgICAgeyBjbGFzc05hbWU6IHRoaXMucHJvcHMuY2xhc3NOYW1lIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KERyYWdEcm9wVHJlZU5vZGUsIHtcbiAgICAgICAgICAgICAgICBjaGlsZHJlbk9ubHk6ICF0aGlzLnByb3BzLnNob3dSb290LFxuICAgICAgICAgICAgICAgIGZvcmNlRXhwYW5kOiB0aGlzLnByb3BzLmZvcmNlRXhwYW5kLFxuICAgICAgICAgICAgICAgIG5vZGU6IHRoaXMucHJvcHMubm9kZSA/IHRoaXMucHJvcHMubm9kZSA6IHRoaXMucHJvcHMuZGF0YU1vZGVsLmdldFJvb3ROb2RlKCksXG4gICAgICAgICAgICAgICAgZGF0YU1vZGVsOiB0aGlzLnByb3BzLmRhdGFNb2RlbCxcbiAgICAgICAgICAgICAgICBvbk5vZGVTZWxlY3Q6IHRoaXMub25Ob2RlU2VsZWN0LFxuICAgICAgICAgICAgICAgIG5vZGVJc1NlbGVjdGVkOiB0aGlzLnByb3BzLm5vZGVJc1NlbGVjdGVkLFxuICAgICAgICAgICAgICAgIGZvcmNlTGFiZWw6IHRoaXMucHJvcHMucm9vdExhYmVsLFxuICAgICAgICAgICAgICAgIGNoZWNrYm94ZXM6IHRoaXMucHJvcHMuY2hlY2tib3hlcyxcbiAgICAgICAgICAgICAgICBjaGVja2JveGVzVmFsdWVzOiB0aGlzLnByb3BzLmNoZWNrYm94ZXNWYWx1ZXMsXG4gICAgICAgICAgICAgICAgY2hlY2tib3hlc0NvbXB1dGVTdGF0dXM6IHRoaXMucHJvcHMuY2hlY2tib3hlc0NvbXB1dGVTdGF0dXMsXG4gICAgICAgICAgICAgICAgb25DaGVja2JveENoZWNrOiB0aGlzLnByb3BzLm9uQ2hlY2tib3hDaGVjayxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEl0ZW1TdHlsZTogdGhpcy5wcm9wcy5zZWxlY3RlZEl0ZW1TdHlsZSxcbiAgICAgICAgICAgICAgICBnZXRJdGVtU3R5bGU6IHRoaXMucHJvcHMuZ2V0SXRlbVN0eWxlXG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG52YXIgVHJlZVZpZXcgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdUcmVlVmlldycsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgc2hvd1Jvb3Q6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICByb290TGFiZWw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIG9uTm9kZVNlbGVjdDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIG5vZGU6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKEFqeHBOb2RlKS5pc1JlcXVpcmVkLFxuICAgICAgICBkYXRhTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFB5ZGlvRGF0YU1vZGVsKS5pc1JlcXVpcmVkLFxuICAgICAgICBzZWxlY3RhYmxlOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgc2VsZWN0YWJsZU11bHRpcGxlOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgaW5pdGlhbFNlbGVjdGlvbk1vZGVsOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXksXG4gICAgICAgIG9uU2VsZWN0aW9uQ2hhbmdlOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgZm9yY2VFeHBhbmQ6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICAvLyBPcHRpb25hbCBjdXJyZW50bHkgc2VsZWN0ZWQgZGV0ZWN0aW9uXG4gICAgICAgIG5vZGVJc1NlbGVjdGVkOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgLy8gT3B0aW9uYWwgY2hlY2tib3hlc1xuICAgICAgICBjaGVja2JveGVzOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXksXG4gICAgICAgIGNoZWNrYm94ZXNWYWx1ZXM6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgICAgIGNoZWNrYm94ZXNDb21wdXRlU3RhdHVzOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgb25DaGVja2JveENoZWNrOiBSZWFjdC5Qcm9wVHlwZXMuZnVuY1xuICAgIH0sXG5cbiAgICBnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uIGdldERlZmF1bHRQcm9wcygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNob3dSb290OiB0cnVlLFxuICAgICAgICAgICAgb25Ob2RlU2VsZWN0OiB0aGlzLm9uTm9kZVNlbGVjdFxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBvbk5vZGVTZWxlY3Q6IGZ1bmN0aW9uIG9uTm9kZVNlbGVjdChub2RlKSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uTm9kZVNlbGVjdCkge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5vbk5vZGVTZWxlY3Qobm9kZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLmRhdGFNb2RlbC5zZXRTZWxlY3RlZE5vZGVzKFtub2RlXSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ3VsJyxcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiB0aGlzLnByb3BzLmNsYXNzTmFtZSB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChTaW1wbGVUcmVlTm9kZSwge1xuICAgICAgICAgICAgICAgIGNoaWxkcmVuT25seTogIXRoaXMucHJvcHMuc2hvd1Jvb3QsXG4gICAgICAgICAgICAgICAgZm9yY2VFeHBhbmQ6IHRoaXMucHJvcHMuZm9yY2VFeHBhbmQsXG4gICAgICAgICAgICAgICAgbm9kZTogdGhpcy5wcm9wcy5ub2RlID8gdGhpcy5wcm9wcy5ub2RlIDogdGhpcy5wcm9wcy5kYXRhTW9kZWwuZ2V0Um9vdE5vZGUoKSxcbiAgICAgICAgICAgICAgICBkYXRhTW9kZWw6IHRoaXMucHJvcHMuZGF0YU1vZGVsLFxuICAgICAgICAgICAgICAgIG9uTm9kZVNlbGVjdDogdGhpcy5vbk5vZGVTZWxlY3QsXG4gICAgICAgICAgICAgICAgbm9kZUlzU2VsZWN0ZWQ6IHRoaXMucHJvcHMubm9kZUlzU2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgZm9yY2VMYWJlbDogdGhpcy5wcm9wcy5yb290TGFiZWwsXG4gICAgICAgICAgICAgICAgY2hlY2tib3hlczogdGhpcy5wcm9wcy5jaGVja2JveGVzLFxuICAgICAgICAgICAgICAgIGNoZWNrYm94ZXNWYWx1ZXM6IHRoaXMucHJvcHMuY2hlY2tib3hlc1ZhbHVlcyxcbiAgICAgICAgICAgICAgICBjaGVja2JveGVzQ29tcHV0ZVN0YXR1czogdGhpcy5wcm9wcy5jaGVja2JveGVzQ29tcHV0ZVN0YXR1cyxcbiAgICAgICAgICAgICAgICBvbkNoZWNrYm94Q2hlY2s6IHRoaXMucHJvcHMub25DaGVja2JveENoZWNrLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkSXRlbVN0eWxlOiB0aGlzLnByb3BzLnNlbGVjdGVkSXRlbVN0eWxlLFxuICAgICAgICAgICAgICAgIGdldEl0ZW1TdHlsZTogdGhpcy5wcm9wcy5nZXRJdGVtU3R5bGVcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcblxudmFyIEZvbGRlcnNUcmVlID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnRm9sZGVyc1RyZWUnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbykuaXNSZXF1aXJlZCxcbiAgICAgICAgZGF0YU1vZGVsOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpb0RhdGFNb2RlbCkuaXNSZXF1aXJlZCxcbiAgICAgICAgY2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICBvbk5vZGVTZWxlY3RlZDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGRyYWdnYWJsZTogUmVhY3QuUHJvcFR5cGVzLmJvb2xcbiAgICB9LFxuXG4gICAgbm9kZU9ic2VydmVyOiBmdW5jdGlvbiBub2RlT2JzZXJ2ZXIoKSB7XG4gICAgICAgIHZhciByID0gdGhpcy5wcm9wcy5kYXRhTW9kZWwuZ2V0Um9vdE5vZGUoKTtcbiAgICAgICAgaWYgKCFyLmlzTG9hZGVkKCkpIHtcbiAgICAgICAgICAgIHIub2JzZXJ2ZU9uY2UoXCJsb2FkZWRcIiwgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZvcmNlVXBkYXRlKCk7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZm9yY2VVcGRhdGUoKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHZhciBkbSA9IHRoaXMucHJvcHMuZGF0YU1vZGVsO1xuICAgICAgICB0aGlzLl9kbU9icyA9IHRoaXMubm9kZU9ic2VydmVyO1xuICAgICAgICBkbS5vYnNlcnZlKFwiY29udGV4dF9jaGFuZ2VkXCIsIHRoaXMuX2RtT2JzKTtcbiAgICAgICAgZG0ub2JzZXJ2ZShcInJvb3Rfbm9kZV9jaGFuZ2VkXCIsIHRoaXMuX2RtT2JzKTtcbiAgICAgICAgdGhpcy5ub2RlT2JzZXJ2ZXIoKTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFVubW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICBpZiAodGhpcy5fZG1PYnMpIHtcbiAgICAgICAgICAgIHZhciBkbSA9IHRoaXMucHJvcHMuZGF0YU1vZGVsO1xuICAgICAgICAgICAgZG0uc3RvcE9ic2VydmluZyhcImNvbnRleHRfY2hhbmdlZFwiLCB0aGlzLl9kbU9icyk7XG4gICAgICAgICAgICBkbS5zdG9wT2JzZXJ2aW5nKFwicm9vdF9ub2RlX2NoYW5nZWRcIiwgdGhpcy5fZG1PYnMpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHRyZWVOb2RlU2VsZWN0ZWQ6IGZ1bmN0aW9uIHRyZWVOb2RlU2VsZWN0ZWQobikge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5vbk5vZGVTZWxlY3RlZCkge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5vbk5vZGVTZWxlY3RlZChuKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuZGF0YU1vZGVsLnJlcXVpcmVDb250ZXh0Q2hhbmdlKG4pO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIG5vZGVJc1NlbGVjdGVkOiBmdW5jdGlvbiBub2RlSXNTZWxlY3RlZChuKSB7XG4gICAgICAgIHJldHVybiBuID09PSB0aGlzLnByb3BzLmRhdGFNb2RlbC5nZXRDb250ZXh0Tm9kZSgpO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuZHJhZ2dhYmxlKSB7XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChQeWRpb0NvbXBvbmVudHMuRE5EVHJlZVZpZXcsIHtcbiAgICAgICAgICAgICAgICBvbk5vZGVTZWxlY3Q6IHRoaXMudHJlZU5vZGVTZWxlY3RlZCxcbiAgICAgICAgICAgICAgICBub2RlSXNTZWxlY3RlZDogdGhpcy5ub2RlSXNTZWxlY3RlZCxcbiAgICAgICAgICAgICAgICBkYXRhTW9kZWw6IHRoaXMucHJvcHMuZGF0YU1vZGVsLFxuICAgICAgICAgICAgICAgIG5vZGU6IHRoaXMucHJvcHMuZGF0YU1vZGVsLmdldFJvb3ROb2RlKCksXG4gICAgICAgICAgICAgICAgc2hvd1Jvb3Q6IHRoaXMucHJvcHMuc2hvd1Jvb3QgPyB0cnVlIDogZmFsc2UsXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRJdGVtU3R5bGU6IHRoaXMucHJvcHMuc2VsZWN0ZWRJdGVtU3R5bGUsXG4gICAgICAgICAgICAgICAgZ2V0SXRlbVN0eWxlOiB0aGlzLnByb3BzLmdldEl0ZW1TdHlsZSxcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiZm9sZGVycy10cmVlXCIgKyAodGhpcy5wcm9wcy5jbGFzc05hbWUgPyAnICcgKyB0aGlzLnByb3BzLmNsYXNzTmFtZSA6ICcnKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChQeWRpb0NvbXBvbmVudHMuVHJlZVZpZXcsIHtcbiAgICAgICAgICAgICAgICBvbk5vZGVTZWxlY3Q6IHRoaXMudHJlZU5vZGVTZWxlY3RlZCxcbiAgICAgICAgICAgICAgICBub2RlSXNTZWxlY3RlZDogdGhpcy5ub2RlSXNTZWxlY3RlZCxcbiAgICAgICAgICAgICAgICBkYXRhTW9kZWw6IHRoaXMucHJvcHMuZGF0YU1vZGVsLFxuICAgICAgICAgICAgICAgIG5vZGU6IHRoaXMucHJvcHMuZGF0YU1vZGVsLmdldFJvb3ROb2RlKCksXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRJdGVtU3R5bGU6IHRoaXMucHJvcHMuc2VsZWN0ZWRJdGVtU3R5bGUsXG4gICAgICAgICAgICAgICAgZ2V0SXRlbVN0eWxlOiB0aGlzLnByb3BzLmdldEl0ZW1TdHlsZSxcbiAgICAgICAgICAgICAgICBzaG93Um9vdDogdGhpcy5wcm9wcy5zaG93Um9vdCA/IHRydWUgOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiZm9sZGVycy10cmVlXCIgKyAodGhpcy5wcm9wcy5jbGFzc05hbWUgPyAnICcgKyB0aGlzLnByb3BzLmNsYXNzTmFtZSA6ICcnKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbn0pO1xuXG5leHBvcnRzLlRyZWVWaWV3ID0gVHJlZVZpZXc7XG5leHBvcnRzLkRORFRyZWVWaWV3ID0gRE5EVHJlZVZpZXc7XG5leHBvcnRzLkZvbGRlcnNUcmVlID0gRm9sZGVyc1RyZWU7XG4iXX0=